Merge branches 'upstream/core', 'upstream/xenfs' and 'upstream/evtchn' into upstream...
authorJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Mon, 22 Nov 2010 20:22:42 +0000 (12:22 -0800)
committerJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Mon, 22 Nov 2010 20:22:42 +0000 (12:22 -0800)
* upstream/core:
  xen/events: Use PIRQ instead of GSI value when unmapping MSI/MSI-X irqs.
  xen: set IO permission early (before early_cpu_init())
  xen: re-enable boot-time ballooning
  xen/balloon: make sure we only include remaining extra ram
  xen/balloon: the balloon_lock is useless
  xen: add extra pages to balloon
  xen/events: use locked set|clear_bit() for cpu_evtchn_mask
  xen/evtchn: clear secondary CPUs' cpu_evtchn_mask[] after restore
  xen: implement XENMEM_machphys_mapping

* upstream/xenfs:
  Revert "xen/privcmd: create address space to allow writable mmaps"
  xen/xenfs: update xenfs_mount for new prototype
  xen: fix header export to userspace
  xen: set vma flag VM_PFNMAP in the privcmd mmap file_op
  xen: xenfs: privcmd: check put_user() return code

* upstream/evtchn:
  xen: make evtchn's name less generic
  xen/evtchn: the evtchn device is non-seekable
  xen/evtchn: add missing static
  xen/evtchn: Fix name of Xen event-channel device
  xen/evtchn: don't do unbind_from_irqhandler under spinlock
  xen/evtchn: remove spurious barrier
  xen/evtchn: ports start enabled
  xen/evtchn: dynamically allocate port_user array
  xen/evtchn: track enabled state for each port

1623 files changed:
Documentation/ABI/obsolete/proc-pid-oom_adj [new file with mode: 0644]
Documentation/DocBook/kgdb.tmpl
Documentation/arm/OMAP/DSS
Documentation/block/switching-sched.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/Locking
Documentation/filesystems/xfs-delayed-logging-design.txt
Documentation/i2c/busses/i2c-i801
Documentation/kernel-parameters.txt
Documentation/leds-class.txt
Documentation/leds/leds-lp5521.txt [new file with mode: 0644]
Documentation/leds/leds-lp5523.txt [new file with mode: 0644]
Documentation/networking/ip-sysctl.txt
Documentation/rbtree.txt
Documentation/scsi/ChangeLog.megaraid_sas
Documentation/sysctl/kernel.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/arm/Kconfig
arch/arm/common/gic.c
arch/arm/configs/mx51_defconfig
arch/arm/include/asm/hardware/cache-l2x0.h
arch/arm/include/asm/hardware/it8152.h
arch/arm/include/asm/kgdb.h
arch/arm/include/asm/memblock.h
arch/arm/include/asm/outercache.h
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/kgdb.c
arch/arm/kernel/machine_kexec.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/stacktrace.c
arch/arm/kernel/traps.c
arch/arm/kernel/unwind.c
arch/arm/kernel/vmlinux.lds.S
arch/arm/mach-ep93xx/include/mach/dma.h
arch/arm/mach-imx/mach-mx27_3ds.c
arch/arm/mach-ixp2000/core.c
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/d2net_v2-setup.c
arch/arm/mach-kirkwood/lacie_v2-common.c
arch/arm/mach-kirkwood/lacie_v2-common.h
arch/arm/mach-kirkwood/mpp.c
arch/arm/mach-kirkwood/netspace_v2-setup.c
arch/arm/mach-kirkwood/netxbig_v2-setup.c
arch/arm/mach-kirkwood/ts41x-setup.c
arch/arm/mach-mmp/include/mach/cputype.h
arch/arm/mach-msm/Kconfig
arch/arm/mach-msm/board-halibut.c
arch/arm/mach-msm/include/mach/debug-macro.S
arch/arm/mach-msm/iommu_dev.c
arch/arm/mach-msm/timer.c
arch/arm/mach-mv78xx0/mpp.c
arch/arm/mach-mx25/Kconfig
arch/arm/mach-mx25/mach-mx25_3ds.c
arch/arm/mach-mx3/Kconfig
arch/arm/mach-mx3/devices.c
arch/arm/mach-mx3/mach-mx31_3ds.c
arch/arm/mach-mx3/mach-mx35_3ds.c
arch/arm/mach-mx5/Kconfig
arch/arm/mach-mx5/Makefile
arch/arm/mach-mx5/board-mx51_babbage.c
arch/arm/mach-mx5/clock-mx51.c
arch/arm/mach-mx5/cpu_op-mx51.c [new file with mode: 0644]
arch/arm/mach-mx5/cpu_op-mx51.h [new file with mode: 0644]
arch/arm/mach-mx5/devices-imx51.h
arch/arm/mach-omap1/devices.c
arch/arm/mach-omap1/include/mach/camera.h
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/omap4-common.c
arch/arm/mach-orion5x/mpp.c
arch/arm/mach-orion5x/ts78xx-setup.c
arch/arm/mach-pxa/cm-x2xx.c
arch/arm/mach-pxa/saar.c
arch/arm/mach-s3c2410/h1940-bluetooth.c
arch/arm/mach-s3c2410/include/mach/gpio.h
arch/arm/mach-s3c2410/include/mach/h1940-latch.h
arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
arch/arm/mach-s3c2410/include/mach/vmalloc.h
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-s3c2412/s3c2412.c
arch/arm/mach-s3c2416/Kconfig
arch/arm/mach-s3c2416/Makefile
arch/arm/mach-s3c2416/irq.c
arch/arm/mach-s3c2416/pm.c [new file with mode: 0644]
arch/arm/mach-s3c2416/s3c2416.c
arch/arm/mach-s3c2440/Kconfig
arch/arm/mach-s3c2440/mach-rx1950.c
arch/arm/mach-s3c2440/s3c244x.c
arch/arm/mach-s3c2443/s3c2443.c
arch/arm/mach-s3c24a0/include/mach/vmalloc.h
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/Makefile
arch/arm/mach-s3c64xx/dev-audio.c
arch/arm/mach-s3c64xx/gpiolib.c
arch/arm/mach-s3c64xx/include/mach/vmalloc.h
arch/arm/mach-s3c64xx/mach-mini6410.c [new file with mode: 0644]
arch/arm/mach-s3c64xx/mach-real6410.c
arch/arm/mach-s3c64xx/setup-fb-24bpp.c
arch/arm/mach-s3c64xx/setup-ide.c
arch/arm/mach-s3c64xx/setup-keypad.c
arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
arch/arm/mach-s5p6442/Kconfig
arch/arm/mach-s5p6442/clock.c
arch/arm/mach-s5p6442/dev-audio.c
arch/arm/mach-s5p6442/dev-spi.c
arch/arm/mach-s5p6442/dma.c
arch/arm/mach-s5p6442/include/mach/regs-clock.h
arch/arm/mach-s5p6442/include/mach/vmalloc.h
arch/arm/mach-s5p64x0/Kconfig
arch/arm/mach-s5p64x0/clock-s5p6440.c
arch/arm/mach-s5p64x0/clock-s5p6450.c
arch/arm/mach-s5p64x0/clock.c
arch/arm/mach-s5p64x0/dev-audio.c
arch/arm/mach-s5p64x0/dev-spi.c
arch/arm/mach-s5p64x0/dma.c
arch/arm/mach-s5p64x0/include/mach/regs-clock.h
arch/arm/mach-s5p64x0/include/mach/vmalloc.h
arch/arm/mach-s5p64x0/setup-i2c0.c
arch/arm/mach-s5p64x0/setup-i2c1.c
arch/arm/mach-s5pc100/Kconfig
arch/arm/mach-s5pc100/Makefile
arch/arm/mach-s5pc100/clock.c
arch/arm/mach-s5pc100/dev-audio.c
arch/arm/mach-s5pc100/dev-spi.c
arch/arm/mach-s5pc100/dma.c
arch/arm/mach-s5pc100/gpiolib.c
arch/arm/mach-s5pc100/include/mach/gpio.h
arch/arm/mach-s5pc100/include/mach/irqs.h
arch/arm/mach-s5pc100/include/mach/map.h
arch/arm/mach-s5pc100/include/mach/regs-gpio.h
arch/arm/mach-s5pc100/include/mach/vmalloc.h
arch/arm/mach-s5pc100/irq-gpio.c [deleted file]
arch/arm/mach-s5pc100/mach-smdkc100.c
arch/arm/mach-s5pc100/setup-fb-24bpp.c
arch/arm/mach-s5pc100/setup-i2c0.c
arch/arm/mach-s5pc100/setup-i2c1.c
arch/arm/mach-s5pc100/setup-ide.c
arch/arm/mach-s5pc100/setup-keypad.c
arch/arm/mach-s5pc100/setup-sdhci-gpio.c
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/Makefile
arch/arm/mach-s5pv210/clock.c
arch/arm/mach-s5pv210/cpu.c
arch/arm/mach-s5pv210/cpufreq.c [new file with mode: 0644]
arch/arm/mach-s5pv210/dev-audio.c
arch/arm/mach-s5pv210/dev-spi.c
arch/arm/mach-s5pv210/dma.c
arch/arm/mach-s5pv210/gpiolib.c
arch/arm/mach-s5pv210/include/mach/irqs.h
arch/arm/mach-s5pv210/include/mach/map.h
arch/arm/mach-s5pv210/include/mach/pm-core.h [new file with mode: 0644]
arch/arm/mach-s5pv210/include/mach/regs-clock.h
arch/arm/mach-s5pv210/include/mach/regs-gpio.h
arch/arm/mach-s5pv210/include/mach/regs-sys.h [new file with mode: 0644]
arch/arm/mach-s5pv210/include/mach/vmalloc.h
arch/arm/mach-s5pv210/mach-aquila.c
arch/arm/mach-s5pv210/mach-goni.c
arch/arm/mach-s5pv210/mach-smdkc110.c
arch/arm/mach-s5pv210/mach-smdkv210.c
arch/arm/mach-s5pv210/mach-torbreck.c [new file with mode: 0644]
arch/arm/mach-s5pv210/pm.c [new file with mode: 0644]
arch/arm/mach-s5pv210/setup-fb-24bpp.c
arch/arm/mach-s5pv210/setup-i2c0.c
arch/arm/mach-s5pv210/setup-i2c1.c
arch/arm/mach-s5pv210/setup-i2c2.c
arch/arm/mach-s5pv210/setup-ide.c
arch/arm/mach-s5pv210/setup-keypad.c
arch/arm/mach-s5pv210/setup-sdhci-gpio.c
arch/arm/mach-s5pv210/sleep.S [new file with mode: 0644]
arch/arm/mach-s5pv310/Kconfig
arch/arm/mach-s5pv310/Makefile
arch/arm/mach-s5pv310/clock.c
arch/arm/mach-s5pv310/cpu.c
arch/arm/mach-s5pv310/gpiolib.c [new file with mode: 0644]
arch/arm/mach-s5pv310/hotplug.c [new file with mode: 0644]
arch/arm/mach-s5pv310/include/mach/irqs.h
arch/arm/mach-s5pv310/include/mach/map.h
arch/arm/mach-s5pv310/include/mach/regs-clock.h
arch/arm/mach-s5pv310/include/mach/regs-gpio.h [new file with mode: 0644]
arch/arm/mach-s5pv310/include/mach/regs-srom.h [new file with mode: 0644]
arch/arm/mach-s5pv310/include/mach/vmalloc.h
arch/arm/mach-s5pv310/irq-combiner.c
arch/arm/mach-s5pv310/irq-eint.c [new file with mode: 0644]
arch/arm/mach-s5pv310/mach-smdkc210.c [new file with mode: 0644]
arch/arm/mach-s5pv310/mach-smdkv310.c
arch/arm/mach-s5pv310/mach-universal_c210.c
arch/arm/mach-s5pv310/setup-i2c0.c
arch/arm/mach-s5pv310/setup-i2c1.c
arch/arm/mach-s5pv310/setup-i2c2.c
arch/arm/mach-s5pv310/setup-i2c3.c [new file with mode: 0644]
arch/arm/mach-s5pv310/setup-i2c4.c [new file with mode: 0644]
arch/arm/mach-s5pv310/setup-i2c5.c [new file with mode: 0644]
arch/arm/mach-s5pv310/setup-i2c6.c [new file with mode: 0644]
arch/arm/mach-s5pv310/setup-i2c7.c [new file with mode: 0644]
arch/arm/mach-s5pv310/setup-sdhci-gpio.c [new file with mode: 0644]
arch/arm/mach-s5pv310/setup-sdhci.c [new file with mode: 0644]
arch/arm/mach-sa1100/cpu-sa1100.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/clock-sh7367.c
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-shmobile/clock-sh7377.c
arch/arm/mach-shmobile/include/mach/gpio.h
arch/arm/mach-shmobile/include/mach/sh7372.h
arch/arm/mach-shmobile/intc-sh7372.c
arch/arm/mach-shmobile/pfc-sh7372.c
arch/arm/mach-shmobile/setup-sh7367.c
arch/arm/mach-shmobile/setup-sh7372.c
arch/arm/mach-shmobile/setup-sh7377.c
arch/arm/mach-u300/clock.c
arch/arm/mach-u300/core.c
arch/arm/mach-u300/include/mach/u300-regs.h
arch/arm/mach-u300/spi.c
arch/arm/mach-ux500/cpu.c
arch/arm/mach-vexpress/ct-ca9x4.c
arch/arm/mm/Kconfig
arch/arm/mm/cache-fa.S
arch/arm/mm/cache-l2x0.c
arch/arm/mm/cache-v3.S
arch/arm/mm/cache-v4.S
arch/arm/mm/cache-v4wb.S
arch/arm/mm/cache-v4wt.S
arch/arm/mm/dma-mapping.c
arch/arm/mm/fault-armv.c
arch/arm/mm/init.c
arch/arm/mm/mmu.c
arch/arm/mm/proc-arm1020.S
arch/arm/mm/proc-arm1020e.S
arch/arm/mm/proc-arm1022.S
arch/arm/mm/proc-arm1026.S
arch/arm/mm/proc-arm920.S
arch/arm/mm/proc-arm922.S
arch/arm/mm/proc-arm925.S
arch/arm/mm/proc-arm926.S
arch/arm/mm/proc-arm940.S
arch/arm/mm/proc-arm946.S
arch/arm/mm/proc-feroceon.S
arch/arm/mm/proc-xsc3.S
arch/arm/mm/proc-xscale.S
arch/arm/plat-mxc/Makefile
arch/arm/plat-mxc/cpufreq.c [new file with mode: 0644]
arch/arm/plat-mxc/devices/Kconfig
arch/arm/plat-mxc/devices/Makefile
arch/arm/plat-mxc/devices/platform-gpio_keys.c [new file with mode: 0644]
arch/arm/plat-mxc/gpio.c
arch/arm/plat-mxc/include/mach/devices-common.h
arch/arm/plat-mxc/include/mach/iomux-mx51.h
arch/arm/plat-mxc/include/mach/mx31.h
arch/arm/plat-mxc/include/mach/mx35.h
arch/arm/plat-mxc/include/mach/mxc.h
arch/arm/plat-omap/devices.c
arch/arm/plat-omap/dma.c
arch/arm/plat-orion/include/plat/pcie.h
arch/arm/plat-orion/pcie.c
arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
arch/arm/plat-s3c24xx/Kconfig
arch/arm/plat-s3c24xx/common-smdk.c
arch/arm/plat-s3c24xx/gpiolib.c
arch/arm/plat-s5p/Kconfig
arch/arm/plat-s5p/Makefile
arch/arm/plat-s5p/clock.c
arch/arm/plat-s5p/include/plat/irqs.h
arch/arm/plat-s5p/include/plat/map-s5p.h
arch/arm/plat-s5p/include/plat/s5p-clock.h
arch/arm/plat-s5p/irq-eint.c
arch/arm/plat-s5p/irq-gpioint.c [new file with mode: 0644]
arch/arm/plat-s5p/irq-pm.c [new file with mode: 0644]
arch/arm/plat-s5p/pm.c [new file with mode: 0644]
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/dev-hsmmc.c
arch/arm/plat-samsung/dev-hsmmc1.c
arch/arm/plat-samsung/dev-hsmmc2.c
arch/arm/plat-samsung/dev-hsmmc3.c
arch/arm/plat-samsung/dev-i2c2.c
arch/arm/plat-samsung/dev-i2c3.c [new file with mode: 0644]
arch/arm/plat-samsung/dev-i2c4.c [new file with mode: 0644]
arch/arm/plat-samsung/dev-i2c5.c [new file with mode: 0644]
arch/arm/plat-samsung/dev-i2c6.c [new file with mode: 0644]
arch/arm/plat-samsung/dev-i2c7.c [new file with mode: 0644]
arch/arm/plat-samsung/gpio-config.c
arch/arm/plat-samsung/gpio.c
arch/arm/plat-samsung/include/plat/audio.h
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
arch/arm/plat-samsung/include/plat/gpio-cfg.h
arch/arm/plat-samsung/include/plat/gpio-core.h
arch/arm/plat-samsung/include/plat/iic.h
arch/arm/plat-samsung/include/plat/map-base.h
arch/arm/plat-samsung/include/plat/nand-core.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/sdhci.h
arch/arm/plat-samsung/pm-gpio.c
arch/arm/plat-samsung/s3c-pl330.c
arch/blackfin/kernel/kgdb.c
arch/ia64/kernel/perfmon.c
arch/m68k/include/asm/irqflags.h
arch/m68k/include/asm/machdep.h
arch/mips/Kconfig
arch/mips/Kconfig.debug
arch/mips/Makefile
arch/mips/ar7/gpio.c
arch/mips/ar7/platform.c
arch/mips/ar7/prom.c
arch/mips/ar7/setup.c
arch/mips/bcm63xx/cpu.c
arch/mips/cavium-octeon/Kconfig
arch/mips/cavium-octeon/csrc-octeon.c
arch/mips/cavium-octeon/dma-octeon.c
arch/mips/cavium-octeon/executive/cvmx-l2c.c
arch/mips/cavium-octeon/octeon-platform.c
arch/mips/cavium-octeon/serial.c
arch/mips/cavium-octeon/setup.c
arch/mips/include/asm/atomic.h
arch/mips/include/asm/bitops.h
arch/mips/include/asm/bootinfo.h
arch/mips/include/asm/cmpxchg.h
arch/mips/include/asm/cpu.h
arch/mips/include/asm/device.h
arch/mips/include/asm/dma-mapping.h
arch/mips/include/asm/dma.h
arch/mips/include/asm/local.h
arch/mips/include/asm/mach-ar7/ar7.h
arch/mips/include/asm/mach-ar7/gpio.h
arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h [new file with mode: 0644]
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
arch/mips/include/asm/mach-ip27/dma-coherence.h
arch/mips/include/asm/mach-ip32/dma-coherence.h
arch/mips/include/asm/mach-jazz/dma-coherence.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/octeon/cvmx-agl-defs.h
arch/mips/include/asm/octeon/cvmx-asm.h
arch/mips/include/asm/octeon/cvmx-ciu-defs.h
arch/mips/include/asm/octeon/cvmx-gpio-defs.h
arch/mips/include/asm/octeon/cvmx-iob-defs.h
arch/mips/include/asm/octeon/cvmx-ipd-defs.h
arch/mips/include/asm/octeon/cvmx-l2c-defs.h
arch/mips/include/asm/octeon/cvmx-l2c.h
arch/mips/include/asm/octeon/cvmx-l2d-defs.h
arch/mips/include/asm/octeon/cvmx-l2t-defs.h
arch/mips/include/asm/octeon/cvmx-led-defs.h
arch/mips/include/asm/octeon/cvmx-mio-defs.h
arch/mips/include/asm/octeon/cvmx-mixx-defs.h
arch/mips/include/asm/octeon/cvmx-npei-defs.h
arch/mips/include/asm/octeon/cvmx-npi-defs.h
arch/mips/include/asm/octeon/cvmx-pci-defs.h
arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
arch/mips/include/asm/octeon/cvmx-pescx-defs.h
arch/mips/include/asm/octeon/cvmx-pexp-defs.h
arch/mips/include/asm/octeon/cvmx-pow-defs.h
arch/mips/include/asm/octeon/cvmx-rnm-defs.h
arch/mips/include/asm/octeon/cvmx-smix-defs.h
arch/mips/include/asm/octeon/cvmx-uctlx-defs.h [new file with mode: 0644]
arch/mips/include/asm/octeon/octeon-model.h
arch/mips/include/asm/octeon/octeon.h
arch/mips/include/asm/octeon/pci-octeon.h
arch/mips/include/asm/perf_event.h [new file with mode: 0644]
arch/mips/include/asm/pgtable-64.h
arch/mips/include/asm/processor.h
arch/mips/include/asm/system.h
arch/mips/include/asm/thread_info.h
arch/mips/include/asm/uaccess.h
arch/mips/kernel/Makefile
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/irq.c
arch/mips/kernel/perf_event.c [new file with mode: 0644]
arch/mips/kernel/perf_event_mipsxx.c [new file with mode: 0644]
arch/mips/kernel/setup.c
arch/mips/kernel/traps.c
arch/mips/kernel/unaligned.c
arch/mips/loongson/Kconfig
arch/mips/math-emu/cp1emu.c
arch/mips/mm/c-octeon.c
arch/mips/mm/c-r4k.c
arch/mips/mm/dma-default.c
arch/mips/mm/fault.c
arch/mips/mm/sc-mips.c
arch/mips/mm/tlbex.c
arch/mips/mm/uasm.c
arch/mips/pci/pci-octeon.c
arch/mips/pci/pcie-octeon.c
arch/powerpc/Kconfig
arch/powerpc/include/asm/fsl_lbc.h
arch/powerpc/include/asm/kgdb.h
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/kvm.c
arch/powerpc/kvm/booke_interrupts.S
arch/powerpc/kvm/e500.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/kvm/timing.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/sysdev/fsl_lbc.c
arch/s390/Kconfig
arch/s390/hypfs/hypfs_diag.c
arch/s390/hypfs/inode.c
arch/s390/include/asm/dasd.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/early.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/kprobes.c
arch/s390/kernel/setup.c
arch/s390/kernel/sysinfo.c
arch/s390/kernel/topology.c
arch/s390/kernel/vdso32/clock_getres.S
arch/s390/kernel/vdso32/clock_gettime.S
arch/s390/kernel/vdso64/clock_getres.S
arch/s390/kernel/vdso64/clock_gettime.S
arch/sh/Kconfig
arch/sh/Makefile
arch/sh/boards/Kconfig
arch/sh/boards/Makefile
arch/sh/boards/board-edosk7705.c [new file with mode: 0644]
arch/sh/boards/board-secureedge5410.c [new file with mode: 0644]
arch/sh/boards/mach-ap325rxa/setup.c
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boards/mach-edosk7705/Makefile [deleted file]
arch/sh/boards/mach-edosk7705/io.c [deleted file]
arch/sh/boards/mach-edosk7705/setup.c [deleted file]
arch/sh/boards/mach-kfr2r09/setup.c
arch/sh/boards/mach-microdev/io.c
arch/sh/boards/mach-microdev/setup.c
arch/sh/boards/mach-migor/setup.c
arch/sh/boards/mach-se/7206/Makefile
arch/sh/boards/mach-se/7206/io.c [deleted file]
arch/sh/boards/mach-se/7206/irq.c
arch/sh/boards/mach-se/7206/setup.c
arch/sh/boards/mach-se/770x/Makefile
arch/sh/boards/mach-se/770x/io.c [deleted file]
arch/sh/boards/mach-se/770x/setup.c
arch/sh/boards/mach-se/7724/setup.c
arch/sh/boards/mach-se/7751/Makefile
arch/sh/boards/mach-se/7751/io.c [deleted file]
arch/sh/boards/mach-se/7751/setup.c
arch/sh/boards/mach-snapgear/Makefile [deleted file]
arch/sh/boards/mach-snapgear/io.c [deleted file]
arch/sh/boards/mach-snapgear/setup.c [deleted file]
arch/sh/boards/mach-systemh/Makefile [deleted file]
arch/sh/boards/mach-systemh/io.c [deleted file]
arch/sh/boards/mach-systemh/irq.c [deleted file]
arch/sh/boards/mach-systemh/setup.c [deleted file]
arch/sh/configs/secureedge5410_defconfig [new file with mode: 0644]
arch/sh/configs/snapgear_defconfig [deleted file]
arch/sh/configs/systemh_defconfig [deleted file]
arch/sh/include/asm/addrspace.h
arch/sh/include/asm/pgtable.h
arch/sh/include/asm/system.h
arch/sh/include/asm/system_32.h
arch/sh/include/asm/system_64.h
arch/sh/include/asm/uncached.h
arch/sh/include/mach-common/mach/edosk7705.h [deleted file]
arch/sh/include/mach-common/mach/microdev.h
arch/sh/include/mach-common/mach/secureedge5410.h [new file with mode: 0644]
arch/sh/include/mach-common/mach/snapgear.h [deleted file]
arch/sh/include/mach-common/mach/systemh7751.h [deleted file]
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
arch/sh/mm/Kconfig
arch/sh/mm/consistent.c
arch/sh/mm/uncached.c
arch/sh/tools/mach-types
arch/sparc/Kconfig
arch/sparc/include/asm/jump_label.h
arch/sparc/kernel/irq_32.c
arch/sparc/kernel/leon_smp.c
arch/sparc/kernel/rtrap_32.S
arch/sparc/kernel/rtrap_64.S
arch/sparc/mm/fault_32.c
arch/tile/include/asm/highmem.h
arch/tile/include/asm/kmap_types.h
arch/tile/include/asm/pgtable.h
arch/tile/include/asm/stat.h
arch/tile/include/asm/unistd.h
arch/tile/kernel/compat.c
arch/tile/kernel/early_printk.c
arch/tile/kernel/hardwall.c
arch/tile/kernel/irq.c
arch/tile/kernel/machine_kexec.c
arch/tile/kernel/messaging.c
arch/tile/kernel/ptrace.c
arch/tile/kernel/reboot.c
arch/tile/kernel/setup.c
arch/tile/kernel/signal.c
arch/tile/kernel/smp.c
arch/tile/kernel/time.c
arch/tile/lib/memcpy_tile64.c
arch/tile/mm/highmem.c
arch/tile/mm/init.c
arch/tile/mm/pgtable.c
arch/um/include/asm/ptrace-generic.h
arch/um/kernel/ptrace.c
arch/x86/Makefile_32.cpu
arch/x86/include/asm/apic.h
arch/x86/include/asm/uv/uv_hub.h
arch/x86/include/asm/uv/uv_mmrs.h
arch/x86/kernel/alternative.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/perf_event_amd.c
arch/x86/kernel/irq_32.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/microcode_amd.c
arch/x86/kernel/mmconf-fam10h_64.c
arch/x86/kernel/pvclock.c
arch/x86/kvm/mmu.c
arch/x86/kvm/x86.c
arch/x86/mm/numa_64.c
arch/x86/mm/tlb.c
arch/x86/pci/acpi.c
arch/x86/pci/xen.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/xen/mmu.c
block/blk-core.c
block/blk-ioc.c
block/blk-map.c
block/compat_ioctl.c
block/elevator.c
block/ioctl.c
block/scsi_ioctl.c
crypto/pcrypt.c
drivers/Makefile
drivers/acpi/debugfs.c
drivers/ata/libata-scsi.c
drivers/ata/pata_legacy.c
drivers/ata/pata_octeon_cf.c
drivers/atm/solos-attrlist.c
drivers/atm/solos-pci.c
drivers/base/devtmpfs.c
drivers/base/power/runtime.c
drivers/block/aoe/aoeblk.c
drivers/block/cciss.c
drivers/block/cciss.h
drivers/block/drbd/drbd_actlog.c
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_proc.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_req.c
drivers/block/drbd/drbd_worker.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/block/xen-blkfront.c
drivers/bluetooth/btusb.c
drivers/char/.gitignore [deleted file]
drivers/char/Makefile
drivers/char/agp/intel-gtt.c
drivers/char/agp/parisc-agp.c
drivers/char/amiserial.c
drivers/char/consolemap.c [deleted file]
drivers/char/cp437.uni [deleted file]
drivers/char/defkeymap.c_shipped [deleted file]
drivers/char/defkeymap.map [deleted file]
drivers/char/i8k.c
drivers/char/keyboard.c [deleted file]
drivers/char/n_gsm.c [deleted file]
drivers/char/n_hdlc.c [deleted file]
drivers/char/n_r3964.c [deleted file]
drivers/char/n_tty.c [deleted file]
drivers/char/nozomi.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/pty.c [deleted file]
drivers/char/selection.c [deleted file]
drivers/char/sysrq.c [deleted file]
drivers/char/tty_audit.c [deleted file]
drivers/char/tty_buffer.c [deleted file]
drivers/char/tty_io.c [deleted file]
drivers/char/tty_ioctl.c [deleted file]
drivers/char/tty_ldisc.c [deleted file]
drivers/char/tty_mutex.c [deleted file]
drivers/char/tty_port.c [deleted file]
drivers/char/vc_screen.c [deleted file]
drivers/char/vt.c [deleted file]
drivers/char/vt_ioctl.c [deleted file]
drivers/clocksource/sh_cmt.c
drivers/clocksource/sh_mtu2.c
drivers/clocksource/sh_tmu.c
drivers/crypto/n2_core.c
drivers/crypto/padlock-aes.c
drivers/dma/Kconfig
drivers/firewire/ohci.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_evict.c
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_opregion.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_fence.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_bo_manager.c
drivers/gpu/drm/ttm/ttm_tt.c
drivers/gpu/drm/via/via_dmablit.c
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
drivers/gpu/stub/Kconfig
drivers/hwmon/ad7414.c
drivers/hwmon/adt7470.c
drivers/hwmon/amc6821.c
drivers/hwmon/gpio-fan.c
drivers/hwmon/lm93.c
drivers/hwmon/lm95241.c
drivers/hwmon/ltc4261.c
drivers/hwmon/max6650.c
drivers/hwmon/w83795.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-intel-mid.c [new file with mode: 0644]
drivers/i2c/busses/i2c-nomadik.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-mux.c
drivers/ide/hpt366.c
drivers/ide/ide-dma.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/qib/qib_fs.c
drivers/input/input.c
drivers/input/keyboard/adp5588-keys.c
drivers/input/keyboard/atkbd.c
drivers/input/misc/pcf8574_keypad.c
drivers/input/mouse/appletouch.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/tablet/acecad.c
drivers/input/touchscreen/ad7879.c
drivers/input/touchscreen/bu21013_ts.c
drivers/isdn/capi/capifs.c
drivers/isdn/hisax/isar.c
drivers/isdn/mISDN/socket.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/led-class.c
drivers/leds/led-triggers.c
drivers/leds/leds-gpio.c
drivers/leds/leds-lp5521.c [new file with mode: 0644]
drivers/leds/leds-lp5523.c [new file with mode: 0644]
drivers/leds/leds-net5501.c
drivers/leds/ledtrig-timer.c
drivers/macintosh/adb-iop.c
drivers/md/bitmap.c
drivers/md/bitmap.h
drivers/md/faulty.c
drivers/md/md.c
drivers/md/md.h
drivers/md/raid1.c
drivers/md/raid1.h
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/IR/ir-keytable.c
drivers/media/Kconfig
drivers/media/common/saa7146_i2c.c
drivers/media/dvb/frontends/dibx000_common.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cx231xx/cx231xx-417.c
drivers/media/video/cx23885/cx23885-417.c
drivers/media/video/cx23885/cx23885-video.c
drivers/media/video/imx074.c
drivers/media/video/ir-kbd-i2c.c
drivers/media/video/mx2_camera.c
drivers/media/video/mx3_camera.c
drivers/media/video/omap1_camera.c
drivers/media/video/ov6650.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/se401.c
drivers/media/video/stk-webcam.c
drivers/media/video/tlg2300/pd-main.c
drivers/media/video/usbvideo/vicam.c
drivers/media/video/v4l2-dev.c
drivers/media/video/zoran/zoran.h
drivers/media/video/zoran/zoran_card.c
drivers/media/video/zoran/zoran_driver.c
drivers/misc/apds9802als.c
drivers/misc/bh1770glc.c
drivers/misc/ibmasm/ibmasmfs.c
drivers/misc/isl29020.c
drivers/misc/kgdbts.c
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/chips/cfi_probe.c
drivers/mtd/chips/cfi_util.c
drivers/mtd/devices/block2mtd.c
drivers/mtd/devices/m25p80.c
drivers/mtd/devices/phram.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/maps/bcm963xx-flash.c [new file with mode: 0644]
drivers/mtd/maps/gpio-addr-flash.c
drivers/mtd/maps/pcmciamtd.c
drivers/mtd/maps/physmap_of.c
drivers/mtd/mtd_blkdevs.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdpart.c
drivers/mtd/mtdsuper.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Makefile
drivers/mtd/nand/bf5xx_nand.c
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/denali.c
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_upm.c
drivers/mtd/nand/fsmc_nand.c [new file with mode: 0644]
drivers/mtd/nand/mpc5121_nfc.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_ids.c
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/ndfc.c
drivers/mtd/nand/omap2.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/mtd/nand/r852.c
drivers/mtd/nand/r852.h
drivers/mtd/ofpart.c
drivers/mtd/onenand/Kconfig
drivers/mtd/onenand/onenand_base.c
drivers/mtd/onenand/samsung.c
drivers/mtd/sm_ftl.h
drivers/net/Kconfig
drivers/net/atarilance.c
drivers/net/atlx/atl1.c
drivers/net/bnx2x/bnx2x.h
drivers/net/bnx2x/bnx2x_cmn.c
drivers/net/bnx2x/bnx2x_hsi.h
drivers/net/bnx2x/bnx2x_link.c
drivers/net/caif/caif_spi.c
drivers/net/caif/caif_spi_slave.c
drivers/net/can/at91_can.c
drivers/net/can/pch_can.c
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/sge.c
drivers/net/cxgb4/cxgb4_main.c
drivers/net/cxgb4vf/cxgb4vf_main.c
drivers/net/cxgb4vf/sge.c
drivers/net/cxgb4vf/t4vf_common.h
drivers/net/cxgb4vf/t4vf_hw.c
drivers/net/e1000e/82571.c
drivers/net/e1000e/e1000.h
drivers/net/e1000e/netdev.c
drivers/net/gianfar_ethtool.c
drivers/net/ibm_newemac/core.c
drivers/net/igb/igb_main.c
drivers/net/igbvf/netdev.c
drivers/net/ixgb/ixgb_main.c
drivers/net/ixgbe/ixgbe_dcb.c
drivers/net/ixgbe/ixgbe_dcb.h
drivers/net/ixgbe/ixgbe_dcb_82599.c
drivers/net/ixgbe/ixgbe_dcb_82599.h
drivers/net/ixgbe/ixgbe_main.c
drivers/net/jme.c
drivers/net/lib8390.c
drivers/net/netxen/netxen_nic_ctx.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/phy/marvell.c
drivers/net/qlcnic/qlcnic_main.c
drivers/net/r8169.c
drivers/net/skge.c
drivers/net/smsc911x.h
drivers/net/stmmac/stmmac_main.c
drivers/net/tulip/de2104x.c
drivers/net/ucc_geth.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/wireless/ath/ath5k/attach.c
drivers/net/wireless/ath/ath9k/ar9002_hw.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/usb.c
drivers/net/wireless/b43/sdio.c
drivers/net/wireless/ipw2x00/libipw_module.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/rt2x00/Kconfig
drivers/oprofile/buffer_sync.c
drivers/oprofile/cpu_buffer.c
drivers/oprofile/cpu_buffer.h
drivers/oprofile/oprofilefs.c
drivers/oprofile/timer_int.c
drivers/pci/bus.c
drivers/pci/hotplug/ibmphp_ebda.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/proc.c
drivers/pci/xen-pcifront.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/pd6729.h
drivers/pcmcia/pxa2xx_sharpsl.c
drivers/pcmcia/sa1100_assabet.c
drivers/pcmcia/sa1100_cerf.c
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/sa1100_h3600.c
drivers/pcmcia/sa1100_shannon.c
drivers/pcmcia/sa1100_simpad.c
drivers/pcmcia/soc_common.c
drivers/rapidio/rio.c
drivers/rtc/rtc-ds1302.c
drivers/rtc/rtc-sh.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_eckd.h
drivers/s390/char/tape_core.c
drivers/s390/char/tape_std.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/scsi/zfcp_fc.h
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_unit.c
drivers/scsi/bfa/bfa.h
drivers/scsi/bfa/bfa_cb_ioim.h
drivers/scsi/bfa/bfa_core.c
drivers/scsi/bfa/bfa_cs.h
drivers/scsi/bfa/bfa_defs.h
drivers/scsi/bfa/bfa_defs_fcs.h
drivers/scsi/bfa/bfa_defs_svc.h
drivers/scsi/bfa/bfa_drv.c
drivers/scsi/bfa/bfa_fc.h
drivers/scsi/bfa/bfa_fcbuild.c
drivers/scsi/bfa/bfa_fcpim.c
drivers/scsi/bfa/bfa_fcpim.h
drivers/scsi/bfa/bfa_fcs.c
drivers/scsi/bfa/bfa_fcs.h
drivers/scsi/bfa/bfa_fcs_fcpim.c
drivers/scsi/bfa/bfa_fcs_lport.c
drivers/scsi/bfa/bfa_fcs_rport.c
drivers/scsi/bfa/bfa_hw_cb.c
drivers/scsi/bfa/bfa_hw_ct.c
drivers/scsi/bfa/bfa_ioc.c
drivers/scsi/bfa/bfa_ioc.h
drivers/scsi/bfa/bfa_ioc_cb.c
drivers/scsi/bfa/bfa_ioc_ct.c
drivers/scsi/bfa/bfa_modules.h
drivers/scsi/bfa/bfa_os_inc.h
drivers/scsi/bfa/bfa_port.c
drivers/scsi/bfa/bfa_svc.c
drivers/scsi/bfa/bfa_svc.h
drivers/scsi/bfa/bfad.c
drivers/scsi/bfa/bfad_attr.c
drivers/scsi/bfa/bfad_debugfs.c
drivers/scsi/bfa/bfad_drv.h
drivers/scsi/bfa/bfad_im.c
drivers/scsi/bfa/bfi.h
drivers/scsi/bfa/bfi_ms.h
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
drivers/scsi/device_handler/scsi_dh_rdac.c
drivers/scsi/fcoe/fcoe.c
drivers/scsi/fcoe/libfcoe.c
drivers/scsi/gdth.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/libfc/fc_disc.c
drivers/scsi/libfc/fc_fcp.c
drivers/scsi/libfc/fc_lport.c
drivers/scsi/libfc/fc_rport.c
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_bsg.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_hw.h
drivers/scsi/lpfc/lpfc_hw4.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_sli4.h
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/osd/osd_initiator.c
drivers/scsi/pmcraid.c
drivers/scsi/pmcraid.h
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_bsg.c
drivers/scsi/qla2xxx/qla_bsg.h
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla4xxx/ql4_dbg.c
drivers/scsi/qla4xxx/ql4_def.h
drivers/scsi/qla4xxx/ql4_fw.h
drivers/scsi/qla4xxx/ql4_glbl.h
drivers/scsi/qla4xxx/ql4_init.c
drivers/scsi/qla4xxx/ql4_iocb.c
drivers/scsi/qla4xxx/ql4_isr.c
drivers/scsi/qla4xxx/ql4_mbx.c
drivers/scsi/qla4xxx/ql4_nx.c
drivers/scsi/qla4xxx/ql4_nx.h
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/qla4xxx/ql4_version.h
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/sd.c
drivers/scsi/sr_ioctl.c
drivers/serial/8250_pci.c
drivers/serial/bfin_5xx.c
drivers/serial/crisv10.c
drivers/serial/kgdboc.c
drivers/sh/clk/core.c
drivers/sh/intc/core.c
drivers/sh/intc/dynamic.c
drivers/sh/intc/virq.c
drivers/spi/spi.c
drivers/spi/spi_bfin5xx.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/ath6kl/Kconfig
drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
drivers/staging/ath6kl/os/linux/ar6000_drv.c
drivers/staging/ath6kl/os/linux/ar6000_raw_if.c
drivers/staging/ath6kl/os/linux/cfg80211.c
drivers/staging/ath6kl/os/linux/include/athendpack_linux.h [deleted file]
drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h [deleted file]
drivers/staging/autofs/init.c
drivers/staging/batman-adv/hard-interface.c
drivers/staging/batman-adv/routing.c
drivers/staging/batman-adv/routing.h
drivers/staging/batman-adv/unicast.c
drivers/staging/bcm/Bcmchar.c
drivers/staging/brcm80211/README
drivers/staging/brcm80211/TODO
drivers/staging/brcm80211/brcmfmac/dhd_linux.c
drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
drivers/staging/brcm80211/sys/wl_mac80211.c
drivers/staging/comedi/drivers/dt9812.c
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/comedi/drivers/usbduxfast.c
drivers/staging/cpia/cpia.c
drivers/staging/dream/Kconfig [deleted file]
drivers/staging/dream/Makefile [deleted file]
drivers/staging/dream/TODO [deleted file]
drivers/staging/dream/camera/Kconfig [deleted file]
drivers/staging/dream/camera/Makefile [deleted file]
drivers/staging/dream/camera/msm_camera.c [deleted file]
drivers/staging/dream/camera/msm_io7x.c [deleted file]
drivers/staging/dream/camera/msm_io8x.c [deleted file]
drivers/staging/dream/camera/msm_v4l2.c [deleted file]
drivers/staging/dream/camera/msm_vfe7x.c [deleted file]
drivers/staging/dream/camera/msm_vfe7x.h [deleted file]
drivers/staging/dream/camera/msm_vfe8x.c [deleted file]
drivers/staging/dream/camera/msm_vfe8x.h [deleted file]
drivers/staging/dream/camera/msm_vfe8x_proc.c [deleted file]
drivers/staging/dream/camera/msm_vfe8x_proc.h [deleted file]
drivers/staging/dream/camera/mt9d112.c [deleted file]
drivers/staging/dream/camera/mt9d112.h [deleted file]
drivers/staging/dream/camera/mt9d112_reg.c [deleted file]
drivers/staging/dream/camera/mt9p012.h [deleted file]
drivers/staging/dream/camera/mt9p012_fox.c [deleted file]
drivers/staging/dream/camera/mt9p012_reg.c [deleted file]
drivers/staging/dream/camera/mt9t013.c [deleted file]
drivers/staging/dream/camera/mt9t013.h [deleted file]
drivers/staging/dream/camera/mt9t013_reg.c [deleted file]
drivers/staging/dream/camera/s5k3e2fx.c [deleted file]
drivers/staging/dream/camera/s5k3e2fx.h [deleted file]
drivers/staging/dream/generic_gpio.c [deleted file]
drivers/staging/dream/gpio_axis.c [deleted file]
drivers/staging/dream/gpio_event.c [deleted file]
drivers/staging/dream/gpio_input.c [deleted file]
drivers/staging/dream/gpio_matrix.c [deleted file]
drivers/staging/dream/gpio_output.c [deleted file]
drivers/staging/dream/include/linux/android_pmem.h [deleted file]
drivers/staging/dream/include/linux/gpio_event.h [deleted file]
drivers/staging/dream/include/linux/msm_adsp.h [deleted file]
drivers/staging/dream/include/linux/msm_audio.h [deleted file]
drivers/staging/dream/include/linux/msm_rpcrouter.h [deleted file]
drivers/staging/dream/include/linux/wakelock.h [deleted file]
drivers/staging/dream/include/mach/camera.h [deleted file]
drivers/staging/dream/include/mach/msm_adsp.h [deleted file]
drivers/staging/dream/include/mach/msm_rpcrouter.h [deleted file]
drivers/staging/dream/include/mach/msm_smd.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h [deleted file]
drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h [deleted file]
drivers/staging/dream/include/media/msm_camera.h [deleted file]
drivers/staging/dream/pmem.c [deleted file]
drivers/staging/dream/qdsp5/Makefile [deleted file]
drivers/staging/dream/qdsp5/adsp.c [deleted file]
drivers/staging/dream/qdsp5/adsp.h [deleted file]
drivers/staging/dream/qdsp5/adsp_6210.c [deleted file]
drivers/staging/dream/qdsp5/adsp_6220.c [deleted file]
drivers/staging/dream/qdsp5/adsp_6225.c [deleted file]
drivers/staging/dream/qdsp5/adsp_driver.c [deleted file]
drivers/staging/dream/qdsp5/adsp_info.c [deleted file]
drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c [deleted file]
drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c [deleted file]
drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c [deleted file]
drivers/staging/dream/qdsp5/audio_aac.c [deleted file]
drivers/staging/dream/qdsp5/audio_amrnb.c [deleted file]
drivers/staging/dream/qdsp5/audio_evrc.c [deleted file]
drivers/staging/dream/qdsp5/audio_in.c [deleted file]
drivers/staging/dream/qdsp5/audio_mp3.c [deleted file]
drivers/staging/dream/qdsp5/audio_out.c [deleted file]
drivers/staging/dream/qdsp5/audio_qcelp.c [deleted file]
drivers/staging/dream/qdsp5/audmgr.c [deleted file]
drivers/staging/dream/qdsp5/audmgr.h [deleted file]
drivers/staging/dream/qdsp5/audmgr_new.h [deleted file]
drivers/staging/dream/qdsp5/audpp.c [deleted file]
drivers/staging/dream/qdsp5/evlog.h [deleted file]
drivers/staging/dream/qdsp5/snd.c [deleted file]
drivers/staging/dream/synaptics_i2c_rmi.c [deleted file]
drivers/staging/dream/synaptics_i2c_rmi.h [deleted file]
drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c
drivers/staging/hv/hv_utils.c
drivers/staging/intel_sst/intel_sst_app_interface.c
drivers/staging/intel_sst/intel_sst_common.h
drivers/staging/keucr/init.c
drivers/staging/keucr/ms.c
drivers/staging/keucr/msscsi.c
drivers/staging/keucr/sdscsi.c
drivers/staging/keucr/smilsub.c
drivers/staging/keucr/transport.c
drivers/staging/msm/msm_fb.c
drivers/staging/olpc_dcon/olpc_dcon.c
drivers/staging/pohmelfs/inode.c
drivers/staging/rt2860/common/cmm_aes.c
drivers/staging/rt2860/usb_main_dev.c
drivers/staging/rtl8192e/r8192E_core.c
drivers/staging/rtl8712/osdep_service.h
drivers/staging/smbfs/inode.c
drivers/staging/solo6x10/solo6010-v4l2-enc.c
drivers/staging/solo6x10/solo6010-v4l2.c
drivers/staging/stradis/stradis.c
drivers/staging/tidspbridge/Kconfig
drivers/staging/tidspbridge/Makefile
drivers/staging/tidspbridge/core/_deh.h
drivers/staging/tidspbridge/core/_tiomap.h
drivers/staging/tidspbridge/core/dsp-mmu.c [deleted file]
drivers/staging/tidspbridge/core/io_sm.c
drivers/staging/tidspbridge/core/tiomap3430.c
drivers/staging/tidspbridge/core/tiomap3430_pwr.c
drivers/staging/tidspbridge/core/tiomap_io.c
drivers/staging/tidspbridge/core/ue_deh.c
drivers/staging/tidspbridge/hw/EasiGlobal.h [new file with mode: 0644]
drivers/staging/tidspbridge/hw/MMUAccInt.h [new file with mode: 0644]
drivers/staging/tidspbridge/hw/MMURegAcM.h [new file with mode: 0644]
drivers/staging/tidspbridge/hw/hw_defs.h [new file with mode: 0644]
drivers/staging/tidspbridge/hw/hw_mmu.c [new file with mode: 0644]
drivers/staging/tidspbridge/hw/hw_mmu.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
drivers/staging/tidspbridge/include/dspbridge/dev.h
drivers/staging/tidspbridge/include/dspbridge/dmm.h [new file with mode: 0644]
drivers/staging/tidspbridge/include/dspbridge/drv.h
drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h [deleted file]
drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
drivers/staging/tidspbridge/include/dspbridge/dspioctl.h
drivers/staging/tidspbridge/include/dspbridge/proc.h
drivers/staging/tidspbridge/pmgr/dev.c
drivers/staging/tidspbridge/pmgr/dmm.c [new file with mode: 0644]
drivers/staging/tidspbridge/pmgr/dspapi.c
drivers/staging/tidspbridge/rmgr/drv.c
drivers/staging/tidspbridge/rmgr/drv_interface.c
drivers/staging/tidspbridge/rmgr/node.c
drivers/staging/tidspbridge/rmgr/proc.c
drivers/staging/tm6000/tm6000-i2c.c
drivers/staging/tm6000/tm6000-video.c
drivers/staging/udlfb/udlfb.c
drivers/staging/vt6656/main_usb.c
drivers/staging/westbridge/astoria/api/src/cyasusb.c
drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c
drivers/staging/wlan-ng/cfg80211.c
drivers/staging/wlan-ng/p80211netdev.c
drivers/tty/Makefile [new file with mode: 0644]
drivers/tty/n_gsm.c [new file with mode: 0644]
drivers/tty/n_hdlc.c [new file with mode: 0644]
drivers/tty/n_r3964.c [new file with mode: 0644]
drivers/tty/n_tty.c [new file with mode: 0644]
drivers/tty/pty.c [new file with mode: 0644]
drivers/tty/sysrq.c [new file with mode: 0644]
drivers/tty/tty_audit.c [new file with mode: 0644]
drivers/tty/tty_buffer.c [new file with mode: 0644]
drivers/tty/tty_io.c [new file with mode: 0644]
drivers/tty/tty_ioctl.c [new file with mode: 0644]
drivers/tty/tty_ldisc.c [new file with mode: 0644]
drivers/tty/tty_mutex.c [new file with mode: 0644]
drivers/tty/tty_port.c [new file with mode: 0644]
drivers/tty/vt/.gitignore [new file with mode: 0644]
drivers/tty/vt/Makefile [new file with mode: 0644]
drivers/tty/vt/consolemap.c [new file with mode: 0644]
drivers/tty/vt/cp437.uni [new file with mode: 0644]
drivers/tty/vt/defkeymap.c_shipped [new file with mode: 0644]
drivers/tty/vt/defkeymap.map [new file with mode: 0644]
drivers/tty/vt/keyboard.c [new file with mode: 0644]
drivers/tty/vt/selection.c [new file with mode: 0644]
drivers/tty/vt/vc_screen.c [new file with mode: 0644]
drivers/tty/vt/vt.c [new file with mode: 0644]
drivers/tty/vt/vt_ioctl.c [new file with mode: 0644]
drivers/usb/core/devio.c
drivers/usb/core/inode.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/goku_udc.h
drivers/usb/gadget/inode.c
drivers/usb/gadget/u_ether.c
drivers/usb/gadget/u_serial.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-mxc.c
drivers/usb/host/ehci-octeon.c [new file with mode: 0644]
drivers/usb/host/octeon2-common.c [new file with mode: 0644]
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-jz4740.c
drivers/usb/host/ohci-octeon.c [new file with mode: 0644]
drivers/usb/misc/iowarrior.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/musb/blackfin.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_regs.h
drivers/usb/musb/musbhsdma.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/option.c
drivers/usb/storage/uas.c
drivers/uwb/allocator.c
drivers/video/backlight/adp8860_bl.c
drivers/video/backlight/l4f00242t03.c
drivers/video/backlight/lms283gf05.c
drivers/video/backlight/mbp_nvidia_bl.c
drivers/video/backlight/pwm_bl.c
drivers/video/backlight/s6e63m0.c
drivers/video/msm/mddi.c
drivers/video/msm/mdp.c
drivers/video/omap2/vram.c
drivers/video/riva/rivafb-i2c.c
drivers/video/sh_mipi_dsi.c
drivers/video/sh_mobile_hdmi.c
drivers/video/sh_mobile_lcdcfb.c
drivers/video/sh_mobile_lcdcfb.h [new file with mode: 0644]
drivers/video/sis/sis_main.c
drivers/watchdog/octeon-wdt-main.c
drivers/xen/Makefile
drivers/xen/evtchn.c
drivers/xen/xenfs/privcmd.c
drivers/xen/xenfs/super.c
fs/9p/vfs_super.c
fs/adfs/super.c
fs/affs/super.c
fs/afs/super.c
fs/anon_inodes.c
fs/autofs4/init.c
fs/befs/linuxvfs.c
fs/bfs/inode.c
fs/binfmt_misc.c
fs/bio.c
fs/block_dev.c
fs/btrfs/compression.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/dir-item.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/extent_map.c
fs/btrfs/free-space-cache.c
fs/btrfs/free-space-cache.h
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ioctl.h
fs/btrfs/ordered-data.c
fs/btrfs/relocation.c
fs/btrfs/root-tree.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/tree-defrag.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/btrfs/xattr.c
fs/btrfs/zlib.c
fs/ceph/super.c
fs/cifs/Kconfig
fs/cifs/TODO
fs/cifs/cifs_fs_sb.h
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/ioctl.c
fs/cifs/misc.c
fs/cifs/sess.c
fs/cifs/transport.c
fs/coda/inode.c
fs/compat.c
fs/configfs/mount.c
fs/cramfs/inode.c
fs/debugfs/inode.c
fs/devpts/inode.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/ecryptfs/main.c
fs/ecryptfs/super.c
fs/efs/super.c
fs/exofs/super.c
fs/ext2/super.c
fs/ext3/super.c
fs/ext4/ext4.h
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/ext4/page-io.c
fs/ext4/super.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c
fs/freevxfs/vxfs_super.c
fs/fs-writeback.c
fs/fuse/control.c
fs/fuse/inode.c
fs/gfs2/export.c
fs/gfs2/glock.c
fs/gfs2/inode.c
fs/gfs2/inode.h
fs/gfs2/ops_fstype.c
fs/gfs2/rgrp.c
fs/hfs/super.c
fs/hfsplus/super.c
fs/hostfs/hostfs_kern.c
fs/hpfs/buffer.c
fs/hpfs/hpfs_fn.h
fs/hpfs/super.c
fs/hppfs/hppfs.c
fs/hugetlbfs/inode.c
fs/internal.h
fs/ioprio.c
fs/isofs/inode.c
fs/jbd2/journal.c
fs/jffs2/build.c
fs/jffs2/compr.c
fs/jffs2/compr.h
fs/jffs2/compr_lzo.c
fs/jffs2/compr_rtime.c
fs/jffs2/compr_rubin.c
fs/jffs2/compr_zlib.c
fs/jffs2/dir.c
fs/jffs2/erase.c
fs/jffs2/fs.c
fs/jffs2/gc.c
fs/jffs2/jffs2_fs_sb.h
fs/jffs2/nodelist.c
fs/jffs2/nodelist.h
fs/jffs2/scan.c
fs/jffs2/super.c
fs/jfs/super.c
fs/libfs.c
fs/locks.c
fs/logfs/dev_bdev.c
fs/logfs/dev_mtd.c
fs/logfs/logfs.h
fs/logfs/super.c
fs/minix/inode.c
fs/namei.c
fs/ncpfs/inode.c
fs/nfs/file.c
fs/nfs/super.c
fs/nfs/unlink.c
fs/nfsd/nfs4state.c
fs/nfsd/nfsctl.c
fs/nilfs2/super.c
fs/notify/Kconfig
fs/notify/fanotify/fanotify.c
fs/notify/fanotify/fanotify_user.c
fs/notify/fsnotify.c
fs/notify/inode_mark.c
fs/notify/inotify/inotify_user.c
fs/notify/vfsmount_mark.c
fs/ntfs/super.c
fs/ocfs2/dlmfs/dlmfs.c
fs/ocfs2/ocfs2.h
fs/ocfs2/super.c
fs/omfs/inode.c
fs/open.c
fs/openpromfs/inode.c
fs/pipe.c
fs/proc/root.c
fs/qnx4/inode.c
fs/ramfs/inode.c
fs/read_write.c
fs/reiserfs/super.c
fs/romfs/super.c
fs/squashfs/super.c
fs/squashfs/xattr.c
fs/squashfs/xattr.h
fs/squashfs/xattr_id.c
fs/super.c
fs/sysfs/mount.c
fs/sysv/super.c
fs/ubifs/super.c
fs/udf/super.c
fs/ufs/super.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/xfs_filestream.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_quota.h
include/asm-generic/audit_change_attr.h
include/asm-generic/stat.h
include/drm/ttm/ttm_bo_api.h
include/drm/ttm/ttm_bo_driver.h
include/linux/Kbuild
include/linux/atomic.h [new file with mode: 0644]
include/linux/audit.h
include/linux/bio.h
include/linux/blk_types.h
include/linux/blkdev.h
include/linux/dccp.h
include/linux/drbd.h
include/linux/fanotify.h
include/linux/fs.h
include/linux/fsl-diu-fb.h
include/linux/fsnotify.h
include/linux/fsnotify_backend.h
include/linux/hardirq.h
include/linux/highmem.h
include/linux/i2c-id.h
include/linux/i2c.h
include/linux/i2c/adp5588.h
include/linux/if_vlan.h
include/linux/input.h
include/linux/iocontext.h
include/linux/irq.h
include/linux/irqnr.h
include/linux/jump_label.h
include/linux/kernel.h
include/linux/kgdb.h
include/linux/leds-lp5521.h [new file with mode: 0644]
include/linux/leds-lp5523.h [new file with mode: 0644]
include/linux/leds.h
include/linux/marvell_phy.h
include/linux/mmc/sh_mmcif.h
include/linux/mtd/bbm.h
include/linux/mtd/cfi.h
include/linux/mtd/fsmc.h [new file with mode: 0644]
include/linux/mtd/inftl.h
include/linux/mtd/mtd.h
include/linux/mtd/nand.h
include/linux/mtd/partitions.h
include/linux/mtd/super.h
include/linux/netdevice.h
include/linux/netfilter.h
include/linux/pci_ids.h
include/linux/perf_event.h
include/linux/printk.h [new file with mode: 0644]
include/linux/pwm_backlight.h
include/linux/radix-tree.h
include/linux/ramfs.h
include/linux/resource.h
include/linux/sched.h
include/linux/security.h
include/linux/semaphore.h
include/linux/sh_clk.h
include/linux/sh_intc.h
include/linux/sh_timer.h
include/linux/socket.h
include/linux/spi/spi.h
include/linux/sunrpc/svc_xprt.h
include/linux/tty.h
include/linux/usb.h
include/linux/usb/musb.h
include/linux/writeback.h
include/mtd/mtd-abi.h
include/mtd/mtd-user.h
include/net/caif/caif_dev.h
include/net/caif/caif_spi.h
include/net/caif/cfcnfg.h
include/net/dn.h
include/net/dst_ops.h
include/net/ip_fib.h
include/net/netlink.h
include/net/sock.h
include/net/tcp.h
include/net/udp.h
include/scsi/libfc.h
include/scsi/osd_initiator.h
include/scsi/osd_protocol.h
include/scsi/osd_types.h
include/trace/events/ext4.h
include/video/sh_mobile_lcdc.h
include/xen/privcmd.h
ipc/mqueue.c
ipc/shm.c
kernel/audit.c
kernel/audit.h
kernel/audit_tree.c
kernel/audit_watch.c
kernel/auditfilter.c
kernel/auditsc.c
kernel/cgroup.c
kernel/cpuset.c
kernel/debug/debug_core.c
kernel/debug/kdb/kdb_main.c
kernel/exit.c
kernel/irq/manage.c
kernel/jump_label.c
kernel/kprobes.c
kernel/latencytop.c
kernel/perf_event.c
kernel/printk.c
kernel/range.c
kernel/relay.c
kernel/sched.c
kernel/sched_fair.c
kernel/sched_stats.h
kernel/sysctl.c
kernel/trace/blktrace.c
kernel/watchdog.c
lib/radix-tree.c
mm/filemap.c
mm/memcontrol.c
mm/mmap.c
mm/mprotect.c
mm/nommu.c
mm/shmem.c
mm/slub.c
mm/vmscan.c
mm/vmstat.c
net/ax25/af_ax25.c
net/bluetooth/hci_event.c
net/bluetooth/hidp/Kconfig
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/core.c
net/caif/caif_config_util.c
net/caif/caif_dev.c
net/caif/caif_socket.c
net/caif/cfcnfg.c
net/caif/cfctrl.c
net/caif/cfdbgl.c
net/caif/cfrfml.c
net/can/bcm.c
net/compat.c
net/core/dev.c
net/core/dst.c
net/core/filter.c
net/core/iovec.c
net/core/pktgen.c
net/core/rtnetlink.c
net/core/sock.c
net/dccp/ccid.h
net/dccp/ccids/ccid2.c
net/dccp/ccids/ccid2.h
net/dccp/ccids/ccid3.c
net/dccp/dccp.h
net/dccp/output.c
net/dccp/proto.c
net/dccp/timer.c
net/decnet/af_decnet.c
net/decnet/sysctl_net_decnet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_hash.c
net/ipv4/fib_lookup.h
net/ipv4/fib_trie.c
net/ipv4/igmp.c
net/ipv4/inet_diag.c
net/ipv4/ip_gre.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/proc.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/proc.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/l2tp/l2tp_debugfs.c
net/mac80211/debugfs_key.c
net/mac80211/iface.c
net/mac80211/main.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_proto.c
net/netfilter/xt_socket.c
net/packet/af_packet.c
net/rds/loop.c
net/rds/message.c
net/rds/rdma.c
net/rds/send.c
net/rds/tcp.c
net/sched/cls_basic.c
net/sched/cls_cgroup.c
net/sched/em_text.c
net/sctp/protocol.c
net/sctp/socket.c
net/sctp/sysctl.c
net/socket.c
net/sunrpc/rpc_pipe.c
net/tipc/socket.c
net/wireless/nl80211.c
net/x25/x25_facilities.c
net/x25/x25_in.c
samples/Kconfig
samples/Makefile
samples/kdb/Makefile [new file with mode: 0644]
samples/kdb/kdb_hello.c [new file with mode: 0644]
scripts/checkpatch.pl
scripts/kconfig/streamline_config.pl
scripts/kconfig/symbol.c
scripts/recordmcount.c
scripts/recordmcount.h
security/Kconfig
security/apparmor/lsm.c
security/apparmor/policy.c
security/capability.c
security/commoncap.c
security/inode.c
security/security.c
security/selinux/hooks.c
security/selinux/selinuxfs.c
security/smack/smack_lsm.c
security/smack/smackfs.c
sound/pci/asihpi/hpi6000.c
sound/pci/asihpi/hpi6205.c
sound/pci/asihpi/hpicmn.c
sound/pci/cs46xx/dsp_spos.c
sound/pci/hda/patch_cirrus.c
sound/pci/lx6464es/lx6464es.c
sound/pci/lx6464es/lx6464es.h
sound/pci/lx6464es/lx_core.c
sound/soc/codecs/Kconfig
sound/soc/codecs/tlv320dac33.c
sound/soc/codecs/tpa6130a2.c
sound/soc/codecs/wm8900.c
sound/soc/codecs/wm_hubs.c
sound/soc/pxa/tosa.c
sound/soc/soc-core.c
sound/usb/mixer_quirks.c
sound/usb/pcm.c
tools/perf/Documentation/perf-trace.txt
tools/perf/builtin-record.c
tools/perf/builtin-top.c
tools/perf/builtin-trace.c
tools/perf/scripts/perl/bin/failed-syscalls-record
tools/perf/scripts/perl/bin/rw-by-file-record
tools/perf/scripts/perl/bin/rw-by-pid-record
tools/perf/scripts/perl/bin/rwtop-record
tools/perf/scripts/perl/bin/wakeup-latency-record
tools/perf/scripts/perl/bin/workqueue-stats-record
tools/perf/scripts/python/bin/failed-syscalls-by-pid-record
tools/perf/scripts/python/bin/futex-contention-record
tools/perf/scripts/python/bin/netdev-times-record
tools/perf/scripts/python/bin/sched-migration-record
tools/perf/scripts/python/bin/sctop-record
tools/perf/scripts/python/bin/syscall-counts-by-pid-record
tools/perf/scripts/python/bin/syscall-counts-record
tools/perf/util/ui/util.c
usr/initramfs_data.S

diff --git a/Documentation/ABI/obsolete/proc-pid-oom_adj b/Documentation/ABI/obsolete/proc-pid-oom_adj
new file mode 100644 (file)
index 0000000..cf63f26
--- /dev/null
@@ -0,0 +1,22 @@
+What:  /proc/<pid>/oom_adj
+When:  August 2012
+Why:   /proc/<pid>/oom_adj allows userspace to influence the oom killer's
+       badness heuristic used to determine which task to kill when the kernel
+       is out of memory.
+
+       The badness heuristic has since been rewritten since the introduction of
+       this tunable such that its meaning is deprecated.  The value was
+       implemented as a bitshift on a score generated by the badness()
+       function that did not have any precise units of measure.  With the
+       rewrite, the score is given as a proportion of available memory to the
+       task allocating pages, so using a bitshift which grows the score
+       exponentially is, thus, impossible to tune with fine granularity.
+
+       A much more powerful interface, /proc/<pid>/oom_score_adj, was
+       introduced with the oom killer rewrite that allows users to increase or
+       decrease the badness() score linearly.  This interface will replace
+       /proc/<pid>/oom_adj.
+
+       A warning will be emitted to the kernel log if an application uses this
+       deprecated interface.  After it is printed once, future warnings will be
+       suppressed until the kernel is rebooted.
index 490d862c5f0ddffc748ebb56de4255ef0769c115..d71b57fcf116bcb263b8a761d2ebf87b3231f56a 100644 (file)
@@ -710,7 +710,18 @@ Task Addr       Pid   Parent [*] cpu State Thread     Command
         <listitem><para>A simple shell</para></listitem>
         <listitem><para>The kdb core command set</para></listitem>
         <listitem><para>A registration API to register additional kdb shell commands.</para>
-        <para>A good example of a self-contained kdb module is the "ftdump" command for dumping the ftrace buffer.  See: kernel/trace/trace_kdb.c</para></listitem>
+       <itemizedlist>
+        <listitem><para>A good example of a self-contained kdb module
+        is the "ftdump" command for dumping the ftrace buffer.  See:
+        kernel/trace/trace_kdb.c</para></listitem>
+        <listitem><para>For an example of how to dynamically register
+        a new kdb command you can build the kdb_hello.ko kernel module
+        from samples/kdb/kdb_hello.c.  To build this example you can
+        set CONFIG_SAMPLES=y and CONFIG_SAMPLE_KDB=m in your kernel
+        config.  Later run "modprobe kdb_hello" and the next time you
+        enter the kdb shell, you can run the "hello"
+        command.</para></listitem>
+       </itemizedlist></listitem>
         <listitem><para>The implementation for kdb_printf() which
         emits messages directly to I/O drivers, bypassing the kernel
         log.</para></listitem>
index 0af0e9eed5d6c1281433b4c0bc26f7c6577fe8a6..888ae7b83ae4783da38b4db2f69b94d45ba193c8 100644 (file)
@@ -255,9 +255,10 @@ framebuffer parameters.
 Kernel boot arguments
 ---------------------
 
-vram=<size>
-       - Amount of total VRAM to preallocate. For example, "10M". omapfb
-         allocates memory for framebuffers from VRAM.
+vram=<size>[,<physaddr>]
+       - Amount of total VRAM to preallocate and optionally a physical start
+         memory address. For example, "10M". omapfb allocates memory for
+         framebuffers from VRAM.
 
 omapfb.mode=<display>:<mode>[,...]
        - Default video mode for specified displays. For example,
index d5af3f630814862c5f15194d871766510e16893c..71cfbdc0f74d1da35a9064c6b48490ff5797d660 100644 (file)
@@ -16,7 +16,7 @@ you can do so by typing:
 As of the Linux 2.6.10 kernel, it is now possible to change the
 IO scheduler for a given block device on the fly (thus making it possible,
 for instance, to set the CFQ scheduler for the system default, but
-set a specific device to use the anticipatory or noop schedulers - which
+set a specific device to use the deadline or noop schedulers - which
 can improve that device's throughput).
 
 To set a specific scheduler, simply do this:
@@ -31,7 +31,7 @@ a "cat /sys/block/DEV/queue/scheduler" - the list of valid names
 will be displayed, with the currently selected scheduler in brackets:
 
 # cat /sys/block/hda/queue/scheduler
-noop anticipatory deadline [cfq]
-# echo anticipatory > /sys/block/hda/queue/scheduler
+noop deadline [cfq]
+# echo deadline > /sys/block/hda/queue/scheduler
 # cat /sys/block/hda/queue/scheduler
-noop [anticipatory] deadline cfq
+noop [deadline] cfq
index d8f36f984faa517c84883f625a93ee45a3f91dcc..6c2f55e05f13c31675bcbcbc70d6254e2d70783d 100644 (file)
@@ -554,3 +554,13 @@ Why:    This is a legacy interface which have been replaced by a more
 Who:    NeilBrown <neilb@suse.de>
 
 ----------------------------
+
+What:  i2c_adapter.id
+When:  June 2011
+Why:   This field is deprecated. I2C device drivers shouldn't change their
+       behavior based on the underlying I2C adapter. Instead, the I2C
+       adapter driver should instantiate the I2C devices and provide the
+       needed platform-specific information.
+Who:   Jean Delvare <khali@linux-fr.org>
+
+----------------------------
index 8a817f656f0a808dffb344c6a46bab960cb8a0ae..a91f30890011ddf69ba9b859484966c943db7fb5 100644 (file)
@@ -322,7 +322,6 @@ fl_release_private: yes     yes
 prototypes:
        int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
        void (*fl_notify)(struct file_lock *);  /* unblock callback */
-       void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
        void (*fl_release_private)(struct file_lock *);
        void (*fl_break)(struct file_lock *); /* break_lease callback */
 
@@ -330,7 +329,6 @@ locking rules:
                        BKL     may block
 fl_compare_owner:      yes     no
 fl_notify:             yes     no
-fl_copy_lock:          yes     no
 fl_release_private:    yes     yes
 fl_break:              yes     no
 
index 96d0df28bed323d5596fc051b0ffb96ed8e3c8df..7445bf335dae7eeba4bd6640a82fa3987f48d2cc 100644 (file)
@@ -794,17 +794,6 @@ designed.
 
 Roadmap:
 
-2.6.37 Remove experimental tag from mount option
-       => should be roughly 6 months after initial merge
-       => enough time to:
-               => gain confidence and fix problems reported by early
-                  adopters (a.k.a. guinea pigs)
-               => address worst performance regressions and undesired
-                  behaviours
-               => start tuning/optimising code for parallelism
-               => start tuning/optimising algorithms consuming
-                  excessive CPU time
-
 2.6.39 Switch default mount option to use delayed logging
        => should be roughly 12 months after initial merge
        => enough time to shake out remaining problems before next round of
index e307914a3edafc84c2019911d48b9922133e7812..93fe76e56522a199a0ab5044544673418be64ec0 100644 (file)
@@ -15,10 +15,14 @@ Supported adapters:
   * Intel 82801I (ICH9)
   * Intel EP80579 (Tolapai)
   * Intel 82801JI (ICH10)
-  * Intel 3400/5 Series (PCH)
+  * Intel 5/3400 Series (PCH)
   * Intel Cougar Point (PCH)
+  * Intel Patsburg (PCH)
    Datasheets: Publicly available at the Intel website
 
+On Intel Patsburg and later chipsets, both the normal host SMBus controller
+and the additional 'Integrated Device Function' controllers are supported.
+
 Authors: 
        Mark Studebaker <mdsxyz123@yahoo.com>
        Jean Delvare <khali@linux-fr.org>
index ed45e9802aa810a71e1f53fdde2a5d7bbba6789e..92e83e53148fe8b1d4848af9a8fd7442cc5624ba 100644 (file)
@@ -706,7 +706,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        arch/x86/kernel/cpu/cpufreq/elanfreq.c.
 
        elevator=       [IOSCHED]
-                       Format: {"anticipatory" | "cfq" | "deadline" | "noop"}
+                       Format: {"cfq" | "deadline" | "noop"}
                        See Documentation/block/as-iosched.txt and
                        Documentation/block/deadline-iosched.txt for details.
 
index 8fd5ca2ae32dde4d9eb27722942a5d099f4afbc3..58b266bd1846f1d0560bdae575f6e764a95fd4b3 100644 (file)
@@ -60,15 +60,18 @@ Hardware accelerated blink of LEDs
 
 Some LEDs can be programmed to blink without any CPU interaction. To
 support this feature, a LED driver can optionally implement the
-blink_set() function (see <linux/leds.h>). If implemented, triggers can
-attempt to use it before falling back to software timers. The blink_set()
-function should return 0 if the blink setting is supported, or -EINVAL
-otherwise, which means that LED blinking will be handled by software.
-
-The blink_set() function should choose a user friendly blinking
-value if it is called with *delay_on==0 && *delay_off==0 parameters. In
-this case the driver should give back the chosen value through delay_on
-and delay_off parameters to the leds subsystem.
+blink_set() function (see <linux/leds.h>). To set an LED to blinking,
+however, it is better to use use the API function led_blink_set(),
+as it will check and implement software fallback if necessary.
+
+To turn off blinking again, use the API function led_brightness_set()
+as that will not just set the LED brightness but also stop any software
+timers that may have been required for blinking.
+
+The blink_set() function should choose a user friendly blinking value
+if it is called with *delay_on==0 && *delay_off==0 parameters. In this
+case the driver should give back the chosen value through delay_on and
+delay_off parameters to the leds subsystem.
 
 Setting the brightness to zero with brightness_set() callback function
 should completely turn off the LED and cancel the previously programmed
diff --git a/Documentation/leds/leds-lp5521.txt b/Documentation/leds/leds-lp5521.txt
new file mode 100644 (file)
index 0000000..c4d8d15
--- /dev/null
@@ -0,0 +1,88 @@
+Kernel driver for lp5521
+========================
+
+* National Semiconductor LP5521 led driver chip
+* Datasheet: http://www.national.com/pf/LP/LP5521.html
+
+Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
+Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
+
+Description
+-----------
+
+LP5521 can drive up to 3 channels. Leds can be controlled directly via
+the led class control interface. Channels have generic names:
+lp5521:channelx, where x is 0 .. 2
+
+All three channels can be also controlled using the engine micro programs.
+More details of the instructions can be found from the public data sheet.
+
+Control interface for the engines:
+x is 1 .. 3
+enginex_mode : disabled, load, run
+enginex_load : store program (visible only in engine load mode)
+
+Example (start to blink the channel 2 led):
+cd   /sys/class/leds/lp5521:channel2/device
+echo "load" > engine3_mode
+echo "037f4d0003ff6000" > engine3_load
+echo "run" > engine3_mode
+
+stop the engine:
+echo "disabled" > engine3_mode
+
+sysfs contains a selftest entry.
+The test communicates with the chip and checks that
+the clock mode is automatically set to the requested one.
+
+Each channel has its own led current settings.
+/sys/class/leds/lp5521:channel0/led_current - RW
+/sys/class/leds/lp5521:channel0/max_current - RO
+Format: 10x mA i.e 10 means 1.0 mA
+
+example platform data:
+
+Note: chan_nr can have values between 0 and 2.
+
+static struct lp5521_led_config lp5521_led_config[] = {
+        {
+                .chan_nr        = 0,
+                .led_current    = 50,
+               .max_current    = 130,
+        }, {
+                .chan_nr        = 1,
+                .led_current    = 0,
+               .max_current    = 130,
+        }, {
+                .chan_nr        = 2,
+                .led_current    = 0,
+               .max_current    = 130,
+        }
+};
+
+static int lp5521_setup(void)
+{
+       /* setup HW resources */
+}
+
+static void lp5521_release(void)
+{
+       /* Release HW resources */
+}
+
+static void lp5521_enable(bool state)
+{
+       /* Control of chip enable signal */
+}
+
+static struct lp5521_platform_data lp5521_platform_data = {
+        .led_config     = lp5521_led_config,
+        .num_channels   = ARRAY_SIZE(lp5521_led_config),
+        .clock_mode     = LP5521_CLOCK_EXT,
+        .setup_resources   = lp5521_setup,
+        .release_resources = lp5521_release,
+        .enable            = lp5521_enable,
+};
+
+If the current is set to 0 in the platform data, that channel is
+disabled and it is not visible in the sysfs.
diff --git a/Documentation/leds/leds-lp5523.txt b/Documentation/leds/leds-lp5523.txt
new file mode 100644 (file)
index 0000000..fad2feb
--- /dev/null
@@ -0,0 +1,83 @@
+Kernel driver for lp5523
+========================
+
+* National Semiconductor LP5523 led driver chip
+* Datasheet: http://www.national.com/pf/LP/LP5523.html
+
+Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
+Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
+
+Description
+-----------
+LP5523 can drive up to 9 channels. Leds can be controlled directly via
+the led class control interface. Channels have generic names:
+lp5523:channelx where x is 0...8
+
+The chip provides 3 engines. Each engine can control channels without
+interaction from the main CPU. Details of the micro engine code can be found
+from the public data sheet. Leds can be muxed to different channels.
+
+Control interface for the engines:
+x is 1 .. 3
+enginex_mode : disabled, load, run
+enginex_load : microcode load (visible only in load mode)
+enginex_leds : led mux control (visible only in load mode)
+
+cd /sys/class/leds/lp5523:channel2/device
+echo "load" > engine3_mode
+echo "9d80400004ff05ff437f0000" > engine3_load
+echo "111111111" > engine3_leds
+echo "run" > engine3_mode
+
+sysfs contains a selftest entry. It measures each channel
+voltage level and checks if it looks reasonable. If the level is too high,
+the led is missing; if the level is too low, there is a short circuit.
+
+Selftest uses always the current from the platform data.
+
+Each channel contains led current settings.
+/sys/class/leds/lp5523:channel2/led_current - RW
+/sys/class/leds/lp5523:channel2/max_current - RO
+Format: 10x mA i.e 10 means 1.0 mA
+
+Example platform data:
+
+Note - chan_nr can have values between 0 and 8.
+
+static struct lp5523_led_config lp5523_led_config[] = {
+        {
+                .chan_nr        = 0,
+                .led_current    = 50,
+               .max_current    = 130,
+        },
+...
+        }, {
+                .chan_nr        = 8,
+                .led_current    = 50,
+               .max_current    = 130,
+        }
+};
+
+static int lp5523_setup(void)
+{
+       /* Setup HW resources */
+}
+
+static void lp5523_release(void)
+{
+       /* Release HW resources */
+}
+
+static void lp5523_enable(bool state)
+{
+       /* Control chip enable signal */
+}
+
+static struct lp5523_platform_data lp5523_platform_data = {
+        .led_config     = lp5523_led_config,
+        .num_channels   = ARRAY_SIZE(lp5523_led_config),
+        .clock_mode     = LP5523_CLOCK_EXT,
+        .setup_resources   = lp5523_setup,
+        .release_resources = lp5523_release,
+        .enable            = lp5523_enable,
+};
index c7165f4cb7927a152ec547caeecb393f5ad3c27e..fe95105992c57f1c81248dd8d3c1c38c3272e0f9 100644 (file)
@@ -20,6 +20,15 @@ ip_no_pmtu_disc - BOOLEAN
 min_pmtu - INTEGER
        default 562 - minimum discovered Path MTU
 
+route/max_size - INTEGER
+       Maximum number of routes allowed in the kernel.  Increase
+       this when using large numbers of interfaces and/or routes.
+
+neigh/default/gc_thresh3 - INTEGER
+       Maximum number of neighbor entries allowed.  Increase this
+       when using large numbers of interfaces and when communicating
+       with large numbers of directly-connected peers.
+
 mtu_expires - INTEGER
        Time, in seconds, that cached PMTU information is kept.
 
index 221f38be98f47be1e682876ef55c2984a8484e76..19f8278c38548405165d43256bcf8be021070087 100644 (file)
@@ -21,8 +21,8 @@ three rotations, respectively, to balance the tree), with slightly slower
 To quote Linux Weekly News:
 
     There are a number of red-black trees in use in the kernel.
-    The anticipatory, deadline, and CFQ I/O schedulers all employ
-    rbtrees to track requests; the packet CD/DVD driver does the same.
+    The deadline and CFQ I/O schedulers employ rbtrees to
+    track requests; the packet CD/DVD driver does the same.
     The high-resolution timer code uses an rbtree to organize outstanding
     timer requests.  The ext3 filesystem tracks directory entries in a
     red-black tree.  Virtual memory areas (VMAs) are tracked with red-black
index 30023568805e2a56077fa4cfbd088ee666522ab0..00301ed9c3715596b35411f46ff31243412444dd 100644 (file)
@@ -1,3 +1,50 @@
+1 Release Date    : Thur.  May 03, 2010 09:12:45 PST 2009 -
+                       (emaild-id:megaraidlinux@lsi.com)
+                       Bo Yang
+
+2 Current Version : 00.00.04.31-rc1
+3 Older Version   : 00.00.04.17.1-rc1
+
+1.     Add the Online Controller Reset (OCR) to the Driver.
+       OCR is the new feature for megaraid_sas driver which
+       will allow the fw to do the chip reset which will not
+       affact the OS behavious.
+
+       To add the OCR support, driver need to do:
+               a). reset the controller chips -- Xscale and Gen2 which
+               will change the function calls and add the reset function
+               related to this two chips.
+
+               b). during the reset, driver will store the pending cmds
+               which not returned by FW to driver's pending queue.  Driver
+               will re-issue those pending cmds again to FW after the OCR
+               finished.
+
+               c). In driver's timeout routine, driver will report to
+               OS as reset. Also driver's queue routine will block the
+               cmds until the OCR finished.
+
+               d). in Driver's ISR routine, if driver get the FW state as
+               state change, FW in Failure status and FW support online controller
+               reset (OCR), driver will start to do the controller reset.
+
+               e). In driver's IOCTL routine, the application cmds will wait for the
+               OCR to finish, then issue the cmds to FW.
+
+               f). Before driver kill adapter, driver will do last chance of
+               OCR to see if driver can bring back the FW.
+
+2.     Add the support update flag to the driver to tell LSI megaraid_sas
+       application which driver will support the device update.  So application
+       will not need to do the device update after application add/del the device
+       from the system.
+3.     In driver's timeout routine, driver will do three time reset if fw is in
+       failed state.  Driver will kill adapter if can't bring back FW after the
+       this three times reset.
+4.     Add the input parameter max_sectors to 1MB support to our GEN2 controller.
+       customer can use the input paramenter max_sectors to add 1MB support to GEN2
+       controller.
+
 1 Release Date    : Thur.  Oct 29, 2009 09:12:45 PST 2009 -
                        (emaild-id:megaraidlinux@lsi.com)
                        Bo Yang
index 3894eaa23486f951ace787893740ac2850f7d6d9..209e1584c3dc25e8e1af61a3061c779a28f5d11e 100644 (file)
@@ -28,6 +28,7 @@ show up in /proc/sys/kernel:
 - core_uses_pid
 - ctrl-alt-del
 - dentry-state
+- dmesg_restrict
 - domainname
 - hostname
 - hotplug
@@ -213,6 +214,19 @@ to decide what to do with it.
 
 ==============================================================
 
+dmesg_restrict:
+
+This toggle indicates whether unprivileged users are prevented from using
+dmesg(8) to view messages from the kernel's log buffer.  When
+dmesg_restrict is set to (0) there are no restrictions.  When
+dmesg_restrict is set set to (1), users must have CAP_SYS_ADMIN to use
+dmesg(8).
+
+The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default
+value of dmesg_restrict.
+
+==============================================================
+
 domainname & hostname:
 
 These files can be used to set the NIS/YP domainname and the
index cb8b580203524baa077ee0bea390efb3d559c4c4..8e6548dbd5db50c4e80f24fd9ae4bdd4597bd6c3 100644 (file)
@@ -161,7 +161,7 @@ M:  Greg Kroah-Hartman <gregkh@suse.de>
 L:     linux-serial@vger.kernel.org
 W:     http://serial.sourceforge.net
 S:     Maintained
-T:     quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
 F:     drivers/serial/8250*
 F:     include/linux/serial_8250.h
 
@@ -945,7 +945,7 @@ M:  Magnus Damm <magnus.damm@gmail.com>
 L:     linux-sh@vger.kernel.org
 W:     http://oss.renesas.com
 Q:     http://patchwork.kernel.org/project/linux-sh/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/genesis-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git rmobile-latest
 S:     Supported
 F:     arch/arm/mach-shmobile/
 F:     drivers/sh/
@@ -1757,6 +1757,7 @@ L:        linux-cris-kernel@axis.com
 W:     http://developer.axis.com
 S:     Maintained
 F:     arch/cris/
+F:     drivers/serial/crisv10.*
 
 CRYPTO API
 M:     Herbert Xu <herbert@gondor.apana.org.au>
@@ -2434,6 +2435,7 @@ F:        drivers/net/wan/sdla.c
 FRAMEBUFFER LAYER
 L:     linux-fbdev@vger.kernel.org
 W:     http://linux-fbdev.sourceforge.net/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6.git
 S:     Orphan
 F:     Documentation/fb/
 F:     drivers/video/fb*
@@ -5675,7 +5677,7 @@ S:        Maintained
 
 STAGING SUBSYSTEM
 M:     Greg Kroah-Hartman <gregkh@suse.de>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-next-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git
 L:     devel@driverdev.osuosl.org
 S:     Maintained
 F:     drivers/staging/
@@ -5704,7 +5706,7 @@ M:        Paul Mundt <lethal@linux-sh.org>
 L:     linux-sh@vger.kernel.org
 W:     http://www.linux-sh.org
 Q:     http://patchwork.kernel.org/project/linux-sh/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git sh-latest
 S:     Supported
 F:     Documentation/sh/
 F:     arch/sh/
@@ -5909,7 +5911,7 @@ S:        Maintained
 TTY LAYER
 M:     Greg Kroah-Hartman <gregkh@suse.de>
 S:     Maintained
-T:     quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
 F:     drivers/char/tty_*
 F:     drivers/serial/serial_core.c
 F:     include/linux/serial_core.h
@@ -6232,7 +6234,7 @@ USB SUBSYSTEM
 M:     Greg Kroah-Hartman <gregkh@suse.de>
 L:     linux-usb@vger.kernel.org
 W:     http://www.linux-usb.org
-T:     quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git
 S:     Supported
 F:     Documentation/usb/
 F:     drivers/net/usb/
@@ -6597,14 +6599,14 @@ F:      drivers/platform/x86
 
 XEN PCI SUBSYSTEM
 M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-L:     xen-devel@lists.xensource.com
+L:     xen-devel@lists.xensource.com (moderated for non-subscribers)
 S:     Supported
 F:     arch/x86/pci/*xen*
 F:     drivers/pci/*xen*
 
 XEN SWIOTLB SUBSYSTEM
 M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-L:     xen-devel@lists.xensource.com
+L:     xen-devel@lists.xensource.com (moderated for non-subscribers)
 S:     Supported
 F:     arch/x86/xen/*swiotlb*
 F:     drivers/xen/*swiotlb*
@@ -6612,7 +6614,7 @@ F:        drivers/xen/*swiotlb*
 XEN HYPERVISOR INTERFACE
 M:     Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
 M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-L:     xen-devel@lists.xen.org
+L:     xen-devel@lists.xensource.com (moderated for non-subscribers)
 L:     virtualization@lists.osdl.org
 S:     Supported
 F:     arch/x86/xen/
index 6b23f1b15fc473b0226bf8525b48a8a3a17c8b28..ab5359db3d177b2e4a83823baa15da908e5b395b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
-SUBLEVEL = 36
-EXTRAVERSION =
+SUBLEVEL = 37
+EXTRAVERSION = -rc2
 NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
@@ -204,6 +204,9 @@ ifeq ($(ARCH),x86_64)
 endif
 
 # Additional ARCH settings for sparc
+ifeq ($(ARCH),sparc32)
+       SRCARCH := sparc
+endif
 ifeq ($(ARCH),sparc64)
        SRCARCH := sparc
 endif
index 53d7f619a1b9b46643c59cd3c7d4ace354148c20..8bf0fa652eb63c57dec1ebfec1a93a407be4ed32 100644 (file)
@@ -42,6 +42,20 @@ config KPROBES
          for kernel debugging, non-intrusive instrumentation and testing.
          If in doubt, say "N".
 
+config JUMP_LABEL
+       bool "Optimize trace point call sites"
+       depends on HAVE_ARCH_JUMP_LABEL
+       help
+         If it is detected that the compiler has support for "asm goto",
+        the kernel will compile trace point locations with just a
+        nop instruction. When trace points are enabled, the nop will
+        be converted to a jump to the trace function. This technique
+        lowers overhead and stress on the branch prediction of the
+        processor.
+
+        On i386, options added to the compiler flags may increase
+        the size of the kernel slightly.
+
 config OPTPROBES
        def_bool y
        depends on KPROBES && HAVE_OPTPROBES
index b527bf5701c9126e4bca98abb56dc8b3ac0bea74..db524e75c4a21e4f45bc4b72e459adcdaf1dda4b 100644 (file)
@@ -6,7 +6,7 @@ config ARM
        select HAVE_MEMBLOCK
        select RTC_LIB
        select SYS_SUPPORTS_APM_EMULATION
-       select GENERIC_ATOMIC64 if (!CPU_32v6K)
+       select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI)
        select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
        select HAVE_ARCH_KGDB
        select HAVE_KPROBES if (!XIP_KERNEL)
@@ -646,7 +646,7 @@ config ARCH_S3C2410
        select ARCH_HAS_CPUFREQ
        select HAVE_CLK
        select ARCH_USES_GETTIMEOFFSET
-       select HAVE_S3C2410_I2C
+       select HAVE_S3C2410_I2C if I2C
        help
          Samsung S3C2410X CPU based systems, such as the Simtec Electronics
          BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
@@ -676,8 +676,8 @@ config ARCH_S3C64XX
        select S3C_DEV_NAND
        select USB_ARCH_HAS_OHCI
        select SAMSUNG_GPIOLIB_4BIT
-       select HAVE_S3C2410_I2C
-       select HAVE_S3C2410_WATCHDOG
+       select HAVE_S3C2410_I2C if I2C
+       select HAVE_S3C2410_WATCHDOG if WATCHDOG
        help
          Samsung S3C64XX series based systems
 
@@ -686,10 +686,10 @@ config ARCH_S5P64X0
        select CPU_V6
        select GENERIC_GPIO
        select HAVE_CLK
-       select HAVE_S3C2410_WATCHDOG
+       select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select ARCH_USES_GETTIMEOFFSET
-       select HAVE_S3C2410_I2C
-       select HAVE_S3C_RTC
+       select HAVE_S3C2410_I2C if I2C
+       select HAVE_S3C_RTC if RTC_CLASS
        help
          Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
          SMDK6450.
@@ -700,7 +700,7 @@ config ARCH_S5P6442
        select GENERIC_GPIO
        select HAVE_CLK
        select ARCH_USES_GETTIMEOFFSET
-       select HAVE_S3C2410_WATCHDOG
+       select HAVE_S3C2410_WATCHDOG if WATCHDOG
        help
          Samsung S5P6442 CPU based systems
 
@@ -711,31 +711,37 @@ config ARCH_S5PC100
        select CPU_V7
        select ARM_L1_CACHE_SHIFT_6
        select ARCH_USES_GETTIMEOFFSET
-       select HAVE_S3C2410_I2C
-       select HAVE_S3C_RTC
-       select HAVE_S3C2410_WATCHDOG
+       select HAVE_S3C2410_I2C if I2C
+       select HAVE_S3C_RTC if RTC_CLASS
+       select HAVE_S3C2410_WATCHDOG if WATCHDOG
        help
          Samsung S5PC100 series based systems
 
 config ARCH_S5PV210
        bool "Samsung S5PV210/S5PC110"
        select CPU_V7
+       select ARCH_SPARSEMEM_ENABLE
        select GENERIC_GPIO
        select HAVE_CLK
        select ARM_L1_CACHE_SHIFT_6
+       select ARCH_HAS_CPUFREQ
        select ARCH_USES_GETTIMEOFFSET
-       select HAVE_S3C2410_I2C
-       select HAVE_S3C_RTC
-       select HAVE_S3C2410_WATCHDOG
+       select HAVE_S3C2410_I2C if I2C
+       select HAVE_S3C_RTC if RTC_CLASS
+       select HAVE_S3C2410_WATCHDOG if WATCHDOG
        help
          Samsung S5PV210/S5PC110 series based systems
 
 config ARCH_S5PV310
        bool "Samsung S5PV310/S5PC210"
        select CPU_V7
+       select ARCH_SPARSEMEM_ENABLE
        select GENERIC_GPIO
        select HAVE_CLK
        select GENERIC_CLOCKEVENTS
+       select HAVE_S3C_RTC if RTC_CLASS
+       select HAVE_S3C2410_I2C if I2C
+       select HAVE_S3C2410_WATCHDOG if WATCHDOG
        help
          Samsung S5PV310 series based systems
 
@@ -1662,6 +1668,12 @@ if ARCH_HAS_CPUFREQ
 
 source "drivers/cpufreq/Kconfig"
 
+config CPU_FREQ_IMX
+       tristate "CPUfreq driver for i.MX CPUs"
+       depends on ARCH_MXC && CPU_FREQ
+       help
+         This enables the CPUfreq driver for i.MX CPUs.
+
 config CPU_FREQ_SA1100
        bool
 
index ada6359160ebef12614e9cd725449e5353a7a85b..772f95f1aecddf49ada9ceea0caa5295d22c9613 100644 (file)
@@ -251,15 +251,16 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
                writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
 
        /*
-        * Set priority on all interrupts.
+        * Set priority on all global interrupts.
         */
-       for (i = 0; i < max_irq; i += 4)
+       for (i = 32; i < max_irq; i += 4)
                writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
 
        /*
-        * Disable all interrupts.
+        * Disable all interrupts.  Leave the PPI and SGIs alone
+        * as these enables are banked registers.
         */
-       for (i = 0; i < max_irq; i += 32)
+       for (i = 32; i < max_irq; i += 32)
                writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
 
        /*
@@ -277,11 +278,30 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
 
 void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
 {
+       void __iomem *dist_base;
+       int i;
+
        if (gic_nr >= MAX_GIC_NR)
                BUG();
 
+       dist_base = gic_data[gic_nr].dist_base;
+       BUG_ON(!dist_base);
+
        gic_data[gic_nr].cpu_base = base;
 
+       /*
+        * Deal with the banked PPI and SGI interrupts - disable all
+        * PPI interrupts, ensure all SGI interrupts are enabled.
+        */
+       writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
+       writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
+
+       /*
+        * Set priority on PPI and SGI interrupts
+        */
+       for (i = 0; i < 32; i += 4)
+               writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
+
        writel(0xf0, base + GIC_CPU_PRIMASK);
        writel(1, base + GIC_CPU_CTRL);
 }
index 163cfee7644c72c3699cd807f5571d1e79aa6123..5c7a87260fab2cc41751905e25cec040096a5370 100644 (file)
@@ -82,6 +82,7 @@ CONFIG_FEC=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
 CONFIG_INPUT_EVBUG=m
 CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_PS2_ELANTECH=y
index 6bcba48800fe55224e81d4b9f426b43e8494cdef..cc42d5fdee17155e920d77ed753074aee0ade487 100644 (file)
@@ -21,9 +21,6 @@
 #define __ASM_ARM_HARDWARE_L2X0_H
 
 #define L2X0_CACHE_ID                  0x000
-#define   L2X0_CACHE_ID_PART_MASK      (0xf << 6)
-#define   L2X0_CACHE_ID_PART_L210      (1 << 6)
-#define   L2X0_CACHE_ID_PART_L310      (3 << 6)
 #define L2X0_CACHE_TYPE                        0x004
 #define L2X0_CTRL                      0x100
 #define L2X0_AUX_CTRL                  0x104
 #define L2X0_LINE_DATA                 0xF10
 #define L2X0_LINE_TAG                  0xF30
 #define L2X0_DEBUG_CTRL                        0xF40
+#define L2X0_PREFETCH_CTRL             0xF60
+#define L2X0_POWER_CTRL                        0xF80
+#define   L2X0_DYNAMIC_CLK_GATING_EN   (1 << 1)
+#define   L2X0_STNDBY_MODE_EN          (1 << 0)
+
+/* Registers shifts and masks */
+#define L2X0_CACHE_ID_PART_MASK                (0xf << 6)
+#define L2X0_CACHE_ID_PART_L210                (1 << 6)
+#define L2X0_CACHE_ID_PART_L310                (3 << 6)
+#define L2X0_AUX_CTRL_WAY_SIZE_MASK    (0x3 << 17)
 
 #ifndef __ASSEMBLY__
 extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
index 6700c7fc7ebd2e3cfc03e9a11accba01e58440e3..21fa272301f804b9bad3218b74147f6e450fa026 100644 (file)
@@ -75,7 +75,7 @@ extern unsigned long it8152_base_address;
   IT8152_PD_IRQ(1)  USB (USBR)
   IT8152_PD_IRQ(0)  Audio controller (ACR)
  */
-#define IT8152_IRQ(x)   (IRQ_BOARD_END + (x))
+#define IT8152_IRQ(x)   (IRQ_BOARD_START + (x))
 
 /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
 #define IT8152_LD_IRQ_COUNT     9
index 08265993227fc1d03bec79f7a420f63c005a3f2c..48066ce9ea34f64961111c487fbc4f26e037b842 100644 (file)
@@ -70,7 +70,8 @@ extern int kgdb_fault_expected;
 #define _GP_REGS               16
 #define _FP_REGS               8
 #define _EXTRA_REGS            2
-#define DBG_MAX_REG_NUM                (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
+#define GDB_MAX_REGS           (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
+#define DBG_MAX_REG_NUM                (_GP_REGS + _FP_REGS + _EXTRA_REGS)
 
 #define KGDB_MAX_NO_CPUS       1
 #define BUFMAX                 400
@@ -93,7 +94,7 @@ extern int kgdb_fault_expected;
 #define _SPT                   13
 #define _LR                    14
 #define _PC                    15
-#define _CPSR                  (DBG_MAX_REG_NUM - 1)
+#define _CPSR                  (GDB_MAX_REGS - 1)
 
 /*
  * So that we can denote the end of a frame for tracing,
index fdbc43b2e6c05ac45a0d7f8d0692eb013e5ed862..b8da2e415e4eb21a870cbb52333b5400a50ad163 100644 (file)
@@ -1,13 +1,6 @@
 #ifndef _ASM_ARM_MEMBLOCK_H
 #define _ASM_ARM_MEMBLOCK_H
 
-#ifdef CONFIG_MMU
-extern phys_addr_t lowmem_end_addr;
-#define MEMBLOCK_REAL_LIMIT    lowmem_end_addr
-#else
-#define MEMBLOCK_REAL_LIMIT    0
-#endif
-
 struct meminfo;
 struct machine_desc;
 
index 25f76bae57ab4e169cc03c977160e28f046e0ca1..fc19009252753314e3e4b1f3b3d46e3183eddf91 100644 (file)
@@ -25,6 +25,9 @@ struct outer_cache_fns {
        void (*inv_range)(unsigned long, unsigned long);
        void (*clean_range)(unsigned long, unsigned long);
        void (*flush_range)(unsigned long, unsigned long);
+       void (*flush_all)(void);
+       void (*inv_all)(void);
+       void (*disable)(void);
 #ifdef CONFIG_OUTER_CACHE_SYNC
        void (*sync)(void);
 #endif
@@ -50,6 +53,24 @@ static inline void outer_flush_range(unsigned long start, unsigned long end)
                outer_cache.flush_range(start, end);
 }
 
+static inline void outer_flush_all(void)
+{
+       if (outer_cache.flush_all)
+               outer_cache.flush_all();
+}
+
+static inline void outer_inv_all(void)
+{
+       if (outer_cache.inv_all)
+               outer_cache.inv_all();
+}
+
+static inline void outer_disable(void)
+{
+       if (outer_cache.disable)
+               outer_cache.disable();
+}
+
 #else
 
 static inline void outer_inv_range(unsigned long start, unsigned long end)
@@ -58,6 +79,9 @@ static inline void outer_clean_range(unsigned long start, unsigned long end)
 { }
 static inline void outer_flush_range(unsigned long start, unsigned long end)
 { }
+static inline void outer_flush_all(void) { }
+static inline void outer_inv_all(void) { }
+static inline void outer_disable(void) { }
 
 #endif
 
index 54593b0c241b4ec78d7b6f23356666787eedd7b4..21e3a4ab3b8c58047304b694aa8161b9ebbf1c31 100644 (file)
@@ -748,8 +748,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
                breakpoint_handler(addr, regs);
                break;
        case ARM_ENTRY_ASYNC_WATCHPOINT:
-               WARN_ON("Asynchronous watchpoint exception taken. "
-                       "Debugging results may be unreliable");
+               WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n");
        case ARM_ENTRY_SYNC_WATCHPOINT:
                watchpoint_handler(addr, regs);
                break;
index d6e8b4d2e60dacde3ceff47584fe43b75ddb496d..778c2f7024ff57304227ce67665e749f39b05fc7 100644 (file)
@@ -79,7 +79,7 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
                return;
 
        /* Initialize to zero */
-       for (regno = 0; regno < DBG_MAX_REG_NUM; regno++)
+       for (regno = 0; regno < GDB_MAX_REGS; regno++)
                gdb_regs[regno] = 0;
 
        /* Otherwise, we have only some registers from switch_to() */
index 1fc74cbd1a193ee4dcd2fd50afdd279804d9e5fd..3a8fd5140d7a52ef33c8bfc444384ab8bc25c84a 100644 (file)
@@ -78,7 +78,10 @@ void machine_kexec(struct kimage *image)
        local_fiq_disable();
        setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
        flush_cache_all();
+       outer_flush_all();
+       outer_disable();
        cpu_proc_fin();
+       outer_inv_all();
        flush_cache_all();
        cpu_reset(reboot_code_buffer_phys);
 }
index 49643b1467e62d529d4edd661990bb64da1e1f73..07a50357492ac6858bc21d0b7913aefc93cbb1cf 100644 (file)
@@ -1749,7 +1749,7 @@ static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
 static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
                                        enum armv7_counters counter)
 {
-       int ret;
+       int ret = 0;
 
        if (counter == ARMV7_CYCLE_COUNTER)
                ret = pmnc & ARMV7_FLAG_C;
index 20b7411e47fdeef9e31606e665957ea862638f5a..c2e112e1a05fbf0d4485db1236448653e25aa8cc 100644 (file)
@@ -28,7 +28,7 @@ int notrace unwind_frame(struct stackframe *frame)
 
        /* only go to a higher address on the stack */
        low = frame->sp;
-       high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE;
+       high = ALIGN(low, THREAD_SIZE);
 
        /* check current frame pointer is within bounds */
        if (fp < (low + 12) || fp + 4 >= high)
index cda78d59aa31b2971ed897b9db78afd6bfb0f36e..446aee97436f22b82ba7d2f16a06d74b507b7042 100644 (file)
@@ -53,10 +53,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
 void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
 {
 #ifdef CONFIG_KALLSYMS
-       char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN];
-       sprint_symbol(sym1, where);
-       sprint_symbol(sym2, from);
-       printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
+       printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
 #else
        printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
 #endif
index 2a161765f6d5fdc0ac07805c2a4a62957adf72a0..d2cb0b3c987216b4b7eea39289b739fbc7d0136d 100644 (file)
@@ -279,7 +279,7 @@ int unwind_frame(struct stackframe *frame)
 
        /* only go to a higher address on the stack */
        low = frame->sp;
-       high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE;
+       high = ALIGN(low, THREAD_SIZE);
 
        pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
                 frame->pc, frame->lr, frame->sp);
index 1953e3d21abf28e112b13bdc5f60f03774d6a32e..cead8893b46bc2d91ac156b9c8382c8aa4ebc71f 100644 (file)
@@ -113,6 +113,7 @@ SECTIONS
                        *(.rodata.*)
                        *(.glue_7)
                        *(.glue_7t)
+               . = ALIGN(4);
                *(.got)                 /* Global offset table          */
                        ARM_CPU_KEEP(PROC_INFO)
        }
index 3a5961d3f3b1bf810c8d7d8369132fc64fcee54e..5e31b2b25da95a4511ddfc431d320c24c7c93211 100644 (file)
@@ -1,5 +1,13 @@
-/*
- * arch/arm/mach-ep93xx/include/mach/dma.h
+/**
+ * DOC: EP93xx DMA M2P memory to peripheral and peripheral to memory engine
+ *
+ * The EP93xx DMA M2P subsystem handles DMA transfers between memory and
+ * peripherals. DMA M2P channels are available for audio, UARTs and IrDA.
+ * See chapter 10 of the EP93xx users guide for full details on the DMA M2P
+ * engine.
+ *
+ * See sound/soc/ep93xx/ep93xx-pcm.c for an example use of the DMA M2P code.
+ *
  */
 
 #ifndef __ASM_ARCH_DMA_H
 #include <linux/list.h>
 #include <linux/types.h>
 
+/**
+ * struct ep93xx_dma_buffer - Information about a buffer to be transferred
+ * using the DMA M2P engine
+ *
+ * @list: Entry in DMA buffer list
+ * @bus_addr: Physical address of the buffer
+ * @size: Size of the buffer in bytes
+ */
 struct ep93xx_dma_buffer {
        struct list_head        list;
        u32                     bus_addr;
        u16                     size;
 };
 
+/**
+ * struct ep93xx_dma_m2p_client - Information about a DMA M2P client
+ *
+ * @name: Unique name for this client
+ * @flags: Client flags
+ * @cookie: User data to pass to callback functions
+ * @buffer_started: Non NULL function to call when a transfer is started.
+ *                     The arguments are the user data cookie and the DMA
+ *                     buffer which is starting.
+ * @buffer_finished: Non NULL function to call when a transfer is completed.
+ *                     The arguments are the user data cookie, the DMA buffer
+ *                     which has completed, and a boolean flag indicating if
+ *                     the transfer had an error.
+ */
 struct ep93xx_dma_m2p_client {
        char                    *name;
        u8                      flags;
@@ -24,10 +54,11 @@ struct ep93xx_dma_m2p_client {
                                        struct ep93xx_dma_buffer *buf,
                                        int bytes, int error);
 
-       /* Internal to the DMA code.  */
+       /* private: Internal use only */
        void                    *channel;
 };
 
+/* DMA M2P ports */
 #define EP93XX_DMA_M2P_PORT_I2S1       0x00
 #define EP93XX_DMA_M2P_PORT_I2S2       0x01
 #define EP93XX_DMA_M2P_PORT_AAC1       0x02
@@ -39,18 +70,80 @@ struct ep93xx_dma_m2p_client {
 #define EP93XX_DMA_M2P_PORT_UART3      0x08
 #define EP93XX_DMA_M2P_PORT_IRDA       0x09
 #define EP93XX_DMA_M2P_PORT_MASK       0x0f
-#define EP93XX_DMA_M2P_TX              0x00
-#define EP93XX_DMA_M2P_RX              0x10
-#define EP93XX_DMA_M2P_ABORT_ON_ERROR  0x20
-#define EP93XX_DMA_M2P_IGNORE_ERROR    0x40
-#define EP93XX_DMA_M2P_ERROR_MASK      0x60
 
-int  ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p);
+/* DMA M2P client flags */
+#define EP93XX_DMA_M2P_TX              0x00    /* Memory to peripheral */
+#define EP93XX_DMA_M2P_RX              0x10    /* Peripheral to memory */
+
+/*
+ * DMA M2P client error handling flags. See the EP93xx users guide
+ * documentation on the DMA M2P CONTROL register for more details
+ */
+#define EP93XX_DMA_M2P_ABORT_ON_ERROR  0x20    /* Abort on peripheral error */
+#define EP93XX_DMA_M2P_IGNORE_ERROR    0x40    /* Ignore peripheral errors */
+#define EP93XX_DMA_M2P_ERROR_MASK      0x60    /* Mask of error bits */
+
+/**
+ * ep93xx_dma_m2p_client_register - Register a client with the DMA M2P
+ * subsystem
+ *
+ * @m2p: Client information to register
+ * returns 0 on success
+ *
+ * The DMA M2P subsystem allocates a channel and an interrupt line for the DMA
+ * client
+ */
+int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p);
+
+/**
+ * ep93xx_dma_m2p_client_unregister - Unregister a client from the DMA M2P
+ * subsystem
+ *
+ * @m2p: Client to unregister
+ *
+ * Any transfers currently in progress will be completed in hardware, but
+ * ignored in software.
+ */
 void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p);
+
+/**
+ * ep93xx_dma_m2p_submit - Submit a DMA M2P transfer
+ *
+ * @m2p: DMA Client to submit the transfer on
+ * @buf: DMA Buffer to submit
+ *
+ * If the current or next transfer positions are free on the M2P client then
+ * the transfer is started immediately. If not, the transfer is added to the
+ * list of pending transfers. This function must not be called from the
+ * buffer_finished callback for an M2P channel.
+ *
+ */
 void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p,
                           struct ep93xx_dma_buffer *buf);
+
+/**
+ * ep93xx_dma_m2p_submit_recursive - Put a DMA transfer on the pending list
+ * for an M2P channel
+ *
+ * @m2p: DMA Client to submit the transfer on
+ * @buf: DMA Buffer to submit
+ *
+ * This function must only be called from the buffer_finished callback for an
+ * M2P channel. It is commonly used to add the next transfer in a chained list
+ * of DMA transfers.
+ */
 void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p,
                                     struct ep93xx_dma_buffer *buf);
+
+/**
+ * ep93xx_dma_m2p_flush - Flush all pending transfers on a DMA M2P client
+ *
+ * @m2p: DMA client to flush transfers on
+ *
+ * Any transfers currently in progress will be completed in hardware, but
+ * ignored in software.
+ *
+ */
 void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *m2p);
 
 #endif /* __ASM_ARCH_DMA_H */
index b8bbd31aa850c4332a602d92a79e0d8749afe4fb..84a5ba03f1bae3d2275743b741a30267cd9ee03a 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/irq.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/iomux-mx27.h>
+#include <mach/mmc.h>
 
 #include "devices-imx27.h"
 #include "devices.h"
 
+#define SD1_EN_GPIO (GPIO_PORTB + 25)
+
 static const int mx27pdk_pins[] __initconst = {
        /* UART1 */
        PE12_PF_UART1_TXD,
@@ -58,6 +62,14 @@ static const int mx27pdk_pins[] __initconst = {
        PD15_AOUT_FEC_COL,
        PD16_AIN_FEC_TX_ER,
        PF23_AIN_FEC_TX_EN,
+       /* SDHC1 */
+       PE18_PF_SD1_D0,
+       PE19_PF_SD1_D1,
+       PE20_PF_SD1_D2,
+       PE21_PF_SD1_D3,
+       PE22_PF_SD1_CMD,
+       PE23_PF_SD1_CLK,
+       SD1_EN_GPIO | GPIO_GPIO | GPIO_OUT,
 };
 
 static const struct imxuart_platform_data uart_pdata __initconst = {
@@ -85,13 +97,39 @@ static struct matrix_keymap_data mx27_3ds_keymap_data = {
        .keymap_size    = ARRAY_SIZE(mx27_3ds_keymap),
 };
 
+static int mx27_3ds_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+                               void *data)
+{
+       return request_irq(IRQ_GPIOB(26), detect_irq, IRQF_TRIGGER_FALLING |
+                       IRQF_TRIGGER_RISING, "sdhc1-card-detect", data);
+}
+
+static void mx27_3ds_sdhc1_exit(struct device *dev, void *data)
+{
+       free_irq(IRQ_GPIOB(26), data);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+       .init = mx27_3ds_sdhc1_init,
+       .exit = mx27_3ds_sdhc1_exit,
+};
+
+static void mx27_3ds_sdhc1_enable_level_translator(void)
+{
+       /* Turn on TXB0108 OE pin */
+       gpio_request(SD1_EN_GPIO, "sd1_enable");
+       gpio_direction_output(SD1_EN_GPIO, 1);
+}
+
 static void __init mx27pdk_init(void)
 {
        mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
                "mx27pdk");
+       mx27_3ds_sdhc1_enable_level_translator();
        imx27_add_imx_uart0(&uart_pdata);
        imx27_add_fec(NULL);
        mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data);
+       mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
 }
 
 static void __init mx27pdk_timer_init(void)
index babb22597163b5d2296983dccfc6bfba49a2ba77..e24e3d05397fd3070b7b553d2976b6022cee2201 100644 (file)
@@ -197,7 +197,7 @@ unsigned long ixp2000_gettimeoffset (void)
        return offset / ticks_per_usec;
 }
 
-static int ixp2000_timer_interrupt(int irq, void *dev_id)
+static irqreturn_t ixp2000_timer_interrupt(int irq, void *dev_id)
 {
        /* clear timer 1 */
        ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
index 51ff23b72d3a3e8d6982b031dd36df0c3c1cc711..3688123b5ad8e5ea233b1346f22d19e3ec149030 100644 (file)
@@ -854,10 +854,9 @@ int __init kirkwood_find_tclk(void)
 
        kirkwood_pcie_id(&dev, &rev);
 
-       if ((dev == MV88F6281_DEV_ID && (rev == MV88F6281_REV_A0 ||
-                                       rev == MV88F6281_REV_A1)) ||
-           (dev == MV88F6282_DEV_ID))
-               return 200000000;
+       if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID)
+               if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0)
+                       return 200000000;
 
        return 166666667;
 }
index 4aa86e4a152c22bc2707463b85d1f3d98240a509..a31c9499ab36c6a0f235e39cf22e4bd7f522d14c 100644 (file)
@@ -225,5 +225,5 @@ MACHINE_START(D2NET_V2, "LaCie d2 Network v2")
        .init_machine   = d2net_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &lacie_v2_timer,
+       .timer          = &kirkwood_timer,
 MACHINE_END
index d3ea1b6c8a02ff8790db0bf51d61f6643028cbc0..285edab776e9f5f389be444c343d7246694058ea 100644 (file)
@@ -111,17 +111,3 @@ void __init lacie_v2_hdd_power_init(int hdd_num)
                        pr_err("Failed to power up HDD%d\n", i + 1);
        }
 }
-
-/*****************************************************************************
- * Timer
- ****************************************************************************/
-
-static void lacie_v2_timer_init(void)
-{
-       kirkwood_tclk = 166666667;
-       orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
-}
-
-struct sys_timer lacie_v2_timer = {
-       .init = lacie_v2_timer_init,
-};
index af521315b87bd621152cac1ae086edfa1db45373..fc64f578536ecc10f74517e991d948c81c331c14 100644 (file)
@@ -13,6 +13,4 @@ void lacie_v2_register_flash(void);
 void lacie_v2_register_i2c_devices(void);
 void lacie_v2_hdd_power_init(int hdd_num);
 
-extern struct sys_timer lacie_v2_timer;
-
 #endif
index 065187d177c6299f12543c3198c23c7cbd8f2476..27901f702feb28d5f4c5a0ff6ce9acbc0780af9d 100644 (file)
@@ -59,7 +59,7 @@ void __init kirkwood_mpp_conf(unsigned int *mpp_list)
        }
        printk("\n");
 
-       while (*mpp_list) {
+       for ( ; *mpp_list; mpp_list++) {
                unsigned int num = MPP_NUM(*mpp_list);
                unsigned int sel = MPP_SEL(*mpp_list);
                int shift, gpio_mode;
@@ -88,8 +88,6 @@ void __init kirkwood_mpp_conf(unsigned int *mpp_list)
                if (sel != 0)
                        gpio_mode = 0;
                orion_gpio_set_valid(num, gpio_mode);
-
-               mpp_list++;
        }
 
        printk(KERN_DEBUG "  final MPP regs:");
index 5ea66f1f4178b0b846cfb42e6e600ddb2d3a1f87..65ee21fd2f3bd5657ede5a034924c47e4a3cd6f8 100644 (file)
@@ -262,7 +262,7 @@ MACHINE_START(NETSPACE_V2, "LaCie Network Space v2")
        .init_machine   = netspace_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &lacie_v2_timer,
+       .timer          = &kirkwood_timer,
 MACHINE_END
 #endif
 
@@ -272,7 +272,7 @@ MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2")
        .init_machine   = netspace_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &lacie_v2_timer,
+       .timer          = &kirkwood_timer,
 MACHINE_END
 #endif
 
@@ -282,6 +282,6 @@ MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2")
        .init_machine   = netspace_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &lacie_v2_timer,
+       .timer          = &kirkwood_timer,
 MACHINE_END
 #endif
index a1b45d501aef57393a47e0d99e67a423ae3355fc..93afd3c8bfd8a66fdb80bdf6acf0cbc1538c31ed 100644 (file)
@@ -403,7 +403,7 @@ MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2")
        .init_machine   = netxbig_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &lacie_v2_timer,
+       .timer          = &kirkwood_timer,
 MACHINE_END
 #endif
 
@@ -413,6 +413,6 @@ MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2")
        .init_machine   = netxbig_v2_init,
        .map_io         = kirkwood_map_io,
        .init_irq       = kirkwood_init_irq,
-       .timer          = &lacie_v2_timer,
+       .timer          = &kirkwood_timer,
 MACHINE_END
 #endif
index 8be09a0ce4ac724a8e5981dba3ab1a723f5e77f5..3587a281d993825076e9e16032ad4c8b76ec4b88 100644 (file)
 #include "mpp.h"
 #include "tsx1x-common.h"
 
+/* for the PCIe reset workaround */
+#include <plat/pcie.h>
+
+
 #define QNAP_TS41X_JUMPER_JP1  45
 
 static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = {
@@ -140,8 +144,16 @@ static void __init qnap_ts41x_init(void)
 
 static int __init ts41x_pci_init(void)
 {
-       if (machine_is_ts41x())
+       if (machine_is_ts41x()) {
+               /*
+                * Without this explicit reset, the PCIe SATA controller
+                * (Marvell 88sx7042/sata_mv) is known to stop working
+                * after a few minutes.
+                */
+               orion_pcie_reset((void __iomem *)PCIE_VIRT_BASE);
+
                kirkwood_pcie_init(KW_PCIE0);
+       }
 
    return 0;
 }
index f43a68b213f111a200e0395638e3cc538e442b3e..8a3b56dfd35d7af96d47b367e5ccf0078d5d2f08 100644 (file)
@@ -46,7 +46,8 @@ static inline int cpu_is_pxa910(void)
 #ifdef CONFIG_CPU_MMP2
 static inline int cpu_is_mmp2(void)
 {
-       return (((cpu_readid_id() >> 8) & 0xff) == 0x58);
+       return (((read_cpuid_id() >> 8) & 0xff) == 0x58);
+}
 #else
 #define cpu_is_mmp2()  (0)
 #endif
index 3115a29dec4ea58b867cfa0dab424833ecbf7e5f..dbbcfeb919db44bd12ff98605561198f16f118c5 100644 (file)
@@ -6,6 +6,7 @@ choice
 
 config ARCH_MSM7X00A
        bool "MSM7x00A / MSM7x01A"
+       select MACH_TROUT if !MACH_HALIBUT
        select ARCH_MSM_ARM11
        select MSM_SMD
        select MSM_SMD_PKG3
@@ -15,34 +16,34 @@ config ARCH_MSM7X00A
 
 config ARCH_MSM7X30
        bool "MSM7x30"
+       select MACH_MSM7X30_SURF # if !
        select ARCH_MSM_SCORPION
        select MSM_SMD
        select MSM_VIC
        select CPU_V7
-       select MSM_REMOTE_SPINLOCK_DEKKERS
        select MSM_GPIOMUX
        select MSM_PROC_COMM
        select HAS_MSM_DEBUG_UART_PHYS
 
 config ARCH_QSD8X50
        bool "QSD8X50"
+       select MACH_QSD8X50_SURF if !MACH_QSD8X50A_ST1_5
        select ARCH_MSM_SCORPION
        select MSM_SMD
        select MSM_VIC
        select CPU_V7
-       select MSM_REMOTE_SPINLOCK_LDREX
        select MSM_GPIOMUX
        select MSM_PROC_COMM
        select HAS_MSM_DEBUG_UART_PHYS
 
 config ARCH_MSM8X60
        bool "MSM8X60"
+       select MACH_MSM8X60_SURF if (!MACH_MSM8X60_RUMI3 && !MACH_MSM8X60_SIM \
+                                 && !MACH_MSM8X60_FFA)
        select ARM_GIC
        select CPU_V7
        select MSM_V2_TLMM
        select MSM_GPIOMUX
-       select MACH_MSM8X60_SURF if (!MACH_MSM8X60_RUMI3 && !MACH_MSM8X60_SIM \
-                                 && !MACH_MSM8X60_FFA)
 
 endchoice
 
index 59edecbe126cc5ab6df4d925ff19458a06167537..75dabb16c802380d6a02e06a1807afe72282cfc9 100644 (file)
@@ -83,7 +83,6 @@ static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags,
 {
        mi->nr_banks=1;
        mi->bank[0].start = PHYS_OFFSET;
-       mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
        mi->bank[0].size = (101*1024*1024);
 }
 
index fbd5d90dcc8ce36ec411e8b8d1be04613a2742f0..646b99ebc77317fba49910dfa3391a0ebef66fca 100644 (file)
@@ -19,7 +19,7 @@
 #include <mach/hardware.h>
 #include <mach/msm_iomap.h>
 
-#ifdef CONFIG_HAS_MSM_DEBUG_UART_PHYS
+#if defined(CONFIG_HAS_MSM_DEBUG_UART_PHYS) && !defined(CONFIG_MSM_DEBUG_UART_NONE)
        .macro  addruart, rp, rv
        ldr     \rp, =MSM_DEBUG_UART_PHYS
        ldr     \rv, =MSM_DEBUG_UART_BASE
        tst     \rd, #0x04
        beq     1001b
        .endm
+#else
+       .macro  addruart, rp, rv
+       mov     \rv, #0xff000000
+       orr     \rv, \rv, #0x00f00000
+       .endm
 
-       .macro  busyuart,rd,rx
+       .macro  senduart,rd,rx
+       .endm
+
+       .macro  waituart,rd,rx
        .endm
 #endif
+
+       .macro  busyuart,rd,rx
+       .endm
index c33ae786c41fb12698a8e8bb85018eb710fecdef..9019cee2907b2a24e833dd3f40ce7da14662eecc 100644 (file)
@@ -128,7 +128,7 @@ static void msm_iommu_reset(void __iomem *base)
 
 static int msm_iommu_probe(struct platform_device *pdev)
 {
-       struct resource *r;
+       struct resource *r, *r2;
        struct clk *iommu_clk;
        struct msm_iommu_drvdata *drvdata;
        struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
@@ -183,27 +183,27 @@ static int msm_iommu_probe(struct platform_device *pdev)
 
                len = r->end - r->start + 1;
 
-               r = request_mem_region(r->start, len, r->name);
-               if (!r) {
+               r2 = request_mem_region(r->start, len, r->name);
+               if (!r2) {
                        pr_err("Could not request memory region: "
                        "start=%p, len=%d\n", (void *) r->start, len);
                        ret = -EBUSY;
                        goto fail;
                }
 
-               regs_base = ioremap(r->start, len);
+               regs_base = ioremap(r2->start, len);
 
                if (!regs_base) {
                        pr_err("Could not ioremap: start=%p, len=%d\n",
-                                (void *) r->start, len);
+                                (void *) r2->start, len);
                        ret = -EBUSY;
-                       goto fail;
+                       goto fail_mem;
                }
 
                irq = platform_get_irq_byname(pdev, "secure_irq");
                if (irq < 0) {
                        ret = -ENODEV;
-                       goto fail;
+                       goto fail_io;
                }
 
                mb();
@@ -211,14 +211,14 @@ static int msm_iommu_probe(struct platform_device *pdev)
                if (GET_IDR(regs_base) == 0) {
                        pr_err("Invalid IDR value detected\n");
                        ret = -ENODEV;
-                       goto fail;
+                       goto fail_io;
                }
 
                ret = request_irq(irq, msm_iommu_fault_handler, 0,
                                "msm_iommu_secure_irpt_handler", drvdata);
                if (ret) {
                        pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
-                       goto fail;
+                       goto fail_io;
                }
 
                msm_iommu_reset(regs_base);
@@ -237,6 +237,10 @@ static int msm_iommu_probe(struct platform_device *pdev)
 
        return 0;
 
+fail_io:
+       iounmap(regs_base);
+fail_mem:
+       release_mem_region(r->start, len);
 fail:
        kfree(drvdata);
        return ret;
index 7689848ec680d28a322040e9bf8e9c7764de27ac..950100f19d0786a866927a2374ab5d4d6156db85 100644 (file)
@@ -137,7 +137,7 @@ static struct msm_clock msm_clocks[] = {
                        .rating         = 200,
                        .read           = msm_gpt_read,
                        .mask           = CLOCKSOURCE_MASK(32),
-                       .shift          = 24,
+                       .shift          = 17,
                        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
                },
                .irq = {
index 354ac514eb899125121eb84127bcb93deac2a115..84db2dfc475ca9b24f5b30fad2637ee099de08f6 100644 (file)
@@ -54,7 +54,7 @@ void __init mv78xx0_mpp_conf(unsigned int *mpp_list)
        }
        printk("\n");
 
-       while (*mpp_list) {
+       for ( ; *mpp_list; mpp_list++) {
                unsigned int num = MPP_NUM(*mpp_list);
                unsigned int sel = MPP_SEL(*mpp_list);
                int shift, gpio_mode;
@@ -83,8 +83,6 @@ void __init mv78xx0_mpp_conf(unsigned int *mpp_list)
                if (sel != 0)
                        gpio_mode = 0;
                orion_gpio_set_valid(num, gpio_mode);
-
-               mpp_list++;
        }
 
        printk(KERN_DEBUG "  final MPP regs:");
index aa57e35ce3cd2c097cd0af5bb8f56d75480c87bd..38ca09a5df9d1ebe07c74279b6e1296555e387ec 100644 (file)
@@ -6,6 +6,7 @@ config MACH_MX25_3DS
        bool "Support MX25PDK (3DS) Platform"
        select IMX_HAVE_PLATFORM_IMX_UART
        select IMX_HAVE_PLATFORM_MXC_NAND
+       select IMX_HAVE_PLATFORM_ESDHC
 
 config MACH_EUKREA_CPUIMX25
        bool "Support Eukrea CPUIMX25 Platform"
index 80805107a73eb74bbf7b18d2e22fd7b18e194965..f8be1eb0c062685eb6193dd2664bc544a46f1458 100644 (file)
@@ -96,6 +96,14 @@ static struct pad_desc mx25pdk_pads[] = {
        MX25_PAD_KPP_COL1__KPP_COL1,
        MX25_PAD_KPP_COL2__KPP_COL2,
        MX25_PAD_KPP_COL3__KPP_COL3,
+
+       /* SD1 */
+       MX25_PAD_SD1_CMD__SD1_CMD,
+       MX25_PAD_SD1_CLK__SD1_CLK,
+       MX25_PAD_SD1_DATA0__SD1_DATA0,
+       MX25_PAD_SD1_DATA1__SD1_DATA1,
+       MX25_PAD_SD1_DATA2__SD1_DATA2,
+       MX25_PAD_SD1_DATA3__SD1_DATA3,
 };
 
 static const struct fec_platform_data mx25_fec_pdata __initconst = {
@@ -193,6 +201,8 @@ static void __init mx25pdk_init(void)
        mx25pdk_fec_reset();
        imx25_add_fec(&mx25_fec_pdata);
        mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data);
+
+       imx25_add_esdhc(0, NULL);
 }
 
 static void __init mx25pdk_timer_init(void)
index 096fd33f8ab9ad6b77c4689361be00172f3bd327..5000ac1f93e3d2838cc7e7f915694214292e38dd 100644 (file)
@@ -143,8 +143,10 @@ config MACH_ARMADILLO5X0
 config MACH_MX35_3DS
        bool "Support MX35PDK platform"
        select ARCH_MX35
+       select MXC_DEBUG_BOARD
        select IMX_HAVE_PLATFORM_IMX_UART
        select IMX_HAVE_PLATFORM_MXC_NAND
+       select IMX_HAVE_PLATFORM_ESDHC
        default n
        help
          Include support for MX35PDK platform. This includes specific
index f4dff11aaee7a68aa58fb9a07a43aca9662f6856..d4da9496089a6ea08eba3cd86714822f811475c5 100644 (file)
@@ -72,24 +72,24 @@ struct platform_device mxc_w1_master_device = {
 #ifdef CONFIG_ARCH_MX31
 static struct resource mxcsdhc0_resources[] = {
        {
-               .start = MMC_SDHC1_BASE_ADDR,
-               .end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
+               .start = MX31_MMC_SDHC1_BASE_ADDR,
+               .end = MX31_MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
                .flags = IORESOURCE_MEM,
        }, {
-               .start = MXC_INT_MMC_SDHC1,
-               .end = MXC_INT_MMC_SDHC1,
+               .start = MX31_INT_MMC_SDHC1,
+               .end = MX31_INT_MMC_SDHC1,
                .flags = IORESOURCE_IRQ,
        },
 };
 
 static struct resource mxcsdhc1_resources[] = {
        {
-               .start = MMC_SDHC2_BASE_ADDR,
-               .end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
+               .start = MX31_MMC_SDHC2_BASE_ADDR,
+               .end = MX31_MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
                .flags = IORESOURCE_MEM,
        }, {
-               .start = MXC_INT_MMC_SDHC2,
-               .end = MXC_INT_MMC_SDHC2,
+               .start = MX31_INT_MMC_SDHC2,
+               .end = MX31_INT_MMC_SDHC2,
                .flags = IORESOURCE_IRQ,
        },
 };
index 5c1d0e86c91e16fd22e0ed2f4d1c190eb87f3a58..0ad9e78210826a37e0883707df6a1078c2d868ce 100644 (file)
 #include "devices-imx31.h"
 #include "devices.h"
 
-/* Definitions for components on the Debug board */
-
-/* Base address of CPLD controller on the Debug board */
-#define DEBUG_BASE_ADDRESS             CS5_IO_ADDRESS(MX3x_CS5_BASE_ADDR)
-
-/* LAN9217 ethernet base address */
-#define LAN9217_BASE_ADDR              MX3x_CS5_BASE_ADDR
-
-/* CPLD config and interrupt base address */
-#define CPLD_ADDR                      (DEBUG_BASE_ADDRESS + 0x20000)
-
-/* status, interrupt */
-#define CPLD_INT_STATUS_REG            (CPLD_ADDR + 0x10)
-#define CPLD_INT_MASK_REG              (CPLD_ADDR + 0x38)
-#define CPLD_INT_RESET_REG             (CPLD_ADDR + 0x20)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER1_REG         (CPLD_ADDR + 0x40)
-#define CPLD_MAGIC_NUMBER2_REG         (CPLD_ADDR + 0x48)
-/* CPLD code version */
-#define CPLD_CODE_VER_REG              (CPLD_ADDR + 0x50)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER3_REG         (CPLD_ADDR + 0x58)
-
 /* CPLD IRQ line for external uart, external ethernet etc */
 #define EXPIO_PARENT_INT       IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
 
-#define MXC_EXP_IO_BASE                (MXC_BOARD_IRQ_START)
-#define MXC_IRQ_TO_EXPIO(irq)  ((irq) - MXC_EXP_IO_BASE)
-
-#define EXPIO_INT_ENET         (MXC_EXP_IO_BASE + 0)
-
-#define MXC_MAX_EXP_IO_LINES   16
-
 /*
  * This file contains the board-specific initialization routines.
  */
@@ -272,7 +242,7 @@ static void __init mxc_board_init(void)
        imx31_add_imx_uart0(&uart_pdata);
        imx31_add_mxc_nand(&mx31_3ds_nand_board_info);
 
-       imx31_add_spi_imx0(&spi1_pdata);
+       imx31_add_spi_imx1(&spi1_pdata);
        spi_register_board_info(mx31_3ds_spi_devs,
                                                ARRAY_SIZE(mx31_3ds_spi_devs));
 
@@ -281,9 +251,9 @@ static void __init mxc_board_init(void)
        mx31_3ds_usbotg_init();
        mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata);
 
-       if (!mxc_expio_init(CS5_BASE_ADDR, EXPIO_PARENT_INT))
-               printk(KERN_WARNING "Init of the debugboard failed, all "
-                                   "devices on the board are unusable.\n");
+       if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+               printk(KERN_WARNING "Init of the debug board failed, all "
+                                   "devices on the debug board are unusable.\n");
 }
 
 static void __init mx31_3ds_timer_init(void)
index 05f628d907250b5118c4e1ecb2df4e2e40a3c33c..b66a75aa2e88d185de011c28f0fe4a2efd627cfb 100644 (file)
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/iomux-mx35.h>
+#include <mach/irqs.h>
+#include <mach/3ds_debugboard.h>
 #include <mach/mxc_ehci.h>
 
 #include "devices-imx35.h"
 #include "devices.h"
 
+#define EXPIO_PARENT_INT       (MXC_INTERNAL_IRQS + GPIO_PORTA + 1)
+
 static const struct imxuart_platform_data uart_pdata __initconst = {
        .flags = IMXUART_HAVE_RTSCTS,
 };
@@ -108,6 +112,13 @@ static struct pad_desc mx35pdk_pads[] = {
        /* USBH1 */
        MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
        MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
+       /* SDCARD */
+       MX35_PAD_SD1_CMD__ESDHC1_CMD,
+       MX35_PAD_SD1_CLK__ESDHC1_CLK,
+       MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+       MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+       MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+       MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
 };
 
 /* OTG config */
@@ -140,6 +151,11 @@ static void __init mxc_board_init(void)
        mxc_register_device(&mxc_usbh1, &usb_host_pdata);
 
        imx35_add_mxc_nand(&mx35pdk_nand_board_info);
+       imx35_add_esdhc(0, NULL);
+
+       if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+               pr_warn("Init of the debugboard failed, all "
+                               "devices on the debugboard are unusable.\n");
 }
 
 static void __init mx35pdk_timer_init(void)
index a2df9ac379964944ca12cd8e81d750d6f2073ddd..3ec910a7a182fed0c22edb0be16e2273399c0d5a 100644 (file)
@@ -6,6 +6,7 @@ config ARCH_MX51
        select MXC_TZIC
        select ARCH_MXC_IOMUX_V3
        select ARCH_MXC_AUDMUX_V2
+       select ARCH_HAS_CPUFREQ
 
 comment "MX5 platforms:"
 
@@ -13,6 +14,7 @@ config MACH_MX51_BABBAGE
        bool "Support MX51 BABBAGE platforms"
        select IMX_HAVE_PLATFORM_IMX_I2C
        select IMX_HAVE_PLATFORM_IMX_UART
+       select IMX_HAVE_PLATFORM_ESDHC
        help
          Include support for MX51 Babbage platform, also known as MX51EVK in
          u-boot. This includes specific configurations for the board and its
index 1769c161a60d48dc3db84277fb0c80be7d931152..462f177eddfefcc2c25d65c3fa2f179b36802c2f 100644 (file)
@@ -5,6 +5,7 @@
 # Object file lists.
 obj-y   := cpu.o mm.o clock-mx51.o devices.o
 
+obj-$(CONFIG_CPU_FREQ_IMX)    += cpu_op-mx51.o
 obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
 obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
 obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o
index 0821fe9b3b27c01afe9942a9137e1a0627fe46d9..acbe30df2e6913f7a06bb4402ba47f4b503cb0a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
  *
  * The code contained herein is licensed under the GNU General Public
@@ -18,6 +18,8 @@
 #include <linux/io.h>
 #include <linux/fsl_devices.h>
 #include <linux/fec.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
 
 #include <mach/common.h>
 #include <mach/hardware.h>
 
 #include "devices-imx51.h"
 #include "devices.h"
+#include "cpu_op-mx51.h"
 
 #define BABBAGE_USB_HUB_RESET  (0*32 + 7)      /* GPIO_1_7 */
 #define BABBAGE_USBH1_STP      (0*32 + 27)     /* GPIO_1_27 */
 #define BABBAGE_PHY_RESET      (1*32 + 5)      /* GPIO_2_5 */
 #define BABBAGE_FEC_PHY_RESET  (1*32 + 14)     /* GPIO_2_14 */
+#define BABBAGE_POWER_KEY      (1*32 + 21)     /* GPIO_2_21 */
 
 /* USB_CTRL_1 */
 #define MX51_USB_CTRL_1_OFFSET                 0x10
 #define        MX51_USB_PLL_DIV_19_2_MHZ       0x01
 #define        MX51_USB_PLL_DIV_24_MHZ 0x02
 
+static struct gpio_keys_button babbage_buttons[] = {
+       {
+               .gpio           = BABBAGE_POWER_KEY,
+               .code           = BTN_0,
+               .desc           = "PWR",
+               .active_low     = 1,
+               .wakeup         = 1,
+       },
+};
+
+static const struct gpio_keys_platform_data imx_button_data __initconst = {
+       .buttons        = babbage_buttons,
+       .nbuttons       = ARRAY_SIZE(babbage_buttons),
+};
+
 static struct pad_desc mx51babbage_pads[] = {
        /* UART1 */
        MX51_PAD_UART1_RXD__UART1_RXD,
@@ -112,6 +131,22 @@ static struct pad_desc mx51babbage_pads[] = {
 
        /* FEC PHY reset line */
        MX51_PAD_EIM_A20__GPIO_2_14,
+
+       /* SD 1 */
+       MX51_PAD_SD1_CMD__SD1_CMD,
+       MX51_PAD_SD1_CLK__SD1_CLK,
+       MX51_PAD_SD1_DATA0__SD1_DATA0,
+       MX51_PAD_SD1_DATA1__SD1_DATA1,
+       MX51_PAD_SD1_DATA2__SD1_DATA2,
+       MX51_PAD_SD1_DATA3__SD1_DATA3,
+
+       /* SD 2 */
+       MX51_PAD_SD2_CMD__SD2_CMD,
+       MX51_PAD_SD2_CLK__SD2_CLK,
+       MX51_PAD_SD2_DATA0__SD2_DATA0,
+       MX51_PAD_SD2_DATA1__SD2_DATA1,
+       MX51_PAD_SD2_DATA2__SD2_DATA2,
+       MX51_PAD_SD2_DATA3__SD2_DATA3,
 };
 
 /* Serial ports */
@@ -281,13 +316,22 @@ __setup("otg_mode=", babbage_otg_mode);
 static void __init mxc_board_init(void)
 {
        struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
+       struct pad_desc power_key = MX51_PAD_EIM_A27__GPIO_2_21;
 
+#if defined(CONFIG_CPU_FREQ_IMX)
+       get_cpu_op = mx51_get_cpu_op;
+#endif
        mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
                                        ARRAY_SIZE(mx51babbage_pads));
        mxc_init_imx_uart();
        babbage_fec_reset();
        imx51_add_fec(NULL);
 
+       /* Set the PAD settings for the pwr key. */
+       power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
+       mxc_iomux_v3_setup_pad(&power_key);
+       imx51_add_gpio_keys(&imx_button_data);
+
        imx51_add_imx_i2c(0, &babbage_i2c_data);
        imx51_add_imx_i2c(1, &babbage_i2c_data);
        mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data);
@@ -304,6 +348,9 @@ static void __init mxc_board_init(void)
        /* setback USBH1_STP to be function */
        mxc_iomux_v3_setup_pad(&usbh1stp);
        babbage_usbhub_reset();
+
+       imx51_add_esdhc(0, NULL);
+       imx51_add_esdhc(1, NULL);
 }
 
 static void __init mx51_babbage_timer_init(void)
index f2aae92cf0e261992c1a8afb4bc3de15f0014c88..8ac36d88292764634b7897f5e55a6bfb3615b293 100644 (file)
@@ -362,7 +362,7 @@ static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
        return 0;
 }
 
-static unsigned long clk_arm_get_rate(struct clk *clk)
+static unsigned long clk_cpu_get_rate(struct clk *clk)
 {
        u32 cacrr, div;
        unsigned long parent_rate;
@@ -374,6 +374,22 @@ static unsigned long clk_arm_get_rate(struct clk *clk)
        return parent_rate / div;
 }
 
+static int clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+       u32 reg, cpu_podf;
+       unsigned long parent_rate;
+
+       parent_rate = clk_get_rate(clk->parent);
+       cpu_podf = parent_rate / rate - 1;
+       /* use post divider to change freq */
+       reg = __raw_readl(MXC_CCM_CACRR);
+       reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
+       reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
+       __raw_writel(reg, MXC_CCM_CACRR);
+
+       return 0;
+}
+
 static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
 {
        u32 reg, mux;
@@ -736,7 +752,8 @@ static struct clk periph_apm_clk = {
 
 static struct clk cpu_clk = {
        .parent = &pll1_sw_clk,
-       .get_rate = clk_arm_get_rate,
+       .get_rate = clk_cpu_get_rate,
+       .set_rate = clk_cpu_set_rate,
 };
 
 static struct clk ahb_clk = {
@@ -1064,6 +1081,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk)
        _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
        _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+       _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
 };
 
 static void clk_tree_init(void)
diff --git a/arch/arm/mach-mx5/cpu_op-mx51.c b/arch/arm/mach-mx5/cpu_op-mx51.c
new file mode 100644 (file)
index 0000000..9d34c3d
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <mach/hardware.h>
+#include <linux/kernel.h>
+
+static struct cpu_op mx51_cpu_op[] = {
+       {
+       .cpu_rate = 160000000,},
+       {
+       .cpu_rate = 800000000,},
+};
+
+struct cpu_op *mx51_get_cpu_op(int *op)
+{
+       *op = ARRAY_SIZE(mx51_cpu_op);
+       return mx51_cpu_op;
+}
diff --git a/arch/arm/mach-mx5/cpu_op-mx51.h b/arch/arm/mach-mx5/cpu_op-mx51.h
new file mode 100644 (file)
index 0000000..97477fe
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+extern struct cpu_op *mx51_get_cpu_op(int *op);
index 5cc910e60538429d1a2e9529d0eef3de44a2f228..8c50cb5d05f51d0452852055f9729d40f4180c7d 100644 (file)
@@ -13,6 +13,8 @@ extern const struct imx_fec_data imx51_fec_data __initconst;
 #define imx51_add_fec(pdata)   \
        imx_add_fec(&imx51_fec_data, pdata)
 
+#define imx51_add_gpio_keys(pdata) imx_add_gpio_keys(pdata)
+
 extern const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst;
 #define imx51_add_imx_i2c(id, pdata)   \
        imx_add_imx_i2c(&imx51_imx_i2c_data[id], pdata)
index ea0d80a89da7560ac0a6a9d5b0d5d3a52a89c258..e7f9ee63dce5f5cd5656dbff364cb4dc149dd2a2 100644 (file)
@@ -321,10 +321,9 @@ static struct platform_device omap_wdt_device = {
 static int __init omap_init_wdt(void)
 {
        if (!cpu_is_omap16xx())
-               return;
+               return -ENODEV;
 
-       platform_device_register(&omap_wdt_device);
-       return 0;
+       return platform_device_register(&omap_wdt_device);
 }
 subsys_initcall(omap_init_wdt);
 #endif
index fd54b452eb2289de01f31bada3de656509614116..847d00f0bb0a6ae2393e0bf116cc3df76e24b92b 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __ASM_ARCH_CAMERA_H_
 #define __ASM_ARCH_CAMERA_H_
 
+#include <media/omap1_camera.h>
+
 void omap1_camera_init(void *);
 
 static inline void omap1_set_camera_info(struct omap1_cam_platform_data *info)
index 067f4379c87fc5d927d201df192883b5bd914820..53ac762518bd7361c28833b626ef06ac5a836996 100644 (file)
@@ -242,9 +242,6 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
        mmc[0].gpio_cd = gpio + 0;
        omap2_hsmmc_init(mmc);
 
-       /* link regulators to MMC adapters */
-       devkit8000_vmmc1_supply.dev = mmc[0].dev;
-
        /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
        gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
 
index 923f9f5f91ce96fc2588f41503b53795e6cdea21..2f895553e6a815e5df735b47fbf89b2c191ba8d8 100644 (file)
@@ -44,6 +44,13 @@ void __init gic_init_irq(void)
 }
 
 #ifdef CONFIG_CACHE_L2X0
+
+static void omap4_l2x0_disable(void)
+{
+       /* Disable PL310 L2 Cache controller */
+       omap_smc1(0x102, 0x0);
+}
+
 static int __init omap_l2_cache_init(void)
 {
        /*
@@ -70,6 +77,12 @@ static int __init omap_l2_cache_init(void)
        else
                l2x0_init(l2cache_base, 0x0e070000, 0xc0000fff);
 
+       /*
+        * Override default outer_cache.disable with a OMAP4
+        * specific one
+       */
+       outer_cache.disable = omap4_l2x0_disable;
+
        return 0;
 }
 early_initcall(omap_l2_cache_init);
index bc4c3b9aaf83346fc054b5cb23eb19287b3e2fc0..db485d3b814484f76faefa2943c4a2a17b8f08c4 100644 (file)
@@ -127,7 +127,7 @@ void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode)
        /* Initialize gpiolib. */
        orion_gpio_init();
 
-       while (mode->mpp >= 0) {
+       for ( ; mode->mpp >= 0; mode++) {
                u32 *reg;
                int num_type;
                int shift;
@@ -160,8 +160,6 @@ void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode)
                        orion_gpio_set_unused(mode->mpp);
 
                orion_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO));
-
-               mode++;
        }
 
        writel(mpp_0_7_ctrl, MPP_0_7_CTRL);
index 16f1bd5324bebb94b01ec5af9db5eb82d4e3509f..c1c1cd04bdde4dc77dd4408096048c3f45b47964 100644 (file)
@@ -239,7 +239,7 @@ static struct platform_nand_data ts78xx_ts_nand_data = {
 static struct resource ts78xx_ts_nand_resources = {
        .start          = TS_NAND_DATA,
        .end            = TS_NAND_DATA + 4,
-       .flags          = IORESOURCE_IO,
+       .flags          = IORESOURCE_MEM,
 };
 
 static struct platform_device ts78xx_ts_nand_device = {
index ac5598ce97241f7d29947ee434d539c5c2109fe6..d34b99febeb99c76eef86caf2b20881f45b39fc1 100644 (file)
@@ -476,8 +476,6 @@ static void __init cmx2xx_init(void)
 
 static void __init cmx2xx_init_irq(void)
 {
-       pxa27x_init_irq();
-
        if (cpu_is_pxa25x()) {
                pxa25x_init_irq();
                cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ);
index 4b521e045d754471df4cf4a66daff5d7434992b5..ffa50e633ee6856b88901228f46b6f21d527cc2f 100644 (file)
@@ -116,7 +116,7 @@ static struct platform_device smc91x_device = {
        },
 };
 
-#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULE)
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 static uint16_t lcd_power_on[] = {
        /* single frame */
        SMART_CMD_NOOP,
index 8cdeb14af5929601492a74a593e9322f3a947c91..8aa2f1902a94092e0379d5d46fb1de734a3c0eb9 100644 (file)
@@ -30,7 +30,7 @@ static void h1940bt_enable(int on)
 {
        if (on) {
                /* Power on the chip */
-               h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER);
+               gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 1);
                /* Reset the chip */
                mdelay(10);
 
@@ -43,7 +43,7 @@ static void h1940bt_enable(int on)
                mdelay(10);
                gpio_set_value(S3C2410_GPH(1), 0);
                mdelay(10);
-               h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0);
+               gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0);
        }
 }
 
@@ -64,7 +64,14 @@ static int __devinit h1940bt_probe(struct platform_device *pdev)
 
        ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
        if (ret) {
-               dev_err(&pdev->dev, "could not get GPH1\n");\
+               dev_err(&pdev->dev, "could not get GPH1\n");
+               return ret;
+       }
+
+       ret = gpio_request(H1940_LATCH_BLUETOOTH_POWER, dev_name(&pdev->dev));
+       if (ret) {
+               gpio_free(S3C2410_GPH(1));
+               dev_err(&pdev->dev, "could not get BT_POWER\n");
                return ret;
        }
 
index b649bf2ccd5c50582fdd02ba00044862cfe917ae..f7f6b07df30eaa956acb0c08da276f44c08f8888 100644 (file)
@@ -22,6 +22,8 @@
 
 #ifdef CONFIG_CPU_S3C244X
 #define ARCH_NR_GPIOS  (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
+#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define ARCH_NR_GPIOS  (32 * 12 + CONFIG_S3C24XX_GPIO_EXTRA)
 #else
 #define ARCH_NR_GPIOS  (256 + CONFIG_S3C24XX_GPIO_EXTRA)
 #endif
 #include <mach/gpio-nrs.h>
 #include <mach/gpio-fns.h>
 
-#ifdef CONFIG_CPU_S3C24XX
-#define S3C_GPIO_END   (S3C2410_GPIO_BANKJ + 32)
+#ifdef CONFIG_CPU_S3C244X
+#define S3C_GPIO_END   (S3C2410_GPJ(0) + 32)
+#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define S3C_GPIO_END   (S3C2410_GPM(0) + 32)
 #else
-#define S3C_GPIO_END   (S3C2410_GPIO_BANKH + 32)
+#define S3C_GPIO_END   (S3C2410_GPH(0) + 32)
 #endif
index d8a832729a8a38a5ab28f44549903e707301b907..97e42bfce81e4e675ac9d6eb8b90735e54696226 100644 (file)
 #ifndef __ASM_ARCH_H1940_LATCH_H
 #define __ASM_ARCH_H1940_LATCH_H
 
+#include <mach/gpio.h>
 
-#ifndef __ASSEMBLY__
-#define H1940_LATCH            ((void __force __iomem *)0xF8000000)
-#else
-#define H1940_LATCH            0xF8000000
-#endif
-
-#define H1940_PA_LATCH         (S3C2410_CS2)
+#define H1940_LATCH_GPIO(x)            (S3C_GPIO_END + (x))
 
 /* SD layer latch */
 
-#define H1940_LATCH_SDQ1               (1<<16)
-#define H1940_LATCH_LCD_P1             (1<<17)
-#define H1940_LATCH_LCD_P2             (1<<18)
-#define H1940_LATCH_LCD_P3             (1<<19)
-#define H1940_LATCH_MAX1698_nSHUTDOWN  (1<<20)         /* LCD backlight */
-#define H1940_LATCH_LED_RED            (1<<21)
-#define H1940_LATCH_SDQ7               (1<<22)
-#define H1940_LATCH_USB_DP             (1<<23)
+#define H1940_LATCH_LCD_P0             H1940_LATCH_GPIO(0)
+#define H1940_LATCH_LCD_P1             H1940_LATCH_GPIO(1)
+#define H1940_LATCH_LCD_P2             H1940_LATCH_GPIO(2)
+#define H1940_LATCH_LCD_P3             H1940_LATCH_GPIO(3)
+#define H1940_LATCH_MAX1698_nSHUTDOWN  H1940_LATCH_GPIO(4)
+#define H1940_LATCH_LED_RED            H1940_LATCH_GPIO(5)
+#define H1940_LATCH_SDQ7               H1940_LATCH_GPIO(6)
+#define H1940_LATCH_USB_DP             H1940_LATCH_GPIO(7)
 
 /* CPU layer latch */
 
-#define H1940_LATCH_UDA_POWER          (1<<24)
-#define H1940_LATCH_AUDIO_POWER                (1<<25)
-#define H1940_LATCH_SM803_ENABLE       (1<<26)
-#define H1940_LATCH_LCD_P4             (1<<27)
-#define H1940_LATCH_CPUQ5              (1<<28)         /* untraced */
-#define H1940_LATCH_BLUETOOTH_POWER    (1<<29)         /* active high */
-#define H1940_LATCH_LED_GREEN          (1<<30)
-#define H1940_LATCH_LED_FLASH          (1<<31)
-
-/* default settings */
-
-#define H1940_LATCH_DEFAULT            \
-       H1940_LATCH_LCD_P4              | \
-       H1940_LATCH_SM803_ENABLE        | \
-       H1940_LATCH_SDQ1                | \
-       H1940_LATCH_LCD_P1              | \
-       H1940_LATCH_LCD_P2              | \
-       H1940_LATCH_LCD_P3              | \
-       H1940_LATCH_MAX1698_nSHUTDOWN   | \
-       H1940_LATCH_CPUQ5
-
-/* control functions */
-
-extern void h1940_latch_control(unsigned int clear, unsigned int set);
+#define H1940_LATCH_UDA_POWER          H1940_LATCH_GPIO(8)
+#define H1940_LATCH_AUDIO_POWER                H1940_LATCH_GPIO(9)
+#define H1940_LATCH_SM803_ENABLE       H1940_LATCH_GPIO(10)
+#define H1940_LATCH_LCD_P4             H1940_LATCH_GPIO(11)
+#define H1940_LATCH_SD_POWER           H1940_LATCH_GPIO(12)
+#define H1940_LATCH_BLUETOOTH_POWER    H1940_LATCH_GPIO(13)
+#define H1940_LATCH_LED_GREEN          H1940_LATCH_GPIO(14)
+#define H1940_LATCH_LED_FLASH          H1940_LATCH_GPIO(15)
 
 #endif /* __ASM_ARCH_H1940_LATCH_H */
index 08ab9dfb6ae64b48a71098a91166e957c0bde1c9..101aeea22310026a164b0ce62be1a79284ac5101 100644 (file)
 #define S3C2443_SCLKCON_UARTCLK                (1<<8)
 #define S3C2443_SCLKCON_USBHOST                (1<<1)
 
+#define S3C2443_PWRCFG_SLEEP           (1<<15)
+
 #include <asm/div64.h>
 
 static inline unsigned int
index 54297eb0bf5ea437103cd104106a8b6340a895f9..7a311e8dddba7dcad273a48ce262d7f8bf6083d4 100644 (file)
@@ -15,6 +15,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END    0xE0000000UL
+#define VMALLOC_END    0xF6000000UL
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index 98c5c9e81ee9d8e20af0c27ee98d7f2e4001a8b5..d7ada8c7e41f89a1d8bf5c525aa79c37c1eb1d97 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/pwm_backlight.h>
+#include <linux/i2c.h>
 #include <video/platform_lcd.h>
 
 #include <linux/mmc/host.h>
 #include <plat/mci.h>
 #include <plat/ts.h>
 
+#include <sound/uda1380.h>
+
+#define H1940_LATCH            ((void __force __iomem *)0xF8000000)
+
+#define H1940_PA_LATCH         S3C2410_CS2
+
+#define H1940_LATCH_BIT(x)     (1 << ((x) + 16 - S3C_GPIO_END))
+
 static struct map_desc h1940_iodesc[] __initdata = {
        [0] = {
                .virtual        = (unsigned long)H1940_LATCH,
@@ -100,9 +109,9 @@ static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
 
 /* Board control latch control */
 
-static unsigned int latch_state = H1940_LATCH_DEFAULT;
+static unsigned int latch_state;
 
-void h1940_latch_control(unsigned int clear, unsigned int set)
+static void h1940_latch_control(unsigned int clear, unsigned int set)
 {
        unsigned long flags;
 
@@ -116,7 +125,42 @@ void h1940_latch_control(unsigned int clear, unsigned int set)
        local_irq_restore(flags);
 }
 
-EXPORT_SYMBOL_GPL(h1940_latch_control);
+static inline int h1940_gpiolib_to_latch(int offset)
+{
+       return 1 << (offset + 16);
+}
+
+static void h1940_gpiolib_latch_set(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       int latch_bit = h1940_gpiolib_to_latch(offset);
+
+       h1940_latch_control(value ? 0 : latch_bit,
+               value ? latch_bit : 0);
+}
+
+static int h1940_gpiolib_latch_output(struct gpio_chip *chip,
+                                       unsigned offset, int value)
+{
+       h1940_gpiolib_latch_set(chip, offset, value);
+       return 0;
+}
+
+static int h1940_gpiolib_latch_get(struct gpio_chip *chip,
+                                       unsigned offset)
+{
+       return (latch_state >> (offset + 16)) & 1;
+}
+
+struct gpio_chip h1940_latch_gpiochip = {
+       .base                   = H1940_LATCH_GPIO(0),
+       .owner                  = THIS_MODULE,
+       .label                  = "H1940_LATCH",
+       .ngpio                  = 16,
+       .direction_output       = h1940_gpiolib_latch_output,
+       .set                    = h1940_gpiolib_latch_set,
+       .get                    = h1940_gpiolib_latch_get,
+};
 
 static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd)
 {
@@ -125,10 +169,10 @@ static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd)
        switch (cmd)
        {
                case S3C2410_UDC_P_ENABLE :
-                       h1940_latch_control(0, H1940_LATCH_USB_DP);
+                       gpio_set_value(H1940_LATCH_USB_DP, 1);
                        break;
                case S3C2410_UDC_P_DISABLE :
-                       h1940_latch_control(H1940_LATCH_USB_DP, 0);
+                       gpio_set_value(H1940_LATCH_USB_DP, 0);
                        break;
                case S3C2410_UDC_P_RESET :
                        break;
@@ -199,10 +243,25 @@ static struct platform_device h1940_device_bluetooth = {
        .id               = -1,
 };
 
+static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+{
+       switch (power_mode) {
+       case MMC_POWER_OFF:
+               gpio_set_value(H1940_LATCH_SD_POWER, 0);
+               break;
+       case MMC_POWER_UP:
+       case MMC_POWER_ON:
+               gpio_set_value(H1940_LATCH_SD_POWER, 1);
+               break;
+       default:
+               break;
+       };
+}
+
 static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
        .gpio_detect   = S3C2410_GPF(5),
        .gpio_wprotect = S3C2410_GPH(8),
-       .set_power     = NULL,
+       .set_power     = h1940_set_mmc_power,
        .ocr_avail     = MMC_VDD_32_33,
 };
 
@@ -213,15 +272,32 @@ static int h1940_backlight_init(struct device *dev)
        gpio_direction_output(S3C2410_GPB(0), 0);
        s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
        s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+       gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
 
        return 0;
 }
 
+static int h1940_backlight_notify(struct device *dev, int brightness)
+{
+       if (!brightness) {
+               gpio_direction_output(S3C2410_GPB(0), 1);
+               gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+       } else {
+               gpio_direction_output(S3C2410_GPB(0), 0);
+               s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+               s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+               gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
+       }
+       return brightness;
+}
+
 static void h1940_backlight_exit(struct device *dev)
 {
        gpio_direction_output(S3C2410_GPB(0), 1);
+       gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
 }
 
+
 static struct platform_pwm_backlight_data backlight_data = {
        .pwm_id         = 0,
        .max_brightness = 100,
@@ -229,6 +305,7 @@ static struct platform_pwm_backlight_data backlight_data = {
        /* tcnt = 0x31 */
        .pwm_period_ns  = 36296,
        .init           = h1940_backlight_init,
+       .notify         = h1940_backlight_notify,
        .exit           = h1940_backlight_exit,
 };
 
@@ -247,19 +324,37 @@ static void h1940_lcd_power_set(struct plat_lcd_data *pd,
        int value;
 
        if (!power) {
-               /* set to 3ec */
-               gpio_direction_output(S3C2410_GPC(0), 0);
+               gpio_set_value(S3C2410_GPC(0), 0);
                /* wait for 3ac */
                do {
                        value = gpio_get_value(S3C2410_GPC(6));
                } while (value);
-               /* set to 38c */
-               gpio_direction_output(S3C2410_GPC(5), 0);
+
+               gpio_set_value(H1940_LATCH_LCD_P2, 0);
+               gpio_set_value(H1940_LATCH_LCD_P3, 0);
+               gpio_set_value(H1940_LATCH_LCD_P4, 0);
+
+               gpio_direction_output(S3C2410_GPC(1), 0);
+               gpio_direction_output(S3C2410_GPC(4), 0);
+
+               gpio_set_value(H1940_LATCH_LCD_P1, 0);
+               gpio_set_value(H1940_LATCH_LCD_P0, 0);
+
+               gpio_set_value(S3C2410_GPC(5), 0);
+
        } else {
-               /* Set to 3ac */
-               gpio_direction_output(S3C2410_GPC(5), 1);
-               /* Set to 3ad */
-               gpio_direction_output(S3C2410_GPC(0), 1);
+               gpio_set_value(H1940_LATCH_LCD_P0, 1);
+               gpio_set_value(H1940_LATCH_LCD_P1, 1);
+
+               s3c_gpio_cfgpin(S3C2410_GPC(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S3C2410_GPC(4), S3C_GPIO_SFN(2));
+
+               gpio_set_value(S3C2410_GPC(5), 1);
+               gpio_set_value(S3C2410_GPC(0), 1);
+
+               gpio_set_value(H1940_LATCH_LCD_P3, 1);
+               gpio_set_value(H1940_LATCH_LCD_P2, 1);
+               gpio_set_value(H1940_LATCH_LCD_P4, 1);
        }
 }
 
@@ -273,12 +368,26 @@ static struct platform_device h1940_lcd_powerdev = {
        .dev.platform_data      = &h1940_lcd_power_data,
 };
 
+static struct uda1380_platform_data uda1380_info = {
+       .gpio_power     = H1940_LATCH_UDA_POWER,
+       .gpio_reset     = S3C2410_GPA(12),
+       .dac_clk        = UDA1380_DAC_CLK_SYSCLK,
+};
+
+static struct i2c_board_info h1940_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("uda1380", 0x1a),
+               .platform_data = &uda1380_info,
+       },
+};
+
 static struct platform_device *h1940_devices[] __initdata = {
        &s3c_device_ohci,
        &s3c_device_lcd,
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
+       &s3c_device_pcm,
        &s3c_device_usbgadget,
        &h1940_device_leds,
        &h1940_device_bluetooth,
@@ -303,6 +412,10 @@ static void __init h1940_map_io(void)
        memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
 #endif
        s3c_pm_init();
+
+       /* Add latch gpio chip, set latch initial value */
+       h1940_latch_control(0, 0);
+       WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
 }
 
 /* H1940 and RX3715 need to reserve this for suspend */
@@ -340,12 +453,38 @@ static void __init h1940_init(void)
        writel(tmp, S3C2410_UPLLCON);
 
        gpio_request(S3C2410_GPC(0), "LCD power");
+       gpio_request(S3C2410_GPC(1), "LCD power");
+       gpio_request(S3C2410_GPC(4), "LCD power");
        gpio_request(S3C2410_GPC(5), "LCD power");
        gpio_request(S3C2410_GPC(6), "LCD power");
-
+       gpio_request(H1940_LATCH_LCD_P0, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P1, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P2, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P3, "LCD power");
+       gpio_request(H1940_LATCH_LCD_P4, "LCD power");
+       gpio_request(H1940_LATCH_MAX1698_nSHUTDOWN, "LCD power");
+       gpio_direction_output(S3C2410_GPC(0), 0);
+       gpio_direction_output(S3C2410_GPC(1), 0);
+       gpio_direction_output(S3C2410_GPC(4), 0);
+       gpio_direction_output(S3C2410_GPC(5), 0);
        gpio_direction_input(S3C2410_GPC(6));
+       gpio_direction_output(H1940_LATCH_LCD_P0, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P1, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P2, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P3, 0);
+       gpio_direction_output(H1940_LATCH_LCD_P4, 0);
+       gpio_direction_output(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+
+       gpio_request(H1940_LATCH_USB_DP, "USB pullup");
+       gpio_direction_output(H1940_LATCH_USB_DP, 0);
+
+       gpio_request(H1940_LATCH_SD_POWER, "SD power");
+       gpio_direction_output(H1940_LATCH_SD_POWER, 0);
 
        platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
+
+       i2c_register_board_info(0, h1940_i2c_devices,
+               ARRAY_SIZE(h1940_i2c_devices));
 }
 
 MACHINE_START(H1940, "IPAQ-H1940")
index bef39f77729d360c8d08cd33ffc6b912c1d802d8..4c6df51ddf33fea00f57ef5b8e68741960a090af 100644 (file)
@@ -51,6 +51,7 @@
 #include <plat/clock.h>
 #include <plat/pm.h>
 #include <plat/pll.h>
+#include <plat/nand-core.h>
 
 #ifndef CONFIG_CPU_S3C2412_ONLY
 void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
@@ -92,7 +93,7 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
        /* rename devices that are s3c2412/s3c2413 specific */
        s3c_device_sdi.name  = "s3c2412-sdi";
        s3c_device_lcd.name  = "s3c2412-lcd";
-       s3c_device_nand.name = "s3c2412-nand";
+       s3c_nand_setname("s3c2412-nand");
 
        /* alter IRQ of SDI controller */
 
index 657e4fe17f399cb038b8528966822b6f029fbb6e..87b9c9f003bd503dec247cfa3f51b6a43fd97f36 100644 (file)
@@ -25,6 +25,11 @@ config S3C2416_DMA
        help
          Internal config node for S3C2416 DMA support
 
+config S3C2416_PM
+       bool
+       help
+         Internal config node to apply S3C2416 power management
+
 menu "S3C2416 Machines"
 
 config MACH_SMDK2416
@@ -33,6 +38,7 @@ config MACH_SMDK2416
        select S3C_DEV_FB
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
+       select S3C2416_PM if PM
        help
          Say Y here if you are using an SMDK2416
 
index 6c12c7bf40adeb2578f170889286218fb4f58c92..ef038d62ffdb08e32b4e67e7fad74b76c0ea2d68 100644 (file)
@@ -11,7 +11,7 @@ obj-                          :=
 
 obj-$(CONFIG_CPU_S3C2416)      += s3c2416.o clock.o
 obj-$(CONFIG_CPU_S3C2416)      += irq.o
-
+obj-$(CONFIG_S3C2416_PM)       += pm.o
 #obj-$(CONFIG_S3C2416_DMA)     += dma.o
 
 # Machine support
index 89f521d59d060060c012bbbbc14104a5a9cf11bd..084d121f368cc87d2dfcd6bce0cf6281ab12ba51 100644 (file)
@@ -243,6 +243,8 @@ static int __init s3c2416_irq_add(struct sys_device *sysdev)
 
 static struct sysdev_driver s3c2416_irq_driver = {
        .add            = s3c2416_irq_add,
+       .suspend        = s3c24xx_irq_suspend,
+       .resume         = s3c24xx_irq_resume,
 };
 
 static int __init s3c2416_irq_init(void)
diff --git a/arch/arm/mach-s3c2416/pm.c b/arch/arm/mach-s3c2416/pm.c
new file mode 100644 (file)
index 0000000..4a04205
--- /dev/null
@@ -0,0 +1,84 @@
+/* linux/arch/arm/mach-s3c2416/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM support)
+ *
+ * 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 <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/regs-power.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+extern void s3c2412_sleep_enter(void);
+
+static void s3c2416_cpu_suspend(void)
+{
+       flush_cache_all();
+
+       /* enable wakeup sources regardless of battery state */
+       __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG);
+
+       /* set the mode as sleep, 2BED represents "Go to BED" */
+       __raw_writel(0x2BED, S3C2443_PWRMODE);
+
+       s3c2412_sleep_enter();
+}
+
+static void s3c2416_pm_prepare(void)
+{
+       /*
+        * write the magic value u-boot uses to check for resume into
+        * the INFORM0 register, and ensure INFORM1 is set to the
+        * correct address to resume from.
+        */
+       __raw_writel(0x2BED, S3C2412_INFORM0);
+       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
+}
+
+static int s3c2416_pm_add(struct sys_device *sysdev)
+{
+       pm_cpu_prep = s3c2416_pm_prepare;
+       pm_cpu_sleep = s3c2416_cpu_suspend;
+
+       return 0;
+}
+
+static int s3c2416_pm_suspend(struct sys_device *dev, pm_message_t state)
+{
+       return 0;
+}
+
+static int s3c2416_pm_resume(struct sys_device *dev)
+{
+       /* unset the return-from-sleep amd inform flags */
+       __raw_writel(0x0, S3C2443_PWRMODE);
+       __raw_writel(0x0, S3C2412_INFORM0);
+       __raw_writel(0x0, S3C2412_INFORM1);
+
+       return 0;
+}
+
+static struct sysdev_driver s3c2416_pm_driver = {
+       .add            = s3c2416_pm_add,
+       .suspend        = s3c2416_pm_suspend,
+       .resume         = s3c2416_pm_resume,
+};
+
+static __init int s3c2416_pm_init(void)
+{
+       return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver);
+}
+
+arch_initcall(s3c2416_pm_init);
index bc30245e133b0b5b31b4ff213f1d8953be17a881..63f39cdc0972f18300b47e28867afcd514a18385 100644 (file)
@@ -56,6 +56,7 @@
 
 #include <plat/iic-core.h>
 #include <plat/fb-core.h>
+#include <plat/nand-core.h>
 
 static struct map_desc s3c2416_iodesc[] __initdata = {
        IODESC_ENT(WATCHDOG),
@@ -100,7 +101,7 @@ void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
        s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
 
-       s3c_device_nand.name = "s3c2416-nand";
+       s3c_nand_setname("s3c2412-nand");
 }
 
 /* s3c2416_map_io
index cd8e7de388f0c32b5828d268894b512aa53f45f6..ff024a6c0f85cd46ca45959dc7137cdb5f20693e 100644 (file)
@@ -4,7 +4,6 @@
 
 config CPU_S3C2440
        bool
-       depends on ARCH_S3C2410
        select CPU_ARM920T
        select S3C_GPIO_PULL_UP
        select S3C2410_CLOCK
@@ -18,7 +17,6 @@ config CPU_S3C2440
 
 config CPU_S3C2442
        bool
-       depends on ARCH_S3C2410
        select CPU_ARM920T
        select S3C2410_CLOCK
        select S3C2410_GPIO
@@ -30,7 +28,7 @@ config CPU_S3C2442
 
 config CPU_S3C244X
        bool
-       depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
+       depends on CPU_S3C2440 || CPU_S3C2442
        help
          Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
 
@@ -72,7 +70,7 @@ config S3C2440_PLL_16934400
 
 config S3C2440_DMA
        bool
-       depends on ARCH_S3C2410 && CPU_S3C24405B
+       depends on CPU_S3C2440
        help
          Support for S3C2440 specific DMA code5A
 
@@ -181,7 +179,6 @@ config MACH_MINI2440
        select CPU_S3C2440
        select EEPROM_AT24
        select LEDS_TRIGGER_BACKLIGHT
-       select SND_S3C24XX_SOC_S3C24XX_UDA134X
        select S3C_DEV_NAND
        select S3C_DEV_USB_HOST
        help
index 32019bd9db3bb8506f2562ff31fc00741b0bdd26..e0622bbb6dfafc1aea22783ac22626e4d72bb11e 100644 (file)
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/sysdev.h>
+#include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 #include <linux/pwm.h>
+#include <linux/s3c_adc_battery.h>
+#include <linux/leds.h>
+#include <linux/i2c.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
@@ -55,6 +59,8 @@
 #include <plat/irq.h>
 #include <plat/ts.h>
 
+#include <sound/uda1380.h>
+
 #define LCD_PWM_PERIOD 192960
 #define LCD_PWM_DUTY 127353
 
@@ -127,6 +133,193 @@ static struct s3c2410fb_display rx1950_display = {
 
 };
 
+static int power_supply_init(struct device *dev)
+{
+       return gpio_request(S3C2410_GPF(2), "cable plugged");
+}
+
+static int rx1950_is_ac_online(void)
+{
+       return !gpio_get_value(S3C2410_GPF(2));
+}
+
+static void power_supply_exit(struct device *dev)
+{
+       gpio_free(S3C2410_GPF(2));
+}
+
+static char *rx1950_supplicants[] = {
+       "main-battery"
+};
+
+static struct pda_power_pdata power_supply_info = {
+       .init                   = power_supply_init,
+       .is_ac_online           = rx1950_is_ac_online,
+       .exit                   = power_supply_exit,
+       .supplied_to            = rx1950_supplicants,
+       .num_supplicants        = ARRAY_SIZE(rx1950_supplicants),
+};
+
+static struct resource power_supply_resources[] = {
+       [0] = {
+                       .name   = "ac",
+                       .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
+                                         IORESOURCE_IRQ_HIGHEDGE,
+                       .start  = IRQ_EINT2,
+                       .end    = IRQ_EINT2,
+       },
+};
+
+static struct platform_device power_supply = {
+       .name                   = "pda-power",
+       .id                     = -1,
+       .dev                    = {
+                                       .platform_data =
+                                               &power_supply_info,
+       },
+       .resource               = power_supply_resources,
+       .num_resources          = ARRAY_SIZE(power_supply_resources),
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
+       { .volt = 4100, .cur = 156, .level = 100},
+       { .volt = 4050, .cur = 156, .level = 95},
+       { .volt = 4025, .cur = 141, .level = 90},
+       { .volt = 3995, .cur = 144, .level = 85},
+       { .volt = 3957, .cur = 162, .level = 80},
+       { .volt = 3931, .cur = 147, .level = 75},
+       { .volt = 3902, .cur = 147, .level = 70},
+       { .volt = 3863, .cur = 153, .level = 65},
+       { .volt = 3838, .cur = 150, .level = 60},
+       { .volt = 3800, .cur = 153, .level = 55},
+       { .volt = 3765, .cur = 153, .level = 50},
+       { .volt = 3748, .cur = 172, .level = 45},
+       { .volt = 3740, .cur = 153, .level = 40},
+       { .volt = 3714, .cur = 175, .level = 35},
+       { .volt = 3710, .cur = 156, .level = 30},
+       { .volt = 3963, .cur = 156, .level = 25},
+       { .volt = 3672, .cur = 178, .level = 20},
+       { .volt = 3651, .cur = 178, .level = 15},
+       { .volt = 3629, .cur = 178, .level = 10},
+       { .volt = 3612, .cur = 162, .level = 5},
+       { .volt = 3605, .cur = 162, .level = 0},
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
+       { .volt = 4200, .cur = 0, .level = 100},
+       { .volt = 4190, .cur = 0, .level = 99},
+       { .volt = 4178, .cur = 0, .level = 95},
+       { .volt = 4110, .cur = 0, .level = 70},
+       { .volt = 4076, .cur = 0, .level = 65},
+       { .volt = 4046, .cur = 0, .level = 60},
+       { .volt = 4021, .cur = 0, .level = 55},
+       { .volt = 3999, .cur = 0, .level = 50},
+       { .volt = 3982, .cur = 0, .level = 45},
+       { .volt = 3965, .cur = 0, .level = 40},
+       { .volt = 3957, .cur = 0, .level = 35},
+       { .volt = 3948, .cur = 0, .level = 30},
+       { .volt = 3936, .cur = 0, .level = 25},
+       { .volt = 3927, .cur = 0, .level = 20},
+       { .volt = 3906, .cur = 0, .level = 15},
+       { .volt = 3880, .cur = 0, .level = 10},
+       { .volt = 3829, .cur = 0, .level = 5},
+       { .volt = 3820, .cur = 0, .level = 0},
+};
+
+int rx1950_bat_init(void)
+{
+       int ret;
+
+       ret = gpio_request(S3C2410_GPJ(2), "rx1950-charger-enable-1");
+       if (ret)
+               goto err_gpio1;
+       ret = gpio_request(S3C2410_GPJ(3), "rx1950-charger-enable-2");
+       if (ret)
+               goto err_gpio2;
+
+       return 0;
+
+err_gpio2:
+       gpio_free(S3C2410_GPJ(2));
+err_gpio1:
+       return ret;
+}
+
+void rx1950_bat_exit(void)
+{
+       gpio_free(S3C2410_GPJ(2));
+       gpio_free(S3C2410_GPJ(3));
+}
+
+void rx1950_enable_charger(void)
+{
+       gpio_direction_output(S3C2410_GPJ(2), 1);
+       gpio_direction_output(S3C2410_GPJ(3), 1);
+}
+
+void rx1950_disable_charger(void)
+{
+       gpio_direction_output(S3C2410_GPJ(2), 0);
+       gpio_direction_output(S3C2410_GPJ(3), 0);
+}
+
+static struct gpio_led rx1950_leds_desc[] = {
+       {
+               .name                           = "Green",
+               .default_trigger        = "main-battery-charging-or-full",
+               .gpio                           = S3C2410_GPA(6),
+       },
+       {
+               .name                           = "Red",
+               .default_trigger        = "main-battery-full",
+               .gpio                           = S3C2410_GPA(7),
+       },
+       {
+               .name                           = "Blue",
+               .default_trigger        = "rx1950-acx-mem",
+               .gpio                           = S3C2410_GPA(11),
+       },
+};
+
+static struct gpio_led_platform_data rx1950_leds_pdata = {
+       .num_leds       = ARRAY_SIZE(rx1950_leds_desc),
+       .leds           = rx1950_leds_desc,
+};
+
+static struct platform_device rx1950_leds = {
+       .name   = "leds-gpio",
+       .id             = -1,
+       .dev    = {
+                               .platform_data = &rx1950_leds_pdata,
+       },
+};
+
+static struct s3c_adc_bat_pdata rx1950_bat_cfg = {
+       .init = rx1950_bat_init,
+       .exit = rx1950_bat_exit,
+       .enable_charger = rx1950_enable_charger,
+       .disable_charger = rx1950_disable_charger,
+       .gpio_charge_finished = S3C2410_GPF(3),
+       .lut_noac = bat_lut_noac,
+       .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
+       .lut_acin = bat_lut_acin,
+       .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
+       .volt_channel = 0,
+       .current_channel = 1,
+       .volt_mult = 4235,
+       .current_mult = 2900,
+       .internal_impedance = 200,
+};
+
+static struct platform_device rx1950_battery = {
+       .name             = "s3c-adc-battery",
+       .id               = -1,
+       .dev = {
+               .parent = &s3c_device_adc.dev,
+               .platform_data = &rx1950_bat_cfg,
+       },
+};
+
 static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
        .displays = &rx1950_display,
        .num_displays = 1,
@@ -481,11 +674,17 @@ static struct platform_device rx1950_device_gpiokeys = {
        .dev.platform_data = &rx1950_gpio_keys_data,
 };
 
-static struct s3c2410_platform_i2c rx1950_i2c_data = {
-       .flags = 0,
-       .slave_addr = 0x42,
-       .frequency = 400 * 1000,
-       .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+static struct uda1380_platform_data uda1380_info = {
+       .gpio_power     = S3C2410_GPJ(0),
+       .gpio_reset     = S3C2410_GPD(0),
+       .dac_clk        = UDA1380_DAC_CLK_SYSCLK,
+};
+
+static struct i2c_board_info rx1950_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("uda1380", 0x1a),
+               .platform_data = &uda1380_info,
+       },
 };
 
 static struct platform_device *rx1950_devices[] __initdata = {
@@ -493,6 +692,7 @@ static struct platform_device *rx1950_devices[] __initdata = {
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
+       &s3c_device_pcm,
        &s3c_device_usbgadget,
        &s3c_device_rtc,
        &s3c_device_nand,
@@ -503,6 +703,9 @@ static struct platform_device *rx1950_devices[] __initdata = {
        &s3c_device_timer[1],
        &rx1950_backlight,
        &rx1950_device_gpiokeys,
+       &power_supply,
+       &rx1950_battery,
+       &rx1950_leds,
 };
 
 static struct clk *rx1950_clocks[] __initdata = {
@@ -538,7 +741,7 @@ static void __init rx1950_init_machine(void)
        s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
        s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
        s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
-       s3c_i2c0_set_platdata(&rx1950_i2c_data);
+       s3c_i2c0_set_platdata(NULL);
        s3c_nand_set_platdata(&rx1950_nand_info);
 
        /* Turn off suspend on both USB ports, and switch the
@@ -569,6 +772,9 @@ static void __init rx1950_init_machine(void)
        WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
 
        platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
+
+       i2c_register_board_info(0, rx1950_i2c_devices,
+               ARRAY_SIZE(rx1950_i2c_devices));
 }
 
 /* H1940 and RX3715 need to reserve this for suspend */
index 5e4a97e765334d1b696c17c77b301562f82334d6..90c1707b9c9546d0709a61ea6f49ac4e56f884fb 100644 (file)
@@ -44,6 +44,7 @@
 #include <plat/cpu.h>
 #include <plat/pm.h>
 #include <plat/pll.h>
+#include <plat/nand-core.h>
 
 static struct map_desc s3c244x_iodesc[] __initdata = {
        IODESC_ENT(CLKPWR),
@@ -68,7 +69,7 @@ void __init s3c244x_map_io(void)
 
        s3c_device_sdi.name  = "s3c2440-sdi";
        s3c_device_i2c0.name  = "s3c2440-i2c";
-       s3c_device_nand.name = "s3c2440-nand";
+       s3c_nand_setname("s3c2440-nand");
        s3c_device_ts.name = "s3c2440-ts";
        s3c_device_usbgadget.name = "s3c2440-usbgadget";
 }
index 839b6b2ced740b80acf6d751bc980ccfd745eee7..33d18dd1ebd5e061ffaffd1934daeb7fedb8aee7 100644 (file)
@@ -36,6 +36,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/fb-core.h>
+#include <plat/nand-core.h>
 
 static struct map_desc s3c2443_iodesc[] __initdata = {
        IODESC_ENT(WATCHDOG),
@@ -62,7 +63,7 @@ int __init s3c2443_init(void)
 
        s3c24xx_reset_hook = s3c2443_hard_reset;
 
-       s3c_device_nand.name = "s3c2412-nand";
+       s3c_nand_setname("s3c2412-nand");
        s3c_fb_setname("s3c2443-fb");
 
        /* change WDT IRQ number */
index 914656820794062b578b4cde002a9a2ecd0ed378..6480b15277f3804cb8faeb7dfdb45a0565c5f737 100644 (file)
@@ -12,6 +12,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END      (0xe0000000UL)
+#define VMALLOC_END    0xF6000000UL
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index 546db5cb8929e11c4cdec689bc4b8700ad44562b..579d2f0f4dd0ec3c536262f2d52706ae81c4bac7 100644 (file)
@@ -98,12 +98,33 @@ config MACH_ANW6410
        help
          Machine support for the A&W6410
 
+config MACH_MINI6410
+       bool "MINI6410"
+       select CPU_S3C6410
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC1
+       select S3C64XX_SETUP_SDHCI
+       select S3C_DEV_USB_HOST
+       select S3C_DEV_NAND
+       select S3C_DEV_FB
+       select S3C64XX_SETUP_FB_24BPP
+       select SAMSUNG_DEV_ADC
+       select SAMSUNG_DEV_TS
+       help
+         Machine support for the FriendlyARM MINI6410
+
 config MACH_REAL6410
        bool "REAL6410"
        select CPU_S3C6410
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C64XX_SETUP_SDHCI
+       select S3C_DEV_FB
+       select S3C64XX_SETUP_FB_24BPP
+       select S3C_DEV_NAND
+       select SAMSUNG_DEV_ADC
+       select SAMSUNG_DEV_TS
+       select S3C_DEV_USB_HOST
        help
          Machine support for the CoreWind REAL6410
 
@@ -122,7 +143,7 @@ config MACH_SMDK6410
        select S3C_DEV_USB_HSOTG
        select S3C_DEV_WDT
        select SAMSUNG_DEV_KEYPAD
-       select HAVE_S3C2410_WATCHDOG
+       select HAVE_S3C2410_WATCHDOG if WATCHDOG
        select S3C64XX_SETUP_SDHCI
        select S3C64XX_SETUP_I2C1
        select S3C64XX_SETUP_IDE
index 90221a2e0c5543c87dda5937b3fe9144091bf88a..4657363f0674a77f1dfb1bec308f0c1d31610489 100644 (file)
@@ -53,6 +53,7 @@ obj-$(CONFIG_MACH_ANW6410)    += mach-anw6410.o
 obj-$(CONFIG_MACH_SMDK6400)    += mach-smdk6400.o
 obj-$(CONFIG_MACH_SMDK6410)    += mach-smdk6410.o
 obj-$(CONFIG_MACH_REAL6410)     += mach-real6410.o
+obj-$(CONFIG_MACH_MINI6410)     += mach-mini6410.o
 obj-$(CONFIG_MACH_NCP)         += mach-ncp.o
 obj-$(CONFIG_MACH_HMT)         += mach-hmt.o
 obj-$(CONFIG_MACH_SMARTQ)      += mach-smartq.o
index 3838335f125b65067d9e771b7e48af8ca1b07218..76426a32c013947aabffafc97d22b68efe63e54b 100644 (file)
 #include <plat/audio.h>
 #include <plat/gpio-cfg.h>
 
-#include <mach/gpio-bank-c.h>
-#include <mach/gpio-bank-d.h>
-#include <mach/gpio-bank-e.h>
-#include <mach/gpio-bank-h.h>
-
 static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
 {
+       unsigned int base;
+
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK);
-               s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
-               s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK);
-               s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI);
-               s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0);
+               base = S3C64XX_GPD(0);
                break;
        case 1:
-               s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK);
-               s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK);
-               s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK);
-               s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI);
-               s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0);
+               base = S3C64XX_GPE(0);
                break;
        default:
                printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
@@ -50,18 +39,17 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
+
        return 0;
 }
 
 static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
 {
-       s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0);
-       s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1);
-       s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2);
-       s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK);
-       s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK);
-       s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK);
-       s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI);
+       s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
+       s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
+       s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
+       s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
 
        return 0;
 }
@@ -170,20 +158,14 @@ EXPORT_SYMBOL(s3c64xx_device_iisv4);
 
 static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
 {
+       unsigned int base;
+
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK);
-               s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK);
-               s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC);
-               s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN);
-               s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT);
+               base = S3C64XX_GPD(0);
                break;
        case 1:
-               s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK);
-               s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK);
-               s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC);
-               s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN);
-               s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
+               base = S3C64XX_GPE(0);
                break;
        default:
                printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
@@ -191,6 +173,7 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
        return 0;
 }
 
@@ -264,24 +247,12 @@ EXPORT_SYMBOL(s3c64xx_device_pcm1);
 
 static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
 {
-       s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_AC97_BITCLK);
-       s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_AC97_nRESET);
-       s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_AC97_SYNC);
-       s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_AC97_SDI);
-       s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_AC97_SDO);
-
-       return 0;
+       return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
 }
 
 static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
 {
-       s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_AC97_BITCLK);
-       s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_AC97_nRESET);
-       s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_AC97_SYNC);
-       s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_AC97_SDI);
-       s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_AC97_SDO);
-
-       return 0;
+       return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
 }
 
 static struct resource s3c64xx_ac97_resource[] = {
index 300dee4a667b41c6daf9354266767a53937db236..fd99a82e82c486e13a92f5d2ec35570b326db08d 100644 (file)
@@ -195,11 +195,6 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
        .get_pull       = s3c_gpio_getpull_updown,
 };
 
-int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
-{
-       return IRQ_EINT(0) + pin;
-}
-
 static struct s3c_gpio_chip gpio_2bit[] = {
        {
                .base   = S3C64XX_GPF_BASE,
@@ -227,12 +222,13 @@ static struct s3c_gpio_chip gpio_2bit[] = {
                },
        }, {
                .base   = S3C64XX_GPN_BASE,
+               .irq_base = IRQ_EINT(0),
                .config = &gpio_2bit_cfg_eint10,
                .chip   = {
                        .base   = S3C64XX_GPN(0),
                        .ngpio  = S3C64XX_GPIO_N_NR,
                        .label  = "GPN",
-                       .to_irq = s3c64xx_gpio2int_gpn,
+                       .to_irq = samsung_gpiolib_to_irq,
                },
        }, {
                .base   = S3C64XX_GPO_BASE,
index bc0e913898642ef3f374188f4d928cc56a83f0a5..23f75e556a30aeb38355612c91bcf5d8d71248a7 100644 (file)
@@ -15,6 +15,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END    0xE0000000UL
+#define VMALLOC_END    0xF6000000UL
 
 #endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
new file mode 100644 (file)
index 0000000..249c629
--- /dev/null
@@ -0,0 +1,357 @@
+/* linux/arch/arm/mach-s3c64xx/mach-mini6410.c
+ *
+ * Copyright 2010 Darius Augulis <augulis.darius@gmail.com>
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * 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 <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/dm9000.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/serial_core.h>
+#include <linux/types.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
+#include <mach/regs-srom.h>
+#include <mach/s3c6410.h>
+
+#include <plat/adc.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
+#include <plat/regs-serial.h>
+#include <plat/ts.h>
+
+#include <video/platform_lcd.h>
+
+#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg mini6410_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport = 0,
+               .flags  = 0,
+               .ucon   = UCON,
+               .ulcon  = ULCON,
+               .ufcon  = UFCON,
+       },
+       [1] = {
+               .hwport = 1,
+               .flags  = 0,
+               .ucon   = UCON,
+               .ulcon  = ULCON,
+               .ufcon  = UFCON,
+       },
+       [2] = {
+               .hwport = 2,
+               .flags  = 0,
+               .ucon   = UCON,
+               .ulcon  = ULCON,
+               .ufcon  = UFCON,
+       },
+       [3] = {
+               .hwport = 3,
+               .flags  = 0,
+               .ucon   = UCON,
+               .ulcon  = ULCON,
+               .ufcon  = UFCON,
+       },
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource mini6410_dm9k_resource[] = {
+       [0] = {
+               .start  = S3C64XX_PA_XM0CSN1,
+               .end    = S3C64XX_PA_XM0CSN1 + 1,
+               .flags  = IORESOURCE_MEM
+       },
+       [1] = {
+               .start  = S3C64XX_PA_XM0CSN1 + 4,
+               .end    = S3C64XX_PA_XM0CSN1 + 5,
+               .flags  = IORESOURCE_MEM
+       },
+       [2] = {
+               .start  = S3C_EINT(7),
+               .end    = S3C_EINT(7),
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
+       }
+};
+
+static struct dm9000_plat_data mini6410_dm9k_pdata = {
+       .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device mini6410_device_eth = {
+       .name           = "dm9000",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(mini6410_dm9k_resource),
+       .resource       = mini6410_dm9k_resource,
+       .dev            = {
+               .platform_data  = &mini6410_dm9k_pdata,
+       },
+};
+
+static struct mtd_partition mini6410_nand_part[] = {
+       [0] = {
+               .name   = "uboot",
+               .size   = SZ_1M,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "kernel",
+               .size   = SZ_2M,
+               .offset = SZ_1M,
+       },
+       [2] = {
+               .name   = "rootfs",
+               .size   = MTDPART_SIZ_FULL,
+               .offset = SZ_1M + SZ_2M,
+       },
+};
+
+static struct s3c2410_nand_set mini6410_nand_sets[] = {
+       [0] = {
+               .name           = "nand",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(mini6410_nand_part),
+               .partitions     = mini6410_nand_part,
+       },
+};
+
+static struct s3c2410_platform_nand mini6410_nand_info = {
+       .tacls          = 25,
+       .twrph0         = 55,
+       .twrph1         = 40,
+       .nr_sets        = ARRAY_SIZE(mini6410_nand_sets),
+       .sets           = mini6410_nand_sets,
+};
+
+static struct s3c_fb_pd_win mini6410_fb_win[] = {
+       {
+               .win_mode       = {     /* 4.3" 480x272 */
+                       .left_margin    = 3,
+                       .right_margin   = 2,
+                       .upper_margin   = 1,
+                       .lower_margin   = 1,
+                       .hsync_len      = 40,
+                       .vsync_len      = 1,
+                       .xres           = 480,
+                       .yres           = 272,
+               },
+               .max_bpp        = 32,
+               .default_bpp    = 16,
+       }, {
+               .win_mode       = {     /* 7.0" 800x480 */
+                       .left_margin    = 8,
+                       .right_margin   = 13,
+                       .upper_margin   = 7,
+                       .lower_margin   = 5,
+                       .hsync_len      = 3,
+                       .vsync_len      = 1,
+                       .xres           = 800,
+                       .yres           = 480,
+               },
+               .max_bpp        = 32,
+               .default_bpp    = 16,
+       },
+};
+
+static struct s3c_fb_platdata mini6410_lcd_pdata __initdata = {
+       .setup_gpio     = s3c64xx_fb_gpio_setup_24bpp,
+       .win[0]         = &mini6410_fb_win[0],
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static void mini6410_lcd_power_set(struct plat_lcd_data *pd,
+                                  unsigned int power)
+{
+       if (power)
+               gpio_direction_output(S3C64XX_GPE(0), 1);
+       else
+               gpio_direction_output(S3C64XX_GPE(0), 0);
+}
+
+static struct plat_lcd_data mini6410_lcd_power_data = {
+       .set_power      = mini6410_lcd_power_set,
+};
+
+static struct platform_device mini6410_lcd_powerdev = {
+       .name                   = "platform-lcd",
+       .dev.parent             = &s3c_device_fb.dev,
+       .dev.platform_data      = &mini6410_lcd_power_data,
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+       .delay                  = 10000,
+       .presc                  = 49,
+       .oversampling_shift     = 2,
+};
+
+static struct platform_device *mini6410_devices[] __initdata = {
+       &mini6410_device_eth,
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc1,
+       &s3c_device_ohci,
+       &s3c_device_nand,
+       &s3c_device_fb,
+       &mini6410_lcd_powerdev,
+       &s3c_device_adc,
+       &s3c_device_ts,
+};
+
+static void __init mini6410_map_io(void)
+{
+       u32 tmp;
+
+       s3c64xx_init_io(NULL, 0);
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
+
+       /* set the LCD type */
+       tmp = __raw_readl(S3C64XX_SPCON);
+       tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+       tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+       __raw_writel(tmp, S3C64XX_SPCON);
+
+       /* remove the LCD bypass */
+       tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+       tmp &= ~MIFPCON_LCD_BYPASS;
+       __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/*
+ * mini6410_features string
+ *
+ * 0-9 LCD configuration
+ *
+ */
+static char mini6410_features_str[12] __initdata = "0";
+
+static int __init mini6410_features_setup(char *str)
+{
+       if (str)
+               strlcpy(mini6410_features_str, str,
+                       sizeof(mini6410_features_str));
+       return 1;
+}
+
+__setup("mini6410=", mini6410_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+
+struct mini6410_features_t {
+       int done;
+       int lcd_index;
+};
+
+static void mini6410_parse_features(
+               struct mini6410_features_t *features,
+               const char *features_str)
+{
+       const char *fp = features_str;
+
+       features->done = 0;
+       features->lcd_index = 0;
+
+       while (*fp) {
+               char f = *fp++;
+
+               switch (f) {
+               case '0'...'9': /* tft screen */
+                       if (features->done & FEATURE_SCREEN) {
+                               printk(KERN_INFO "MINI6410: '%c' ignored, "
+                                       "screen type already set\n", f);
+                       } else {
+                               int li = f - '0';
+                               if (li >= ARRAY_SIZE(mini6410_fb_win))
+                                       printk(KERN_INFO "MINI6410: '%c' out "
+                                               "of range LCD mode\n", f);
+                               else {
+                                       features->lcd_index = li;
+                               }
+                       }
+                       features->done |= FEATURE_SCREEN;
+                       break;
+               }
+       }
+}
+
+static void __init mini6410_machine_init(void)
+{
+       u32 cs1;
+       struct mini6410_features_t features = { 0 };
+
+       printk(KERN_INFO "MINI6410: Option string mini6410=%s\n",
+                       mini6410_features_str);
+
+       /* Parse the feature string */
+       mini6410_parse_features(&features, mini6410_features_str);
+
+       mini6410_lcd_pdata.win[0] = &mini6410_fb_win[features.lcd_index];
+
+       printk(KERN_INFO "MINI6410: selected LCD display is %dx%d\n",
+               mini6410_lcd_pdata.win[0]->win_mode.xres,
+               mini6410_lcd_pdata.win[0]->win_mode.yres);
+
+       s3c_nand_set_platdata(&mini6410_nand_info);
+       s3c_fb_set_platdata(&mini6410_lcd_pdata);
+       s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+       /* configure nCS1 width to 16 bits */
+
+       cs1 = __raw_readl(S3C64XX_SROM_BW) &
+               ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+       cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+               (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+               (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+                       S3C64XX_SROM_BW__NCS1__SHIFT;
+       __raw_writel(cs1, S3C64XX_SROM_BW);
+
+       /* set timing for nCS1 suitable for ethernet chip */
+
+       __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+               (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+               (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+               (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+               (13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
+               (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+               (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+       gpio_request(S3C64XX_GPF(15), "LCD power");
+       gpio_request(S3C64XX_GPE(0), "LCD power");
+
+       platform_add_devices(mini6410_devices, ARRAY_SIZE(mini6410_devices));
+}
+
+MACHINE_START(MINI6410, "MINI6410")
+       /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
+       .boot_params    = S3C64XX_PA_SDRAM + 0x100,
+       .init_irq       = s3c6410_init_irq,
+       .map_io         = mini6410_map_io,
+       .init_machine   = mini6410_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
index 4b4475da8ec6f129c478b6c0ade9c2116738372e..f9ef9b5c5f5a09f9aa692e3b705e14905ad4cae9 100644 (file)
  *
 */
 
-#include <linux/kernel.h>
-#include <linux/types.h>
+#include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
 #include <linux/list.h>
-#include <linux/init.h>
 #include <linux/dm9000.h>
-#include <linux/serial_core.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
 #include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/types.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+
 #include <mach/map.h>
-#include <mach/s3c6410.h>
+#include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
 #include <mach/regs-srom.h>
+#include <mach/s3c6410.h>
+
+#include <plat/adc.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
 #include <plat/regs-serial.h>
+#include <plat/ts.h>
+
+#include <video/platform_lcd.h>
 
 #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
@@ -99,22 +115,192 @@ static struct platform_device real6410_device_eth = {
        },
 };
 
+static struct s3c_fb_pd_win real6410_fb_win[] = {
+       {
+               .win_mode       = {     /* 4.3" 480x272 */
+                       .left_margin    = 3,
+                       .right_margin   = 2,
+                       .upper_margin   = 1,
+                       .lower_margin   = 1,
+                       .hsync_len      = 40,
+                       .vsync_len      = 1,
+                       .xres           = 480,
+                       .yres           = 272,
+               },
+               .max_bpp        = 32,
+               .default_bpp    = 16,
+       }, {
+               .win_mode       = {     /* 7.0" 800x480 */
+                       .left_margin    = 8,
+                       .right_margin   = 13,
+                       .upper_margin   = 7,
+                       .lower_margin   = 5,
+                       .hsync_len      = 3,
+                       .vsync_len      = 1,
+                       .xres           = 800,
+                       .yres           = 480,
+               },
+               .max_bpp        = 32,
+               .default_bpp    = 16,
+       },
+};
+
+static struct s3c_fb_platdata real6410_lcd_pdata __initdata = {
+       .setup_gpio     = s3c64xx_fb_gpio_setup_24bpp,
+       .win[0]         = &real6410_fb_win[0],
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct mtd_partition real6410_nand_part[] = {
+       [0] = {
+               .name   = "uboot",
+               .size   = SZ_1M,
+               .offset = 0,
+       },
+       [1] = {
+               .name   = "kernel",
+               .size   = SZ_2M,
+               .offset = SZ_1M,
+       },
+       [2] = {
+               .name   = "rootfs",
+               .size   = MTDPART_SIZ_FULL,
+               .offset = SZ_1M + SZ_2M,
+       },
+};
+
+static struct s3c2410_nand_set real6410_nand_sets[] = {
+       [0] = {
+               .name           = "nand",
+               .nr_chips       = 1,
+               .nr_partitions  = ARRAY_SIZE(real6410_nand_part),
+               .partitions     = real6410_nand_part,
+       },
+};
+
+static struct s3c2410_platform_nand real6410_nand_info = {
+       .tacls          = 25,
+       .twrph0         = 55,
+       .twrph1         = 40,
+       .nr_sets        = ARRAY_SIZE(real6410_nand_sets),
+       .sets           = real6410_nand_sets,
+};
+
 static struct platform_device *real6410_devices[] __initdata = {
        &real6410_device_eth,
        &s3c_device_hsmmc0,
        &s3c_device_hsmmc1,
+       &s3c_device_fb,
+       &s3c_device_nand,
+       &s3c_device_adc,
+       &s3c_device_ts,
+       &s3c_device_ohci,
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+       .delay                  = 10000,
+       .presc                  = 49,
+       .oversampling_shift     = 2,
 };
 
 static void __init real6410_map_io(void)
 {
+       u32 tmp;
+
        s3c64xx_init_io(NULL, 0);
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs));
+
+       /* set the LCD type */
+       tmp = __raw_readl(S3C64XX_SPCON);
+       tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+       tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+       __raw_writel(tmp, S3C64XX_SPCON);
+
+       /* remove the LCD bypass */
+       tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+       tmp &= ~MIFPCON_LCD_BYPASS;
+       __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/*
+ * real6410_features string
+ *
+ * 0-9 LCD configuration
+ *
+ */
+static char real6410_features_str[12] __initdata = "0";
+
+static int __init real6410_features_setup(char *str)
+{
+       if (str)
+               strlcpy(real6410_features_str, str,
+                       sizeof(real6410_features_str));
+       return 1;
+}
+
+__setup("real6410=", real6410_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+
+struct real6410_features_t {
+       int done;
+       int lcd_index;
+};
+
+static void real6410_parse_features(
+               struct real6410_features_t *features,
+               const char *features_str)
+{
+       const char *fp = features_str;
+
+       features->done = 0;
+       features->lcd_index = 0;
+
+       while (*fp) {
+               char f = *fp++;
+
+               switch (f) {
+               case '0'...'9': /* tft screen */
+                       if (features->done & FEATURE_SCREEN) {
+                               printk(KERN_INFO "REAL6410: '%c' ignored, "
+                                       "screen type already set\n", f);
+                       } else {
+                               int li = f - '0';
+                               if (li >= ARRAY_SIZE(real6410_fb_win))
+                                       printk(KERN_INFO "REAL6410: '%c' out "
+                                               "of range LCD mode\n", f);
+                               else {
+                                       features->lcd_index = li;
+                               }
+                       }
+                       features->done |= FEATURE_SCREEN;
+                       break;
+               }
+       }
 }
 
 static void __init real6410_machine_init(void)
 {
        u32 cs1;
+       struct real6410_features_t features = { 0 };
+
+       printk(KERN_INFO "REAL6410: Option string real6410=%s\n",
+                       real6410_features_str);
+
+       /* Parse the feature string */
+       real6410_parse_features(&features, real6410_features_str);
+
+       real6410_lcd_pdata.win[0] = &real6410_fb_win[features.lcd_index];
+
+       printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n",
+               real6410_lcd_pdata.win[0]->win_mode.xres,
+               real6410_lcd_pdata.win[0]->win_mode.yres);
+
+       s3c_fb_set_platdata(&real6410_lcd_pdata);
+       s3c_nand_set_platdata(&real6410_nand_info);
+       s3c24xx_ts_set_platdata(&s3c_ts_platform);
 
        /* configure nCS1 width to 16 bits */
 
@@ -136,6 +322,8 @@ static void __init real6410_machine_init(void)
                (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
                (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
 
+       gpio_request(S3C64XX_GPF(15), "LCD power");
+
        platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices));
 }
 
index 000736877df212c3782bf2858398542e6c0e10c7..8f3091182f9c51bf41fcbc65c29713bc85dfbc58 100644 (file)
 
 extern void s3c64xx_fb_gpio_setup_24bpp(void)
 {
-       unsigned int gpio;
-
-       for (gpio = S3C64XX_GPI(0); gpio <= S3C64XX_GPI(15); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-
-       for (gpio = S3C64XX_GPJ(0); gpio <= S3C64XX_GPJ(11); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2));
+       s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2));
 }
index c12c315f33bc462f80cc3d264dbc7b160ba31f45..41b425602d8832ac0d71ea7a26abeef726ebac50 100644 (file)
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 #include <plat/gpio-cfg.h>
+#include <plat/ata.h>
 
 void s3c64xx_ide_setup_gpio(void)
 {
        u32 reg;
-       u32 gpio = 0;
 
        reg = readl(S3C_MEM_SYS_CFG) & (~0x3f);
 
@@ -32,15 +32,12 @@ void s3c64xx_ide_setup_gpio(void)
        s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4));
 
        /* Set XhiDATA[15:0] pins as CF Data[15:0] */
-       for (gpio = S3C64XX_GPK(0); gpio <= S3C64XX_GPK(15); gpio++)
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(5));
+       s3c_gpio_cfgpin_range(S3C64XX_GPK(0), 16, S3C_GPIO_SFN(5));
 
        /* Set XhiADDR[2:0] pins as CF ADDR[2:0] */
-       for (gpio = S3C64XX_GPL(0); gpio <= S3C64XX_GPL(2); gpio++)
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
+       s3c_gpio_cfgpin_range(S3C64XX_GPL(0), 3, S3C_GPIO_SFN(6));
 
        /* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */
        s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1));
-       for (gpio = S3C64XX_GPM(0); gpio <= S3C64XX_GPM(4); gpio++)
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
+       s3c_gpio_cfgpin_range(S3C64XX_GPM(0), 5, S3C_GPIO_SFN(6));
 }
index abc34e4e1a93d0813d19111182e80c40155e32a7..f8ed0d22db70c0a1140940e7d505c393a87e7999 100644 (file)
 
 #include <linux/gpio.h>
 #include <plat/gpio-cfg.h>
+#include <plat/keypad.h>
 
 void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
 {
-       unsigned int gpio;
-       unsigned int end;
-
        /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */
-       end = S3C64XX_GPK(8 + rows);
-       for (gpio = S3C64XX_GPK(8); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), 8 + rows, S3C_GPIO_SFN(3));
 
        /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */
-       end = S3C64XX_GPL(0 + cols);
-       for (gpio = S3C64XX_GPL(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3));
 }
index 322359591374de9ac1bda7efa38f33d5deb7dfa3..6eac071afae2afe47b44d18d4ef253c538a65d3a 100644 (file)
 void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
 {
        struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
-       unsigned int end;
 
-       end = S3C64XX_GPG(2 + width);
-
-       /* Set all the necessary GPG pins to special-function 0 */
-       for (gpio = S3C64XX_GPG(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       /* Set all the necessary GPG pins to special-function 2 */
+       s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2));
 
        if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
                s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
@@ -44,16 +37,9 @@ void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
 void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
 {
        struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
-       unsigned int end;
 
-       end = S3C64XX_GPH(2 + width);
-
-       /* Set all the necessary GPG pins to special-function 0 */
-       for (gpio = S3C64XX_GPH(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       /* Set all the necessary GPH pins to special-function 2 */
+       s3c_gpio_cfgrange_nopull(S3C64XX_GPH(0), 2 + width, S3C_GPIO_SFN(2));
 
        if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
                s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
@@ -63,20 +49,9 @@ void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
 
 void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
 {
-       unsigned int gpio;
-       unsigned int end;
+       /* Set all the necessary GPH pins to special-function 3 */
+       s3c_gpio_cfgrange_nopull(S3C64XX_GPH(6), width, S3C_GPIO_SFN(3));
 
-       end = S3C64XX_GPH(6 + width);
-
-       /* Set all the necessary GPH pins to special-function 1 */
-       for (gpio = S3C64XX_GPH(6); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-
-       /* Set all the necessary GPC pins to special-function 1 */
-       for (gpio = S3C64XX_GPC(4); gpio < S3C64XX_GPC(6); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       /* Set all the necessary GPC pins to special-function 3 */
+       s3c_gpio_cfgrange_nopull(S3C64XX_GPC(4), 2, S3C_GPIO_SFN(3));
 }
index 0fda0a5df9684c679e82d3298c377b99b147d8be..33569e4007c4ab2016075a69a4205d6a791194e7 100644 (file)
@@ -11,7 +11,6 @@ if ARCH_S5P6442
 
 config CPU_S5P6442
        bool
-       select PLAT_S5P
        select S3C_PL330_DMA
        help
          Enable S5P6442 CPU support
index dcd20f17212a551c52abb165f95b3cb92722493a..16d6e7e61b50a964432c5a405829eab99d7b9b43 100644 (file)
@@ -192,6 +192,11 @@ static struct clk clk_pclkd1 = {
        .parent         = &clk_hclkd1,
 };
 
+int s5p6442_clk_ip0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
+}
+
 int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable)
 {
        return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
@@ -335,6 +340,16 @@ void __init_or_cpufreq s5p6442_setup_clocks(void)
        clk_pclkd1.rate = pclkd1;
 }
 
+static struct clk init_clocks_disable[] = {
+       {
+               .name           = "pdma",
+               .id             = -1,
+               .parent         = &clk_pclkd1,
+               .enable         = s5p6442_clk_ip0_ctrl,
+               .ctrlbit        = (1 << 3),
+       },
+};
+
 static struct clk init_clocks[] = {
        {
                .name           = "systimer",
@@ -393,10 +408,23 @@ static struct clk *clks[] __initdata = {
 
 void __init s5p6442_register_clocks(void)
 {
+       struct clk *clkptr;
+       int i, ret;
+
        s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
 
        s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
 
+       clkptr = init_clocks_disable;
+       for (i = 0; i < ARRAY_SIZE(init_clocks_disable); i++, clkptr++) {
+               ret = s3c24xx_register_clock(clkptr);
+               if (ret < 0) {
+                       printk(KERN_ERR "Fail to register clock %s (%d)\n",
+                                       clkptr->name, ret);
+               } else
+                       (clkptr->enable)(clkptr, 0);
+       }
+
        s3c_pwmclk_init();
 }
index 7a4e34720b7bc8168bb73e9e31af4a16d99c5894..3462197ff352bb786200618611c2b847b753e345 100644 (file)
 
 static int s5p6442_cfg_i2s(struct platform_device *pdev)
 {
+       unsigned int base;
+
        /* configure GPIO for i2s port */
        switch (pdev->id) {
        case 1:
-               s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(2));
+               base = S5P6442_GPC1(0);
                break;
 
        case -1:
-               s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(2));
+               base = S5P6442_GPC0(0);
                break;
 
        default:
@@ -44,6 +38,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
        return 0;
 }
 
@@ -111,21 +106,15 @@ struct platform_device s5p6442_device_iis1 = {
 
 static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
 {
+       unsigned int base;
+
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(3));
+               base = S5P6442_GPC0(0);
                break;
 
        case 1:
-               s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(3));
+               base = S5P6442_GPC1(0);
                break;
 
        default:
@@ -133,6 +122,7 @@ static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
        return 0;
 }
 
index e894651a88bd369f29aa999d0792882946bc21f7..cce8c2470709c85d0e1423c02ffb84cc7ffb15d7 100644 (file)
@@ -38,11 +38,9 @@ static int s5p6442_spi_cfg_gpio(struct platform_device *pdev)
        switch (pdev->id) {
        case 0:
                s3c_gpio_cfgpin(S5P6442_GPB(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPB(2), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6442_GPB(3), S3C_GPIO_SFN(2));
                s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6442_GPB(2), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6442_GPB(3), S3C_GPIO_PULL_UP);
+               s3c_gpio_cfgall_range(S5P6442_GPB(2), 2,
+                                     S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
                break;
 
        default:
index ad4f8704b93d7d5da4565a43f96b98a7d7ccbd26..7dfb13654f8ab4a85d231e4a52b6b97a03714410 100644 (file)
@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5p6442_pdma_pdata = {
 
 static struct platform_device s5p6442_device_pdma = {
        .name           = "s3c-pl330",
-       .id             = 1,
+       .id             = -1,
        .num_resources  = ARRAY_SIZE(s5p6442_pdma_resource),
        .resource       = s5p6442_pdma_resource,
        .dev            = {
index d8360b5d4ecea471263538c23dbc54520c2e57f1..00828a33699133514242931ba7634c81a6877ba7 100644 (file)
@@ -46,6 +46,7 @@
 #define S5P_CLK_DIV5           S5P_CLKREG(0x314)
 #define S5P_CLK_DIV6           S5P_CLKREG(0x318)
 
+#define S5P_CLKGATE_IP0                S5P_CLKREG(0x460)
 #define S5P_CLKGATE_IP3                S5P_CLKREG(0x46C)
 
 /* CLK_OUT */
index f5c83f02c18efe57aed0b021779d160469dcc86f..4aa55e55ac47501cb0a3dfaf1f085aa93170c665 100644 (file)
@@ -12,6 +12,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END    0xE0000000UL
+#define VMALLOC_END    0xF6000000UL
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index fbcae9352022e6983ec662dc3461f291419c0186..164d2783d3818da2e5f90ccfe8af769df3ee8db1 100644 (file)
@@ -9,14 +9,12 @@ if ARCH_S5P64X0
 
 config CPU_S5P6440
        bool
-       select PLAT_S5P
        select S3C_PL330_DMA
        help
          Enable S5P6440 CPU support
 
 config CPU_S5P6450
        bool
-       select PLAT_S5P
        select S3C_PL330_DMA
        help
          Enable S5P6450 CPU support
index f93dcd8b4d6aeef3aa2b2c97bd9c503845d9c280..e4883dc1c8d76d08958a127ff5b45f367dc5927a 100644 (file)
@@ -79,13 +79,16 @@ static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
        __raw_writel(epll_con, S5P64X0_EPLL_CON);
        __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
 
+       printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+                       clk->rate, rate);
+
        clk->rate = rate;
 
        return 0;
 }
 
 static struct clk_ops s5p6440_epll_ops = {
-       .get_rate = s5p64x0_epll_get_rate,
+       .get_rate = s5p_epll_get_rate,
        .set_rate = s5p6440_epll_set_rate,
 };
 
@@ -149,6 +152,12 @@ static struct clk init_clocks_disable[] = {
                .parent         = &clk_hclk.clk,
                .enable         = s5p64x0_hclk0_ctrl,
                .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "pdma",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 12),
        }, {
                .name           = "hsmmc",
                .id             = 0,
@@ -330,12 +339,6 @@ static struct clk init_clocks[] = {
                .parent         = &clk_hclk.clk,
                .enable         = s5p64x0_hclk0_ctrl,
                .ctrlbit        = (1 << 21),
-       }, {
-               .name           = "dma",
-               .id             = -1,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p64x0_hclk0_ctrl,
-               .ctrlbit        = (1 << 12),
        }, {
                .name           = "uart",
                .id             = 0,
@@ -548,7 +551,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
 
        /* Set S5P6440 functions for clk_fout_epll */
 
-       clk_fout_epll.enable = s5p64x0_epll_enable;
+       clk_fout_epll.enable = s5p_epll_enable;
        clk_fout_epll.ops = &s5p6440_epll_ops;
 
        clk_48m.enable = s5p64x0_clk48m_ctrl;
index f9afb05b217c9ac20a8b4a9c835c28949327c378..7dbf3c968f53d88697c3e000d8de53ba11fc0c0e 100644 (file)
@@ -80,13 +80,16 @@ static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate)
        __raw_writel(epll_con, S5P64X0_EPLL_CON);
        __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
 
+       printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+                       clk->rate, rate);
+
        clk->rate = rate;
 
        return 0;
 }
 
 static struct clk_ops s5p6450_epll_ops = {
-       .get_rate = s5p64x0_epll_get_rate,
+       .get_rate = s5p_epll_get_rate,
        .set_rate = s5p6450_epll_set_rate,
 };
 
@@ -185,6 +188,12 @@ static struct clk init_clocks_disable[] = {
                .parent         = &clk_hclk_low.clk,
                .enable         = s5p64x0_hclk0_ctrl,
                .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "pdma",
+               .id             = -1,
+               .parent         = &clk_hclk_low.clk,
+               .enable         = s5p64x0_hclk0_ctrl,
+               .ctrlbit        = (1 << 12),
        }, {
                .name           = "hsmmc",
                .id             = 0,
@@ -282,12 +291,6 @@ static struct clk init_clocks[] = {
                .parent         = &clk_hclk.clk,
                .enable         = s5p64x0_hclk0_ctrl,
                .ctrlbit        = (1 << 21),
-       }, {
-               .name           = "dma",
-               .id             = -1,
-               .parent         = &clk_hclk_low.clk,
-               .enable         = s5p64x0_hclk0_ctrl,
-               .ctrlbit        = (1 << 12),
        }, {
                .name           = "uart",
                .id             = 0,
@@ -581,7 +584,7 @@ void __init_or_cpufreq s5p6450_setup_clocks(void)
 
        /* Set S5P6450 functions for clk_fout_epll */
 
-       clk_fout_epll.enable = s5p64x0_epll_enable;
+       clk_fout_epll.enable = s5p_epll_enable;
        clk_fout_epll.ops = &s5p6450_epll_ops;
 
        clk_48m.enable = s5p64x0_clk48m_ctrl;
index 523ba8039ac2994548c604297762636f684a5473..b52c6e2f37a66868ab34b2bee2d79b669a59a887 100644 (file)
@@ -73,24 +73,6 @@ static const u32 clock_table[][3] = {
        {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
 };
 
-int s5p64x0_epll_enable(struct clk *clk, int enable)
-{
-       unsigned int ctrlbit = clk->ctrlbit;
-       unsigned int epll_con = __raw_readl(S5P64X0_EPLL_CON) & ~ctrlbit;
-
-       if (enable)
-               __raw_writel(epll_con | ctrlbit, S5P64X0_EPLL_CON);
-       else
-               __raw_writel(epll_con, S5P64X0_EPLL_CON);
-
-       return 0;
-}
-
-unsigned long s5p64x0_epll_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-
 unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
 {
        unsigned long rate = clk_get_rate(clk->parent);
index fa097bd68ca40163b68594d9df3f6e003dea5579..396bacc0a39a67289bec66f96225924dcc09f00d 100644 (file)
@@ -24,13 +24,8 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev)
        /* configure GPIO for i2s port */
        switch (pdev->id) {
        case -1:
-               s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5));
                break;
 
        default:
@@ -47,13 +42,9 @@ static int s5p6450_cfg_i2s(struct platform_device *pdev)
        switch (pdev->id) {
        case -1:
                s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6450_GPR(4), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6450_GPR(5), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6450_GPR(6), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6450_GPR(7), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6450_GPR(8), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6450_GPR(13), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5P6450_GPR(14), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
+
                break;
 
        default:
@@ -116,11 +107,8 @@ static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
 {
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin_range(S5P6440_GPR(6), 3, S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(2));
                break;
 
        default:
index 5b69ec4c8af375e63a0c1745019906f05e65049c..e78ee18c76e321bf3a8b43862b3fa0dd0e5e6bc1 100644 (file)
@@ -39,23 +39,15 @@ static char *s5p64x0_spi_src_clks[] = {
  */
 static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
 {
+       unsigned int base;
+
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP);
+               base = S5P6440_GPC(0);
                break;
 
        case 1:
-               s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP);
+               base = S5P6440_GPC(4);
                break;
 
        default:
@@ -63,28 +55,23 @@ static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       s3c_gpio_cfgall_range(base, 3,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
        return 0;
 }
 
 static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
 {
+       unsigned int base;
+
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S5P6450_GPC(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6450_GPC(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6450_GPC(2), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5P6450_GPC(0), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6450_GPC(1), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6450_GPC(2), S3C_GPIO_PULL_UP);
+               base = S5P6450_GPC(0);
                break;
 
        case 1:
-               s3c_gpio_cfgpin(S5P6450_GPC(4), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6450_GPC(5), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5P6450_GPC(6), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5P6450_GPC(4), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6450_GPC(5), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5P6450_GPC(6), S3C_GPIO_PULL_UP);
+               base = S5P6450_GPC(4);
                break;
 
        default:
@@ -92,6 +79,9 @@ static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       s3c_gpio_cfgall_range(base, 3,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
        return 0;
 }
 
index 29a8c2410049f7fa6b41c51a71f938abcdec9eb7..d7ad944b3475bdc9904e8918424b97a768df7d9d 100644 (file)
@@ -122,7 +122,7 @@ static struct s3c_pl330_platdata s5p6450_pdma_pdata = {
 
 static struct platform_device s5p64x0_device_pdma = {
        .name           = "s3c-pl330",
-       .id             = 0,
+       .id             = -1,
        .num_resources  = ARRAY_SIZE(s5p64x0_pdma_resource),
        .resource       = s5p64x0_pdma_resource,
        .dev            = {
index 58e1bc813804e3d3e1c8665d6f706bcfa269a4ba..a133f22fa155f38edf2e91711c893defd120eee0 100644 (file)
@@ -60,4 +60,6 @@
 #define ARM_DIV_RATIO_SHIFT            0
 #define ARM_DIV_MASK                   (0xF << ARM_DIV_RATIO_SHIFT)
 
+#define S5P_EPLL_CON                   S5P64X0_EPLL_CON
+
 #endif /* __ASM_ARCH_REGS_CLOCK_H */
index 97a9df38f1cf5ef2438cce77a77f95c5cfad88c7..38dcc71a03cc9a472d8e5e595193c0547a1fceef 100644 (file)
@@ -15,6 +15,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END    0xE0000000UL
+#define VMALLOC_END    0xF6000000UL
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index dc4cc65a5019c3ba74321dc3fd78247003df6cae..46b463917c54d65a9ff864e70b9505531fabb28f 100644 (file)
@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */
 
 void s5p6440_i2c0_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5P6440_GPB(5), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5P6440_GPB(5), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5P6440_GPB(6), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5P6440_GPB(6), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5P6440_GPB(5), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
 
 void s5p6450_i2c0_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5P6450_GPB(5), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5P6450_GPB(5), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5P6450_GPB(6), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5P6450_GPB(6), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5P6450_GPB(5), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev) { }
index 2edd7912f8e405afa674b17d02e0f6a93d1ea04d..6ad3b986021c922ff325ab2bc9a14e423e5d78f4 100644 (file)
@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */
 
 void s5p6440_i2c1_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5P6440_GPR(9), S3C_GPIO_SFN(6));
-       s3c_gpio_setpull(S5P6440_GPR(9), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5P6440_GPR(10), S3C_GPIO_SFN(6));
-       s3c_gpio_setpull(S5P6440_GPR(10), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5P6440_GPR(9), 2,
+                             S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
 }
 
 void s5p6450_i2c1_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5P6450_GPR(9), S3C_GPIO_SFN(6));
-       s3c_gpio_setpull(S5P6450_GPR(9), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5P6450_GPR(10), S3C_GPIO_SFN(6));
-       s3c_gpio_setpull(S5P6450_GPR(10), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5P6450_GPR(9), 2,
+                             S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
 }
 
 void s3c_i2c1_cfg_gpio(struct platform_device *dev) { }
index 77ae4bfb74ba8c217a7425325be0c01351f7c243..b8fbf2fcba6f68b0c3a5f12f7fa424b177213744 100644 (file)
@@ -9,7 +9,6 @@ if ARCH_S5PC100
 
 config CPU_S5PC100
        bool
-       select PLAT_S5P
        select S5P_EXT_INT
        select S3C_PL330_DMA
        help
index a021ed1fb4b6c6975d77323a35afd9e6479cbece..eecab57d2e5d4f4727b43d51818d59c5968df51d 100644 (file)
@@ -11,7 +11,7 @@ obj-                          :=
 
 # Core support for S5PC100 system
 
-obj-$(CONFIG_CPU_S5PC100)      += cpu.o init.o clock.o gpiolib.o irq-gpio.o
+obj-$(CONFIG_CPU_S5PC100)      += cpu.o init.o clock.o gpiolib.o
 obj-$(CONFIG_CPU_S5PC100)      += setup-i2c0.o
 obj-$(CONFIG_CPU_S5PC100)      += dma.o
 
index 084abd13b0a56e963dbdc189078e7a822f6f317b..2d4a761a516368008d4a607cc38098c4c53bdae6 100644 (file)
@@ -273,24 +273,6 @@ static struct clksrc_clk clk_div_hdmi = {
        .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 },
 };
 
-static int s5pc100_epll_enable(struct clk *clk, int enable)
-{
-       unsigned int ctrlbit = clk->ctrlbit;
-       unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
-
-       if (enable)
-               __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
-       else
-               __raw_writel(epll_con, S5P_EPLL_CON);
-
-       return 0;
-}
-
-static unsigned long s5pc100_epll_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-
 static u32 epll_div[][4] = {
        { 32750000,     131, 3, 4 },
        { 32768000,     131, 3, 4 },
@@ -341,13 +323,16 @@ static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate)
 
        __raw_writel(epll_con, S5P_EPLL_CON);
 
+       printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+                       clk->rate, rate);
+
        clk->rate = rate;
 
        return 0;
 }
 
 static struct clk_ops s5pc100_epll_ops = {
-       .get_rate = s5pc100_epll_get_rate,
+       .get_rate = s5p_epll_get_rate,
        .set_rate = s5pc100_epll_set_rate,
 };
 
@@ -691,55 +676,55 @@ static struct clk init_clocks_disable[] = {
        }, {
                .name           = "iis",
                .id             = 0,
-               .parent         = &clk_div_d1_bus.clk,
+               .parent         = &clk_div_pclkd1.clk,
                .enable         = s5pc100_d1_5_ctrl,
                .ctrlbit        = (1 << 0),
        }, {
                .name           = "iis",
                .id             = 1,
-               .parent         = &clk_div_d1_bus.clk,
+               .parent         = &clk_div_pclkd1.clk,
                .enable         = s5pc100_d1_5_ctrl,
                .ctrlbit        = (1 << 1),
        }, {
                .name           = "iis",
                .id             = 2,
-               .parent         = &clk_div_d1_bus.clk,
+               .parent         = &clk_div_pclkd1.clk,
                .enable         = s5pc100_d1_5_ctrl,
                .ctrlbit        = (1 << 2),
        }, {
                .name           = "ac97",
                .id             = -1,
-               .parent         = &clk_div_d1_bus.clk,
+               .parent         = &clk_div_pclkd1.clk,
                .enable         = s5pc100_d1_5_ctrl,
                .ctrlbit        = (1 << 3),
        }, {
                .name           = "pcm",
                .id             = 0,
-               .parent         = &clk_div_d1_bus.clk,
+               .parent         = &clk_div_pclkd1.clk,
                .enable         = s5pc100_d1_5_ctrl,
                .ctrlbit        = (1 << 4),
        }, {
                .name           = "pcm",
                .id             = 1,
-               .parent         = &clk_div_d1_bus.clk,
+               .parent         = &clk_div_pclkd1.clk,
                .enable         = s5pc100_d1_5_ctrl,
                .ctrlbit        = (1 << 5),
        }, {
                .name           = "spdif",
                .id             = -1,
-               .parent         = &clk_div_d1_bus.clk,
+               .parent         = &clk_div_pclkd1.clk,
                .enable         = s5pc100_d1_5_ctrl,
                .ctrlbit        = (1 << 6),
        }, {
                .name           = "adc",
                .id             = -1,
-               .parent         = &clk_div_d1_bus.clk,
+               .parent         = &clk_div_pclkd1.clk,
                .enable         = s5pc100_d1_5_ctrl,
                .ctrlbit        = (1 << 7),
        }, {
                .name           = "keypad",
                .id             = -1,
-               .parent         = &clk_div_d1_bus.clk,
+               .parent         = &clk_div_pclkd1.clk,
                .enable         = s5pc100_d1_5_ctrl,
                .ctrlbit        = (1 << 8),
        }, {
@@ -848,6 +833,18 @@ struct clksrc_sources clk_src_group3 = {
        .nr_sources     = ARRAY_SIZE(clk_src_group3_list),
 };
 
+static struct clksrc_clk clk_sclk_audio0 = {
+       .clk    = {
+               .name           = "sclk_audio",
+               .id             = 0,
+               .ctrlbit        = (1 << 8),
+               .enable         = s5pc100_sclk1_ctrl,
+       },
+       .sources = &clk_src_group3,
+       .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
+       .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
+};
+
 static struct clk *clk_src_group4_list[] = {
        [0] = &clk_mout_epll.clk,
        [1] = &clk_div_mpll.clk,
@@ -862,6 +859,18 @@ struct clksrc_sources clk_src_group4 = {
        .nr_sources     = ARRAY_SIZE(clk_src_group4_list),
 };
 
+static struct clksrc_clk clk_sclk_audio1 = {
+       .clk    = {
+               .name           = "sclk_audio",
+               .id             = 1,
+               .ctrlbit        = (1 << 9),
+               .enable         = s5pc100_sclk1_ctrl,
+       },
+       .sources = &clk_src_group4,
+       .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
+       .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
+};
+
 static struct clk *clk_src_group5_list[] = {
        [0] = &clk_mout_epll.clk,
        [1] = &clk_div_mpll.clk,
@@ -875,6 +884,18 @@ struct clksrc_sources clk_src_group5 = {
        .nr_sources     = ARRAY_SIZE(clk_src_group5_list),
 };
 
+static struct clksrc_clk clk_sclk_audio2 = {
+       .clk    = {
+               .name           = "sclk_audio",
+               .id             = 2,
+               .ctrlbit        = (1 << 10),
+               .enable         = s5pc100_sclk1_ctrl,
+       },
+       .sources = &clk_src_group5,
+       .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
+       .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
+};
+
 static struct clk *clk_src_group6_list[] = {
        [0] = &s5p_clk_27m,
        [1] = &clk_vclk54m,
@@ -944,6 +965,64 @@ struct clksrc_sources clk_src_pwi = {
        .nr_sources     = ARRAY_SIZE(clk_src_pwi_list),
 };
 
+static struct clk *clk_sclk_spdif_list[] = {
+       [0] = &clk_sclk_audio0.clk,
+       [1] = &clk_sclk_audio1.clk,
+       [2] = &clk_sclk_audio2.clk,
+};
+
+struct clksrc_sources clk_src_sclk_spdif = {
+       .sources        = clk_sclk_spdif_list,
+       .nr_sources     = ARRAY_SIZE(clk_sclk_spdif_list),
+};
+
+static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+       struct clk *pclk;
+       int ret;
+
+       pclk = clk_get_parent(clk);
+       if (IS_ERR(pclk))
+               return -EINVAL;
+
+       ret = pclk->ops->set_rate(pclk, rate);
+       clk_put(pclk);
+
+       return ret;
+}
+
+static unsigned long s5pc100_spdif_get_rate(struct clk *clk)
+{
+       struct clk *pclk;
+       int rate;
+
+       pclk = clk_get_parent(clk);
+       if (IS_ERR(pclk))
+               return -EINVAL;
+
+       rate = pclk->ops->get_rate(clk);
+       clk_put(pclk);
+
+       return rate;
+}
+
+static struct clk_ops s5pc100_sclk_spdif_ops = {
+       .set_rate       = s5pc100_spdif_set_rate,
+       .get_rate       = s5pc100_spdif_get_rate,
+};
+
+static struct clksrc_clk clk_sclk_spdif = {
+       .clk    = {
+               .name           = "sclk_spdif",
+               .id             = -1,
+               .ctrlbit        = (1 << 11),
+               .enable         = s5pc100_sclk1_ctrl,
+               .ops            = &s5pc100_sclk_spdif_ops,
+       },
+       .sources = &clk_src_sclk_spdif,
+       .reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 },
+};
+
 static struct clksrc_clk clksrcs[] = {
        {
                .clk    = {
@@ -999,39 +1078,6 @@ static struct clksrc_clk clksrcs[] = {
                },
                .sources = &clk_src_group6,
                .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_audio",
-                       .id             = 0,
-                       .ctrlbit        = (1 << 8),
-                       .enable         = s5pc100_sclk1_ctrl,
-
-               },
-               .sources = &clk_src_group3,
-               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
-               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_audio",
-                       .id             = 1,
-                       .ctrlbit        = (1 << 9),
-                       .enable         = s5pc100_sclk1_ctrl,
-
-               },
-               .sources = &clk_src_group4,
-               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
-               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_audio",
-                       .id             = 2,
-                       .ctrlbit        = (1 << 10),
-                       .enable         = s5pc100_sclk1_ctrl,
-
-               },
-               .sources = &clk_src_group5,
-               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
-               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
        }, {
                .clk    = {
                        .name           = "sclk_lcd",
@@ -1179,6 +1225,10 @@ static struct clksrc_clk *sysclks[] = {
        &clk_div_pclkd1,
        &clk_div_cam,
        &clk_div_hdmi,
+       &clk_sclk_audio0,
+       &clk_sclk_audio1,
+       &clk_sclk_audio2,
+       &clk_sclk_spdif,
 };
 
 void __init_or_cpufreq s5pc100_setup_clocks(void)
@@ -1196,7 +1246,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
        unsigned int ptr;
 
        /* Set S5PC100 functions for clk_fout_epll */
-       clk_fout_epll.enable = s5pc100_epll_enable;
+       clk_fout_epll.enable = s5p_epll_enable;
        clk_fout_epll.ops = &s5pc100_epll_ops;
 
        printk(KERN_DEBUG "%s: registering clocks\n", __func__);
index a699ed6acc235e0d652fa9a7ea74a03bb288f921..564e195ec493355737f4bb90a92af18f77f2ae1e 100644 (file)
@@ -24,19 +24,11 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
        /* configure GPIO for i2s port */
        switch (pdev->id) {
        case 1:
-               s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
                break;
 
        case 2:
-               s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(4));
-               s3c_gpio_cfgpin(S5PC100_GPG3(1), S3C_GPIO_SFN(4));
-               s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(4));
-               s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(4));
-               s3c_gpio_cfgpin(S5PC100_GPG3(4), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
                break;
 
        case -1: /* Dedicated pins */
@@ -144,19 +136,11 @@ static int s5pc100_pcm_cfg_gpio(struct platform_device *pdev)
 {
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5PC100_GPG3(1), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(5));
-               s3c_gpio_cfgpin(S5PC100_GPG3(4), S3C_GPIO_SFN(5));
+               s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(5));
                break;
 
        case 1:
-               s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(3));
                break;
 
        default:
@@ -231,13 +215,7 @@ struct platform_device s5pc100_device_pcm1 = {
 
 static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev)
 {
-       s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(4));
-       s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(4));
-       s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(4));
-       s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(4));
-       s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(4));
-
-       return 0;
+       return s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(4));
 }
 
 static struct resource s5pc100_ac97_resource[] = {
@@ -285,3 +263,57 @@ struct platform_device s5pc100_device_ac97 = {
                .coherent_dma_mask = DMA_BIT_MASK(32),
        },
 };
+
+/* S/PDIF Controller platform_device */
+static int s5pc100_spdif_cfg_gpd(struct platform_device *pdev)
+{
+       s3c_gpio_cfgpin_range(S5PC100_GPD(5), 2, S3C_GPIO_SFN(3));
+
+       return 0;
+}
+
+static int s5pc100_spdif_cfg_gpg3(struct platform_device *pdev)
+{
+       s3c_gpio_cfgpin_range(S5PC100_GPG3(5), 2, S3C_GPIO_SFN(3));
+
+       return 0;
+}
+
+static struct resource s5pc100_spdif_resource[] = {
+       [0] = {
+               .start  = S5PC100_PA_SPDIF,
+               .end    = S5PC100_PA_SPDIF + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_SPDIF,
+               .end    = DMACH_SPDIF,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct s3c_audio_pdata s5p_spdif_pdata = {
+       .cfg_gpio = s5pc100_spdif_cfg_gpd,
+};
+
+static u64 s5pc100_spdif_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pc100_device_spdif = {
+       .name           = "samsung-spdif",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5pc100_spdif_resource),
+       .resource       = s5pc100_spdif_resource,
+       .dev = {
+               .platform_data = &s5p_spdif_pdata,
+               .dma_mask = &s5pc100_spdif_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
+
+void __init s5pc100_spdif_setup_gpio(int gpio)
+{
+       if (gpio == S5PC100_SPDIF_GPD)
+               s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpd;
+       else
+               s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpg3;
+}
index a0ef7c302c16e62deee6db35274163d73fe54e80..57b19794d9bbb50a5013023ed3d1b7e5902f27d0 100644 (file)
@@ -38,30 +38,20 @@ static int s5pc100_spi_cfg_gpio(struct platform_device *pdev)
 {
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S5PC100_GPB(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PC100_GPB(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PC100_GPB(2), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5PC100_GPB(0), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PC100_GPB(1), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PC100_GPB(2), S3C_GPIO_PULL_UP);
+               s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
+                                     S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
                break;
 
        case 1:
-               s3c_gpio_cfgpin(S5PC100_GPB(4), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PC100_GPB(5), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PC100_GPB(6), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5PC100_GPB(4), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PC100_GPB(5), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PC100_GPB(6), S3C_GPIO_PULL_UP);
+               s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
+                                     S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
                break;
 
        case 2:
                s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(3));
                s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PC100_GPG3(2), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PC100_GPG3(3), S3C_GPIO_PULL_UP);
+               s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
+                                     S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
                break;
 
        default:
index 0f5517571e2c0fc2ec51dff440c83da7975a1442..bf4cd0fb97c6afe38d01860412775f5fb52590ae 100644 (file)
@@ -81,7 +81,7 @@ static struct s3c_pl330_platdata s5pc100_pdma0_pdata = {
 
 static struct platform_device s5pc100_device_pdma0 = {
        .name           = "s3c-pl330",
-       .id             = 1,
+       .id             = 0,
        .num_resources  = ARRAY_SIZE(s5pc100_pdma0_resource),
        .resource       = s5pc100_pdma0_resource,
        .dev            = {
@@ -143,7 +143,7 @@ static struct s3c_pl330_platdata s5pc100_pdma1_pdata = {
 
 static struct platform_device s5pc100_device_pdma1 = {
        .name           = "s3c-pl330",
-       .id             = 2,
+       .id             = 1,
        .num_resources  = ARRAY_SIZE(s5pc100_pdma1_resource),
        .resource       = s5pc100_pdma1_resource,
        .dev            = {
index 0fab7f2cd8bfaacd395737cd0a0f847e1daf5525..20856eb7dd51851e578b89939d4077b9d8c7e6c6 100644 (file)
@@ -1,5 +1,7 @@
-/*
- * arch/arm/plat-s5pc100/gpiolib.c
+/* linux/arch/arm/mach-s5pc100/gpiolib.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
  *
  *  Copyright 2009 Samsung Electronics Co
  *  Kyungmin Park <kyungmin.park@samsung.com>
  * L3  8       4Bit    None
  */
 
-static int s5pc100_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
-       return S3C_IRQ_GPIO(chip->base + offset);
-}
-
-static int s5pc100_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
-{
-       int base;
-
-       base = chip->base - S5PC100_GPH0(0);
-       if (base == 0)
-               return IRQ_EINT(offset);
-       base = chip->base - S5PC100_GPH1(0);
-       if (base == 0)
-               return IRQ_EINT(8 + offset);
-       base = chip->base - S5PC100_GPH2(0);
-       if (base == 0)
-               return IRQ_EINT(16 + offset);
-       base = chip->base - S5PC100_GPH3(0);
-       if (base == 0)
-               return IRQ_EINT(24 + offset);
-       return -EINVAL;
-}
-
 static struct s3c_gpio_cfg gpio_cfg = {
        .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
        .set_pull       = s3c_gpio_setpull_updown,
@@ -104,209 +82,150 @@ static struct s3c_gpio_cfg gpio_cfg_noint = {
        .get_pull       = s3c_gpio_getpull_updown,
 };
 
+/*
+ * GPIO bank's base address given the index of the bank in the
+ * list of all gpio banks.
+ */
+#define S5PC100_BANK_BASE(bank_nr)     (S5P_VA_GPIO + ((bank_nr) * 0x20))
+
+/*
+ * Following are the gpio banks in S5PC100.
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure gpio_cfg in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of s3c_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
 static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
        {
-               .base   = S5PC100_GPA0_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPA0(0),
                        .ngpio  = S5PC100_GPIO_A0_NR,
                        .label  = "GPA0",
                },
        }, {
-               .base   = S5PC100_GPA1_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPA1(0),
                        .ngpio  = S5PC100_GPIO_A1_NR,
                        .label  = "GPA1",
                },
        }, {
-               .base   = S5PC100_GPB_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPB(0),
                        .ngpio  = S5PC100_GPIO_B_NR,
                        .label  = "GPB",
                },
        }, {
-               .base   = S5PC100_GPC_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPC(0),
                        .ngpio  = S5PC100_GPIO_C_NR,
                        .label  = "GPC",
                },
        }, {
-               .base   = S5PC100_GPD_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPD(0),
                        .ngpio  = S5PC100_GPIO_D_NR,
                        .label  = "GPD",
                },
        }, {
-               .base   = S5PC100_GPE0_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPE0(0),
                        .ngpio  = S5PC100_GPIO_E0_NR,
                        .label  = "GPE0",
                },
        }, {
-               .base   = S5PC100_GPE1_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPE1(0),
                        .ngpio  = S5PC100_GPIO_E1_NR,
                        .label  = "GPE1",
                },
        }, {
-               .base   = S5PC100_GPF0_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPF0(0),
                        .ngpio  = S5PC100_GPIO_F0_NR,
                        .label  = "GPF0",
                },
        }, {
-               .base   = S5PC100_GPF1_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPF1(0),
                        .ngpio  = S5PC100_GPIO_F1_NR,
                        .label  = "GPF1",
                },
        }, {
-               .base   = S5PC100_GPF2_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPF2(0),
                        .ngpio  = S5PC100_GPIO_F2_NR,
                        .label  = "GPF2",
                },
        }, {
-               .base   = S5PC100_GPF3_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPF3(0),
                        .ngpio  = S5PC100_GPIO_F3_NR,
                        .label  = "GPF3",
                },
        }, {
-               .base   = S5PC100_GPG0_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPG0(0),
                        .ngpio  = S5PC100_GPIO_G0_NR,
                        .label  = "GPG0",
                },
        }, {
-               .base   = S5PC100_GPG1_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPG1(0),
                        .ngpio  = S5PC100_GPIO_G1_NR,
                        .label  = "GPG1",
                },
        }, {
-               .base   = S5PC100_GPG2_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPG2(0),
                        .ngpio  = S5PC100_GPIO_G2_NR,
                        .label  = "GPG2",
                },
        }, {
-               .base   = S5PC100_GPG3_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPG3(0),
                        .ngpio  = S5PC100_GPIO_G3_NR,
                        .label  = "GPG3",
                },
        }, {
-               .base   = S5PC100_GPH0_BASE,
-               .config = &gpio_cfg_eint,
-               .chip   = {
-                       .base   = S5PC100_GPH0(0),
-                       .ngpio  = S5PC100_GPIO_H0_NR,
-                       .label  = "GPH0",
-               },
-       }, {
-               .base   = S5PC100_GPH1_BASE,
-               .config = &gpio_cfg_eint,
-               .chip   = {
-                       .base   = S5PC100_GPH1(0),
-                       .ngpio  = S5PC100_GPIO_H1_NR,
-                       .label  = "GPH1",
-               },
-       }, {
-               .base   = S5PC100_GPH2_BASE,
-               .config = &gpio_cfg_eint,
-               .chip   = {
-                       .base   = S5PC100_GPH2(0),
-                       .ngpio  = S5PC100_GPIO_H2_NR,
-                       .label  = "GPH2",
-               },
-       }, {
-               .base   = S5PC100_GPH3_BASE,
-               .config = &gpio_cfg_eint,
-               .chip   = {
-                       .base   = S5PC100_GPH3(0),
-                       .ngpio  = S5PC100_GPIO_H3_NR,
-                       .label  = "GPH3",
-               },
-       }, {
-               .base   = S5PC100_GPI_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPI(0),
                        .ngpio  = S5PC100_GPIO_I_NR,
                        .label  = "GPI",
                },
        }, {
-               .base   = S5PC100_GPJ0_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPJ0(0),
                        .ngpio  = S5PC100_GPIO_J0_NR,
                        .label  = "GPJ0",
                },
        }, {
-               .base   = S5PC100_GPJ1_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPJ1(0),
                        .ngpio  = S5PC100_GPIO_J1_NR,
                        .label  = "GPJ1",
                },
        }, {
-               .base   = S5PC100_GPJ2_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPJ2(0),
                        .ngpio  = S5PC100_GPIO_J2_NR,
                        .label  = "GPJ2",
                },
        }, {
-               .base   = S5PC100_GPJ3_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPJ3(0),
                        .ngpio  = S5PC100_GPIO_J3_NR,
                        .label  = "GPJ3",
                },
        }, {
-               .base   = S5PC100_GPJ4_BASE,
-               .config = &gpio_cfg,
                .chip   = {
                        .base   = S5PC100_GPJ4(0),
                        .ngpio  = S5PC100_GPIO_J4_NR,
                        .label  = "GPJ4",
                },
        }, {
-               .base   = S5PC100_GPK0_BASE,
                .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PC100_GPK0(0),
@@ -314,7 +233,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
                        .label  = "GPK0",
                },
        }, {
-               .base   = S5PC100_GPK1_BASE,
                .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PC100_GPK1(0),
@@ -322,7 +240,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
                        .label  = "GPK1",
                },
        }, {
-               .base   = S5PC100_GPK2_BASE,
                .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PC100_GPK2(0),
@@ -330,7 +247,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
                        .label  = "GPK2",
                },
        }, {
-               .base   = S5PC100_GPK3_BASE,
                .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PC100_GPK3(0),
@@ -338,7 +254,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
                        .label  = "GPK3",
                },
        }, {
-               .base   = S5PC100_GPL0_BASE,
                .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PC100_GPL0(0),
@@ -346,7 +261,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
                        .label  = "GPL0",
                },
        }, {
-               .base   = S5PC100_GPL1_BASE,
                .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PC100_GPL1(0),
@@ -354,7 +268,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
                        .label  = "GPL1",
                },
        }, {
-               .base   = S5PC100_GPL2_BASE,
                .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PC100_GPL2(0),
@@ -362,7 +275,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
                        .label  = "GPL2",
                },
        }, {
-               .base   = S5PC100_GPL3_BASE,
                .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PC100_GPL3(0),
@@ -370,56 +282,72 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
                        .label  = "GPL3",
                },
        }, {
-               .base   = S5PC100_GPL4_BASE,
                .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PC100_GPL4(0),
                        .ngpio  = S5PC100_GPIO_L4_NR,
                        .label  = "GPL4",
                },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC00),
+               .config = &gpio_cfg_eint,
+               .irq_base = IRQ_EINT(0),
+               .chip   = {
+                       .base   = S5PC100_GPH0(0),
+                       .ngpio  = S5PC100_GPIO_H0_NR,
+                       .label  = "GPH0",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC20),
+               .config = &gpio_cfg_eint,
+               .irq_base = IRQ_EINT(8),
+               .chip   = {
+                       .base   = S5PC100_GPH1(0),
+                       .ngpio  = S5PC100_GPIO_H1_NR,
+                       .label  = "GPH1",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC40),
+               .config = &gpio_cfg_eint,
+               .irq_base = IRQ_EINT(16),
+               .chip   = {
+                       .base   = S5PC100_GPH2(0),
+                       .ngpio  = S5PC100_GPIO_H2_NR,
+                       .label  = "GPH2",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC60),
+               .config = &gpio_cfg_eint,
+               .irq_base = IRQ_EINT(24),
+               .chip   = {
+                       .base   = S5PC100_GPH3(0),
+                       .ngpio  = S5PC100_GPIO_H3_NR,
+                       .label  = "GPH3",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
        },
 };
 
-/* FIXME move from irq-gpio.c */
-extern struct irq_chip s5pc100_gpioint;
-extern void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
-
-static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip)
+static __init int s5pc100_gpiolib_init(void)
 {
-       /* Interrupt */
-       if (chip->config == &gpio_cfg) {
-               int i, irq;
-
-               chip->chip.to_irq = s5pc100_gpiolib_to_irq;
+       struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
+       int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
+       int gpioint_group = 0;
+       int i;
 
-               for (i = 0;  i < chip->chip.ngpio; i++) {
-                       irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
-                       set_irq_chip(irq, &s5pc100_gpioint);
-                       set_irq_data(irq, &chip->chip);
-                       set_irq_handler(irq, handle_level_irq);
-                       set_irq_flags(irq, IRQF_VALID);
+       for (i = 0; i < nr_chips; i++, chip++) {
+               if (chip->config == NULL) {
+                       chip->config = &gpio_cfg;
+                       chip->group = gpioint_group++;
                }
-       } else if (chip->config == &gpio_cfg_eint) {
-               chip->chip.to_irq = s5pc100_gpiolib_to_eint;
+               if (chip->base == NULL)
+                       chip->base = S5PC100_BANK_BASE(i);
        }
-}
-
-static __init int s5pc100_gpiolib_init(void)
-{
-       struct s3c_gpio_chip *chip;
-       int nr_chips;
-
-       chip = s5pc100_gpio_chips;
-       nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
-
-       for (; nr_chips > 0; nr_chips--, chip++)
-               s5pc100_gpiolib_link(chip);
-
-       samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips,
-                                      ARRAY_SIZE(s5pc100_gpio_chips));
 
-       /* Interrupt */
-       set_irq_chained_handler(IRQ_GPIOINT, s5pc100_irq_gpioint_handler);
+       samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
 
        return 0;
 }
index 71ae1f52df1d27bb511a878bbca6eb8d25457404..29a8a12d9b4f9046a4cce984917329b74683bf2b 100644 (file)
@@ -146,13 +146,6 @@ enum s5p_gpio_number {
 /* define the number of gpios we need to the one after the MP04() range */
 #define ARCH_NR_GPIOS          (S5PC100_GPIO_END + 1)
 
-#define EINT_MODE              S3C_GPIO_SFN(0x2)
-
-#define EINT_GPIO_0(x)         S5PC100_GPH0(x)
-#define EINT_GPIO_1(x)         S5PC100_GPH1(x)
-#define EINT_GPIO_2(x)         S5PC100_GPH2(x)
-#define EINT_GPIO_3(x)         S5PC100_GPH3(x)
-
 #include <asm-generic/gpio.h>
 
 #endif /* __ASM_ARCH_GPIO_H */
index 06513e647242324ea90b426abd5aaf1d70bd1428..d2eb4757381f30b5464f061ad6e9d9a4771cffe5 100644 (file)
@@ -48,8 +48,8 @@
 #define IRQ_SPI1               S5P_IRQ_VIC1(16)
 #define IRQ_SPI2               S5P_IRQ_VIC1(17)
 #define IRQ_IRDA               S5P_IRQ_VIC1(18)
-#define IRQ_CAN0               S5P_IRQ_VIC1(19)
-#define IRQ_CAN1               S5P_IRQ_VIC1(20)
+#define IRQ_IIC2               S5P_IRQ_VIC1(19)
+#define IRQ_IIC3               S5P_IRQ_VIC1(20)
 #define IRQ_HSIRX              S5P_IRQ_VIC1(21)
 #define IRQ_HSITX              S5P_IRQ_VIC1(22)
 #define IRQ_UHOST              S5P_IRQ_VIC1(23)
 #define S5P_EINT_BASE1         (S5P_IRQ_VIC0(0))
 #define S5P_EINT_BASE2         (IRQ_VIC_END + 1)
 
-#define S3C_IRQ_GPIO_BASE      (IRQ_EINT(31) + 1)
-#define S3C_IRQ_GPIO(x)                (S3C_IRQ_GPIO_BASE + (x))
+/* GPIO interrupt */
+#define S5P_GPIOINT_BASE       (IRQ_EINT(31) + 1)
+#define S5P_GPIOINT_GROUP_MAXNR        21
 
-/* Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs */
-#define NR_IRQS                (S3C_IRQ_GPIO(320) + 1)
+/* Set the default NR_IRQS */
+#define NR_IRQS                        (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
 
 /* Compatibility */
 #define IRQ_LCD_FIFO           IRQ_LCD0
index 8751ef4a6804d481d3f1d4ae2c5842dd88f4635a..32e9cab5c8645b0481f092dc3c77eeb2109ceb2e 100644 (file)
 #define S5PC100_PA_PCM0                0xF2400000
 #define S5PC100_PA_PCM1                0xF2500000
 
+#define S5PC100_PA_SPDIF       0xF2600000
+
 #define S5PC100_PA_TSADC       (0xF3000000)
 
 /* KEYPAD */
index dd6295e1251dbb0161c044fe335fa088c44aa91e..0bf73209ec7b74a557889930676c11bb725958e2 100644 (file)
 
 #include <mach/map.h>
 
-/* S5PC100 */
-#define S5PC100_GPIO_BASE      S5P_VA_GPIO
-#define S5PC100_GPA0_BASE      (S5PC100_GPIO_BASE + 0x0000)
-#define S5PC100_GPA1_BASE      (S5PC100_GPIO_BASE + 0x0020)
-#define S5PC100_GPB_BASE       (S5PC100_GPIO_BASE + 0x0040)
-#define S5PC100_GPC_BASE       (S5PC100_GPIO_BASE + 0x0060)
-#define S5PC100_GPD_BASE       (S5PC100_GPIO_BASE + 0x0080)
-#define S5PC100_GPE0_BASE      (S5PC100_GPIO_BASE + 0x00A0)
-#define S5PC100_GPE1_BASE      (S5PC100_GPIO_BASE + 0x00C0)
-#define S5PC100_GPF0_BASE      (S5PC100_GPIO_BASE + 0x00E0)
-#define S5PC100_GPF1_BASE      (S5PC100_GPIO_BASE + 0x0100)
-#define S5PC100_GPF2_BASE      (S5PC100_GPIO_BASE + 0x0120)
-#define S5PC100_GPF3_BASE      (S5PC100_GPIO_BASE + 0x0140)
-#define S5PC100_GPG0_BASE      (S5PC100_GPIO_BASE + 0x0160)
-#define S5PC100_GPG1_BASE      (S5PC100_GPIO_BASE + 0x0180)
-#define S5PC100_GPG2_BASE      (S5PC100_GPIO_BASE + 0x01A0)
-#define S5PC100_GPG3_BASE      (S5PC100_GPIO_BASE + 0x01C0)
-#define S5PC100_GPH0_BASE      (S5PC100_GPIO_BASE + 0x0C00)
-#define S5PC100_GPH1_BASE      (S5PC100_GPIO_BASE + 0x0C20)
-#define S5PC100_GPH2_BASE      (S5PC100_GPIO_BASE + 0x0C40)
-#define S5PC100_GPH3_BASE      (S5PC100_GPIO_BASE + 0x0C60)
-#define S5PC100_GPI_BASE       (S5PC100_GPIO_BASE + 0x01E0)
-#define S5PC100_GPJ0_BASE      (S5PC100_GPIO_BASE + 0x0200)
-#define S5PC100_GPJ1_BASE      (S5PC100_GPIO_BASE + 0x0220)
-#define S5PC100_GPJ2_BASE      (S5PC100_GPIO_BASE + 0x0240)
-#define S5PC100_GPJ3_BASE      (S5PC100_GPIO_BASE + 0x0260)
-#define S5PC100_GPJ4_BASE      (S5PC100_GPIO_BASE + 0x0280)
-#define S5PC100_GPK0_BASE      (S5PC100_GPIO_BASE + 0x02A0)
-#define S5PC100_GPK1_BASE      (S5PC100_GPIO_BASE + 0x02C0)
-#define S5PC100_GPK2_BASE      (S5PC100_GPIO_BASE + 0x02E0)
-#define S5PC100_GPK3_BASE      (S5PC100_GPIO_BASE + 0x0300)
-#define S5PC100_GPL0_BASE      (S5PC100_GPIO_BASE + 0x0320)
-#define S5PC100_GPL1_BASE      (S5PC100_GPIO_BASE + 0x0340)
-#define S5PC100_GPL2_BASE      (S5PC100_GPIO_BASE + 0x0360)
-#define S5PC100_GPL3_BASE      (S5PC100_GPIO_BASE + 0x0380)
-#define S5PC100_GPL4_BASE      (S5PC100_GPIO_BASE + 0x03A0)
-
 #define S5PC100EINT30CON               (S5P_VA_GPIO + 0xE00)
 #define S5P_EINT_CON(x)                        (S5PC100EINT30CON + ((x) * 0x4))
 
 
 #define eint_irq_to_bit(irq)           (1 << (EINT_OFFSET(irq) & 0x7))
 
-/* values for S5P_EXTINT0 */
-#define S5P_EXTINT_LOWLEV              (0x00)
-#define S5P_EXTINT_HILEV               (0x01)
-#define S5P_EXTINT_FALLEDGE            (0x02)
-#define S5P_EXTINT_RISEEDGE            (0x03)
-#define S5P_EXTINT_BOTHEDGE            (0x04)
+#define EINT_MODE              S3C_GPIO_SFN(0x2)
+
+#define EINT_GPIO_0(x)         S5PC100_GPH0(x)
+#define EINT_GPIO_1(x)         S5PC100_GPH1(x)
+#define EINT_GPIO_2(x)         S5PC100_GPH2(x)
+#define EINT_GPIO_3(x)         S5PC100_GPH3(x)
 
 #endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */
 
index be9df79903ed508e14f994bfcd9ac57fa3e6f237..44c8e5726d9dca22bc6fb264de5fb485d9f54c29 100644 (file)
@@ -12,6 +12,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END      (0xe0000000UL)
+#define VMALLOC_END    0xF6000000UL
 
 #endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pc100/irq-gpio.c b/arch/arm/mach-s5pc100/irq-gpio.c
deleted file mode 100644 (file)
index 2bf86c1..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * arch/arm/mach-s5pc100/irq-gpio.c
- *
- * Copyright (C) 2009 Samsung Electronics
- *
- * S5PC100 - Interrupt handling for IRQ_GPIO${group}(x)
- *
- * 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 <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/map.h>
-#include <plat/gpio-cfg.h>
-
-#define S5P_GPIOREG(x)         (S5P_VA_GPIO + (x))
-
-#define CON_OFFSET                     0x700
-#define MASK_OFFSET                    0x900
-#define PEND_OFFSET                    0xA00
-#define CON_OFFSET_2                   0xE00
-#define MASK_OFFSET_2                  0xF00
-#define PEND_OFFSET_2                  0xF40
-
-#define GPIOINT_LEVEL_LOW              0x0
-#define GPIOINT_LEVEL_HIGH             0x1
-#define GPIOINT_EDGE_FALLING           0x2
-#define GPIOINT_EDGE_RISING            0x3
-#define GPIOINT_EDGE_BOTH              0x4
-
-static int group_to_con_offset(int group)
-{
-       return group << 2;
-}
-
-static int group_to_mask_offset(int group)
-{
-       return group << 2;
-}
-
-static int group_to_pend_offset(int group)
-{
-       return group << 2;
-}
-
-static int s5pc100_get_start(unsigned int group)
-{
-       switch (group) {
-       case 0: return S5PC100_GPIO_A0_START;
-       case 1: return S5PC100_GPIO_A1_START;
-       case 2: return S5PC100_GPIO_B_START;
-       case 3: return S5PC100_GPIO_C_START;
-       case 4: return S5PC100_GPIO_D_START;
-       case 5: return S5PC100_GPIO_E0_START;
-       case 6: return S5PC100_GPIO_E1_START;
-       case 7: return S5PC100_GPIO_F0_START;
-       case 8: return S5PC100_GPIO_F1_START;
-       case 9: return S5PC100_GPIO_F2_START;
-       case 10: return S5PC100_GPIO_F3_START;
-       case 11: return S5PC100_GPIO_G0_START;
-       case 12: return S5PC100_GPIO_G1_START;
-       case 13: return S5PC100_GPIO_G2_START;
-       case 14: return S5PC100_GPIO_G3_START;
-       case 15: return S5PC100_GPIO_I_START;
-       case 16: return S5PC100_GPIO_J0_START;
-       case 17: return S5PC100_GPIO_J1_START;
-       case 18: return S5PC100_GPIO_J2_START;
-       case 19: return S5PC100_GPIO_J3_START;
-       case 20: return S5PC100_GPIO_J4_START;
-       default:
-               BUG();
-       }
-
-       return -EINVAL;
-}
-
-static int s5pc100_get_group(unsigned int irq)
-{
-       irq -= S3C_IRQ_GPIO(0);
-
-       switch (irq) {
-       case S5PC100_GPIO_A0_START ... S5PC100_GPIO_A1_START - 1:
-               return 0;
-       case S5PC100_GPIO_A1_START ... S5PC100_GPIO_B_START - 1:
-               return 1;
-       case S5PC100_GPIO_B_START ... S5PC100_GPIO_C_START - 1:
-               return 2;
-       case S5PC100_GPIO_C_START ... S5PC100_GPIO_D_START - 1:
-               return 3;
-       case S5PC100_GPIO_D_START ... S5PC100_GPIO_E0_START - 1:
-               return 4;
-       case S5PC100_GPIO_E0_START ... S5PC100_GPIO_E1_START - 1:
-               return 5;
-       case S5PC100_GPIO_E1_START ... S5PC100_GPIO_F0_START - 1:
-               return 6;
-       case S5PC100_GPIO_F0_START ... S5PC100_GPIO_F1_START - 1:
-               return 7;
-       case S5PC100_GPIO_F1_START ... S5PC100_GPIO_F2_START - 1:
-               return 8;
-       case S5PC100_GPIO_F2_START ... S5PC100_GPIO_F3_START - 1:
-               return 9;
-       case S5PC100_GPIO_F3_START ... S5PC100_GPIO_G0_START - 1:
-               return 10;
-       case S5PC100_GPIO_G0_START ... S5PC100_GPIO_G1_START - 1:
-               return 11;
-       case S5PC100_GPIO_G1_START ... S5PC100_GPIO_G2_START - 1:
-               return 12;
-       case S5PC100_GPIO_G2_START ... S5PC100_GPIO_G3_START - 1:
-               return 13;
-       case S5PC100_GPIO_G3_START ... S5PC100_GPIO_H0_START - 1:
-               return 14;
-       case S5PC100_GPIO_I_START ... S5PC100_GPIO_J0_START - 1:
-               return 15;
-       case S5PC100_GPIO_J0_START ... S5PC100_GPIO_J1_START - 1:
-               return 16;
-       case S5PC100_GPIO_J1_START ... S5PC100_GPIO_J2_START - 1:
-               return 17;
-       case S5PC100_GPIO_J2_START ... S5PC100_GPIO_J3_START - 1:
-               return 18;
-       case S5PC100_GPIO_J3_START ... S5PC100_GPIO_J4_START - 1:
-               return 19;
-       case S5PC100_GPIO_J4_START ... S5PC100_GPIO_K0_START - 1:
-               return 20;
-       default:
-               BUG();
-       }
-
-       return -EINVAL;
-}
-
-static int s5pc100_get_offset(unsigned int irq)
-{
-       struct gpio_chip *chip = get_irq_data(irq);
-       return irq - S3C_IRQ_GPIO(chip->base);
-}
-
-static void s5pc100_gpioint_ack(unsigned int irq)
-{
-       int group, offset, pend_offset;
-       unsigned int value;
-
-       group = s5pc100_get_group(irq);
-       offset = s5pc100_get_offset(irq);
-       pend_offset = group_to_pend_offset(group);
-
-       value = __raw_readl(S5P_GPIOREG(PEND_OFFSET) + pend_offset);
-       value |= 1 << offset;
-       __raw_writel(value, S5P_GPIOREG(PEND_OFFSET) + pend_offset);
-}
-
-static void s5pc100_gpioint_mask(unsigned int irq)
-{
-       int group, offset, mask_offset;
-       unsigned int value;
-
-       group = s5pc100_get_group(irq);
-       offset = s5pc100_get_offset(irq);
-       mask_offset = group_to_mask_offset(group);
-
-       value = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
-       value |= 1 << offset;
-       __raw_writel(value, S5P_GPIOREG(MASK_OFFSET) + mask_offset);
-}
-
-static void s5pc100_gpioint_unmask(unsigned int irq)
-{
-       int group, offset, mask_offset;
-       unsigned int value;
-
-       group = s5pc100_get_group(irq);
-       offset = s5pc100_get_offset(irq);
-       mask_offset = group_to_mask_offset(group);
-
-       value = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
-       value &= ~(1 << offset);
-       __raw_writel(value, S5P_GPIOREG(MASK_OFFSET) + mask_offset);
-}
-
-static void s5pc100_gpioint_mask_ack(unsigned int irq)
-{
-       s5pc100_gpioint_mask(irq);
-       s5pc100_gpioint_ack(irq);
-}
-
-static int s5pc100_gpioint_set_type(unsigned int irq, unsigned int type)
-{
-       int group, offset, con_offset;
-       unsigned int value;
-
-       group = s5pc100_get_group(irq);
-       offset = s5pc100_get_offset(irq);
-       con_offset = group_to_con_offset(group);
-
-       switch (type) {
-       case IRQ_TYPE_NONE:
-               printk(KERN_WARNING "No irq type\n");
-               return -EINVAL;
-       case IRQ_TYPE_EDGE_RISING:
-               type = GPIOINT_EDGE_RISING;
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               type = GPIOINT_EDGE_FALLING;
-               break;
-       case IRQ_TYPE_EDGE_BOTH:
-               type = GPIOINT_EDGE_BOTH;
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               type = GPIOINT_LEVEL_HIGH;
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-               type = GPIOINT_LEVEL_LOW;
-               break;
-       default:
-               BUG();
-       }
-
-
-       value = __raw_readl(S5P_GPIOREG(CON_OFFSET) + con_offset);
-       value &= ~(0xf << (offset * 0x4));
-       value |= (type << (offset * 0x4));
-       __raw_writel(value, S5P_GPIOREG(CON_OFFSET) + con_offset);
-
-       return 0;
-}
-
-struct irq_chip s5pc100_gpioint = {
-       .name           = "GPIO",
-       .ack            = s5pc100_gpioint_ack,
-       .mask           = s5pc100_gpioint_mask,
-       .mask_ack       = s5pc100_gpioint_mask_ack,
-       .unmask         = s5pc100_gpioint_unmask,
-       .set_type       = s5pc100_gpioint_set_type,
-};
-
-void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc)
-{
-       int group, offset, pend_offset, mask_offset;
-       int real_irq, group_end;
-       unsigned int pend, mask;
-
-       group_end = 21;
-
-       for (group = 0; group < group_end; group++) {
-               pend_offset = group_to_pend_offset(group);
-               pend = __raw_readl(S5P_GPIOREG(PEND_OFFSET) + pend_offset);
-               if (!pend)
-                       continue;
-
-               mask_offset = group_to_mask_offset(group);
-               mask = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
-               pend &= ~mask;
-
-               for (offset = 0; offset < 8; offset++) {
-                       if (pend & (1 << offset)) {
-                               real_irq = s5pc100_get_start(group) + offset;
-                               generic_handle_irq(S3C_IRQ_GPIO(real_irq));
-                       }
-               }
-       }
-}
index 880fb075092cf3d65ed3fb7236652cb7a737caf0..18b405d514d63fe34d61bd7290ac82c96ca9798a 100644 (file)
@@ -47,6 +47,7 @@
 #include <plat/adc.h>
 #include <plat/keypad.h>
 #include <plat/ts.h>
+#include <plat/audio.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKC100_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
@@ -196,6 +197,7 @@ static struct platform_device *smdkc100_devices[] __initdata = {
        &s5p_device_fimc0,
        &s5p_device_fimc1,
        &s5p_device_fimc2,
+       &s5pc100_device_spdif,
 };
 
 static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
@@ -226,6 +228,8 @@ static void __init smdkc100_machine_init(void)
 
        samsung_keypad_set_platdata(&smdkc100_keypad_data);
 
+       s5pc100_spdif_setup_gpio(S5PC100_SPDIF_GPD);
+
        /* LCD init */
        gpio_request(S5PC100_GPD(0), "GPD");
        gpio_request(S5PC100_GPH0(6), "GPH0");
index 6eba6cb8e2f486bc2445419ce4f2f149de1bcbf6..d31c0f3fe22273d978ef6023eee725011f1986eb 100644 (file)
 
 #define DISR_OFFSET    0x7008
 
-void s5pc100_fb_gpio_setup_24bpp(void)
+static void s5pc100_fb_setgpios(unsigned int base, unsigned int nr)
 {
-       unsigned int gpio = 0;
-
-       for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-
-       for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-
-       for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
+}
 
-       for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+void s5pc100_fb_gpio_setup_24bpp(void)
+{
+       s5pc100_fb_setgpios(S5PC100_GPF0(0), 8);
+       s5pc100_fb_setgpios(S5PC100_GPF1(0), 8);
+       s5pc100_fb_setgpios(S5PC100_GPF2(0), 8);
+       s5pc100_fb_setgpios(S5PC100_GPF3(0), 4);
 }
index dd3174e6ecc59c123efd7c73a10c8d38cb817f9a..eaef7a3bda49ac8012632c3bbdbd0867a9ca30bd 100644 (file)
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5PC100_GPD(3), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
index d1fec26b69eeab1470ac9059f91db9ea407d1585..aaff74a90dee7d3c2ca8db48b6378c2bc86dc83e 100644 (file)
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
 
 void s3c_i2c1_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5PC100_GPD(5), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
index 83575671fb598510beedd045ce31f67197f79713..223aae044466f59f46d8d9aa614c3b07e51a80a8 100644 (file)
 #include <mach/regs-clock.h>
 #include <plat/gpio-cfg.h>
 
+static void s5pc100_ide_cfg_gpios(unsigned int base, unsigned int nr)
+{
+       s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
+
+       for (; nr > 0; nr--, base++)
+               s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
+}
+
 void s5pc100_ide_setup_gpio(void)
 {
        u32 reg;
-       u32 gpio = 0;
 
        /* Independent CF interface, CF chip select configuration */
        reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f);
        writel(reg | MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S5PC100_MEM_SYS_CFG);
 
        /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
-       for (gpio = S5PC100_GPJ0(0); gpio <= S5PC100_GPJ0(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
+       s5pc100_ide_cfg_gpios(S5PC100_GPJ0(0), 8);
 
        /*CF_Data[0 - 7] */
-       for (gpio = S5PC100_GPJ2(0); gpio <= S5PC100_GPJ2(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
+       s5pc100_ide_cfg_gpios(S5PC100_GPJ2(0), 8);
 
        /* CF_Data[8 - 15] */
-       for (gpio = S5PC100_GPJ3(0); gpio <= S5PC100_GPJ3(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
+       s5pc100_ide_cfg_gpios(S5PC100_GPJ3(0), 8);
 
        /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
-       for (gpio = S5PC100_GPJ4(0); gpio <= S5PC100_GPJ4(3); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
+       s5pc100_ide_cfg_gpios(S5PC100_GPJ4(0), 4);
 
        /* EBI_OE, EBI_WE */
-       for (gpio = S5PC100_GPK0(6); gpio <= S5PC100_GPK0(7); gpio++)
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0));
+       s3c_gpio_cfgpin_range(S5PC100_GPK0(6), 2, S3C_GPIO_SFN(0));
 
        /* CF_OE, CF_WE */
-       for (gpio = S5PC100_GPK1(6); gpio <= S5PC100_GPK1(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PC100_GPK1(6), 8, S3C_GPIO_SFN(2));
 
        /* CF_CD */
        s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2));
index d0837a72a58e8a95e121edac2720635113ae13f5..ada377f0c2060a770a622f921887538307ddfb97 100644 (file)
 
 void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
 {
-       unsigned int gpio;
-       unsigned int end;
-
        /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
-       end = S5PC100_GPH3(rows);
-       for (gpio = S5PC100_GPH3(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PC100_GPH3(0), rows, S3C_GPIO_SFN(3));
 
        /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
-       end = S5PC100_GPH2(cols);
-       for (gpio = S5PC100_GPH2(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PC100_GPH2(0), cols, S3C_GPIO_SFN(3));
 }
index dc7208c639ea0804a80700dd43a917c5b8ee5e01..03c02d04c68cd6e6cf0424bf559833a37881a01f 100644 (file)
@@ -25,8 +25,6 @@
 void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
 {
        struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
-       unsigned int end;
        unsigned int num;
 
        num = width;
@@ -34,20 +32,11 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
        if (width == 8)
                num = width - 2;
 
-       end = S5PC100_GPG0(2 + num);
-
        /* Set all the necessary GPG0/GPG1 pins to special-function 0 */
-       for (gpio = S5PC100_GPG0(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PC100_GPG0(0), 2 + num, S3C_GPIO_SFN(2));
 
-       if (width == 8) {
-               for (gpio = S5PC100_GPG1(0); gpio <= S5PC100_GPG1(1); gpio++) {
-                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               }
-       }
+       if (width == 8)
+               s3c_gpio_cfgrange_nopull(S5PC100_GPG1(0), 2, S3C_GPIO_SFN(2));
 
        if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
                s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
@@ -58,16 +47,9 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
 void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
 {
        struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
-       unsigned int end;
-
-       end = S5PC100_GPG2(2 + width);
 
        /* Set all the necessary GPG2 pins to special-function 2 */
-       for (gpio = S5PC100_GPG2(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PC100_GPG2(0), 2 + width, S3C_GPIO_SFN(2));
 
        if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
                s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
@@ -78,16 +60,9 @@ void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
 void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
 {
        struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
-       unsigned int end;
-
-       end = S5PC100_GPG3(2 + width);
 
        /* Set all the necessary GPG3 pins to special-function 2 */
-       for (gpio = S5PC100_GPG3(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PC100_GPG3(0), 2 + width, S3C_GPIO_SFN(2));
 
        if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
                s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
index 5315fec3db86ae31df32ff0629a91e913b66a502..862f239a0fdbba45ad4fb895548fac66063ec404 100644 (file)
@@ -11,9 +11,9 @@ if ARCH_S5PV210
 
 config CPU_S5PV210
        bool
-       select PLAT_S5P
        select S3C_PL330_DMA
        select S5P_EXT_INT
+       select S5PV210_PM if PM
        help
          Enable S5PV210 CPU support
 
@@ -58,7 +58,6 @@ menu "S5PC110 Machines"
 config MACH_AQUILA
        bool "Aquila"
        select CPU_S5PV210
-       select ARCH_SPARSEMEM_ENABLE
        select S3C_DEV_FB
        select S5P_DEV_FIMC0
        select S5P_DEV_FIMC1
@@ -75,7 +74,7 @@ config MACH_AQUILA
 config MACH_GONI
        bool "GONI"
        select CPU_S5PV210
-       select ARCH_SPARSEMEM_ENABLE
+       select S5P_GPIO_INT
        select S3C_DEV_FB
        select S5P_DEV_FIMC0
        select S5P_DEV_FIMC1
@@ -83,8 +82,15 @@ config MACH_GONI
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C_DEV_HSMMC2
+       select S3C_DEV_I2C1
+       select S3C_DEV_I2C2
+       select S3C_DEV_USB_HSOTG
        select S5P_DEV_ONENAND
+       select SAMSUNG_DEV_KEYPAD
        select S5PV210_SETUP_FB_24BPP
+       select S5PV210_SETUP_I2C1
+       select S5PV210_SETUP_I2C2
+       select S5PV210_SETUP_KEYPAD
        select S5PV210_SETUP_SDHCI
        help
          Machine support for Samsung GONI board
@@ -93,7 +99,6 @@ config MACH_GONI
 config MACH_SMDKC110
        bool "SMDKC110"
        select CPU_S5PV210
-       select ARCH_SPARSEMEM_ENABLE
        select S3C_DEV_I2C1
        select S3C_DEV_I2C2
        select S3C_DEV_RTC
@@ -113,7 +118,6 @@ menu "S5PV210 Machines"
 config MACH_SMDKV210
        bool "SMDKV210"
        select CPU_S5PV210
-       select ARCH_SPARSEMEM_ENABLE
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C_DEV_HSMMC2
@@ -134,6 +138,29 @@ config MACH_SMDKV210
        help
          Machine support for Samsung SMDKV210
 
+config MACH_TORBRECK
+       bool "Torbreck"
+       select CPU_S5PV210
+       select ARCH_SPARSEMEM_ENABLE
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC1
+       select S3C_DEV_HSMMC2
+       select S3C_DEV_HSMMC3
+       select S3C_DEV_I2C1
+       select S3C_DEV_I2C2
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select S5PV210_SETUP_I2C1
+       select S5PV210_SETUP_I2C2
+       select S5PV210_SETUP_SDHCI
+       help
+         Machine support for aESOP Torbreck
+
 endmenu
 
+config S5PV210_PM
+       bool
+       help
+         Power Management code common to S5PV210
+
 endif
index 7045489124082d69715df5c9f4ec62061738763b..ff1a0db57a2fc976d1d09ed388ed3a62660559bb 100644 (file)
@@ -14,6 +14,8 @@ obj-                          :=
 
 obj-$(CONFIG_CPU_S5PV210)      += cpu.o init.o clock.o dma.o gpiolib.o
 obj-$(CONFIG_CPU_S5PV210)      += setup-i2c0.o
+obj-$(CONFIG_S5PV210_PM)       += pm.o sleep.o
+obj-$(CONFIG_CPU_FREQ)         += cpufreq.o
 
 # machine support
 
@@ -21,6 +23,7 @@ obj-$(CONFIG_MACH_AQUILA)     += mach-aquila.o
 obj-$(CONFIG_MACH_SMDKV210)    += mach-smdkv210.o
 obj-$(CONFIG_MACH_SMDKC110)    += mach-smdkc110.o
 obj-$(CONFIG_MACH_GONI)                += mach-goni.o
+obj-$(CONFIG_MACH_TORBRECK)    += mach-torbreck.o
 
 # device support
 
index d562670e1b0b44005ade9644f69338de44b459bb..019c3a69b0e476ca3af20f7d47ff076481f54e60 100644 (file)
@@ -31,6 +31,8 @@
 #include <plat/clock-clksrc.h>
 #include <plat/s5pv210.h>
 
+static unsigned long xtal;
+
 static struct clksrc_clk clk_mout_apll = {
        .clk    = {
                .name           = "mout_apll",
@@ -259,6 +261,36 @@ static struct clksrc_clk clk_sclk_vpll = {
        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
 };
 
+static struct clk *clkset_moutdmc0src_list[] = {
+       [0] = &clk_sclk_a2m.clk,
+       [1] = &clk_mout_mpll.clk,
+       [2] = NULL,
+       [3] = NULL,
+};
+
+static struct clksrc_sources clkset_moutdmc0src = {
+       .sources        = clkset_moutdmc0src_list,
+       .nr_sources     = ARRAY_SIZE(clkset_moutdmc0src_list),
+};
+
+static struct clksrc_clk clk_mout_dmc0 = {
+       .clk    = {
+               .name           = "mout_dmc0",
+               .id             = -1,
+       },
+       .sources        = &clkset_moutdmc0src,
+       .reg_src        = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
+};
+
+static struct clksrc_clk clk_sclk_dmc0 = {
+       .clk    = {
+               .name           = "sclk_dmc0",
+               .id             = -1,
+               .parent         = &clk_mout_dmc0.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
+};
+
 static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
 {
        return clk_get_rate(clk->parent) / 2;
@@ -268,8 +300,29 @@ static struct clk_ops clk_hclk_imem_ops = {
        .get_rate       = s5pv210_clk_imem_get_rate,
 };
 
+static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk)
+{
+       return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
+}
+
+static struct clk_ops clk_fout_apll_ops = {
+       .get_rate       = s5pv210_clk_fout_apll_get_rate,
+};
+
 static struct clk init_clocks_disable[] = {
        {
+               .name           = "pdma",
+               .id             = 0,
+               .parent         = &clk_hclk_psys.clk,
+               .enable         = s5pv210_clk_ip0_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "pdma",
+               .id             = 1,
+               .parent         = &clk_hclk_psys.clk,
+               .enable         = s5pv210_clk_ip0_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
                .name           = "rot",
                .id             = -1,
                .parent         = &clk_hclk_dsys.clk,
@@ -431,6 +484,12 @@ static struct clk init_clocks_disable[] = {
                .parent         = &clk_p,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "spdif",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s5pv210_clk_ip3_ctrl,
+               .ctrlbit        = (1 << 0),
        },
 };
 
@@ -660,6 +719,53 @@ static struct clksrc_sources clkset_sclk_spdif = {
        .nr_sources     = ARRAY_SIZE(clkset_sclk_spdif_list),
 };
 
+static int s5pv210_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+       struct clk *pclk;
+       int ret;
+
+       pclk = clk_get_parent(clk);
+       if (IS_ERR(pclk))
+               return -EINVAL;
+
+       ret = pclk->ops->set_rate(pclk, rate);
+       clk_put(pclk);
+
+       return ret;
+}
+
+static unsigned long s5pv210_spdif_get_rate(struct clk *clk)
+{
+       struct clk *pclk;
+       int rate;
+
+       pclk = clk_get_parent(clk);
+       if (IS_ERR(pclk))
+               return -EINVAL;
+
+       rate = pclk->ops->get_rate(clk);
+       clk_put(pclk);
+
+       return rate;
+}
+
+static struct clk_ops s5pv210_sclk_spdif_ops = {
+       .set_rate       = s5pv210_spdif_set_rate,
+       .get_rate       = s5pv210_spdif_get_rate,
+};
+
+static struct clksrc_clk clk_sclk_spdif = {
+       .clk            = {
+               .name           = "sclk_spdif",
+               .id             = -1,
+               .enable         = s5pv210_clk_mask0_ctrl,
+               .ctrlbit        = (1 << 27),
+               .ops            = &s5pv210_sclk_spdif_ops,
+       },
+       .sources = &clkset_sclk_spdif,
+       .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
+};
+
 static struct clk *clkset_group2_list[] = {
        [0] = &clk_ext_xtal_mux,
        [1] = &clk_xusbxti,
@@ -743,15 +849,6 @@ static struct clksrc_clk clksrcs[] = {
                },
                .sources = &clkset_sclk_mixer,
                .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_spdif",
-                       .id             = -1,
-                       .enable         = s5pv210_clk_mask0_ctrl,
-                       .ctrlbit        = (1 << 27),
-               },
-               .sources = &clkset_sclk_spdif,
-               .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
        }, {
                .clk    = {
                        .name           = "sclk_fimc",
@@ -953,12 +1050,93 @@ static struct clksrc_clk *sysclks[] = {
        &clk_sclk_dac,
        &clk_sclk_pixel,
        &clk_sclk_hdmi,
+       &clk_mout_dmc0,
+       &clk_sclk_dmc0,
+       &clk_sclk_audio0,
+       &clk_sclk_audio1,
+       &clk_sclk_audio2,
+       &clk_sclk_spdif,
+};
+
+static u32 epll_div[][6] = {
+       {  48000000, 0, 48, 3, 3, 0 },
+       {  96000000, 0, 48, 3, 2, 0 },
+       { 144000000, 1, 72, 3, 2, 0 },
+       { 192000000, 0, 48, 3, 1, 0 },
+       { 288000000, 1, 72, 3, 1, 0 },
+       {  32750000, 1, 65, 3, 4, 35127 },
+       {  32768000, 1, 65, 3, 4, 35127 },
+       {  45158400, 0, 45, 3, 3, 10355 },
+       {  45000000, 0, 45, 3, 3, 10355 },
+       {  45158000, 0, 45, 3, 3, 10355 },
+       {  49125000, 0, 49, 3, 3, 9961 },
+       {  49152000, 0, 49, 3, 3, 9961 },
+       {  67737600, 1, 67, 3, 3, 48366 },
+       {  67738000, 1, 67, 3, 3, 48366 },
+       {  73800000, 1, 73, 3, 3, 47710 },
+       {  73728000, 1, 73, 3, 3, 47710 },
+       {  36000000, 1, 32, 3, 4, 0 },
+       {  60000000, 1, 60, 3, 3, 0 },
+       {  72000000, 1, 72, 3, 3, 0 },
+       {  80000000, 1, 80, 3, 3, 0 },
+       {  84000000, 0, 42, 3, 2, 0 },
+       {  50000000, 0, 50, 3, 3, 0 },
+};
+
+static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int epll_con, epll_con_k;
+       unsigned int i;
+
+       /* Return if nothing changed */
+       if (clk->rate == rate)
+               return 0;
+
+       epll_con = __raw_readl(S5P_EPLL_CON);
+       epll_con_k = __raw_readl(S5P_EPLL_CON1);
+
+       epll_con_k &= ~PLL46XX_KDIV_MASK;
+       epll_con &= ~(1 << 27 |
+                       PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
+                       PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
+                       PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+               if (epll_div[i][0] == rate) {
+                       epll_con_k |= epll_div[i][5] << 0;
+                       epll_con |= (epll_div[i][1] << 27 |
+                                       epll_div[i][2] << PLL46XX_MDIV_SHIFT |
+                                       epll_div[i][3] << PLL46XX_PDIV_SHIFT |
+                                       epll_div[i][4] << PLL46XX_SDIV_SHIFT);
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(epll_div)) {
+               printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
+                               __func__);
+               return -EINVAL;
+       }
+
+       __raw_writel(epll_con, S5P_EPLL_CON);
+       __raw_writel(epll_con_k, S5P_EPLL_CON1);
+
+       printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+                       clk->rate, rate);
+
+       clk->rate = rate;
+
+       return 0;
+}
+
+static struct clk_ops s5pv210_epll_ops = {
+       .set_rate = s5pv210_epll_set_rate,
+       .get_rate = s5p_epll_get_rate,
 };
 
 void __init_or_cpufreq s5pv210_setup_clocks(void)
 {
        struct clk *xtal_clk;
-       unsigned long xtal;
        unsigned long vpllsrc;
        unsigned long armclk;
        unsigned long hclk_msys;
@@ -974,6 +1152,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
        unsigned int ptr;
        u32 clkdiv0, clkdiv1;
 
+       /* Set functions for clk_fout_epll */
+       clk_fout_epll.enable = s5p_epll_enable;
+       clk_fout_epll.ops = &s5pv210_epll_ops;
+
        printk(KERN_DEBUG "%s: registering clocks\n", __func__);
 
        clkdiv0 = __raw_readl(S5P_CLK_DIV0);
@@ -992,11 +1174,12 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
 
        apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
        mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
-       epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
+       epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON),
+                               __raw_readl(S5P_EPLL_CON1), pll_4600);
        vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
        vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
 
-       clk_fout_apll.rate = apll;
+       clk_fout_apll.ops = &clk_fout_apll_ops;
        clk_fout_mpll.rate = mpll;
        clk_fout_epll.rate = epll;
        clk_fout_vpll.rate = vpll;
index 2f16bfc0a116cd4bde8298b8c83ed4f076145080..8eb480e201b054bfa4eed1408b5e0f02961a4b20 100644 (file)
@@ -85,6 +85,21 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
                .pfn            = __phys_to_pfn(S5PV210_PA_SROMC),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_DMC0,
+               .pfn            = __phys_to_pfn(S5PV210_PA_DMC0),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_DMC1,
+               .pfn            = __phys_to_pfn(S5PV210_PA_DMC1),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S3C_VA_USB_HSPHY,
+               .pfn            =__phys_to_pfn(S5PV210_PA_HSPHY),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
        }
 };
 
diff --git a/arch/arm/mach-s5pv210/cpufreq.c b/arch/arm/mach-s5pv210/cpufreq.c
new file mode 100644 (file)
index 0000000..a6f2292
--- /dev/null
@@ -0,0 +1,484 @@
+/* linux/arch/arm/mach-s5pv210/cpufreq.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * CPU frequency scaling for S5PC110/S5PV210
+ *
+ * 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 <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+static struct clk *cpu_clk;
+static struct clk *dmc0_clk;
+static struct clk *dmc1_clk;
+static struct cpufreq_freqs freqs;
+
+/* APLL M,P,S values for 1G/800Mhz */
+#define APLL_VAL_1000  ((1 << 31) | (125 << 16) | (3 << 8) | 1)
+#define APLL_VAL_800   ((1 << 31) | (100 << 16) | (3 << 8) | 1)
+
+/*
+ * DRAM configurations to calculate refresh counter for changing
+ * frequency of memory.
+ */
+struct dram_conf {
+       unsigned long freq;     /* HZ */
+       unsigned long refresh;  /* DRAM refresh counter * 1000 */
+};
+
+/* DRAM configuration (DMC0 and DMC1) */
+static struct dram_conf s5pv210_dram_conf[2];
+
+enum perf_level {
+       L0, L1, L2, L3, L4,
+};
+
+enum s5pv210_mem_type {
+       LPDDR   = 0x1,
+       LPDDR2  = 0x2,
+       DDR2    = 0x4,
+};
+
+enum s5pv210_dmc_port {
+       DMC0 = 0,
+       DMC1,
+};
+
+static struct cpufreq_frequency_table s5pv210_freq_table[] = {
+       {L0, 1000*1000},
+       {L1, 800*1000},
+       {L2, 400*1000},
+       {L3, 200*1000},
+       {L4, 100*1000},
+       {0, CPUFREQ_TABLE_END},
+};
+
+static u32 clkdiv_val[5][11] = {
+       /*
+        * Clock divider value for following
+        * { APLL, A2M, HCLK_MSYS, PCLK_MSYS,
+        *   HCLK_DSYS, PCLK_DSYS, HCLK_PSYS, PCLK_PSYS,
+        *   ONEDRAM, MFC, G3D }
+        */
+
+       /* L0 : [1000/200/100][166/83][133/66][200/200] */
+       {0, 4, 4, 1, 3, 1, 4, 1, 3, 0, 0},
+
+       /* L1 : [800/200/100][166/83][133/66][200/200] */
+       {0, 3, 3, 1, 3, 1, 4, 1, 3, 0, 0},
+
+       /* L2 : [400/200/100][166/83][133/66][200/200] */
+       {1, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
+
+       /* L3 : [200/200/100][166/83][133/66][200/200] */
+       {3, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
+
+       /* L4 : [100/100/100][83/83][66/66][100/100] */
+       {7, 7, 0, 0, 7, 0, 9, 0, 7, 0, 0},
+};
+
+/*
+ * This function set DRAM refresh counter
+ * accoriding to operating frequency of DRAM
+ * ch: DMC port number 0 or 1
+ * freq: Operating frequency of DRAM(KHz)
+ */
+static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq)
+{
+       unsigned long tmp, tmp1;
+       void __iomem *reg = NULL;
+
+       if (ch == DMC0)
+               reg = (S5P_VA_DMC0 + 0x30);
+       else if (ch == DMC1)
+               reg = (S5P_VA_DMC1 + 0x30);
+       else
+               printk(KERN_ERR "Cannot find DMC port\n");
+
+       /* Find current DRAM frequency */
+       tmp = s5pv210_dram_conf[ch].freq;
+
+       do_div(tmp, freq);
+
+       tmp1 = s5pv210_dram_conf[ch].refresh;
+
+       do_div(tmp1, tmp);
+
+       __raw_writel(tmp1, reg);
+}
+
+int s5pv210_verify_speed(struct cpufreq_policy *policy)
+{
+       if (policy->cpu)
+               return -EINVAL;
+
+       return cpufreq_frequency_table_verify(policy, s5pv210_freq_table);
+}
+
+unsigned int s5pv210_getspeed(unsigned int cpu)
+{
+       if (cpu)
+               return 0;
+
+       return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int s5pv210_target(struct cpufreq_policy *policy,
+                         unsigned int target_freq,
+                         unsigned int relation)
+{
+       unsigned long reg;
+       unsigned int index, priv_index;
+       unsigned int pll_changing = 0;
+       unsigned int bus_speed_changing = 0;
+
+       freqs.old = s5pv210_getspeed(0);
+
+       if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
+                                          target_freq, relation, &index))
+               return -EINVAL;
+
+       freqs.new = s5pv210_freq_table[index].frequency;
+       freqs.cpu = 0;
+
+       if (freqs.new == freqs.old)
+               return 0;
+
+       /* Finding current running level index */
+       if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
+                                          freqs.old, relation, &priv_index))
+               return -EINVAL;
+
+       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+       if (freqs.new > freqs.old) {
+               /* Voltage up: will be implemented */
+       }
+
+       /* Check if there need to change PLL */
+       if ((index == L0) || (priv_index == L0))
+               pll_changing = 1;
+
+       /* Check if there need to change System bus clock */
+       if ((index == L4) || (priv_index == L4))
+               bus_speed_changing = 1;
+
+       if (bus_speed_changing) {
+               /*
+                * Reconfigure DRAM refresh counter value for minimum
+                * temporary clock while changing divider.
+                * expected clock is 83Mhz : 7.8usec/(1/83Mhz) = 0x287
+                */
+               if (pll_changing)
+                       s5pv210_set_refresh(DMC1, 83000);
+               else
+                       s5pv210_set_refresh(DMC1, 100000);
+
+               s5pv210_set_refresh(DMC0, 83000);
+       }
+
+       /*
+        * APLL should be changed in this level
+        * APLL -> MPLL(for stable transition) -> APLL
+        * Some clock source's clock API are not prepared.
+        * Do not use clock API in below code.
+        */
+       if (pll_changing) {
+               /*
+                * 1. Temporary Change divider for MFC and G3D
+                * SCLKA2M(200/1=200)->(200/4=50)Mhz
+                */
+               reg = __raw_readl(S5P_CLK_DIV2);
+               reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
+               reg |= (3 << S5P_CLKDIV2_G3D_SHIFT) |
+                       (3 << S5P_CLKDIV2_MFC_SHIFT);
+               __raw_writel(reg, S5P_CLK_DIV2);
+
+               /* For MFC, G3D dividing */
+               do {
+                       reg = __raw_readl(S5P_CLKDIV_STAT0);
+               } while (reg & ((1 << 16) | (1 << 17)));
+
+               /*
+                * 2. Change SCLKA2M(200Mhz)to SCLKMPLL in MFC_MUX, G3D MUX
+                * (200/4=50)->(667/4=166)Mhz
+                */
+               reg = __raw_readl(S5P_CLK_SRC2);
+               reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
+               reg |= (1 << S5P_CLKSRC2_G3D_SHIFT) |
+                       (1 << S5P_CLKSRC2_MFC_SHIFT);
+               __raw_writel(reg, S5P_CLK_SRC2);
+
+               do {
+                       reg = __raw_readl(S5P_CLKMUX_STAT1);
+               } while (reg & ((1 << 7) | (1 << 3)));
+
+               /*
+                * 3. DMC1 refresh count for 133Mhz if (index == L4) is
+                * true refresh counter is already programed in upper
+                * code. 0x287@83Mhz
+                */
+               if (!bus_speed_changing)
+                       s5pv210_set_refresh(DMC1, 133000);
+
+               /* 4. SCLKAPLL -> SCLKMPLL */
+               reg = __raw_readl(S5P_CLK_SRC0);
+               reg &= ~(S5P_CLKSRC0_MUX200_MASK);
+               reg |= (0x1 << S5P_CLKSRC0_MUX200_SHIFT);
+               __raw_writel(reg, S5P_CLK_SRC0);
+
+               do {
+                       reg = __raw_readl(S5P_CLKMUX_STAT0);
+               } while (reg & (0x1 << 18));
+
+       }
+
+       /* Change divider */
+       reg = __raw_readl(S5P_CLK_DIV0);
+
+       reg &= ~(S5P_CLKDIV0_APLL_MASK | S5P_CLKDIV0_A2M_MASK |
+               S5P_CLKDIV0_HCLK200_MASK | S5P_CLKDIV0_PCLK100_MASK |
+               S5P_CLKDIV0_HCLK166_MASK | S5P_CLKDIV0_PCLK83_MASK |
+               S5P_CLKDIV0_HCLK133_MASK | S5P_CLKDIV0_PCLK66_MASK);
+
+       reg |= ((clkdiv_val[index][0] << S5P_CLKDIV0_APLL_SHIFT) |
+               (clkdiv_val[index][1] << S5P_CLKDIV0_A2M_SHIFT) |
+               (clkdiv_val[index][2] << S5P_CLKDIV0_HCLK200_SHIFT) |
+               (clkdiv_val[index][3] << S5P_CLKDIV0_PCLK100_SHIFT) |
+               (clkdiv_val[index][4] << S5P_CLKDIV0_HCLK166_SHIFT) |
+               (clkdiv_val[index][5] << S5P_CLKDIV0_PCLK83_SHIFT) |
+               (clkdiv_val[index][6] << S5P_CLKDIV0_HCLK133_SHIFT) |
+               (clkdiv_val[index][7] << S5P_CLKDIV0_PCLK66_SHIFT));
+
+       __raw_writel(reg, S5P_CLK_DIV0);
+
+       do {
+               reg = __raw_readl(S5P_CLKDIV_STAT0);
+       } while (reg & 0xff);
+
+       /* ARM MCS value changed */
+       reg = __raw_readl(S5P_ARM_MCS_CON);
+       reg &= ~0x3;
+       if (index >= L3)
+               reg |= 0x3;
+       else
+               reg |= 0x1;
+
+       __raw_writel(reg, S5P_ARM_MCS_CON);
+
+       if (pll_changing) {
+               /* 5. Set Lock time = 30us*24Mhz = 0x2cf */
+               __raw_writel(0x2cf, S5P_APLL_LOCK);
+
+               /*
+                * 6. Turn on APLL
+                * 6-1. Set PMS values
+                * 6-2. Wait untile the PLL is locked
+                */
+               if (index == L0)
+                       __raw_writel(APLL_VAL_1000, S5P_APLL_CON);
+               else
+                       __raw_writel(APLL_VAL_800, S5P_APLL_CON);
+
+               do {
+                       reg = __raw_readl(S5P_APLL_CON);
+               } while (!(reg & (0x1 << 29)));
+
+               /*
+                * 7. Change souce clock from SCLKMPLL(667Mhz)
+                * to SCLKA2M(200Mhz) in MFC_MUX and G3D MUX
+                * (667/4=166)->(200/4=50)Mhz
+                */
+               reg = __raw_readl(S5P_CLK_SRC2);
+               reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
+               reg |= (0 << S5P_CLKSRC2_G3D_SHIFT) |
+                       (0 << S5P_CLKSRC2_MFC_SHIFT);
+               __raw_writel(reg, S5P_CLK_SRC2);
+
+               do {
+                       reg = __raw_readl(S5P_CLKMUX_STAT1);
+               } while (reg & ((1 << 7) | (1 << 3)));
+
+               /*
+                * 8. Change divider for MFC and G3D
+                * (200/4=50)->(200/1=200)Mhz
+                */
+               reg = __raw_readl(S5P_CLK_DIV2);
+               reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
+               reg |= (clkdiv_val[index][10] << S5P_CLKDIV2_G3D_SHIFT) |
+                       (clkdiv_val[index][9] << S5P_CLKDIV2_MFC_SHIFT);
+               __raw_writel(reg, S5P_CLK_DIV2);
+
+               /* For MFC, G3D dividing */
+               do {
+                       reg = __raw_readl(S5P_CLKDIV_STAT0);
+               } while (reg & ((1 << 16) | (1 << 17)));
+
+               /* 9. Change MPLL to APLL in MSYS_MUX */
+               reg = __raw_readl(S5P_CLK_SRC0);
+               reg &= ~(S5P_CLKSRC0_MUX200_MASK);
+               reg |= (0x0 << S5P_CLKSRC0_MUX200_SHIFT);
+               __raw_writel(reg, S5P_CLK_SRC0);
+
+               do {
+                       reg = __raw_readl(S5P_CLKMUX_STAT0);
+               } while (reg & (0x1 << 18));
+
+               /*
+                * 10. DMC1 refresh counter
+                * L4 : DMC1 = 100Mhz 7.8us/(1/100) = 0x30c
+                * Others : DMC1 = 200Mhz 7.8us/(1/200) = 0x618
+                */
+               if (!bus_speed_changing)
+                       s5pv210_set_refresh(DMC1, 200000);
+       }
+
+       /*
+        * L4 level need to change memory bus speed, hence onedram clock divier
+        * and memory refresh parameter should be changed
+        */
+       if (bus_speed_changing) {
+               reg = __raw_readl(S5P_CLK_DIV6);
+               reg &= ~S5P_CLKDIV6_ONEDRAM_MASK;
+               reg |= (clkdiv_val[index][8] << S5P_CLKDIV6_ONEDRAM_SHIFT);
+               __raw_writel(reg, S5P_CLK_DIV6);
+
+               do {
+                       reg = __raw_readl(S5P_CLKDIV_STAT1);
+               } while (reg & (1 << 15));
+
+               /* Reconfigure DRAM refresh counter value */
+               if (index != L4) {
+                       /*
+                        * DMC0 : 166Mhz
+                        * DMC1 : 200Mhz
+                        */
+                       s5pv210_set_refresh(DMC0, 166000);
+                       s5pv210_set_refresh(DMC1, 200000);
+               } else {
+                       /*
+                        * DMC0 : 83Mhz
+                        * DMC1 : 100Mhz
+                        */
+                       s5pv210_set_refresh(DMC0, 83000);
+                       s5pv210_set_refresh(DMC1, 100000);
+               }
+       }
+
+       if (freqs.new < freqs.old) {
+               /* Voltage down: will be implemented */
+       }
+
+       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+       printk(KERN_DEBUG "Perf changed[L%d]\n", index);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy,
+                                  pm_message_t pmsg)
+{
+       return 0;
+}
+
+static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy)
+{
+       return 0;
+}
+#endif
+
+static int check_mem_type(void __iomem *dmc_reg)
+{
+       unsigned long val;
+
+       val = __raw_readl(dmc_reg + 0x4);
+       val = (val & (0xf << 8));
+
+       return val >> 8;
+}
+
+static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
+{
+       unsigned long mem_type;
+
+       cpu_clk = clk_get(NULL, "armclk");
+       if (IS_ERR(cpu_clk))
+               return PTR_ERR(cpu_clk);
+
+       dmc0_clk = clk_get(NULL, "sclk_dmc0");
+       if (IS_ERR(dmc0_clk)) {
+               clk_put(cpu_clk);
+               return PTR_ERR(dmc0_clk);
+       }
+
+       dmc1_clk = clk_get(NULL, "hclk_msys");
+       if (IS_ERR(dmc1_clk)) {
+               clk_put(dmc0_clk);
+               clk_put(cpu_clk);
+               return PTR_ERR(dmc1_clk);
+       }
+
+       if (policy->cpu != 0)
+               return -EINVAL;
+
+       /*
+        * check_mem_type : This driver only support LPDDR & LPDDR2.
+        * other memory type is not supported.
+        */
+       mem_type = check_mem_type(S5P_VA_DMC0);
+
+       if ((mem_type != LPDDR) && (mem_type != LPDDR2)) {
+               printk(KERN_ERR "CPUFreq doesn't support this memory type\n");
+               return -EINVAL;
+       }
+
+       /* Find current refresh counter and frequency each DMC */
+       s5pv210_dram_conf[0].refresh = (__raw_readl(S5P_VA_DMC0 + 0x30) * 1000);
+       s5pv210_dram_conf[0].freq = clk_get_rate(dmc0_clk);
+
+       s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000);
+       s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk);
+
+       policy->cur = policy->min = policy->max = s5pv210_getspeed(0);
+
+       cpufreq_frequency_table_get_attr(s5pv210_freq_table, policy->cpu);
+
+       policy->cpuinfo.transition_latency = 40000;
+
+       return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table);
+}
+
+static struct cpufreq_driver s5pv210_driver = {
+       .flags          = CPUFREQ_STICKY,
+       .verify         = s5pv210_verify_speed,
+       .target         = s5pv210_target,
+       .get            = s5pv210_getspeed,
+       .init           = s5pv210_cpu_init,
+       .name           = "s5pv210",
+#ifdef CONFIG_PM
+       .suspend        = s5pv210_cpufreq_suspend,
+       .resume         = s5pv210_cpufreq_resume,
+#endif
+};
+
+static int __init s5pv210_cpufreq_init(void)
+{
+       return cpufreq_register_driver(&s5pv210_driver);
+}
+
+late_initcall(s5pv210_cpufreq_init);
index 21dc6cf955c35c6eb01b70d9096bf8fde9137485..1303fcb12b517b7b71b3ef03876b9cd0635dfd8f 100644 (file)
@@ -24,29 +24,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev)
        /* configure GPIO for i2s port */
        switch (pdev->id) {
        case 1:
-               s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
                break;
 
        case 2:
-               s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(4));
-               s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(4));
-               s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(4));
-               s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(4));
-               s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
                break;
 
        case -1:
-               s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPI(5), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPI(6), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
                break;
 
        default:
@@ -151,25 +137,13 @@ static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
 {
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin_range(S5PV210_GPI(0), 5, S3C_GPIO_SFN(3));
                break;
        case 1:
-               s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3));
-               s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(3));
                break;
        case 2:
-               s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(2));
                break;
        default:
                printk(KERN_DEBUG "Invalid PCM Controller number!");
@@ -271,13 +245,7 @@ struct platform_device s5pv210_device_pcm2 = {
 
 static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
 {
-       s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4));
-       s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4));
-       s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4));
-       s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4));
-       s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4));
-
-       return 0;
+       return s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(4));
 }
 
 static struct resource s5pv210_ac97_resource[] = {
@@ -325,3 +293,43 @@ struct platform_device s5pv210_device_ac97 = {
                .coherent_dma_mask = DMA_BIT_MASK(32),
        },
 };
+
+/* S/PDIF Controller platform_device */
+
+static int s5pv210_spdif_cfg_gpio(struct platform_device *pdev)
+{
+       s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 2, S3C_GPIO_SFN(3));
+
+       return 0;
+}
+
+static struct resource s5pv210_spdif_resource[] = {
+       [0] = {
+               .start  = S5PV210_PA_SPDIF,
+               .end    = S5PV210_PA_SPDIF + 0x100 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = DMACH_SPDIF,
+               .end    = DMACH_SPDIF,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct s3c_audio_pdata samsung_spdif_pdata = {
+       .cfg_gpio = s5pv210_spdif_cfg_gpio,
+};
+
+static u64 s5pv210_spdif_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pv210_device_spdif = {
+       .name           = "samsung-spdif",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s5pv210_spdif_resource),
+       .resource       = s5pv210_spdif_resource,
+       .dev = {
+               .platform_data = &samsung_spdif_pdata,
+               .dma_mask = &s5pv210_spdif_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
index 826cdbc43e20d6155fd268391b5c14aae2446822..e3249a47e3b1de90bc8ed5e5345debb75de29260 100644 (file)
@@ -35,23 +35,15 @@ static char *spi_src_clks[] = {
  */
 static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
 {
+       unsigned int base;
+
        switch (pdev->id) {
        case 0:
-               s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPB(1), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPB(2), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PV210_GPB(1), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PV210_GPB(2), S3C_GPIO_PULL_UP);
+               base = S5PV210_GPB(0);
                break;
 
        case 1:
-               s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPB(5), S3C_GPIO_SFN(2));
-               s3c_gpio_cfgpin(S5PV210_GPB(6), S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PV210_GPB(5), S3C_GPIO_PULL_UP);
-               s3c_gpio_setpull(S5PV210_GPB(6), S3C_GPIO_PULL_UP);
+               base = S5PV210_GPB(4);
                break;
 
        default:
@@ -59,6 +51,9 @@ static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       s3c_gpio_cfgall_range(base, 3,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
        return 0;
 }
 
index 778ad5fe231a3f0d6774d53979f5d29d0585ce44..497d3439a142289e535938961c37313a77a3e1a8 100644 (file)
@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
 
 static struct platform_device s5pv210_device_pdma0 = {
        .name           = "s3c-pl330",
-       .id             = 1,
+       .id             = 0,
        .num_resources  = ARRAY_SIZE(s5pv210_pdma0_resource),
        .resource       = s5pv210_pdma0_resource,
        .dev            = {
@@ -144,7 +144,7 @@ static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
 
 static struct platform_device s5pv210_device_pdma1 = {
        .name           = "s3c-pl330",
-       .id             = 2,
+       .id             = 1,
        .num_resources  = ARRAY_SIZE(s5pv210_pdma1_resource),
        .resource       = s5pv210_pdma1_resource,
        .dev            = {
index 0d459112d0396645f2c2a391de89662bd43120db..ab673effd767833b68526ce3cebda66c5e41663d 100644 (file)
@@ -150,6 +150,7 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
                        .label  = "GPG3",
                },
        }, {
+               .config = &gpio_cfg_noint,
                .chip   = {
                        .base   = S5PV210_GPI(0),
                        .ngpio  = S5PV210_GPIO_I_NR,
@@ -223,34 +224,42 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
        }, {
                .base   = (S5P_VA_GPIO + 0xC00),
                .config = &gpio_cfg_noint,
+               .irq_base = IRQ_EINT(0),
                .chip   = {
                        .base   = S5PV210_GPH0(0),
                        .ngpio  = S5PV210_GPIO_H0_NR,
                        .label  = "GPH0",
+                       .to_irq = samsung_gpiolib_to_irq,
                },
        }, {
                .base   = (S5P_VA_GPIO + 0xC20),
                .config = &gpio_cfg_noint,
+               .irq_base = IRQ_EINT(8),
                .chip   = {
                        .base   = S5PV210_GPH1(0),
                        .ngpio  = S5PV210_GPIO_H1_NR,
                        .label  = "GPH1",
+                       .to_irq = samsung_gpiolib_to_irq,
                },
        }, {
                .base   = (S5P_VA_GPIO + 0xC40),
                .config = &gpio_cfg_noint,
+               .irq_base = IRQ_EINT(16),
                .chip   = {
                        .base   = S5PV210_GPH2(0),
                        .ngpio  = S5PV210_GPIO_H2_NR,
                        .label  = "GPH2",
+                       .to_irq = samsung_gpiolib_to_irq,
                },
        }, {
                .base   = (S5P_VA_GPIO + 0xC60),
                .config = &gpio_cfg_noint,
+               .irq_base = IRQ_EINT(24),
                .chip   = {
                        .base   = S5PV210_GPH3(0),
                        .ngpio  = S5PV210_GPIO_H3_NR,
                        .label  = "GPH3",
+                       .to_irq = samsung_gpiolib_to_irq,
                },
        },
 };
@@ -259,11 +268,14 @@ static __init int s5pv210_gpiolib_init(void)
 {
        struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
        int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
+       int gpioint_group = 0;
        int i = 0;
 
        for (i = 0; i < nr_chips; i++, chip++) {
-               if (chip->config == NULL)
+               if (chip->config == NULL) {
                        chip->config = &gpio_cfg;
+                       chip->group = gpioint_group++;
+               }
                if (chip->base == NULL)
                        chip->base = S5PV210_BANK_BASE(i);
        }
index e1c020e5a49baf2d7c8729c9048402e61b84dbf7..119b95fdc3cef1c945124f4e8cc21e89b3854f65 100644 (file)
@@ -55,8 +55,8 @@
 #define IRQ_SPI1               S5P_IRQ_VIC1(16)
 #define IRQ_SPI2               S5P_IRQ_VIC1(17)
 #define IRQ_IRDA               S5P_IRQ_VIC1(18)
-#define IRQ_CAN0               S5P_IRQ_VIC1(19)
-#define IRQ_CAN1               S5P_IRQ_VIC1(20)
+#define IRQ_IIC2               S5P_IRQ_VIC1(19)
+#define IRQ_IIC3               S5P_IRQ_VIC1(20)
 #define IRQ_HSIRX              S5P_IRQ_VIC1(21)
 #define IRQ_HSITX              S5P_IRQ_VIC1(22)
 #define IRQ_UHOST              S5P_IRQ_VIC1(23)
 
 #define IRQ_IPC                        S5P_IRQ_VIC3(0)
 #define IRQ_HOSTIF             S5P_IRQ_VIC3(1)
-#define IRQ_MMC3               S5P_IRQ_VIC3(2)
+#define IRQ_HSMMC3             S5P_IRQ_VIC3(2)
 #define IRQ_CEC                        S5P_IRQ_VIC3(3)
 #define IRQ_TSI                        S5P_IRQ_VIC3(4)
 #define IRQ_MDNIE0             S5P_IRQ_VIC3(5)
 #define S5P_EINT_BASE1         (S5P_IRQ_VIC0(0))
 #define S5P_EINT_BASE2         (IRQ_VIC_END + 1)
 
+/* GPIO interrupt */
+#define S5P_GPIOINT_BASE       (IRQ_EINT(31) + 1)
+#define S5P_GPIOINT_GROUP_MAXNR        22
+
 /* Set the default NR_IRQS */
-#define NR_IRQS                        (IRQ_EINT(31) + 1)
+#define NR_IRQS                        (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
 
 /* Compatibility */
 #define IRQ_LCD_FIFO           IRQ_LCD0
index bd9afd52466ad2cb787ed90ba394cc1f73870cb0..861d7fe11fc99db6ee0427adcf5babe028c04806 100644 (file)
@@ -57,6 +57,8 @@
 
 #define S5P_SZ_UART            SZ_256
 
+#define S3C_VA_UARTx(x)                (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+
 #define S5PV210_PA_SROMC       (0xE8000000)
 
 #define S5PV210_PA_CFCON       (0xE8200000)
@@ -73,6 +75,9 @@
 
 #define S5PV210_PA_HSMMC(x)    (0xEB000000 + ((x) * 0x100000))
 
+#define S5PV210_PA_HSOTG       (0xEC000000)
+#define S5PV210_PA_HSPHY       (0xEC100000)
+
 #define S5PV210_PA_VIC0                (0xF2000000)
 #define S5PV210_PA_VIC1                (0xF2100000)
 #define S5PV210_PA_VIC2                (0xF2200000)
@@ -81,6 +86,9 @@
 #define S5PV210_PA_SDRAM       (0x20000000)
 #define S5P_PA_SDRAM           S5PV210_PA_SDRAM
 
+/* S/PDIF */
+#define S5PV210_PA_SPDIF       0xE1100000
+
 /* I2S */
 #define S5PV210_PA_IIS0                0xEEE30000
 #define S5PV210_PA_IIS1                0xE2100000
 
 #define S5PV210_PA_ADC         (0xE1700000)
 
+#define S5PV210_PA_DMC0                (0xF0000000)
+#define S5PV210_PA_DMC1                (0xF1400000)
+
 /* compatibiltiy defines. */
 #define S3C_PA_UART            S5PV210_PA_UART
 #define S3C_PA_HSMMC0          S5PV210_PA_HSMMC(0)
 #define S3C_PA_FB              S5PV210_PA_FB
 #define S3C_PA_RTC             S5PV210_PA_RTC
 #define S3C_PA_WDT             S5PV210_PA_WATCHDOG
+#define S3C_PA_USB_HSOTG       S5PV210_PA_HSOTG
 #define S5P_PA_FIMC0           S5PV210_PA_FIMC0
 #define S5P_PA_FIMC1           S5PV210_PA_FIMC1
 #define S5P_PA_FIMC2           S5PV210_PA_FIMC2
diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h
new file mode 100644 (file)
index 0000000..e8d394f
--- /dev/null
@@ -0,0 +1,43 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * S5PV210 - PM core support for arch/arm/plat-s5p/pm.c
+ *
+ * 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.
+*/
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+       /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+       __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
+       __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+       /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+       /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+                                          struct pm_uart_save *save)
+{
+       /* nothing here yet */
+}
index 499aef737476abebb29cff138e722eefc02e4e36..ebaabe021af911e642eb0d830b913d37fec6e5d4 100644 (file)
@@ -25,6 +25,7 @@
 #define S5P_APLL_CON           S5P_CLKREG(0x100)
 #define S5P_MPLL_CON           S5P_CLKREG(0x108)
 #define S5P_EPLL_CON           S5P_CLKREG(0x110)
+#define S5P_EPLL_CON1          S5P_CLKREG(0x114)
 #define S5P_VPLL_CON           S5P_CLKREG(0x120)
 
 #define S5P_CLK_SRC0           S5P_CLKREG(0x200)
 #define S5P_CLKGATE_BUS1       S5P_CLKREG(0x488)
 #define S5P_CLK_OUT            S5P_CLKREG(0x500)
 
+/* DIV/MUX STATUS */
+#define S5P_CLKDIV_STAT0       S5P_CLKREG(0x1000)
+#define S5P_CLKDIV_STAT1       S5P_CLKREG(0x1004)
+#define S5P_CLKMUX_STAT0       S5P_CLKREG(0x1100)
+#define S5P_CLKMUX_STAT1       S5P_CLKREG(0x1104)
+
 /* CLKSRC0 */
-#define S5P_CLKSRC0_MUX200_MASK                (0x1<<16)
+#define S5P_CLKSRC0_MUX200_SHIFT       (16)
+#define S5P_CLKSRC0_MUX200_MASK                (0x1 << S5P_CLKSRC0_MUX200_SHIFT)
 #define S5P_CLKSRC0_MUX166_MASK                (0x1<<20)
 #define S5P_CLKSRC0_MUX133_MASK                (0x1<<24)
 
+/* CLKSRC2 */
+#define S5P_CLKSRC2_G3D_SHIFT           (0)
+#define S5P_CLKSRC2_G3D_MASK            (0x3 << S5P_CLKSRC2_G3D_SHIFT)
+#define S5P_CLKSRC2_MFC_SHIFT           (4)
+#define S5P_CLKSRC2_MFC_MASK            (0x3 << S5P_CLKSRC2_MFC_SHIFT)
+
+/* CLKSRC6*/
+#define S5P_CLKSRC6_ONEDRAM_SHIFT       (24)
+#define S5P_CLKSRC6_ONEDRAM_MASK        (0x3 << S5P_CLKSRC6_ONEDRAM_SHIFT)
+
 /* CLKDIV0 */
 #define S5P_CLKDIV0_APLL_SHIFT         (0)
 #define S5P_CLKDIV0_APLL_MASK          (0x7 << S5P_CLKDIV0_APLL_SHIFT)
 #define S5P_CLKDIV0_PCLK66_SHIFT       (28)
 #define S5P_CLKDIV0_PCLK66_MASK                (0x7 << S5P_CLKDIV0_PCLK66_SHIFT)
 
+/* CLKDIV2 */
+#define S5P_CLKDIV2_G3D_SHIFT           (0)
+#define S5P_CLKDIV2_G3D_MASK            (0xF << S5P_CLKDIV2_G3D_SHIFT)
+#define S5P_CLKDIV2_MFC_SHIFT           (4)
+#define S5P_CLKDIV2_MFC_MASK            (0xF << S5P_CLKDIV2_MFC_SHIFT)
+
+/* CLKDIV6 */
+#define S5P_CLKDIV6_ONEDRAM_SHIFT       (28)
+#define S5P_CLKDIV6_ONEDRAM_MASK        (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT)
+
 #define S5P_SWRESET            S5P_CLKREG(0x2000)
 
+#define S5P_ARM_MCS_CON                S5P_CLKREG(0x6100)
+
 /* Registers related to power management */
 #define S5P_PWR_CFG            S5P_CLKREG(0xC000)
 #define S5P_EINT_WAKEUP_MASK   S5P_CLKREG(0xC004)
-#define S5P_WAKEUP_MASK        S5P_CLKREG(0xC008)
+#define S5P_WAKEUP_MASK                S5P_CLKREG(0xC008)
 #define S5P_PWR_MODE           S5P_CLKREG(0xC00C)
 #define S5P_NORMAL_CFG         S5P_CLKREG(0xC010)
 #define S5P_IDLE_CFG           S5P_CLKREG(0xC020)
 #define S5P_SLEEP_CFG_USBOSC_EN                (1 << 1)
 
 /* OTHERS Resgister */
+#define S5P_OTHERS_RET_IO              (1 << 31)
+#define S5P_OTHERS_RET_CF              (1 << 30)
+#define S5P_OTHERS_RET_MMC             (1 << 29)
+#define S5P_OTHERS_RET_UART            (1 << 28)
 #define S5P_OTHERS_USB_SIG_MASK                (1 << 16)
-#define S5P_OTHERS_MIPI_DPHY_EN                (1 << 28)
 
 /* MIPI */
 #define S5P_MIPI_DPHY_EN               (3)
index 49e029b4978ab552a210c5dcee3a94d980777345..de0c89976078a768fc02e1d7c631268397bfd5ee 100644 (file)
 
 #define eint_irq_to_bit(irq)           (1 << (EINT_OFFSET(irq) & 0x7))
 
-/* values for S5P_EXTINT0 */
-#define S5P_EXTINT_LOWLEV              (0x00)
-#define S5P_EXTINT_HILEV               (0x01)
-#define S5P_EXTINT_FALLEDGE            (0x02)
-#define S5P_EXTINT_RISEEDGE            (0x03)
-#define S5P_EXTINT_BOTHEDGE            (0x04)
-
 #define EINT_MODE              S3C_GPIO_SFN(0xf)
 
 #define EINT_GPIO_0(x)         S5PV210_GPH0(x)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h
new file mode 100644 (file)
index 0000000..26691d3
--- /dev/null
@@ -0,0 +1,19 @@
+/* arch/arm/mach-s5pv210/include/mach/regs-sys.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5PV210 - System registers definitions
+ *
+ * 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.
+*/
+
+#define S5PV210_USB_PHY_CON    (S3C_VA_SYS + 0xE80C)
+#define S5PV210_USB_PHY0_EN    (1 << 0)
+#define S5PV210_USB_PHY1_EN    (1 << 1)
+
+/* compatibility defines for s3c-hsotg driver */
+#define S3C64XX_OTHERS         S5PV210_USB_PHY_CON
+#define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN
index df9a28808323e44efed82fe7d67b880180dfa6b6..a6c659d68a5d40ff9c808942df7f2d7975c6cd0c 100644 (file)
@@ -17,6 +17,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H __FILE__
 
-#define VMALLOC_END    (0xE0000000UL)
+#define VMALLOC_END    0xF6000000UL
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index 00883087363c9229acde4d81e96e7d43668c412d..28677caf3613cca0ec00bf02862ba01c049fd6fd 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 #include <linux/mfd/max8998.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/regulator/fixed.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
@@ -379,6 +381,119 @@ static struct max8998_platform_data aquila_max8998_pdata = {
 };
 #endif
 
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+       {
+               .dev_name       = "5-001a",
+               .supply         = "DBVDD",
+       }, {
+               .dev_name       = "5-001a",
+               .supply         = "AVDD2",
+       }, {
+               .dev_name       = "5-001a",
+               .supply         = "CPVDD",
+       },
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+       {
+               .dev_name       = "5-001a",
+               .supply         = "SPKVDD1",
+       }, {
+               .dev_name       = "5-001a",
+               .supply         = "SPKVDD2",
+       },
+};
+
+static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
+       .constraints = {
+               .always_on = 1,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
+       .consumer_supplies      = wm8994_fixed_voltage0_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
+       .constraints = {
+               .always_on = 1,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
+       .consumer_supplies      = wm8994_fixed_voltage1_supplies,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
+       .supply_name    = "VCC_1.8V_PDA",
+       .microvolts     = 1800000,
+       .gpio           = -EINVAL,
+       .init_data      = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+       .supply_name    = "V_BAT",
+       .microvolts     = 3700000,
+       .gpio           = -EINVAL,
+       .init_data      = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+       .name           = "reg-fixed-voltage",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &wm8994_fixed_voltage0_config,
+       },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+       .name           = "reg-fixed-voltage",
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &wm8994_fixed_voltage1_config,
+       },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply = {
+       .dev_name       = "5-001a",
+       .supply         = "AVDD1",
+};
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply = {
+       .dev_name       = "5-001a",
+       .supply         = "DCVDD",
+};
+
+static struct regulator_init_data wm8994_ldo1_data = {
+       .constraints    = {
+               .name           = "AVDD1_3.0V",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+       .constraints    = {
+               .name           = "DCVDD_1.0V",
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+       /* configure gpio1 function: 0x0001(Logic level input/output) */
+       .gpio_defaults[0] = 0x0001,
+       /* configure gpio3/4/5/7 function for AIF2 voice */
+       .gpio_defaults[2] = 0x8100,
+       .gpio_defaults[3] = 0x8100,
+       .gpio_defaults[4] = 0x8100,
+       .gpio_defaults[6] = 0x0100,
+       /* configure gpio8/9/10/11 function for AIF3 BT */
+       .gpio_defaults[7] = 0x8100,
+       .gpio_defaults[8] = 0x0100,
+       .gpio_defaults[9] = 0x0100,
+       .gpio_defaults[10] = 0x0100,
+       .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
+       .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
 /* GPIO I2C PMIC */
 #define AP_I2C_GPIO_PMIC_BUS_4 4
 static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = {
@@ -404,6 +519,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
 #endif
 };
 
+/* GPIO I2C AP 1.8V */
+#define AP_I2C_GPIO_BUS_5      5
+static struct i2c_gpio_platform_data aquila_i2c_gpio5_data = {
+       .sda_pin        = S5PV210_MP05(3),      /* XM0ADDR_11 */
+       .scl_pin        = S5PV210_MP05(2),      /* XM0ADDR_10 */
+};
+
+static struct platform_device aquila_i2c_gpio5 = {
+       .name           = "i2c-gpio",
+       .id             = AP_I2C_GPIO_BUS_5,
+       .dev            = {
+               .platform_data  = &aquila_i2c_gpio5_data,
+       },
+};
+
+static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
+       {
+               /* CS/ADDR = low 0x34 (FYI: high = 0x36) */
+               I2C_BOARD_INFO("wm8994", 0x1a),
+               .platform_data  = &wm8994_platform_data,
+       },
+};
+
 /* PMIC Power button */
 static struct gpio_keys_button aquila_gpio_keys_table[] = {
        {
@@ -475,6 +613,7 @@ static void aquila_setup_sdhci(void)
 
 static struct platform_device *aquila_devices[] __initdata = {
        &aquila_i2c_gpio_pmic,
+       &aquila_i2c_gpio5,
        &aquila_device_gpiokeys,
        &s3c_device_fb,
        &s5p_device_onenand,
@@ -484,8 +623,33 @@ static struct platform_device *aquila_devices[] __initdata = {
        &s5p_device_fimc0,
        &s5p_device_fimc1,
        &s5p_device_fimc2,
+       &s5pv210_device_iis0,
+       &wm8994_fixed_voltage0,
+       &wm8994_fixed_voltage1,
 };
 
+static void __init aquila_sound_init(void)
+{
+       unsigned int gpio;
+
+       /* CODEC_XTAL_EN
+        *
+        * The Aquila board have a oscillator which provide main clock
+        * to WM8994 codec. The oscillator provide 24MHz clock to WM8994
+        * clock. Set gpio setting of "CODEC_XTAL_EN" to enable a oscillator.
+        * */
+       gpio = S5PV210_GPH3(2);         /* XEINT_26 */
+       gpio_request(gpio, "CODEC_XTAL_EN");
+       s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+       /* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
+        * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
+        * because it needs 24MHz clock to operate WM8994 codec.
+        */
+       __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
+}
+
 static void __init aquila_map_io(void)
 {
        s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -506,6 +670,11 @@ static void __init aquila_machine_init(void)
        s3c_fimc_setname(1, "s5p-fimc");
        s3c_fimc_setname(2, "s5p-fimc");
 
+       /* SOUND */
+       aquila_sound_init();
+       i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
+                       ARRAY_SIZE(i2c_gpio5_devs));
+
        /* FB */
        s3c_fb_set_platdata(&aquila_lcd_pdata);
 
index d9ecf57fc2a5698ce0ff4067b243b052a9661efc..b1dcf964a768773772659b7a01b9e3b6cb8de545 100644 (file)
 #include <linux/fb.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/i2c/qt602240_ts.h>
 #include <linux/mfd/max8998.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/regulator/fixed.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/lcd.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/fb.h>
+#include <plat/iic.h>
+#include <plat/keypad.h>
 #include <plat/sdhci.h>
+#include <plat/clock.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define GONI_UCON_DEFAULT      (S3C2410_UCON_TXILEVEL |        \
@@ -87,13 +96,12 @@ static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = {
 /* Frame Buffer */
 static struct s3c_fb_pd_win goni_fb_win0 = {
        .win_mode = {
-               .pixclock = 1000000000000ULL / ((16+16+2+480)*(28+3+2+800)*55),
                .left_margin    = 16,
                .right_margin   = 16,
-               .upper_margin   = 3,
+               .upper_margin   = 2,
                .lower_margin   = 28,
                .hsync_len      = 2,
-               .vsync_len      = 2,
+               .vsync_len      = 1,
                .xres           = 480,
                .yres           = 800,
                .refresh        = 55,
@@ -111,9 +119,160 @@ static struct s3c_fb_platdata goni_lcd_pdata __initdata = {
        .setup_gpio     = s5pv210_fb_gpio_setup_24bpp,
 };
 
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+       return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+       static unsigned int first = 1;
+       int reset_gpio = -1;
+
+       reset_gpio = S5PV210_MP05(5);
+
+       if (first) {
+               gpio_request(reset_gpio, "MLCD_RST");
+               first = 0;
+       }
+
+       gpio_direction_output(reset_gpio, 1);
+       return 1;
+}
+
+static struct lcd_platform_data goni_lcd_platform_data = {
+       .reset                  = reset_lcd,
+       .power_on               = lcd_power_on,
+       .lcd_enabled            = 0,
+       .reset_delay            = 120,  /* 120ms */
+       .power_on_delay         = 25,   /* 25ms */
+       .power_off_delay        = 200,  /* 200ms */
+};
+
+#define LCD_BUS_NUM    3
+static struct spi_board_info spi_board_info[] __initdata = {
+       {
+               .modalias       = "s6e63m0",
+               .platform_data  = &goni_lcd_platform_data,
+               .max_speed_hz   = 1200000,
+               .bus_num        = LCD_BUS_NUM,
+               .chip_select    = 0,
+               .mode           = SPI_MODE_3,
+               .controller_data = (void *)S5PV210_MP01(1), /* DISPLAY_CS */
+       },
+};
+
+static struct spi_gpio_platform_data lcd_spi_gpio_data = {
+       .sck    = S5PV210_MP04(1), /* DISPLAY_CLK */
+       .mosi   = S5PV210_MP04(3), /* DISPLAY_SI */
+       .miso   = SPI_GPIO_NO_MISO,
+       .num_chipselect = 1,
+};
+
+static struct platform_device goni_spi_gpio = {
+       .name   = "spi_gpio",
+       .id     = LCD_BUS_NUM,
+       .dev    = {
+               .parent         = &s3c_device_fb.dev,
+               .platform_data  = &lcd_spi_gpio_data,
+       },
+};
+
+/* KEYPAD */
+static uint32_t keymap[] __initdata = {
+       /* KEY(row, col, keycode) */
+       KEY(0, 1, KEY_MENU),            /* Send */
+       KEY(0, 2, KEY_BACK),            /* End */
+       KEY(1, 1, KEY_CONFIG),          /* Half shot */
+       KEY(1, 2, KEY_VOLUMEUP),
+       KEY(2, 1, KEY_CAMERA),          /* Full shot */
+       KEY(2, 2, KEY_VOLUMEDOWN),
+};
+
+static struct matrix_keymap_data keymap_data __initdata = {
+       .keymap         = keymap,
+       .keymap_size    = ARRAY_SIZE(keymap),
+};
+
+static struct samsung_keypad_platdata keypad_data __initdata = {
+       .keymap_data    = &keymap_data,
+       .rows           = 3,
+       .cols           = 3,
+};
+
+/* Radio */
+static struct i2c_board_info i2c1_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("si470x", 0x10),
+       },
+};
+
+static void __init goni_radio_init(void)
+{
+       int gpio;
+
+       gpio = S5PV210_GPJ2(4);                 /* XMSMDATA_4 */
+       gpio_request(gpio, "FM_INT");
+       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+       i2c1_devs[0].irq = gpio_to_irq(gpio);
+
+       gpio = S5PV210_GPJ2(5);                 /* XMSMDATA_5 */
+       gpio_request(gpio, "FM_RST");
+       gpio_direction_output(gpio, 1);
+}
+
+/* TSP */
+static struct qt602240_platform_data qt602240_platform_data = {
+       .x_line         = 17,
+       .y_line         = 11,
+       .x_size         = 800,
+       .y_size         = 480,
+       .blen           = 0x21,
+       .threshold      = 0x28,
+       .voltage        = 2800000,              /* 2.8V */
+       .orient         = QT602240_DIAGONAL,
+};
+
+static struct s3c2410_platform_i2c i2c2_data __initdata = {
+       .flags          = 0,
+       .bus_num        = 2,
+       .slave_addr     = 0x10,
+       .frequency      = 400 * 1000,
+       .sda_delay      = 100,
+};
+
+static struct i2c_board_info i2c2_devs[] __initdata = {
+       {
+               I2C_BOARD_INFO("qt602240_ts", 0x4a),
+               .platform_data = &qt602240_platform_data,
+       },
+};
+
+static void __init goni_tsp_init(void)
+{
+       int gpio;
+
+       gpio = S5PV210_GPJ1(3);         /* XMSMADDR_11 */
+       gpio_request(gpio, "TSP_LDO_ON");
+       gpio_direction_output(gpio, 1);
+       gpio_export(gpio, 0);
+
+       gpio = S5PV210_GPJ0(5);         /* XMSMADDR_5 */
+       gpio_request(gpio, "TSP_INT");
+
+       s5p_register_gpio_interrupt(gpio);
+       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+       i2c2_devs[0].irq = gpio_to_irq(gpio);
+}
+
 /* MAX8998 regulators */
 #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
 
+static struct regulator_consumer_supply goni_ldo5_consumers[] = {
+       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+};
+
 static struct regulator_init_data goni_ldo2_data = {
        .constraints    = {
                .name           = "VALIVE_1.1V",
@@ -153,6 +312,8 @@ static struct regulator_init_data goni_ldo5_data = {
                .max_uV         = 2800000,
                .apply_uV       = 1,
        },
+       .num_consumer_supplies = ARRAY_SIZE(goni_ldo5_consumers),
+       .consumer_supplies = goni_ldo5_consumers,
 };
 
 static struct regulator_init_data goni_ldo6_data = {
@@ -360,6 +521,119 @@ static struct max8998_platform_data goni_max8998_pdata = {
 };
 #endif
 
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+       {
+               .dev_name       = "5-001a",
+               .supply         = "DBVDD",
+       }, {
+               .dev_name       = "5-001a",
+               .supply         = "AVDD2",
+       }, {
+               .dev_name       = "5-001a",
+               .supply         = "CPVDD",
+       },
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+       {
+               .dev_name       = "5-001a",
+               .supply         = "SPKVDD1",
+       }, {
+               .dev_name       = "5-001a",
+               .supply         = "SPKVDD2",
+       },
+};
+
+static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
+       .constraints = {
+               .always_on = 1,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
+       .consumer_supplies      = wm8994_fixed_voltage0_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
+       .constraints = {
+               .always_on = 1,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
+       .consumer_supplies      = wm8994_fixed_voltage1_supplies,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
+       .supply_name    = "VCC_1.8V_PDA",
+       .microvolts     = 1800000,
+       .gpio           = -EINVAL,
+       .init_data      = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+       .supply_name    = "V_BAT",
+       .microvolts     = 3700000,
+       .gpio           = -EINVAL,
+       .init_data      = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+       .name           = "reg-fixed-voltage",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &wm8994_fixed_voltage0_config,
+       },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+       .name           = "reg-fixed-voltage",
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &wm8994_fixed_voltage1_config,
+       },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply = {
+       .dev_name       = "5-001a",
+       .supply         = "AVDD1",
+};
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply = {
+       .dev_name       = "5-001a",
+       .supply         = "DCVDD",
+};
+
+static struct regulator_init_data wm8994_ldo1_data = {
+       .constraints    = {
+               .name           = "AVDD1_3.0V",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+       .constraints    = {
+               .name           = "DCVDD_1.0V",
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+       /* configure gpio1 function: 0x0001(Logic level input/output) */
+       .gpio_defaults[0] = 0x0001,
+       /* configure gpio3/4/5/7 function for AIF2 voice */
+       .gpio_defaults[2] = 0x8100,
+       .gpio_defaults[3] = 0x8100,
+       .gpio_defaults[4] = 0x8100,
+       .gpio_defaults[6] = 0x0100,
+       /* configure gpio8/9/10/11 function for AIF3 BT */
+       .gpio_defaults[7] = 0x8100,
+       .gpio_defaults[8] = 0x0100,
+       .gpio_defaults[9] = 0x0100,
+       .gpio_defaults[10] = 0x0100,
+       .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
+       .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
 /* GPIO I2C PMIC */
 #define AP_I2C_GPIO_PMIC_BUS_4 4
 static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = {
@@ -385,6 +659,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
 #endif
 };
 
+/* GPIO I2C AP 1.8V */
+#define AP_I2C_GPIO_BUS_5      5
+static struct i2c_gpio_platform_data goni_i2c_gpio5_data = {
+       .sda_pin        = S5PV210_MP05(3),      /* XM0ADDR_11 */
+       .scl_pin        = S5PV210_MP05(2),      /* XM0ADDR_10 */
+};
+
+static struct platform_device goni_i2c_gpio5 = {
+       .name           = "i2c-gpio",
+       .id             = AP_I2C_GPIO_BUS_5,
+       .dev            = {
+               .platform_data  = &goni_i2c_gpio5_data,
+       },
+};
+
+static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
+       {
+               /* CS/ADDR = low 0x34 (FYI: high = 0x36) */
+               I2C_BOARD_INFO("wm8994", 0x1a),
+               .platform_data  = &wm8994_platform_data,
+       },
+};
+
 /* PMIC Power button */
 static struct gpio_keys_button goni_gpio_keys_table[] = {
        {
@@ -444,11 +741,37 @@ static struct s3c_sdhci_platdata goni_hsmmc2_data __initdata = {
        .ext_cd_gpio_invert     = 1,
 };
 
+static struct regulator_consumer_supply mmc2_supplies[] = {
+       REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"),
+};
+
+static struct regulator_init_data mmc2_fixed_voltage_init_data = {
+       .constraints            = {
+               .name           = "V_TF_2.8V",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(mmc2_supplies),
+       .consumer_supplies      = mmc2_supplies,
+};
+
+static struct fixed_voltage_config mmc2_fixed_voltage_config = {
+       .supply_name            = "EXT_FLASH_EN",
+       .microvolts             = 2800000,
+       .gpio                   = GONI_EXT_FLASH_EN,
+       .enable_high            = true,
+       .init_data              = &mmc2_fixed_voltage_init_data,
+};
+
+static struct platform_device mmc2_fixed_voltage = {
+       .name           = "reg-fixed-voltage",
+       .id             = 2,
+       .dev            = {
+               .platform_data  = &mmc2_fixed_voltage_config,
+       },
+};
+
 static void goni_setup_sdhci(void)
 {
-       gpio_request(GONI_EXT_FLASH_EN, "FLASH_EN");
-       gpio_direction_output(GONI_EXT_FLASH_EN, 1);
-
        s3c_sdhci0_set_platdata(&goni_hsmmc0_data);
        s3c_sdhci1_set_platdata(&goni_hsmmc1_data);
        s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
@@ -457,7 +780,10 @@ static void goni_setup_sdhci(void)
 static struct platform_device *goni_devices[] __initdata = {
        &s3c_device_fb,
        &s5p_device_onenand,
+       &goni_spi_gpio,
        &goni_i2c_gpio_pmic,
+       &goni_i2c_gpio5,
+       &mmc2_fixed_voltage,
        &goni_device_gpiokeys,
        &s5p_device_fimc0,
        &s5p_device_fimc1,
@@ -465,8 +791,24 @@ static struct platform_device *goni_devices[] __initdata = {
        &s3c_device_hsmmc0,
        &s3c_device_hsmmc1,
        &s3c_device_hsmmc2,
+       &s5pv210_device_iis0,
+       &s3c_device_usb_hsotg,
+       &samsung_device_keypad,
+       &s3c_device_i2c1,
+       &s3c_device_i2c2,
+       &wm8994_fixed_voltage0,
+       &wm8994_fixed_voltage1,
 };
 
+static void __init goni_sound_init(void)
+{
+       /* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
+        * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
+        * because it needs 24MHz clock to operate WM8994 codec.
+        */
+       __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
+}
+
 static void __init goni_map_io(void)
 {
        s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -476,6 +818,20 @@ static void __init goni_map_io(void)
 
 static void __init goni_machine_init(void)
 {
+       /* Radio: call before I2C 1 registeration */
+       goni_radio_init();
+
+       /* I2C1 */
+       s3c_i2c1_set_platdata(NULL);
+       i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+
+       /* TSP: call before I2C 2 registeration */
+       goni_tsp_init();
+
+       /* I2C2 */
+       s3c_i2c2_set_platdata(&i2c2_data);
+       i2c_register_board_info(2, i2c2_devs, ARRAY_SIZE(i2c2_devs));
+
        /* PMIC */
        goni_pmic_init();
        i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
@@ -483,9 +839,22 @@ static void __init goni_machine_init(void)
        /* SDHCI */
        goni_setup_sdhci();
 
+       /* SOUND */
+       goni_sound_init();
+       i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
+                       ARRAY_SIZE(i2c_gpio5_devs));
+
        /* FB */
        s3c_fb_set_platdata(&goni_lcd_pdata);
 
+       /* SPI */
+       spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+       /* KEYPAD */
+       samsung_keypad_set_platdata(&keypad_data);
+
+       clk_xusbxti.rate = 24000000;
+
        platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
 }
 
index cea9bca79d880c20bc0cb46df7dd8b77883976d8..0ad7924fe62e8faa12c54f5aafc07c2aa81474dc 100644 (file)
@@ -28,6 +28,7 @@
 #include <plat/cpu.h>
 #include <plat/ata.h>
 #include <plat/iic.h>
+#include <plat/pm.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKC110_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
@@ -81,6 +82,7 @@ static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = {
 static struct platform_device *smdkc110_devices[] __initdata = {
        &s5pv210_device_iis0,
        &s5pv210_device_ac97,
+       &s5pv210_device_spdif,
        &s3c_device_cfcon,
        &s3c_device_i2c0,
        &s3c_device_i2c1,
@@ -110,6 +112,8 @@ static void __init smdkc110_map_io(void)
 
 static void __init smdkc110_machine_init(void)
 {
+       s3c_pm_init();
+
        s3c_i2c0_set_platdata(NULL);
        s3c_i2c1_set_platdata(NULL);
        s3c_i2c2_set_platdata(NULL);
index 83189ae9da9ad9dad00f16f6fc9ca459aaa89808..bcd7a5d53401ae37d751cc59418f6aa74f2eab42 100644 (file)
@@ -31,6 +31,7 @@
 #include <plat/ata.h>
 #include <plat/iic.h>
 #include <plat/keypad.h>
+#include <plat/pm.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKV210_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
@@ -103,6 +104,7 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
 static struct platform_device *smdkv210_devices[] __initdata = {
        &s5pv210_device_iis0,
        &s5pv210_device_ac97,
+       &s5pv210_device_spdif,
        &s3c_device_adc,
        &s3c_device_cfcon,
        &s3c_device_hsmmc0,
@@ -145,6 +147,8 @@ static void __init smdkv210_map_io(void)
 
 static void __init smdkv210_machine_init(void)
 {
+       s3c_pm_init();
+
        samsung_keypad_set_platdata(&smdkv210_keypad_data);
        s3c24xx_ts_set_platdata(&s3c_ts_platform);
 
diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c
new file mode 100644 (file)
index 0000000..043c938
--- /dev/null
@@ -0,0 +1,131 @@
+/* linux/arch/arm/mach-s5pv210/mach-torbreck.c
+ *
+ * Copyright (c) 2010 aESOP Community
+ *             http://www.aesop.or.kr/
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define TORBRECK_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
+                                S3C2410_UCON_RXILEVEL |        \
+                                S3C2410_UCON_TXIRQMODE |       \
+                                S3C2410_UCON_RXIRQMODE |       \
+                                S3C2410_UCON_RXFIFO_TOI |      \
+                                S3C2443_UCON_RXERR_IRQEN)
+
+#define TORBRECK_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define TORBRECK_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE |       \
+                                S5PV210_UFCON_TXTRIG4 |        \
+                                S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg torbreck_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = TORBRECK_UCON_DEFAULT,
+               .ulcon          = TORBRECK_ULCON_DEFAULT,
+               .ufcon          = TORBRECK_UFCON_DEFAULT,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = TORBRECK_UCON_DEFAULT,
+               .ulcon          = TORBRECK_ULCON_DEFAULT,
+               .ufcon          = TORBRECK_UFCON_DEFAULT,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = TORBRECK_UCON_DEFAULT,
+               .ulcon          = TORBRECK_ULCON_DEFAULT,
+               .ufcon          = TORBRECK_UFCON_DEFAULT,
+       },
+       [3] = {
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = TORBRECK_UCON_DEFAULT,
+               .ulcon          = TORBRECK_ULCON_DEFAULT,
+               .ufcon          = TORBRECK_UFCON_DEFAULT,
+       },
+};
+
+static struct platform_device *torbreck_devices[] __initdata = {
+       &s5pv210_device_iis0,
+       &s3c_device_cfcon,
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc1,
+       &s3c_device_hsmmc2,
+       &s3c_device_hsmmc3,
+       &s3c_device_i2c0,
+       &s3c_device_i2c1,
+       &s3c_device_i2c2,
+       &s3c_device_rtc,
+       &s3c_device_wdt,
+};
+
+static struct i2c_board_info torbreck_i2c_devs0[] __initdata = {
+       /* To Be Updated */
+};
+
+static struct i2c_board_info torbreck_i2c_devs1[] __initdata = {
+       /* To Be Updated */
+};
+
+static struct i2c_board_info torbreck_i2c_devs2[] __initdata = {
+       /* To Be Updated */
+};
+
+static void __init torbreck_map_io(void)
+{
+       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+       s3c24xx_init_clocks(24000000);
+       s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
+}
+
+static void __init torbreck_machine_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       s3c_i2c1_set_platdata(NULL);
+       s3c_i2c2_set_platdata(NULL);
+       i2c_register_board_info(0, torbreck_i2c_devs0,
+                       ARRAY_SIZE(torbreck_i2c_devs0));
+       i2c_register_board_info(1, torbreck_i2c_devs1,
+                       ARRAY_SIZE(torbreck_i2c_devs1));
+       i2c_register_board_info(2, torbreck_i2c_devs2,
+                       ARRAY_SIZE(torbreck_i2c_devs2));
+
+       platform_add_devices(torbreck_devices, ARRAY_SIZE(torbreck_devices));
+}
+
+MACHINE_START(TORBRECK, "TORBRECK")
+       /* Maintainer: Hyunchul Ko <ghcstop@gmail.com> */
+       .boot_params    = S5P_PA_SDRAM + 0x100,
+       .init_irq       = s5pv210_init_irq,
+       .map_io         = torbreck_map_io,
+       .init_machine   = torbreck_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
new file mode 100644 (file)
index 0000000..549d792
--- /dev/null
@@ -0,0 +1,166 @@
+/* linux/arch/arm/mach-s5pv210/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5PV210 - Power Management support
+ *
+ * Based on arch/arm/mach-s3c2410/pm.c
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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 <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/regs-timer.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-clock.h>
+
+static struct sleep_save s5pv210_core_save[] = {
+       /* Clock source */
+       SAVE_ITEM(S5P_CLK_SRC0),
+       SAVE_ITEM(S5P_CLK_SRC1),
+       SAVE_ITEM(S5P_CLK_SRC2),
+       SAVE_ITEM(S5P_CLK_SRC3),
+       SAVE_ITEM(S5P_CLK_SRC4),
+       SAVE_ITEM(S5P_CLK_SRC5),
+       SAVE_ITEM(S5P_CLK_SRC6),
+
+       /* Clock source Mask */
+       SAVE_ITEM(S5P_CLK_SRC_MASK0),
+       SAVE_ITEM(S5P_CLK_SRC_MASK1),
+
+       /* Clock Divider */
+       SAVE_ITEM(S5P_CLK_DIV0),
+       SAVE_ITEM(S5P_CLK_DIV1),
+       SAVE_ITEM(S5P_CLK_DIV2),
+       SAVE_ITEM(S5P_CLK_DIV3),
+       SAVE_ITEM(S5P_CLK_DIV4),
+       SAVE_ITEM(S5P_CLK_DIV5),
+       SAVE_ITEM(S5P_CLK_DIV6),
+       SAVE_ITEM(S5P_CLK_DIV7),
+
+       /* Clock Main Gate */
+       SAVE_ITEM(S5P_CLKGATE_MAIN0),
+       SAVE_ITEM(S5P_CLKGATE_MAIN1),
+       SAVE_ITEM(S5P_CLKGATE_MAIN2),
+
+       /* Clock source Peri Gate */
+       SAVE_ITEM(S5P_CLKGATE_PERI0),
+       SAVE_ITEM(S5P_CLKGATE_PERI1),
+
+       /* Clock source SCLK Gate */
+       SAVE_ITEM(S5P_CLKGATE_SCLK0),
+       SAVE_ITEM(S5P_CLKGATE_SCLK1),
+
+       /* Clock IP Clock gate */
+       SAVE_ITEM(S5P_CLKGATE_IP0),
+       SAVE_ITEM(S5P_CLKGATE_IP1),
+       SAVE_ITEM(S5P_CLKGATE_IP2),
+       SAVE_ITEM(S5P_CLKGATE_IP3),
+       SAVE_ITEM(S5P_CLKGATE_IP4),
+
+       /* Clock Blcok and Bus gate */
+       SAVE_ITEM(S5P_CLKGATE_BLOCK),
+       SAVE_ITEM(S5P_CLKGATE_BUS0),
+
+       /* Clock ETC */
+       SAVE_ITEM(S5P_CLK_OUT),
+       SAVE_ITEM(S5P_MDNIE_SEL),
+
+       /* PWM Register */
+       SAVE_ITEM(S3C2410_TCFG0),
+       SAVE_ITEM(S3C2410_TCFG1),
+       SAVE_ITEM(S3C64XX_TINT_CSTAT),
+       SAVE_ITEM(S3C2410_TCON),
+       SAVE_ITEM(S3C2410_TCNTB(0)),
+       SAVE_ITEM(S3C2410_TCMPB(0)),
+       SAVE_ITEM(S3C2410_TCNTO(0)),
+};
+
+void s5pv210_cpu_suspend(void)
+{
+       unsigned long tmp;
+
+       /* issue the standby signal into the pm unit. Note, we
+        * issue a write-buffer drain just in case */
+
+       tmp = 0;
+
+       asm("b 1f\n\t"
+           ".align 5\n\t"
+           "1:\n\t"
+           "mcr p15, 0, %0, c7, c10, 5\n\t"
+           "mcr p15, 0, %0, c7, c10, 4\n\t"
+           "wfi" : : "r" (tmp));
+
+       /* we should never get past here */
+       panic("sleep resumed to originator?");
+}
+
+static void s5pv210_pm_prepare(void)
+{
+       unsigned int tmp;
+
+       /* ensure at least INFORM0 has the resume address */
+       __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
+
+       tmp = __raw_readl(S5P_SLEEP_CFG);
+       tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN);
+       __raw_writel(tmp, S5P_SLEEP_CFG);
+
+       /* WFI for SLEEP mode configuration by SYSCON */
+       tmp = __raw_readl(S5P_PWR_CFG);
+       tmp &= S5P_CFG_WFI_CLEAN;
+       tmp |= S5P_CFG_WFI_SLEEP;
+       __raw_writel(tmp, S5P_PWR_CFG);
+
+       /* SYSCON interrupt handling disable */
+       tmp = __raw_readl(S5P_OTHERS);
+       tmp |= S5P_OTHER_SYSC_INTOFF;
+       __raw_writel(tmp, S5P_OTHERS);
+
+       s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
+}
+
+static int s5pv210_pm_add(struct sys_device *sysdev)
+{
+       pm_cpu_prep = s5pv210_pm_prepare;
+       pm_cpu_sleep = s5pv210_cpu_suspend;
+
+       return 0;
+}
+
+static int s5pv210_pm_resume(struct sys_device *dev)
+{
+       u32 tmp;
+
+       tmp = __raw_readl(S5P_OTHERS);
+       tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF |\
+               S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART);
+       __raw_writel(tmp , S5P_OTHERS);
+
+       s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
+
+       return 0;
+}
+
+static struct sysdev_driver s5pv210_pm_driver = {
+       .add            = s5pv210_pm_add,
+       .resume         = s5pv210_pm_resume,
+};
+
+static __init int s5pv210_pm_drvinit(void)
+{
+       return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
+}
+arch_initcall(s5pv210_pm_drvinit);
index 928cf1f125fa6e9e19a9df4dce6424ac92578329..e932ebfac56df3159608cf61cf32042be2ee58d9 100644 (file)
 #include <mach/regs-clock.h>
 #include <plat/gpio-cfg.h>
 
-void s5pv210_fb_gpio_setup_24bpp(void)
+static void s5pv210_fb_cfg_gpios(unsigned int base, unsigned int nr)
 {
-       unsigned int gpio = 0;
-
-       for (gpio = S5PV210_GPF0(0); gpio <= S5PV210_GPF0(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
+       s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
 
-       for (gpio = S5PV210_GPF1(0); gpio <= S5PV210_GPF1(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
+       for (; nr > 0; nr--, base++)
+               s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
+}
 
-       for (gpio = S5PV210_GPF2(0); gpio <= S5PV210_GPF2(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
 
-       for (gpio = S5PV210_GPF3(0); gpio <= S5PV210_GPF3(3); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
+void s5pv210_fb_gpio_setup_24bpp(void)
+{
+       s5pv210_fb_cfg_gpios(S5PV210_GPF0(0), 8);
+       s5pv210_fb_cfg_gpios(S5PV210_GPF1(0), 8);
+       s5pv210_fb_cfg_gpios(S5PV210_GPF2(0), 8);
+       s5pv210_fb_cfg_gpios(S5PV210_GPF3(0), 4);
 
        /* Set DISPLAY_CONTROL register for Display path selection.
         *
index d38f7cb7e662223f14f85ca4809ef3b57f8e26b1..0f1cc3a1c1e8abf620b76a157e4f9bdbb048a17f 100644 (file)
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5PV210_GPD1(0), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
index 148bb7857d896279def1965103a1d26c2390c9dd..f61365a34c56c81d1478b0d4a177ba7d412ab0fc 100644 (file)
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
 
 void s3c_i2c1_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV210_GPD1(2), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PV210_GPD1(3), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV210_GPD1(3), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5PV210_GPD1(2), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
index 2396cb8c373e9c1aae67ad68ab90d6b408d4a248..2f91b5cefbc6af06bbc9b569b651bba5e940afdf 100644 (file)
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
 
 void s3c_i2c2_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5PV210_GPD1(4), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
index b558b1cc8d6010d233fca44edc53bda6a8de7ea6..ea123d546bd2ccb0604e809cfc2c0cd8a7c4f44a 100644 (file)
 
 #include <plat/gpio-cfg.h>
 
+static void s5pv210_ide_cfg_gpios(unsigned int base, unsigned int nr)
+{
+       s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
+
+       for (; nr > 0; nr--, base++)
+               s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
+}
+
 void s5pv210_ide_setup_gpio(void)
 {
-       unsigned int gpio = 0;
-
-       for (gpio = S5PV210_GPJ0(0); gpio <= S5PV210_GPJ0(7); gpio++) {
-               /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST,
-                       CF_DMACK */
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-
-       for (gpio = S5PV210_GPJ2(0); gpio <= S5PV210_GPJ2(7); gpio++) {
-               /*CF_Data[0 - 7] */
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-
-       for (gpio = S5PV210_GPJ3(0); gpio <= S5PV210_GPJ3(7); gpio++) {
-               /* CF_Data[8 - 15] */
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
-
-       for (gpio = S5PV210_GPJ4(0); gpio <= S5PV210_GPJ4(3); gpio++) {
-               /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-       }
+       /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
+       s5pv210_ide_cfg_gpios(S5PV210_GPJ0(0), 8);
+
+       /* CF_Data[0 - 7] */
+       s5pv210_ide_cfg_gpios(S5PV210_GPJ2(0), 8);
+
+       /* CF_Data[8 - 15] */
+       s5pv210_ide_cfg_gpios(S5PV210_GPJ3(0), 8);
+
+       /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
+       s5pv210_ide_cfg_gpios(S5PV210_GPJ4(0), 4);
 }
index 37b2790aafc30fa566c1a4789021b45df01620dc..c56420a52f48f2e96cb9d0eb212a86b3179b0004 100644 (file)
 
 void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
 {
-       unsigned int gpio, end;
-
        /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
-       end = S5PV210_GPH3(rows);
-       for (gpio = S5PV210_GPH3(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PV210_GPH3(0), rows, S3C_GPIO_SFN(3));
 
        /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
-       end = S5PV210_GPH2(cols);
-       for (gpio = S5PV210_GPH2(0); gpio < end; gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PV210_GPH2(0), cols, S3C_GPIO_SFN(3));
 }
index b18587b1ec5894b0800d7106dd6b11fc3ce3e675..746777d56df95ab51e817227cf3c97ce4db34b62 100644 (file)
 void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
 {
        struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
 
        /* Set all the necessary GPG0/GPG1 pins to special-function 2 */
-       for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PV210_GPG0(0), 2, S3C_GPIO_SFN(2));
+
        switch (width) {
        case 8:
                /* GPG1[3:6] special-funtion 3 */
-               for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
-                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               }
+               s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3));
        case 4:
                /* GPG0[3:6] special-funtion 2 */
-               for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) {
-                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               }
+               s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2));
        default:
                break;
        }
@@ -59,19 +50,12 @@ void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
 void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
 {
        struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
 
        /* Set all the necessary GPG1[0:1] pins to special-function 2 */
-       for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PV210_GPG1(0), 2, S3C_GPIO_SFN(2));
 
        /* Data pin GPG1[3:6] to special-function 2 */
-       for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(2));
 
        if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
                s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
@@ -82,27 +66,17 @@ void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
 void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
 {
        struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
 
        /* Set all the necessary GPG2[0:1] pins to special-function 2 */
-       for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PV210_GPG2(0), 2, S3C_GPIO_SFN(2));
 
        switch (width) {
        case 8:
                /* Data pin GPG3[3:6] to special-function 3 */
-               for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
-                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               }
+               s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(3));
        case 4:
                /* Data pin GPG2[3:6] to special-function 2 */
-               for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) {
-                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-               }
+               s3c_gpio_cfgrange_nopull(S5PV210_GPG2(3), 4, S3C_GPIO_SFN(2));
        default:
                break;
        }
@@ -116,19 +90,12 @@ void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
 void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
 {
        struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-       unsigned int gpio;
 
-       /* Set all the necessary GPG3[0:2] pins to special-function 2 */
-       for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       /* Set all the necessary GPG3[0:1] pins to special-function 2 */
+       s3c_gpio_cfgrange_nopull(S5PV210_GPG3(0), 2, S3C_GPIO_SFN(2));
 
        /* Data pin GPG3[3:6] to special-function 2 */
-       for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
+       s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(2));
 
        if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
                s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
new file mode 100644 (file)
index 0000000..d4d222b
--- /dev/null
@@ -0,0 +1,170 @@
+/* linux/arch/arm/plat-s5p/sleep.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5PV210 power Manager (Suspend-To-RAM) support
+ * Based on S3C2410 sleep code by:
+ *     Ben Dooks, (c) 2004 Simtec Electronics
+ *
+ * Based on PXA/SA1100 sleep code by:
+ *     Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ *     Cliff Brake, (c) 2001
+ *
+ * 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 <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+       .text
+
+       /* s3c_cpu_save
+        *
+        * entry:
+        *      r0 = save address (virtual addr of s3c_sleep_save_phys)
+       */
+
+ENTRY(s3c_cpu_save)
+
+       stmfd   sp!, { r3 - r12, lr }
+
+       mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
+       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
+       mrc     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
+       mrc     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
+       mrc     p15, 0, r8, c2, c0, 2   @ Translation Table Control
+       mrc     p15, 0, r9, c1, c0, 0   @ Control register
+       mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
+       mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
+       mrc     p15, 0, r12, c10, c2, 0 @ Read PRRR
+       mrc     p15, 0, r3, c10, c2, 1  @ READ NMRR
+
+       stmia   r0, { r3 - r13 }
+
+       bl      s3c_pm_cb_flushcache
+
+       ldr     r0, =pm_cpu_sleep
+       ldr     r0, [ r0 ]
+       mov     pc, r0
+
+resume_with_mmu:
+       /*
+        * After MMU is turned on, restore the previous MMU table.
+        */
+       ldr     r9 , =(PAGE_OFFSET - PHYS_OFFSET)
+       add     r4, r4, r9
+       str     r12, [r4]
+
+       ldmfd   sp!, { r3 - r12, pc }
+
+       .ltorg
+
+       .data
+
+       .global s3c_sleep_save_phys
+s3c_sleep_save_phys:
+       .word   0
+
+       /* sleep magic, to allow the bootloader to check for an valid
+        * image to resume to. Must be the first word before the
+        * s3c_cpu_resume entry.
+       */
+
+       .word   0x2bedf00d
+
+       /* s3c_cpu_resume
+        *
+        * resume code entry for bootloader to call
+        *
+        * we must put this code here in the data segment as we have no
+        * other way of restoring the stack pointer after sleep, and we
+        * must not write to the code segment (code is read-only)
+       */
+
+ENTRY(s3c_cpu_resume)
+       mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+       msr     cpsr_c, r0
+
+       mov     r1, #0
+       mcr     p15, 0, r1, c8, c7, 0           @ invalidate TLBs
+       mcr     p15, 0, r1, c7, c5, 0           @ invalidate I Cache
+
+       ldr     r0, s3c_sleep_save_phys         @ address of restore block
+       ldmia   r0, { r3 - r13 }
+
+       mcr     p15, 0, r4, c13, c0, 0          @ FCSE/PID
+       mcr     p15, 0, r5, c3, c0, 0           @ Domain ID
+
+       mcr     p15, 0, r8, c2, c0, 2           @ Translation Table Control
+       mcr     p15, 0, r7, c2, c0, 1           @ Translation Table BASE1
+       mcr     p15, 0, r6, c2, c0, 0           @ Translation Table BASE0
+
+       mcr     p15, 0, r10, c1, c0, 1          @ Auxiliary control register
+
+       mov     r0, #0
+       mcr     p15, 0, r0, c8, c7, 0           @ Invalidate I & D TLB
+
+       mov     r0, #0                          @ restore copro access
+       mcr     p15, 0, r11, c1, c0, 2          @ Co-processor access
+       mcr     p15, 0, r0, c7, c5, 4
+
+       mcr     p15, 0, r12, c10, c2, 0         @ write PRRR
+       mcr     p15, 0, r3, c10, c2, 1          @ write NMRR
+
+       /*
+        * In Cortex-A8, when MMU is turned on, the pipeline is flushed.
+        * And there are no valid entries in the MMU table at this point.
+        * So before turning on the MMU, the MMU entry for the DRAM address
+        * range is added. After the MMU is turned on, the other entries
+        * in the MMU table will be restored.
+       */
+
+       /* r6 = Translation Table BASE0 */
+       mov     r4, r6
+       mov     r4, r4, LSR #14
+       mov     r4, r4, LSL #14
+
+       /* Load address for adding to MMU table list */
+       ldr     r11, =0xE010F000                @ INFORM0 reg.
+       ldr     r10, [r11, #0]
+       mov     r10, r10, LSR #18
+       bic     r10, r10, #0x3
+       orr     r4, r4, r10
+
+       /* Calculate MMU table entry */
+       mov     r10, r10, LSL #18
+       ldr     r5, =0x40E
+       orr     r10, r10, r5
+
+       /* Back up originally data */
+       ldr     r12, [r4]
+
+       /* Add calculated MMU table entry into MMU table list */
+       str     r10, [r4]
+
+       ldr     r2, =resume_with_mmu
+       mcr     p15, 0, r9, c1, c0, 0           @ turn on MMU, etc
+
+       nop
+       nop
+       nop
+       nop
+       nop                                     @ second-to-last before mmu
+
+       mov     pc, r2                          @ go back to virtual address
+
+       .ltorg
index 331b5bd97aba5d57befdf2ae8066a4cb675c96ea..1150b360f38cfc2c06cfca522d101f26e3d1d5e8 100644 (file)
@@ -11,7 +11,6 @@ if ARCH_S5PV310
 
 config CPU_S5PV310
        bool
-       select PLAT_S5P
        help
          Enable S5PV310 CPU support
 
@@ -25,21 +24,105 @@ config S5PV310_SETUP_I2C2
        help
          Common setup code for i2c bus 2.
 
+config S5PV310_SETUP_I2C3
+       bool
+       help
+         Common setup code for i2c bus 3.
+
+config S5PV310_SETUP_I2C4
+       bool
+       help
+         Common setup code for i2c bus 4.
+
+config S5PV310_SETUP_I2C5
+       bool
+       help
+         Common setup code for i2c bus 5.
+
+config S5PV310_SETUP_I2C6
+       bool
+       help
+         Common setup code for i2c bus 6.
+
+config S5PV310_SETUP_I2C7
+       bool
+       help
+         Common setup code for i2c bus 7.
+
+config S5PV310_SETUP_SDHCI
+       bool
+       select S5PV310_SETUP_SDHCI_GPIO
+       help
+         Internal helper functions for S5PV310 based SDHCI systems.
+
+config S5PV310_SETUP_SDHCI_GPIO
+       bool
+       help
+         Common setup code for SDHCI gpio.
+
 # machine support
 
-config MACH_SMDKV310
-       bool "SMDKV310"
+menu "S5PC210 Machines"
+
+config MACH_SMDKC210
+       bool "SMDKC210"
        select CPU_S5PV310
-       select ARCH_SPARSEMEM_ENABLE
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC1
+       select S3C_DEV_HSMMC2
+       select S3C_DEV_HSMMC3
+       select S5PV310_SETUP_SDHCI
        help
-         Machine support for Samsung SMDKV310
+         Machine support for Samsung SMDKC210
+         S5PC210(MCP) is one of package option of S5PV310
 
 config MACH_UNIVERSAL_C210
        bool "Mobile UNIVERSAL_C210 Board"
        select CPU_S5PV310
-       select ARCH_SPARSEMEM_ENABLE
+       select S5P_DEV_ONENAND
+       select S3C_DEV_I2C1
+       select S5PV310_SETUP_I2C1
        help
          Machine support for Samsung Mobile Universal S5PC210 Reference
          Board. S5PC210(MCP) is one of package option of S5PV310
 
+endmenu
+
+menu "S5PV310 Machines"
+
+config MACH_SMDKV310
+       bool "SMDKV310"
+       select CPU_S5PV310
+       select S3C_DEV_RTC
+       select S3C_DEV_WDT
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC1
+       select S3C_DEV_HSMMC2
+       select S3C_DEV_HSMMC3
+       select S5PV310_SETUP_SDHCI
+       help
+         Machine support for Samsung SMDKV310
+
+endmenu
+
+comment "Configuration for HSMMC bus width"
+
+menu "Use 8-bit bus width"
+
+config S5PV310_SDHCI_CH0_8BIT
+       bool "Channel 0 with 8-bit bus"
+       help
+         Support HSMMC Channel 0 8-bit bus.
+         If selected, Channel 1 is disabled.
+
+config S5PV310_SDHCI_CH2_8BIT
+       bool "Channel 2 with 8-bit bus"
+       help
+         Support HSMMC Channel 2 8-bit bus.
+         If selected, Channel 3 is disabled.
+
+endmenu
+
 endif
index d5b51c72340fc04bdf8356af6a65a58597b6971e..84afc64e7c01a5007f58e9163f86c1366460625f 100644 (file)
@@ -13,7 +13,7 @@ obj-                          :=
 # Core support for S5PV310 system
 
 obj-$(CONFIG_CPU_S5PV310)      += cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_S5PV310)      += setup-i2c0.o time.o
+obj-$(CONFIG_CPU_S5PV310)      += setup-i2c0.o time.o gpiolib.o irq-eint.o
 
 obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
 obj-$(CONFIG_LOCAL_TIMERS)     += localtimer.o
@@ -21,6 +21,7 @@ obj-$(CONFIG_HOTPLUG_CPU)     += hotplug.o
 
 # machine support
 
+obj-$(CONFIG_MACH_SMDKC210)    += mach-smdkc210.o
 obj-$(CONFIG_MACH_SMDKV310)    += mach-smdkv310.o
 obj-$(CONFIG_MACH_UNIVERSAL_C210)      += mach-universal_c210.o
 
@@ -28,3 +29,10 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210)    += mach-universal_c210.o
 
 obj-$(CONFIG_S5PV310_SETUP_I2C1)       += setup-i2c1.o
 obj-$(CONFIG_S5PV310_SETUP_I2C2)       += setup-i2c2.o
+obj-$(CONFIG_S5PV310_SETUP_I2C3)       += setup-i2c3.o
+obj-$(CONFIG_S5PV310_SETUP_I2C4)       += setup-i2c4.o
+obj-$(CONFIG_S5PV310_SETUP_I2C5)       += setup-i2c5.o
+obj-$(CONFIG_S5PV310_SETUP_I2C6)       += setup-i2c6.o
+obj-$(CONFIG_S5PV310_SETUP_I2C7)       += setup-i2c7.o
+obj-$(CONFIG_S5PV310_SETUP_SDHCI)      += setup-sdhci.o
+obj-$(CONFIG_S5PV310_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
index 26a0f03df8eaf2ae85323cda81e3b1044ec66d97..58c9d33f36fec8caef7150a929e94800f97b8b04 100644 (file)
@@ -30,16 +30,92 @@ static struct clk clk_sclk_hdmi27m = {
        .rate           = 27000000,
 };
 
+static struct clk clk_sclk_hdmiphy = {
+       .name           = "sclk_hdmiphy",
+       .id             = -1,
+};
+
+static struct clk clk_sclk_usbphy0 = {
+       .name           = "sclk_usbphy0",
+       .id             = -1,
+       .rate           = 27000000,
+};
+
+static struct clk clk_sclk_usbphy1 = {
+       .name           = "sclk_usbphy1",
+       .id             = -1,
+};
+
+static int s5pv310_clksrc_mask_top_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
+}
+
+static int s5pv310_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
+}
+
+static int s5pv310_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
+}
+
+static int s5pv310_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
+}
+
+static int s5pv310_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
+}
+
 static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
 {
        return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
 }
 
+static int s5pv310_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
+}
+
+static int s5pv310_clk_ip_cam_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
+}
+
+static int s5pv310_clk_ip_image_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
+}
+
+static int s5pv310_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
+}
+
+static int s5pv310_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
+}
+
+static int s5pv310_clk_ip_fsys_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
+}
+
 static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable)
 {
        return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
 }
 
+static int s5pv310_clk_ip_perir_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
+}
+
 /* Core list of CMU_CPU side */
 
 static struct clksrc_clk clk_mout_apll = {
@@ -79,7 +155,7 @@ static struct clksrc_clk clk_mout_mpll = {
 };
 
 static struct clk *clkset_moutcore_list[] = {
-       [0] = &clk_sclk_apll.clk,
+       [0] = &clk_mout_apll.clk,
        [1] = &clk_mout_mpll.clk,
 };
 
@@ -150,24 +226,6 @@ static struct clksrc_clk clk_periphclk = {
        .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
 };
 
-static struct clksrc_clk clk_atclk = {
-       .clk    = {
-               .name           = "atclk",
-               .id             = -1,
-               .parent         = &clk_moutcore.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk clk_pclk_dbg = {
-       .clk    = {
-               .name           = "pclk_dbg",
-               .id             = -1,
-               .parent         = &clk_atclk.clk,
-       },
-       .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 20, .size = 3 },
-};
-
 /* Core list of CMU_CORE side */
 
 static struct clk *clkset_corebus_list[] = {
@@ -241,7 +299,7 @@ static struct clk *clkset_aclk_top_list[] = {
        [1] = &clk_sclk_apll.clk,
 };
 
-static struct clksrc_sources clkset_aclk_200 = {
+static struct clksrc_sources clkset_aclk = {
        .sources        = clkset_aclk_top_list,
        .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
 };
@@ -251,52 +309,37 @@ static struct clksrc_clk clk_aclk_200 = {
                .name           = "aclk_200",
                .id             = -1,
        },
-       .sources        = &clkset_aclk_200,
+       .sources        = &clkset_aclk,
        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
 };
 
-static struct clksrc_sources clkset_aclk_100 = {
-       .sources        = clkset_aclk_top_list,
-       .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
-};
-
 static struct clksrc_clk clk_aclk_100 = {
        .clk    = {
                .name           = "aclk_100",
                .id             = -1,
        },
-       .sources        = &clkset_aclk_100,
+       .sources        = &clkset_aclk,
        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
 };
 
-static struct clksrc_sources clkset_aclk_160 = {
-       .sources        = clkset_aclk_top_list,
-       .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
-};
-
 static struct clksrc_clk clk_aclk_160 = {
        .clk    = {
                .name           = "aclk_160",
                .id             = -1,
        },
-       .sources        = &clkset_aclk_160,
+       .sources        = &clkset_aclk,
        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
 };
 
-static struct clksrc_sources clkset_aclk_133 = {
-       .sources        = clkset_aclk_top_list,
-       .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
-};
-
 static struct clksrc_clk clk_aclk_133 = {
        .clk    = {
                .name           = "aclk_133",
                .id             = -1,
        },
-       .sources        = &clkset_aclk_133,
+       .sources        = &clkset_aclk,
        .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
        .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
 };
@@ -315,6 +358,8 @@ static struct clksrc_clk clk_vpllsrc = {
        .clk    = {
                .name           = "vpll_src",
                .id             = -1,
+               .enable         = s5pv310_clksrc_mask_top_ctrl,
+               .ctrlbit        = (1 << 0),
        },
        .sources        = &clkset_vpllsrc,
        .reg_src        = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
@@ -346,7 +391,175 @@ static struct clk init_clocks_disable[] = {
                .parent         = &clk_aclk_100.clk,
                .enable         = s5pv310_clk_ip_peril_ctrl,
                .ctrlbit        = (1<<24),
-       }
+       }, {
+               .name           = "csis",
+               .id             = 0,
+               .enable         = s5pv310_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "csis",
+               .id             = 1,
+               .enable         = s5pv310_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "fimc",
+               .id             = 0,
+               .enable         = s5pv310_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "fimc",
+               .id             = 1,
+               .enable         = s5pv310_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "fimc",
+               .id             = 2,
+               .enable         = s5pv310_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "fimc",
+               .id             = 3,
+               .enable         = s5pv310_clk_ip_cam_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "fimd",
+               .id             = 0,
+               .enable         = s5pv310_clk_ip_lcd0_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "fimd",
+               .id             = 1,
+               .enable         = s5pv310_clk_ip_lcd1_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "hsmmc",
+               .id             = 0,
+               .parent         = &clk_aclk_133.clk,
+               .enable         = s5pv310_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "hsmmc",
+               .id             = 1,
+               .parent         = &clk_aclk_133.clk,
+               .enable         = s5pv310_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "hsmmc",
+               .id             = 2,
+               .parent         = &clk_aclk_133.clk,
+               .enable         = s5pv310_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "hsmmc",
+               .id             = 3,
+               .parent         = &clk_aclk_133.clk,
+               .enable         = s5pv310_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "hsmmc",
+               .id             = 4,
+               .parent         = &clk_aclk_133.clk,
+               .enable         = s5pv310_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "sata",
+               .id             = -1,
+               .enable         = s5pv310_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "adc",
+               .id             = -1,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 15),
+       }, {
+               .name           = "rtc",
+               .id             = -1,
+               .enable         = s5pv310_clk_ip_perir_ctrl,
+               .ctrlbit        = (1 << 15),
+       }, {
+               .name           = "watchdog",
+               .id             = -1,
+               .enable         = s5pv310_clk_ip_perir_ctrl,
+               .ctrlbit        = (1 << 14),
+       }, {
+               .name           = "usbhost",
+               .id             = -1,
+               .enable         = s5pv310_clk_ip_fsys_ctrl ,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "otg",
+               .id             = -1,
+               .enable         = s5pv310_clk_ip_fsys_ctrl,
+               .ctrlbit        = (1 << 13),
+       }, {
+               .name           = "spi",
+               .id             = 0,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 16),
+       }, {
+               .name           = "spi",
+               .id             = 1,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 17),
+       }, {
+               .name           = "spi",
+               .id             = 2,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 18),
+       }, {
+               .name           = "fimg2d",
+               .id             = -1,
+               .enable         = s5pv310_clk_ip_image_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "i2c",
+               .id             = 0,
+               .parent         = &clk_aclk_100.clk,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "i2c",
+               .id             = 1,
+               .parent         = &clk_aclk_100.clk,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "i2c",
+               .id             = 2,
+               .parent         = &clk_aclk_100.clk,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "i2c",
+               .id             = 3,
+               .parent         = &clk_aclk_100.clk,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "i2c",
+               .id             = 4,
+               .parent         = &clk_aclk_100.clk,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "i2c",
+               .id             = 5,
+               .parent         = &clk_aclk_100.clk,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 11),
+       }, {
+               .name           = "i2c",
+               .id             = 6,
+               .parent         = &clk_aclk_100.clk,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "i2c",
+               .id             = 7,
+               .parent         = &clk_aclk_100.clk,
+               .enable         = s5pv310_clk_ip_peril_ctrl,
+               .ctrlbit        = (1 << 13),
+       },
 };
 
 static struct clk init_clocks[] = {
@@ -387,6 +600,9 @@ static struct clk *clkset_group_list[] = {
        [0] = &clk_ext_xtal_mux,
        [1] = &clk_xusbxti,
        [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
        [6] = &clk_mout_mpll.clk,
        [7] = &clk_mout_epll.clk,
        [8] = &clk_sclk_vpll.clk,
@@ -397,6 +613,104 @@ static struct clksrc_sources clkset_group = {
        .nr_sources     = ARRAY_SIZE(clkset_group_list),
 };
 
+static struct clk *clkset_mout_g2d0_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources clkset_mout_g2d0 = {
+       .sources        = clkset_mout_g2d0_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d0_list),
+};
+
+static struct clksrc_clk clk_mout_g2d0 = {
+       .clk    = {
+               .name           = "mout_g2d0",
+               .id             = -1,
+       },
+       .sources        = &clkset_mout_g2d0,
+       .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_mout_g2d1_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_mout_g2d1 = {
+       .sources        = clkset_mout_g2d1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d1_list),
+};
+
+static struct clksrc_clk clk_mout_g2d1 = {
+       .clk    = {
+               .name           = "mout_g2d1",
+               .id             = -1,
+       },
+       .sources        = &clkset_mout_g2d1,
+       .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
+};
+
+static struct clk *clkset_mout_g2d_list[] = {
+       [0] = &clk_mout_g2d0.clk,
+       [1] = &clk_mout_g2d1.clk,
+};
+
+static struct clksrc_sources clkset_mout_g2d = {
+       .sources        = clkset_mout_g2d_list,
+       .nr_sources     = ARRAY_SIZE(clkset_mout_g2d_list),
+};
+
+static struct clksrc_clk clk_dout_mmc0 = {
+       .clk            = {
+               .name           = "dout_mmc0",
+               .id             = -1,
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc1 = {
+       .clk            = {
+               .name           = "dout_mmc1",
+               .id             = -1,
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc2 = {
+       .clk            = {
+               .name           = "dout_mmc2",
+               .id             = -1,
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc3 = {
+       .clk            = {
+               .name           = "dout_mmc3",
+               .id             = -1,
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_mmc4 = {
+       .clk            = {
+               .name           = "dout_mmc4",
+               .id             = -1,
+       },
+       .sources = &clkset_group,
+       .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
+       .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
+};
+
 static struct clksrc_clk clksrcs[] = {
        {
                .clk    = {
@@ -448,7 +762,200 @@ static struct clksrc_clk clksrcs[] = {
                .sources = &clkset_group,
                .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
                .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
-       },
+       }, {
+               .clk            = {
+                       .name           = "sclk_csis",
+                       .id             = 0,
+                       .enable         = s5pv310_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_csis",
+                       .id             = 1,
+                       .enable         = s5pv310_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 28),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_cam",
+                       .id             = 0,
+                       .enable         = s5pv310_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_cam",
+                       .id             = 1,
+                       .enable         = s5pv310_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 20),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimc",
+                       .id             = 0,
+                       .enable         = s5pv310_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimc",
+                       .id             = 1,
+                       .enable         = s5pv310_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 4),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimc",
+                       .id             = 2,
+                       .enable         = s5pv310_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 8),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimc",
+                       .id             = 3,
+                       .enable         = s5pv310_clksrc_mask_cam_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimd",
+                       .id             = 0,
+                       .enable         = s5pv310_clksrc_mask_lcd0_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimd",
+                       .id             = 1,
+                       .enable         = s5pv310_clksrc_mask_lcd1_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_sata",
+                       .id             = -1,
+                       .enable         = s5pv310_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &clkset_mout_corebus,
+               .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .id             = 0,
+                       .enable         = s5pv310_clksrc_mask_peril1_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .id             = 1,
+                       .enable         = s5pv310_clksrc_mask_peril1_ctrl,
+                       .ctrlbit        = (1 << 20),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .id             = 2,
+                       .enable         = s5pv310_clksrc_mask_peril1_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &clkset_group,
+               .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
+               .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimg2d",
+                       .id             = -1,
+               },
+               .sources = &clkset_mout_g2d,
+               .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
+               .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 0,
+                       .parent         = &clk_dout_mmc0.clk,
+                       .enable         = s5pv310_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 1,
+                       .parent         = &clk_dout_mmc1.clk,
+                       .enable         = s5pv310_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 4),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 2,
+                       .parent         = &clk_dout_mmc2.clk,
+                       .enable         = s5pv310_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 8),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 3,
+                       .parent         = &clk_dout_mmc3.clk,
+                       .enable         = s5pv310_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 4,
+                       .parent         = &clk_dout_mmc4.clk,
+                       .enable         = s5pv310_clksrc_mask_fsys_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
+       }
 };
 
 /* Clock initialization code */
@@ -464,8 +971,6 @@ static struct clksrc_clk *sysclks[] = {
        &clk_aclk_cores,
        &clk_aclk_corem1,
        &clk_periphclk,
-       &clk_atclk,
-       &clk_pclk_dbg,
        &clk_mout_corebus,
        &clk_sclk_dmc,
        &clk_aclk_cored,
@@ -478,6 +983,11 @@ static struct clksrc_clk *sysclks[] = {
        &clk_aclk_100,
        &clk_aclk_160,
        &clk_aclk_133,
+       &clk_dout_mmc0,
+       &clk_dout_mmc1,
+       &clk_dout_mmc2,
+       &clk_dout_mmc3,
+       &clk_dout_mmc4,
 };
 
 void __init_or_cpufreq s5pv310_setup_clocks(void)
@@ -490,15 +1000,11 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
        unsigned long vpllsrc;
        unsigned long xtal;
        unsigned long armclk;
-       unsigned long aclk_corem0;
-       unsigned long aclk_cores;
-       unsigned long aclk_corem1;
-       unsigned long periphclk;
        unsigned long sclk_dmc;
-       unsigned long aclk_cored;
-       unsigned long aclk_corep;
-       unsigned long aclk_acp;
-       unsigned long pclk_acp;
+       unsigned long aclk_200;
+       unsigned long aclk_100;
+       unsigned long aclk_160;
+       unsigned long aclk_133;
        unsigned int ptr;
 
        printk(KERN_DEBUG "%s: registering clocks\n", __func__);
@@ -529,26 +1035,21 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
                        apll, mpll, epll, vpll);
 
        armclk = clk_get_rate(&clk_armclk.clk);
-       aclk_corem0 = clk_get_rate(&clk_aclk_corem0.clk);
-       aclk_cores = clk_get_rate(&clk_aclk_cores.clk);
-       aclk_corem1 = clk_get_rate(&clk_aclk_corem1.clk);
-       periphclk = clk_get_rate(&clk_periphclk.clk);
        sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
-       aclk_cored = clk_get_rate(&clk_aclk_cored.clk);
-       aclk_corep = clk_get_rate(&clk_aclk_corep.clk);
-       aclk_acp = clk_get_rate(&clk_aclk_acp.clk);
-       pclk_acp = clk_get_rate(&clk_pclk_acp.clk);
-
-       printk(KERN_INFO "S5PV310: ARMCLK=%ld, COREM0=%ld, CORES=%ld\n"
-                        "COREM1=%ld, PERI=%ld, DMC=%ld, CORED=%ld\n"
-                        "COREP=%ld, ACLK_ACP=%ld, PCLK_ACP=%ld",
-                       armclk, aclk_corem0, aclk_cores, aclk_corem1,
-                       periphclk, sclk_dmc, aclk_cored, aclk_corep,
-                       aclk_acp, pclk_acp);
+
+       aclk_200 = clk_get_rate(&clk_aclk_200.clk);
+       aclk_100 = clk_get_rate(&clk_aclk_100.clk);
+       aclk_160 = clk_get_rate(&clk_aclk_160.clk);
+       aclk_133 = clk_get_rate(&clk_aclk_133.clk);
+
+       printk(KERN_INFO "S5PV310: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
+                        "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
+                       armclk, sclk_dmc, aclk_200,
+                       aclk_100, aclk_160, aclk_133);
 
        clk_f.rate = armclk;
        clk_h.rate = sclk_dmc;
-       clk_p.rate = periphclk;
+       clk_p.rate = aclk_100;
 
        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
                s3c_set_clksrc(&clksrcs[ptr], true);
index 4add39853ff9dcf34f3e3c4aeeb25ea8e194da80..82ce4aa6d61a5c07f004f26cc08e11d80f583b0d 100644 (file)
 #include <asm/mach/irq.h>
 
 #include <asm/proc-fns.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #include <plat/cpu.h>
 #include <plat/clock.h>
 #include <plat/s5pv310.h>
+#include <plat/sdhci.h>
 
 #include <mach/regs-irq.h>
 
@@ -56,15 +58,30 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
                .length         = SZ_4K,
                .type           = MT_DEVICE,
        }, {
-               .virtual        = (unsigned long)S5P_VA_GPIO,
+               .virtual        = (unsigned long)S5P_VA_GPIO1,
                .pfn            = __phys_to_pfn(S5PV310_PA_GPIO1),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GPIO2,
+               .pfn            = __phys_to_pfn(S5PV310_PA_GPIO2),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_GPIO3,
+               .pfn            = __phys_to_pfn(S5PV310_PA_GPIO3),
+               .length         = SZ_256,
+               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S3C_VA_UART,
                .pfn            = __phys_to_pfn(S3C_PA_UART),
                .length         = SZ_512K,
                .type           = MT_DEVICE,
+       }, {
+               .virtual        = (unsigned long)S5P_VA_SROMC,
+               .pfn            = __phys_to_pfn(S5PV310_PA_SROMC),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
        },
 };
 
@@ -83,6 +100,12 @@ static void s5pv310_idle(void)
 void __init s5pv310_map_io(void)
 {
        iotable_init(s5pv310_iodesc, ARRAY_SIZE(s5pv310_iodesc));
+
+       /* initialize device information early */
+       s5pv310_default_sdhci0();
+       s5pv310_default_sdhci1();
+       s5pv310_default_sdhci2();
+       s5pv310_default_sdhci3();
 }
 
 void __init s5pv310_init_clocks(int xtal)
@@ -131,6 +154,28 @@ static int __init s5pv310_core_init(void)
 
 core_initcall(s5pv310_core_init);
 
+#ifdef CONFIG_CACHE_L2X0
+static int __init s5pv310_l2x0_cache_init(void)
+{
+       /* TAG, Data Latency Control: 2cycle */
+       __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
+       __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
+
+       /* L2X0 Prefetch Control */
+       __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
+
+       /* L2X0 Power Control */
+       __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
+                    S5P_VA_L2CC + L2X0_POWER_CTRL);
+
+       l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff);
+
+       return 0;
+}
+
+early_initcall(s5pv310_l2x0_cache_init);
+#endif
+
 int __init s5pv310_init(void)
 {
        printk(KERN_INFO "S5PV310: Initializing architecture\n");
diff --git a/arch/arm/mach-s5pv310/gpiolib.c b/arch/arm/mach-s5pv310/gpiolib.c
new file mode 100644 (file)
index 0000000..55217b8
--- /dev/null
@@ -0,0 +1,304 @@
+/* linux/arch/arm/mach-s5pv310/gpiolib.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5PV310 - GPIOlib support
+ *
+ * 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 <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+static struct s3c_gpio_cfg gpio_cfg = {
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+/*
+ * Following are the gpio banks in v310.
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure gpio_cfg in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of s3c_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
+static struct s3c_gpio_chip s5pv310_gpio_part1_4bit[] = {
+       {
+               .chip   = {
+                       .base   = S5PV310_GPA0(0),
+                       .ngpio  = S5PV310_GPIO_A0_NR,
+                       .label  = "GPA0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPA1(0),
+                       .ngpio  = S5PV310_GPIO_A1_NR,
+                       .label  = "GPA1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPB(0),
+                       .ngpio  = S5PV310_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPC0(0),
+                       .ngpio  = S5PV310_GPIO_C0_NR,
+                       .label  = "GPC0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPC1(0),
+                       .ngpio  = S5PV310_GPIO_C1_NR,
+                       .label  = "GPC1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPD0(0),
+                       .ngpio  = S5PV310_GPIO_D0_NR,
+                       .label  = "GPD0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPD1(0),
+                       .ngpio  = S5PV310_GPIO_D1_NR,
+                       .label  = "GPD1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPE0(0),
+                       .ngpio  = S5PV310_GPIO_E0_NR,
+                       .label  = "GPE0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPE1(0),
+                       .ngpio  = S5PV310_GPIO_E1_NR,
+                       .label  = "GPE1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPE2(0),
+                       .ngpio  = S5PV310_GPIO_E2_NR,
+                       .label  = "GPE2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPE3(0),
+                       .ngpio  = S5PV310_GPIO_E3_NR,
+                       .label  = "GPE3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPE4(0),
+                       .ngpio  = S5PV310_GPIO_E4_NR,
+                       .label  = "GPE4",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPF0(0),
+                       .ngpio  = S5PV310_GPIO_F0_NR,
+                       .label  = "GPF0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPF1(0),
+                       .ngpio  = S5PV310_GPIO_F1_NR,
+                       .label  = "GPF1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPF2(0),
+                       .ngpio  = S5PV310_GPIO_F2_NR,
+                       .label  = "GPF2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPF3(0),
+                       .ngpio  = S5PV310_GPIO_F3_NR,
+                       .label  = "GPF3",
+               },
+       },
+};
+
+static struct s3c_gpio_chip s5pv310_gpio_part2_4bit[] = {
+       {
+               .chip   = {
+                       .base   = S5PV310_GPJ0(0),
+                       .ngpio  = S5PV310_GPIO_J0_NR,
+                       .label  = "GPJ0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPJ1(0),
+                       .ngpio  = S5PV310_GPIO_J1_NR,
+                       .label  = "GPJ1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPK0(0),
+                       .ngpio  = S5PV310_GPIO_K0_NR,
+                       .label  = "GPK0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPK1(0),
+                       .ngpio  = S5PV310_GPIO_K1_NR,
+                       .label  = "GPK1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPK2(0),
+                       .ngpio  = S5PV310_GPIO_K2_NR,
+                       .label  = "GPK2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPK3(0),
+                       .ngpio  = S5PV310_GPIO_K3_NR,
+                       .label  = "GPK3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPL0(0),
+                       .ngpio  = S5PV310_GPIO_L0_NR,
+                       .label  = "GPL0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPL1(0),
+                       .ngpio  = S5PV310_GPIO_L1_NR,
+                       .label  = "GPL1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV310_GPL2(0),
+                       .ngpio  = S5PV310_GPIO_L2_NR,
+                       .label  = "GPL2",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO2 + 0xC00),
+               .config = &gpio_cfg_noint,
+               .irq_base = IRQ_EINT(0),
+               .chip   = {
+                       .base   = S5PV310_GPX0(0),
+                       .ngpio  = S5PV310_GPIO_X0_NR,
+                       .label  = "GPX0",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO2 + 0xC20),
+               .config = &gpio_cfg_noint,
+               .irq_base = IRQ_EINT(8),
+               .chip   = {
+                       .base   = S5PV310_GPX1(0),
+                       .ngpio  = S5PV310_GPIO_X1_NR,
+                       .label  = "GPX1",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO2 + 0xC40),
+               .config = &gpio_cfg_noint,
+               .irq_base = IRQ_EINT(16),
+               .chip   = {
+                       .base   = S5PV310_GPX2(0),
+                       .ngpio  = S5PV310_GPIO_X2_NR,
+                       .label  = "GPX2",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       }, {
+               .base   = (S5P_VA_GPIO2 + 0xC60),
+               .config = &gpio_cfg_noint,
+               .irq_base = IRQ_EINT(24),
+               .chip   = {
+                       .base   = S5PV310_GPX3(0),
+                       .ngpio  = S5PV310_GPIO_X3_NR,
+                       .label  = "GPX3",
+                       .to_irq = samsung_gpiolib_to_irq,
+               },
+       },
+};
+
+static struct s3c_gpio_chip s5pv310_gpio_part3_4bit[] = {
+       {
+               .chip   = {
+                       .base   = S5PV310_GPZ(0),
+                       .ngpio  = S5PV310_GPIO_Z_NR,
+                       .label  = "GPZ",
+               },
+       },
+};
+
+static __init int s5pv310_gpiolib_init(void)
+{
+       struct s3c_gpio_chip *chip;
+       int i;
+       int nr_chips;
+
+       /* GPIO part 1 */
+
+       chip = s5pv310_gpio_part1_4bit;
+       nr_chips = ARRAY_SIZE(s5pv310_gpio_part1_4bit);
+
+       for (i = 0; i < nr_chips; i++, chip++) {
+               if (chip->config == NULL)
+                       chip->config = &gpio_cfg;
+               if (chip->base == NULL)
+                       chip->base = S5P_VA_GPIO1 + (i) * 0x20;
+       }
+
+       samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part1_4bit, nr_chips);
+
+       /* GPIO part 2 */
+
+       chip = s5pv310_gpio_part2_4bit;
+       nr_chips = ARRAY_SIZE(s5pv310_gpio_part2_4bit);
+
+       for (i = 0; i < nr_chips; i++, chip++) {
+               if (chip->config == NULL)
+                       chip->config = &gpio_cfg;
+               if (chip->base == NULL)
+                       chip->base = S5P_VA_GPIO2 + (i) * 0x20;
+       }
+
+       samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part2_4bit, nr_chips);
+
+       /* GPIO part 3 */
+
+       chip = s5pv310_gpio_part3_4bit;
+       nr_chips = ARRAY_SIZE(s5pv310_gpio_part3_4bit);
+
+       for (i = 0; i < nr_chips; i++, chip++) {
+               if (chip->config == NULL)
+                       chip->config = &gpio_cfg;
+               if (chip->base == NULL)
+                       chip->base = S5P_VA_GPIO3 + (i) * 0x20;
+       }
+
+       samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part3_4bit, nr_chips);
+
+       return 0;
+}
+core_initcall(s5pv310_gpiolib_init);
diff --git a/arch/arm/mach-s5pv310/hotplug.c b/arch/arm/mach-s5pv310/hotplug.c
new file mode 100644 (file)
index 0000000..03652c3
--- /dev/null
@@ -0,0 +1,144 @@
+/* linux arch/arm/mach-s5pv310/hotplug.c
+ *
+ *  Cloned from linux/arch/arm/mach-realview/hotplug.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+
+#include <asm/cacheflush.h>
+
+extern volatile int pen_release;
+
+static DECLARE_COMPLETION(cpu_killed);
+
+static inline void cpu_enter_lowpower(void)
+{
+       unsigned int v;
+
+       flush_cache_all();
+       asm volatile(
+       "       mcr     p15, 0, %1, c7, c5, 0\n"
+       "       mcr     p15, 0, %1, c7, c10, 4\n"
+       /*
+        * Turn off coherency
+        */
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       bic     %0, %0, #0x20\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, #0x04\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+         : "=&r" (v)
+         : "r" (0)
+         : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+       unsigned int v;
+
+       asm volatile(
+       "mrc    p15, 0, %0, c1, c0, 0\n"
+       "       orr     %0, %0, #0x04\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       orr     %0, %0, #0x20\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+         : "=&r" (v)
+         :
+         : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu)
+{
+       /*
+        * there is no power-control hardware on this platform, so all
+        * we can do is put the core into WFI; this is safe as the calling
+        * code will have already disabled interrupts
+        */
+       for (;;) {
+               /*
+                * here's the WFI
+                */
+               asm(".word      0xe320f003\n"
+                   :
+                   :
+                   : "memory", "cc");
+
+               if (pen_release == cpu) {
+                       /*
+                        * OK, proper wakeup, we're done
+                        */
+                       break;
+               }
+
+               /*
+                * getting here, means that we have come out of WFI without
+                * having been woken up - this shouldn't happen
+                *
+                * The trouble is, letting people know about this is not really
+                * possible, since we are currently running incoherently, and
+                * therefore cannot safely call printk() or anything else
+                */
+#ifdef DEBUG
+               printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
+#endif
+       }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+       return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+#ifdef DEBUG
+       unsigned int this_cpu = hard_smp_processor_id();
+
+       if (cpu != this_cpu) {
+               printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
+                          this_cpu, cpu);
+               BUG();
+       }
+#endif
+
+       printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+       complete(&cpu_killed);
+
+       /*
+        * we're ready for shutdown now, so do it
+        */
+       cpu_enter_lowpower();
+       platform_do_lowpower(cpu);
+
+       /*
+        * bring this CPU back into the world of cache
+        * coherency, and then restore interrupts
+        */
+       cpu_leave_lowpower();
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+       /*
+        * we don't allow CPU 0 to be shutdown (it is still too special
+        * e.g. clock tick interrupts)
+        */
+       return cpu == 0 ? -EPERM : 0;
+}
index 471fc3bb199a7a10becae92cd99fae46871ad997..99e7dad8a85a0c76a8c6e8d233aca34ea04c8f8e 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com/
  *
- * S5PV210 - IRQ definitions
+ * S5PV310 - IRQ definitions
  *
  * 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
@@ -60,6 +60,9 @@
 #define IRQ_TIMER3_VIC         COMBINER_IRQ(22, 3)
 #define IRQ_TIMER4_VIC         COMBINER_IRQ(22, 4)
 
+#define IRQ_RTC_ALARM          COMBINER_IRQ(23, 0)
+#define IRQ_RTC_TIC            COMBINER_IRQ(23, 1)
+
 #define IRQ_UART0              COMBINER_IRQ(26, 0)
 #define IRQ_UART1              COMBINER_IRQ(26, 1)
 #define IRQ_UART2              COMBINER_IRQ(26, 2)
 #define IRQ_UART4              COMBINER_IRQ(26, 4)
 
 #define IRQ_IIC                        COMBINER_IRQ(27, 0)
+#define IRQ_IIC1               COMBINER_IRQ(27, 1)
+#define IRQ_IIC2               COMBINER_IRQ(27, 2)
+#define IRQ_IIC3               COMBINER_IRQ(27, 3)
+#define IRQ_IIC4               COMBINER_IRQ(27, 4)
+#define IRQ_IIC5               COMBINER_IRQ(27, 5)
+#define IRQ_IIC6               COMBINER_IRQ(27, 6)
+#define IRQ_IIC7               COMBINER_IRQ(27, 7)
+
+#define IRQ_HSMMC0             COMBINER_IRQ(29, 0)
+#define IRQ_HSMMC1             COMBINER_IRQ(29, 1)
+#define IRQ_HSMMC2             COMBINER_IRQ(29, 2)
+#define IRQ_HSMMC3             COMBINER_IRQ(29, 3)
 
 #define IRQ_ONENAND_AUDI       COMBINER_IRQ(34, 0)
 
-/* Set the default NR_IRQS */
+#define IRQ_EINT4              COMBINER_IRQ(37, 0)
+#define IRQ_EINT5              COMBINER_IRQ(37, 1)
+#define IRQ_EINT6              COMBINER_IRQ(37, 2)
+#define IRQ_EINT7              COMBINER_IRQ(37, 3)
+#define IRQ_EINT8              COMBINER_IRQ(38, 0)
+
+#define IRQ_EINT9              COMBINER_IRQ(38, 1)
+#define IRQ_EINT10             COMBINER_IRQ(38, 2)
+#define IRQ_EINT11             COMBINER_IRQ(38, 3)
+#define IRQ_EINT12             COMBINER_IRQ(38, 4)
+#define IRQ_EINT13             COMBINER_IRQ(38, 5)
+#define IRQ_EINT14             COMBINER_IRQ(38, 6)
+#define IRQ_EINT15             COMBINER_IRQ(38, 7)
+
+#define IRQ_EINT16_31          COMBINER_IRQ(39, 0)
 
-#define NR_IRQS                        COMBINER_IRQ(MAX_COMBINER_NR, 0)
+#define MAX_COMBINER_NR                40
+
+#define S5P_IRQ_EINT_BASE      COMBINER_IRQ(MAX_COMBINER_NR, 0)
+
+#define S5P_EINT_BASE1         (S5P_IRQ_EINT_BASE + 0)
+#define S5P_EINT_BASE2         (S5P_IRQ_EINT_BASE + 16)
+
+/* Set the default NR_IRQS */
 
-#define MAX_COMBINER_NR                39
+#define NR_IRQS                        (S5P_IRQ_EINT_BASE + 32)
 
 #endif /* __ASM_ARCH_IRQS_H */
index aff6d23624bb6d457e118ee7381a004a79968ceb..7acf4e77e92e442436542ed6b9e4682875f63e7c 100644 (file)
@@ -25,6 +25,8 @@
 
 #define S5PV310_PA_SYSRAM              (0x02025000)
 
+#define S5PV310_PA_SROM_BANK(x)                (0x04000000 + ((x) * 0x01000000))
+
 #define S5PC210_PA_ONENAND             (0x0C000000)
 #define S5P_PA_ONENAND                 S5PC210_PA_ONENAND
 
 #define S5PV310_PA_CHIPID              (0x10000000)
 #define S5P_PA_CHIPID                  S5PV310_PA_CHIPID
 
-#define S5PV310_PA_SYSCON              (0x10020000)
+#define S5PV310_PA_SYSCON              (0x10010000)
 #define S5P_PA_SYSCON                  S5PV310_PA_SYSCON
 
 #define S5PV310_PA_CMU                 (0x10030000)
 
 #define S5PV310_PA_WATCHDOG            (0x10060000)
+#define S5PV310_PA_RTC                 (0x10070000)
 
 #define S5PV310_PA_COMBINER            (0x10448000)
 
@@ -55,6 +58,8 @@
 
 #define S5PV310_PA_HSMMC(x)            (0x12510000 + ((x) * 0x10000))
 
+#define S5PV310_PA_SROMC               (0x12570000)
+
 #define S5PV310_PA_UART                        (0x13800000)
 
 #define S5P_PA_UART(x)                 (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET))
@@ -66,7 +71,7 @@
 
 #define S5P_SZ_UART                    SZ_256
 
-#define S5PV310_PA_IIC0                        (0x13860000)
+#define S5PV310_PA_IIC(x)              (0x13860000 + ((x) * 0x10000))
 
 #define S5PV310_PA_TIMER               (0x139D0000)
 #define S5P_PA_TIMER                   S5PV310_PA_TIMER
 #define S3C_PA_HSMMC1                  S5PV310_PA_HSMMC(1)
 #define S3C_PA_HSMMC2                  S5PV310_PA_HSMMC(2)
 #define S3C_PA_HSMMC3                  S5PV310_PA_HSMMC(3)
-#define S3C_PA_IIC                     S5PV310_PA_IIC0
+#define S3C_PA_IIC                     S5PV310_PA_IIC(0)
+#define S3C_PA_IIC1                    S5PV310_PA_IIC(1)
+#define S3C_PA_IIC2                    S5PV310_PA_IIC(2)
+#define S3C_PA_IIC3                    S5PV310_PA_IIC(3)
+#define S3C_PA_IIC4                    S5PV310_PA_IIC(4)
+#define S3C_PA_IIC5                    S5PV310_PA_IIC(5)
+#define S3C_PA_IIC6                    S5PV310_PA_IIC(6)
+#define S3C_PA_IIC7                    S5PV310_PA_IIC(7)
+#define S3C_PA_RTC                     S5PV310_PA_RTC
 #define S3C_PA_WDT                     S5PV310_PA_WATCHDOG
 
 #endif /* __ASM_ARCH_MAP_H */
index 4013553cd9be8de219ffb3cfbd51905b35f517c7..f1028cad978890e9bb3bd49989ce0ba24c35ba78 100644 (file)
 
 #define S5P_CLKSRC_TOP0                        S5P_CLKREG(0x0C210)
 #define S5P_CLKSRC_TOP1                        S5P_CLKREG(0x0C214)
-
+#define S5P_CLKSRC_CAM                 S5P_CLKREG(0x0C220)
+#define S5P_CLKSRC_IMAGE               S5P_CLKREG(0x0C230)
+#define S5P_CLKSRC_LCD0                        S5P_CLKREG(0x0C234)
+#define S5P_CLKSRC_LCD1                        S5P_CLKREG(0x0C238)
+#define S5P_CLKSRC_FSYS                        S5P_CLKREG(0x0C240)
 #define S5P_CLKSRC_PERIL0              S5P_CLKREG(0x0C250)
+#define S5P_CLKSRC_PERIL1              S5P_CLKREG(0x0C254)
 
 #define S5P_CLKDIV_TOP                 S5P_CLKREG(0x0C510)
-
+#define S5P_CLKDIV_CAM                 S5P_CLKREG(0x0C520)
+#define S5P_CLKDIV_IMAGE               S5P_CLKREG(0x0C530)
+#define S5P_CLKDIV_LCD0                        S5P_CLKREG(0x0C534)
+#define S5P_CLKDIV_LCD1                        S5P_CLKREG(0x0C538)
+#define S5P_CLKDIV_FSYS0               S5P_CLKREG(0x0C540)
+#define S5P_CLKDIV_FSYS1               S5P_CLKREG(0x0C544)
+#define S5P_CLKDIV_FSYS2               S5P_CLKREG(0x0C548)
+#define S5P_CLKDIV_FSYS3               S5P_CLKREG(0x0C54C)
 #define S5P_CLKDIV_PERIL0              S5P_CLKREG(0x0C550)
 #define S5P_CLKDIV_PERIL1              S5P_CLKREG(0x0C554)
 #define S5P_CLKDIV_PERIL2              S5P_CLKREG(0x0C558)
 #define S5P_CLKDIV_PERIL4              S5P_CLKREG(0x0C560)
 #define S5P_CLKDIV_PERIL5              S5P_CLKREG(0x0C564)
 
+#define S5P_CLKSRC_MASK_TOP            S5P_CLKREG(0x0C310)
+#define S5P_CLKSRC_MASK_CAM            S5P_CLKREG(0x0C320)
+#define S5P_CLKSRC_MASK_LCD0           S5P_CLKREG(0x0C334)
+#define S5P_CLKSRC_MASK_LCD1           S5P_CLKREG(0x0C338)
+#define S5P_CLKSRC_MASK_FSYS           S5P_CLKREG(0x0C340)
 #define S5P_CLKSRC_MASK_PERIL0         S5P_CLKREG(0x0C350)
+#define S5P_CLKSRC_MASK_PERIL1         S5P_CLKREG(0x0C354)
 
+#define S5P_CLKGATE_IP_CAM             S5P_CLKREG(0x0C920)
+#define S5P_CLKGATE_IP_IMAGE           S5P_CLKREG(0x0C930)
+#define S5P_CLKGATE_IP_LCD0            S5P_CLKREG(0x0C934)
+#define S5P_CLKGATE_IP_LCD1            S5P_CLKREG(0x0C938)
+#define S5P_CLKGATE_IP_FSYS            S5P_CLKREG(0x0C940)
 #define S5P_CLKGATE_IP_PERIL           S5P_CLKREG(0x0C950)
+#define S5P_CLKGATE_IP_PERIR           S5P_CLKREG(0x0C960)
 
 #define S5P_CLKSRC_CORE                        S5P_CLKREG(0x10200)
 #define S5P_CLKDIV_CORE0               S5P_CLKREG(0x10500)
@@ -60,4 +84,8 @@
 
 #define S5P_CLKGATE_SCLKCPU            S5P_CLKREG(0x14800)
 
+/* Compatibility defines */
+
+#define S5P_EPLL_CON                   S5P_EPLL_CON0
+
 #endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-gpio.h b/arch/arm/mach-s5pv310/include/mach/regs-gpio.h
new file mode 100644 (file)
index 0000000..82e9e0c
--- /dev/null
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-s5pv310/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5PV310 - GPIO (including EINT) register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#define S5PV310_EINT40CON              (S5P_VA_GPIO2 + 0xE00)
+#define S5P_EINT_CON(x)                        (S5PV310_EINT40CON + ((x) * 0x4))
+
+#define S5PV310_EINT40FLTCON0          (S5P_VA_GPIO2 + 0xE80)
+#define S5P_EINT_FLTCON(x)             (S5PV310_EINT40FLTCON0 + ((x) * 0x4))
+
+#define S5PV310_EINT40MASK             (S5P_VA_GPIO2 + 0xF00)
+#define S5P_EINT_MASK(x)               (S5PV310_EINT40MASK + ((x) * 0x4))
+
+#define S5PV310_EINT40PEND             (S5P_VA_GPIO2 + 0xF40)
+#define S5P_EINT_PEND(x)               (S5PV310_EINT40PEND + ((x) * 0x4))
+
+#define EINT_REG_NR(x)                 (EINT_OFFSET(x) >> 3)
+
+#define eint_irq_to_bit(irq)           (1 << (EINT_OFFSET(irq) & 0x7))
+
+#define EINT_MODE                      S3C_GPIO_SFN(0xf)
+
+#define EINT_GPIO_0(x)                 S5PV310_GPX0(x)
+#define EINT_GPIO_1(x)                 S5PV310_GPX1(x)
+#define EINT_GPIO_2(x)                 S5PV310_GPX2(x)
+#define EINT_GPIO_3(x)                 S5PV310_GPX3(x)
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-srom.h b/arch/arm/mach-s5pv310/include/mach/regs-srom.h
new file mode 100644 (file)
index 0000000..1898b3e
--- /dev/null
@@ -0,0 +1,50 @@
+/* linux/arch/arm/mach-s5pv310/include/mach/regs-srom.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5PV310 - SROMC register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_SROM_H
+#define __ASM_ARCH_REGS_SROM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5PV310_SROMREG(x)     (S5P_VA_SROMC + (x))
+
+#define S5PV310_SROM_BW                S5PV310_SROMREG(0x0)
+#define S5PV310_SROM_BC0       S5PV310_SROMREG(0x4)
+#define S5PV310_SROM_BC1       S5PV310_SROMREG(0x8)
+#define S5PV310_SROM_BC2       S5PV310_SROMREG(0xc)
+#define S5PV310_SROM_BC3       S5PV310_SROMREG(0x10)
+
+/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
+
+#define S5PV310_SROM_BW__DATAWIDTH__SHIFT      0
+#define S5PV310_SROM_BW__ADDRMODE__SHIFT       1
+#define S5PV310_SROM_BW__WAITENABLE__SHIFT     2
+#define S5PV310_SROM_BW__BYTEENABLE__SHIFT     3
+
+#define S5PV310_SROM_BW__CS_MASK               0xf
+
+#define S5PV310_SROM_BW__NCS0__SHIFT           0
+#define S5PV310_SROM_BW__NCS1__SHIFT           4
+#define S5PV310_SROM_BW__NCS2__SHIFT           8
+#define S5PV310_SROM_BW__NCS3__SHIFT           12
+
+/* applies to same to BCS0 - BCS3 */
+
+#define S5PV310_SROM_BCX__PMC__SHIFT           0
+#define S5PV310_SROM_BCX__TACP__SHIFT          4
+#define S5PV310_SROM_BCX__TCAH__SHIFT          8
+#define S5PV310_SROM_BCX__TCOH__SHIFT          12
+#define S5PV310_SROM_BCX__TACC__SHIFT          16
+#define S5PV310_SROM_BCX__TCOS__SHIFT          24
+#define S5PV310_SROM_BCX__TACS__SHIFT          28
+
+#endif /* __ASM_ARCH_REGS_SROM_H */
index 256f221edf3aca654d59000d3016cdbabe1f80c1..65759fb97581c14e183b0ad3681c810c20297632 100644 (file)
@@ -17,6 +17,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H __FILE__
 
-#define VMALLOC_END    (0xF0000000UL)
+#define VMALLOC_END    0xF6000000UL
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index 0f7052164f23116500451253c58351f06e18fe57..c3f88c3faf6c79b943aabbe420d3aa2e976be761 100644 (file)
@@ -66,11 +66,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
        if (status == 0)
                goto out;
 
-       for (combiner_irq = 0; combiner_irq < 32; combiner_irq++) {
-               if (status & 0x1)
-                       break;
-               status >>= 1;
-       }
+       combiner_irq = __ffs(status);
 
        cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
        if (unlikely(cascade_irq >= NR_IRQS))
diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c
new file mode 100644 (file)
index 0000000..5877503
--- /dev/null
@@ -0,0 +1,228 @@
+/* linux/arch/arm/mach-s5pv310/irq-eint.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5PV310 - IRQ EINT support
+ *
+ * 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 <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/gpio.h>
+
+#include <plat/pm.h>
+#include <plat/cpu.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-gpio.h>
+
+static DEFINE_SPINLOCK(eint_lock);
+
+static unsigned int eint0_15_data[16];
+
+static unsigned int s5pv310_get_irq_nr(unsigned int number)
+{
+       u32 ret = 0;
+
+       switch (number) {
+       case 0 ... 3:
+               ret = (number + IRQ_EINT0);
+               break;
+       case 4 ... 7:
+               ret = (number + (IRQ_EINT4 - 4));
+               break;
+       case 8 ... 15:
+               ret = (number + (IRQ_EINT8 - 8));
+               break;
+       default:
+               printk(KERN_ERR "number available : %d\n", number);
+       }
+
+       return ret;
+}
+
+static inline void s5pv310_irq_eint_mask(unsigned int irq)
+{
+       u32 mask;
+
+       spin_lock(&eint_lock);
+       mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
+       mask |= eint_irq_to_bit(irq);
+       __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
+       spin_unlock(&eint_lock);
+}
+
+static void s5pv310_irq_eint_unmask(unsigned int irq)
+{
+       u32 mask;
+
+       spin_lock(&eint_lock);
+       mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
+       mask &= ~(eint_irq_to_bit(irq));
+       __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
+       spin_unlock(&eint_lock);
+}
+
+static inline void s5pv310_irq_eint_ack(unsigned int irq)
+{
+       __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq)));
+}
+
+static void s5pv310_irq_eint_maskack(unsigned int irq)
+{
+       s5pv310_irq_eint_mask(irq);
+       s5pv310_irq_eint_ack(irq);
+}
+
+static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type)
+{
+       int offs = EINT_OFFSET(irq);
+       int shift;
+       u32 ctrl, mask;
+       u32 newvalue = 0;
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               newvalue = S5P_IRQ_TYPE_EDGE_RISING;
+               break;
+
+       case IRQ_TYPE_EDGE_FALLING:
+               newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
+               break;
+
+       case IRQ_TYPE_EDGE_BOTH:
+               newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
+               break;
+
+       case IRQ_TYPE_LEVEL_LOW:
+               newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
+               break;
+
+       case IRQ_TYPE_LEVEL_HIGH:
+               newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
+               break;
+
+       default:
+               printk(KERN_ERR "No such irq type %d", type);
+               return -EINVAL;
+       }
+
+       shift = (offs & 0x7) * 4;
+       mask = 0x7 << shift;
+
+       spin_lock(&eint_lock);
+       ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(irq)));
+       ctrl &= ~mask;
+       ctrl |= newvalue << shift;
+       __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(irq)));
+       spin_unlock(&eint_lock);
+
+       switch (offs) {
+       case 0 ... 7:
+               s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
+               break;
+       case 8 ... 15:
+               s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
+               break;
+       case 16 ... 23:
+               s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
+               break;
+       case 24 ... 31:
+               s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
+               break;
+       default:
+               printk(KERN_ERR "No such irq number %d", offs);
+       }
+
+       return 0;
+}
+
+static struct irq_chip s5pv310_irq_eint = {
+       .name           = "s5pv310-eint",
+       .mask           = s5pv310_irq_eint_mask,
+       .unmask         = s5pv310_irq_eint_unmask,
+       .mask_ack       = s5pv310_irq_eint_maskack,
+       .ack            = s5pv310_irq_eint_ack,
+       .set_type       = s5pv310_irq_eint_set_type,
+#ifdef CONFIG_PM
+       .set_wake       = s3c_irqext_wake,
+#endif
+};
+
+/* s5pv310_irq_demux_eint
+ *
+ * This function demuxes the IRQ from from EINTs 16 to 31.
+ * It is designed to be inlined into the specific handler
+ * s5p_irq_demux_eintX_Y.
+ *
+ * Each EINT pend/mask registers handle eight of them.
+ */
+static inline void s5pv310_irq_demux_eint(unsigned int start)
+{
+       unsigned int irq;
+
+       u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
+       u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
+
+       status &= ~mask;
+       status &= 0xff;
+
+       while (status) {
+               irq = fls(status) - 1;
+               generic_handle_irq(irq + start);
+               status &= ~(1 << irq);
+       }
+}
+
+static void s5pv310_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+{
+       s5pv310_irq_demux_eint(IRQ_EINT(16));
+       s5pv310_irq_demux_eint(IRQ_EINT(24));
+}
+
+static void s5pv310_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
+{
+       u32 *irq_data = get_irq_data(irq);
+       struct irq_chip *chip = get_irq_chip(irq);
+
+       chip->mask(irq);
+
+       if (chip->ack)
+               chip->ack(irq);
+
+       generic_handle_irq(*irq_data);
+
+       chip->unmask(irq);
+}
+
+int __init s5pv310_init_irq_eint(void)
+{
+       int irq;
+
+       for (irq = 0 ; irq <= 31 ; irq++) {
+               set_irq_chip(IRQ_EINT(irq), &s5pv310_irq_eint);
+               set_irq_handler(IRQ_EINT(irq), handle_level_irq);
+               set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
+       }
+
+       set_irq_chained_handler(IRQ_EINT16_31, s5pv310_irq_demux_eint16_31);
+
+       for (irq = 0 ; irq <= 15 ; irq++) {
+               eint0_15_data[irq] = IRQ_EINT(irq);
+
+               set_irq_data(s5pv310_get_irq_nr(irq), &eint0_15_data[irq]);
+               set_irq_chained_handler(s5pv310_get_irq_nr(irq),
+                                       s5pv310_irq_eint0_15);
+       }
+
+       return 0;
+}
+
+arch_initcall(s5pv310_init_irq_eint);
diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c
new file mode 100644 (file)
index 0000000..2b8d4fc
--- /dev/null
@@ -0,0 +1,202 @@
+/* linux/arch/arm/mach-s5pv310/mach-smdkc210.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/serial_core.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv310.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+
+#include <mach/map.h>
+#include <mach/regs-srom.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKC210_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
+                                S3C2410_UCON_RXILEVEL |        \
+                                S3C2410_UCON_TXIRQMODE |       \
+                                S3C2410_UCON_RXIRQMODE |       \
+                                S3C2410_UCON_RXFIFO_TOI |      \
+                                S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKC210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKC210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE |       \
+                                S5PV210_UFCON_TXTRIG4 |        \
+                                S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkc210_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport         = 0,
+               .flags          = 0,
+               .ucon           = SMDKC210_UCON_DEFAULT,
+               .ulcon          = SMDKC210_ULCON_DEFAULT,
+               .ufcon          = SMDKC210_UFCON_DEFAULT,
+       },
+       [1] = {
+               .hwport         = 1,
+               .flags          = 0,
+               .ucon           = SMDKC210_UCON_DEFAULT,
+               .ulcon          = SMDKC210_ULCON_DEFAULT,
+               .ufcon          = SMDKC210_UFCON_DEFAULT,
+       },
+       [2] = {
+               .hwport         = 2,
+               .flags          = 0,
+               .ucon           = SMDKC210_UCON_DEFAULT,
+               .ulcon          = SMDKC210_ULCON_DEFAULT,
+               .ufcon          = SMDKC210_UFCON_DEFAULT,
+       },
+       [3] = {
+               .hwport         = 3,
+               .flags          = 0,
+               .ucon           = SMDKC210_UCON_DEFAULT,
+               .ulcon          = SMDKC210_ULCON_DEFAULT,
+               .ufcon          = SMDKC210_UFCON_DEFAULT,
+       },
+};
+
+static struct s3c_sdhci_platdata smdkc210_hsmmc0_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S5PV310_GPK0(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_S5PV310_SDHCI_CH0_8BIT
+       .max_width              = 8,
+       .host_caps              = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkc210_hsmmc1_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S5PV310_GPK0(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct s3c_sdhci_platdata smdkc210_hsmmc2_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S5PV310_GPK2(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_S5PV310_SDHCI_CH2_8BIT
+       .max_width              = 8,
+       .host_caps              = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S5PV310_GPK2(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct resource smdkc210_smsc911x_resources[] = {
+       [0] = {
+               .start  = S5PV310_PA_SROM_BANK(1),
+               .end    = S5PV310_PA_SROM_BANK(1) + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_EINT(5),
+               .end    = IRQ_EINT(5),
+               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+       },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+       .flags          = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+       .mac            = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdkc210_smsc911x = {
+       .name           = "smsc911x",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(smdkc210_smsc911x_resources),
+       .resource       = smdkc210_smsc911x_resources,
+       .dev            = {
+               .platform_data  = &smsc9215_config,
+       },
+};
+
+static struct platform_device *smdkc210_devices[] __initdata = {
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc1,
+       &s3c_device_hsmmc2,
+       &s3c_device_hsmmc3,
+       &s3c_device_rtc,
+       &s3c_device_wdt,
+       &smdkc210_smsc911x,
+};
+
+static void __init smdkc210_smsc911x_init(void)
+{
+       u32 cs1;
+
+       /* configure nCS1 width to 16 bits */
+       cs1 = __raw_readl(S5PV310_SROM_BW) &
+                   ~(S5PV310_SROM_BW__CS_MASK <<
+                                   S5PV310_SROM_BW__NCS1__SHIFT);
+       cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
+               (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
+               (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
+               S5PV310_SROM_BW__NCS1__SHIFT;
+       __raw_writel(cs1, S5PV310_SROM_BW);
+
+       /* set timing for nCS1 suitable for ethernet chip */
+       __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
+                    (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
+                    (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
+                    (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
+                    (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
+                    (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
+                    (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
+}
+
+static void __init smdkc210_map_io(void)
+{
+       s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+       s3c24xx_init_clocks(24000000);
+       s3c24xx_init_uarts(smdkc210_uartcfgs, ARRAY_SIZE(smdkc210_uartcfgs));
+}
+
+static void __init smdkc210_machine_init(void)
+{
+       smdkc210_smsc911x_init();
+
+       s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata);
+       s3c_sdhci1_set_platdata(&smdkc210_hsmmc1_pdata);
+       s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
+       s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
+
+       platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+}
+
+MACHINE_START(SMDKC210, "SMDKC210")
+       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+       .boot_params    = S5P_PA_SDRAM + 0x100,
+       .init_irq       = s5pv310_init_irq,
+       .map_io         = smdkc210_map_io,
+       .init_machine   = smdkc210_machine_init,
+       .timer          = &s5pv310_timer,
+MACHINE_END
index 46215a14b3bb49ec24ba11f9592565733a08b266..35826d66632c1586aa38830aa6d132cbfd41d750 100644 (file)
@@ -9,16 +9,23 @@
 */
 
 #include <linux/serial_core.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/cache-l2x0.h>
 
 #include <plat/regs-serial.h>
 #include <plat/s5pv310.h>
 #include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
 
 #include <mach/map.h>
+#include <mach/regs-srom.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKV310_UCON_DEFAULT  (S3C2410_UCON_TXILEVEL |        \
@@ -65,6 +72,107 @@ static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
        },
 };
 
+static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S5PV310_GPK0(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_S5PV310_SDHCI_CH0_8BIT
+       .max_width              = 8,
+       .host_caps              = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S5PV310_GPK0(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S5PV310_GPK2(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_S5PV310_SDHCI_CH2_8BIT
+       .max_width              = 8,
+       .host_caps              = MMC_CAP_8_BIT_DATA,
+#endif
+};
+
+static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
+       .cd_type                = S3C_SDHCI_CD_GPIO,
+       .ext_cd_gpio            = S5PV310_GPK2(2),
+       .ext_cd_gpio_invert     = 1,
+       .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct resource smdkv310_smsc911x_resources[] = {
+       [0] = {
+               .start  = S5PV310_PA_SROM_BANK(1),
+               .end    = S5PV310_PA_SROM_BANK(1) + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_EINT(5),
+               .end    = IRQ_EINT(5),
+               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+       },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+       .flags          = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+       .mac            = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdkv310_smsc911x = {
+       .name           = "smsc911x",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(smdkv310_smsc911x_resources),
+       .resource       = smdkv310_smsc911x_resources,
+       .dev            = {
+               .platform_data  = &smsc9215_config,
+       },
+};
+
+static struct platform_device *smdkv310_devices[] __initdata = {
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc1,
+       &s3c_device_hsmmc2,
+       &s3c_device_hsmmc3,
+       &s3c_device_rtc,
+       &s3c_device_wdt,
+       &smdkv310_smsc911x,
+};
+
+static void __init smdkv310_smsc911x_init(void)
+{
+       u32 cs1;
+
+       /* configure nCS1 width to 16 bits */
+       cs1 = __raw_readl(S5PV310_SROM_BW) &
+                   ~(S5PV310_SROM_BW__CS_MASK <<
+                                   S5PV310_SROM_BW__NCS1__SHIFT);
+       cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
+               (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
+               (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
+               S5PV310_SROM_BW__NCS1__SHIFT;
+       __raw_writel(cs1, S5PV310_SROM_BW);
+
+       /* set timing for nCS1 suitable for ethernet chip */
+       __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
+                    (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
+                    (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
+                    (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
+                    (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
+                    (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
+                    (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
+}
+
 static void __init smdkv310_map_io(void)
 {
        s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -74,9 +182,14 @@ static void __init smdkv310_map_io(void)
 
 static void __init smdkv310_machine_init(void)
 {
-#ifdef CONFIG_CACHE_L2X0
-       l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff);
-#endif
+       smdkv310_smsc911x_init();
+
+       s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
+       s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
+       s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
+       s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
+
+       platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
 }
 
 MACHINE_START(SMDKV310, "SMDKV310")
index d7c2ec770f88bf1e80cc74e2749262726e10c598..16d8fc00cafd92e0e669db7f8ca7d420c8238622 100644 (file)
@@ -7,15 +7,20 @@
  * published by the Free Software Foundation.
 */
 
+#include <linux/platform_device.h>
 #include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/cache-l2x0.h>
 
 #include <plat/regs-serial.h>
 #include <plat/s5pv310.h>
 #include <plat/cpu.h>
+#include <plat/devs.h>
 
 #include <mach/map.h>
 
@@ -60,6 +65,72 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
        },
 };
 
+static struct gpio_keys_button universal_gpio_keys_tables[] = {
+       {
+               .code                   = KEY_VOLUMEUP,
+               .gpio                   = S5PV310_GPX2(0),      /* XEINT16 */
+               .desc                   = "gpio-keys: KEY_VOLUMEUP",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_VOLUMEDOWN,
+               .gpio                   = S5PV310_GPX2(1),      /* XEINT17 */
+               .desc                   = "gpio-keys: KEY_VOLUMEDOWN",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_CONFIG,
+               .gpio                   = S5PV310_GPX2(2),      /* XEINT18 */
+               .desc                   = "gpio-keys: KEY_CONFIG",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_CAMERA,
+               .gpio                   = S5PV310_GPX2(3),      /* XEINT19 */
+               .desc                   = "gpio-keys: KEY_CAMERA",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       }, {
+               .code                   = KEY_OK,
+               .gpio                   = S5PV310_GPX3(5),      /* XEINT29 */
+               .desc                   = "gpio-keys: KEY_OK",
+               .type                   = EV_KEY,
+               .active_low             = 1,
+               .debounce_interval      = 1,
+       },
+};
+
+static struct gpio_keys_platform_data universal_gpio_keys_data = {
+       .buttons        = universal_gpio_keys_tables,
+       .nbuttons       = ARRAY_SIZE(universal_gpio_keys_tables),
+};
+
+static struct platform_device universal_gpio_keys = {
+       .name                   = "gpio-keys",
+       .dev                    = {
+               .platform_data  = &universal_gpio_keys_data,
+       },
+};
+
+/* I2C0 */
+static struct i2c_board_info i2c0_devs[] __initdata = {
+       /* Camera, To be updated */
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c1_devs[] __initdata = {
+       /* Gyro, To be updated */
+};
+
+static struct platform_device *universal_devices[] __initdata = {
+       &universal_gpio_keys,
+       &s5p_device_onenand,
+};
+
 static void __init universal_map_io(void)
 {
        s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -69,9 +140,11 @@ static void __init universal_map_io(void)
 
 static void __init universal_machine_init(void)
 {
-#ifdef CONFIG_CACHE_L2X0
-       l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff);
-#endif
+       i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
+       i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+
+       /* Last */
+       platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
 }
 
 MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
index 436712807383e43c4cd073b13dbe61ec01be2039..f47f8f3152ecf642ec491c2723a0e0ef9400307a 100644 (file)
@@ -21,8 +21,6 @@ struct platform_device; /* don't need the contents */
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5PV310_GPD1(0), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV310_GPD1(0), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PV310_GPD1(1), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV310_GPD1(1), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5PV310_GPD1(0), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
index 1ecd5bc35b5a622877bd579a94fad39ec8975820..9d07e4e2f14cb0ed64e1f084b1ed688ae5c7c7b4 100644 (file)
@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
 
 void s3c_i2c1_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5PV310_GPD1(2), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV310_GPD1(2), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PV310_GPD1(3), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PV310_GPD1(3), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5PV310_GPD1(2), 2,
+                             S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
index 4c0d8def660ae80c31dc29689c9cbdca5ab9bc18..4163b1233dafbef696f95861e6c31b6588dd9481 100644 (file)
@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
 
 void s3c_i2c2_cfg_gpio(struct platform_device *dev)
 {
-       s3c_gpio_cfgpin(S5PV310_GPA0(6), S3C_GPIO_SFN(3));
-       s3c_gpio_setpull(S5PV310_GPA0(6), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PV310_GPA0(7), S3C_GPIO_SFN(3));
-       s3c_gpio_setpull(S5PV310_GPA0(7), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgall_range(S5PV310_GPA0(6), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
 }
diff --git a/arch/arm/mach-s5pv310/setup-i2c3.c b/arch/arm/mach-s5pv310/setup-i2c3.c
new file mode 100644 (file)
index 0000000..180f153
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C3 GPIO configuration.
+ *
+ * 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c3_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(S5PV310_GPA1(2), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-i2c4.c b/arch/arm/mach-s5pv310/setup-i2c4.c
new file mode 100644 (file)
index 0000000..909e8df
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c4.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C4 GPIO configuration.
+ *
+ * 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c4_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(S5PV310_GPB(2), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-i2c5.c b/arch/arm/mach-s5pv310/setup-i2c5.c
new file mode 100644 (file)
index 0000000..5d0fa4a
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c5.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C5 GPIO configuration.
+ *
+ * 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c5_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(S5PV310_GPB(6), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-i2c6.c b/arch/arm/mach-s5pv310/setup-i2c6.c
new file mode 100644 (file)
index 0000000..34aafab
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c6.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C6 GPIO configuration.
+ *
+ * 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c6_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(S5PV310_GPC1(3), 2,
+                             S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-i2c7.c b/arch/arm/mach-s5pv310/setup-i2c7.c
new file mode 100644 (file)
index 0000000..9b25b8d
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-s5pv310/setup-i2c7.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C7 GPIO configuration.
+ *
+ * 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.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c7_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgall_range(S5PV310_GPD0(2), 2,
+                             S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv310/setup-sdhci-gpio.c b/arch/arm/mach-s5pv310/setup-sdhci-gpio.c
new file mode 100644 (file)
index 0000000..86d38cc
--- /dev/null
@@ -0,0 +1,152 @@
+/* linux/arch/arm/mach-s5pv310/setup-sdhci-gpio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5PV310 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+       unsigned int gpio;
+
+       /* Set all the necessary GPK0[0:1] pins to special-function 2 */
+       for (gpio = S5PV310_GPK0(0); gpio < S5PV310_GPK0(2); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       switch (width) {
+       case 8:
+               for (gpio = S5PV310_GPK1(3); gpio <= S5PV310_GPK1(6); gpio++) {
+                       /* Data pin GPK1[3:6] to special-funtion 3 */
+                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+               }
+       case 4:
+               for (gpio = S5PV310_GPK0(3); gpio <= S5PV310_GPK0(6); gpio++) {
+                       /* Data pin GPK0[3:6] to special-funtion 2 */
+                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+               }
+       default:
+               break;
+       }
+
+       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+               s3c_gpio_cfgpin(S5PV310_GPK0(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(S5PV310_GPK0(2), S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+}
+
+void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+       unsigned int gpio;
+
+       /* Set all the necessary GPK1[0:1] pins to special-function 2 */
+       for (gpio = S5PV310_GPK1(0); gpio < S5PV310_GPK1(2); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       for (gpio = S5PV310_GPK1(3); gpio <= S5PV310_GPK1(6); gpio++) {
+               /* Data pin GPK1[3:6] to special-function 2 */
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+               s3c_gpio_cfgpin(S5PV310_GPK1(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(S5PV310_GPK1(2), S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+}
+
+void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+       unsigned int gpio;
+
+       /* Set all the necessary GPK2[0:1] pins to special-function 2 */
+       for (gpio = S5PV310_GPK2(0); gpio < S5PV310_GPK2(2); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       switch (width) {
+       case 8:
+               for (gpio = S5PV310_GPK3(3); gpio <= S5PV310_GPK3(6); gpio++) {
+                       /* Data pin GPK3[3:6] to special-function 3 */
+                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+               }
+       case 4:
+               for (gpio = S5PV310_GPK2(3); gpio <= S5PV310_GPK2(6); gpio++) {
+                       /* Data pin GPK2[3:6] to special-function 2 */
+                       s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+                       s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+                       s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+               }
+       default:
+               break;
+       }
+
+       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+               s3c_gpio_cfgpin(S5PV310_GPK2(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(S5PV310_GPK2(2), S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+}
+
+void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
+{
+       struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+       unsigned int gpio;
+
+       /* Set all the necessary GPK3[0:1] pins to special-function 2 */
+       for (gpio = S5PV310_GPK3(0); gpio < S5PV310_GPK3(2); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       for (gpio = S5PV310_GPK3(3); gpio <= S5PV310_GPK3(6); gpio++) {
+               /* Data pin GPK3[3:6] to special-function 2 */
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+
+       if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+               s3c_gpio_cfgpin(S5PV310_GPK3(2), S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(S5PV310_GPK3(2), S3C_GPIO_PULL_UP);
+               s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+       }
+}
diff --git a/arch/arm/mach-s5pv310/setup-sdhci.c b/arch/arm/mach-s5pv310/setup-sdhci.c
new file mode 100644 (file)
index 0000000..db8358f
--- /dev/null
@@ -0,0 +1,69 @@
+/* linux/arch/arm/mach-s5pv310/setup-sdhci.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5PV310 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * 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 <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s5pv310_hsmmc_clksrcs[4] = {
+       [0] = NULL,
+       [1] = NULL,
+       [2] = "sclk_mmc",       /* mmc_bus */
+       [3] = NULL,
+};
+
+void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev, void __iomem *r,
+                                 struct mmc_ios *ios, struct mmc_card *card)
+{
+       u32 ctrl2, ctrl3;
+
+       /* don't need to alter anything acording to card-type */
+
+       ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+
+       /* select base clock source to HCLK */
+
+       ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+
+       /*
+        * clear async mode, enable conflict mask, rx feedback ctrl, SD
+        * clk hold and no use debounce count
+        */
+
+       ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+                 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+                 S3C_SDHCI_CTRL2_ENFBCLKRX |
+                 S3C_SDHCI_CTRL2_DFCNT_NONE |
+                 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+       /* Tx and Rx feedback clock delay control */
+
+       if (ios->clock < 25 * 1000000)
+               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+                        S3C_SDHCI_CTRL3_FCSEL2 |
+                        S3C_SDHCI_CTRL3_FCSEL1 |
+                        S3C_SDHCI_CTRL3_FCSEL0);
+       else
+               ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+       writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+       writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
index c0a13ef5436f52891c989773228ffb566eb3badd..96f7dc103b5987c586a663a9e19729027f832e70 100644 (file)
@@ -184,16 +184,15 @@ static int sa1100_target(struct cpufreq_policy *policy,
 {
        unsigned int cur = sa11x0_getspeed(0);
        unsigned int new_ppcr;
-
        struct cpufreq_freqs freqs;
+
+       new_ppcr = sa11x0_freq_to_ppcr(target_freq);
        switch(relation){
        case CPUFREQ_RELATION_L:
-               new_ppcr = sa11x0_freq_to_ppcr(target_freq);
                if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max)
                        new_ppcr--;
                break;
        case CPUFREQ_RELATION_H:
-               new_ppcr = sa11x0_freq_to_ppcr(target_freq);
                if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) &&
                    (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min))
                        new_ppcr--;
index 54b479c35ee01d2db0f2f5c75f9786f329293146..51dcd59eda6a1aeb965d02b5b94bf66e8737e2ff 100644 (file)
@@ -116,4 +116,6 @@ endmenu
 config SH_CLK_CPG
        bool
 
+source "drivers/sh/Kconfig"
+
 endif
index 22a2b44ddb7bf14218d70db85ea732938fa09d54..d3260542b943df9a4743b7ba5489f3a0d5733780 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
-#include <linux/mmc/host.h>
 #include <linux/mmc/sh_mmcif.h>
 #include <linux/i2c.h>
 #include <linux/i2c/tsc2007.h>
 #include <linux/input/sh_keysc.h>
 #include <linux/usb/r8a66597.h>
 
+#include <media/sh_mobile_ceu.h>
+#include <media/sh_mobile_csi2.h>
+#include <media/soc_camera.h>
+
 #include <sound/sh_fsi.h>
 
 #include <video/sh_mobile_hdmi.h>
@@ -160,11 +163,13 @@ static struct mtd_partition nor_flash_partitions[] = {
                .name           = "loader",
                .offset         = 0x00000000,
                .size           = 512 * 1024,
+               .mask_flags     = MTD_WRITEABLE,
        },
        {
                .name           = "bootenv",
                .offset         = MTDPART_OFS_APPEND,
                .size           = 512 * 1024,
+               .mask_flags     = MTD_WRITEABLE,
        },
        {
                .name           = "kernel_ro",
@@ -250,7 +255,7 @@ static int slot_cn7_get_cd(struct platform_device *pdev)
 /* SH_MMCIF */
 static struct resource sh_mmcif_resources[] = {
        [0] = {
-               .name   = "SH_MMCIF",
+               .name   = "MMCIF",
                .start  = 0xE6BD0000,
                .end    = 0xE6BD00FF,
                .flags  = IORESOURCE_MEM,
@@ -390,10 +395,40 @@ static struct platform_device usb1_host_device = {
        .resource       = usb1_host_resources,
 };
 
+const static struct fb_videomode ap4evb_lcdc_modes[] = {
+       {
+#ifdef CONFIG_AP4EVB_QHD
+               .name           = "R63302(QHD)",
+               .xres           = 544,
+               .yres           = 961,
+               .left_margin    = 72,
+               .right_margin   = 600,
+               .hsync_len      = 16,
+               .upper_margin   = 8,
+               .lower_margin   = 8,
+               .vsync_len      = 2,
+               .sync           = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+#else
+               .name           = "WVGA Panel",
+               .xres           = 800,
+               .yres           = 480,
+               .left_margin    = 220,
+               .right_margin   = 110,
+               .hsync_len      = 70,
+               .upper_margin   = 20,
+               .lower_margin   = 5,
+               .vsync_len      = 5,
+               .sync           = 0,
+#endif
+       },
+};
+
 static struct sh_mobile_lcdc_info lcdc_info = {
        .ch[0] = {
                .chan = LCDC_CHAN_MAINLCD,
                .bpp = 16,
+               .lcd_cfg = ap4evb_lcdc_modes,
+               .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
        }
 };
 
@@ -532,26 +567,41 @@ static struct platform_device *qhd_devices[] __initdata = {
 
 /* FSI */
 #define IRQ_FSI                evt2irq(0x1840)
-#define FSIACKCR       0xE6150018
-static void fsiackcr_init(struct clk *clk)
+
+static int fsi_set_rate(int is_porta, int rate)
 {
-       u32 status = __raw_readl(clk->enable_reg);
+       struct clk *fsib_clk;
+       struct clk *fdiv_clk = &sh7372_fsidivb_clk;
+       int ret;
 
-       /* use external clock */
-       status &= ~0x000000ff;
-       status |= 0x00000080;
-       __raw_writel(status, clk->enable_reg);
-}
+       /* set_rate is not needed if port A */
+       if (is_porta)
+               return 0;
+
+       fsib_clk = clk_get(NULL, "fsib_clk");
+       if (IS_ERR(fsib_clk))
+               return -EINVAL;
+
+       switch (rate) {
+       case 44100:
+               clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000));
+               ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
+               break;
+       case 48000:
+               clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000));
+               clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000));
+               ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
+               break;
+       default:
+               pr_err("unsupported rate in FSI2 port B\n");
+               ret = -EINVAL;
+               break;
+       }
 
-static struct clk_ops fsiackcr_clk_ops = {
-       .init = fsiackcr_init,
-};
+       clk_put(fsib_clk);
 
-static struct clk fsiackcr_clk = {
-       .ops            = &fsiackcr_clk_ops,
-       .enable_reg     = (void __iomem *)FSIACKCR,
-       .rate           = 0, /* unknown */
-};
+       return ret;
+}
 
 static struct sh_fsi_platform_info fsi_info = {
        .porta_flags = SH_FSI_BRS_INV |
@@ -559,6 +609,12 @@ static struct sh_fsi_platform_info fsi_info = {
                       SH_FSI_IN_SLAVE_MODE |
                       SH_FSI_OFMT(PCM) |
                       SH_FSI_IFMT(PCM),
+
+       .portb_flags = SH_FSI_BRS_INV |
+                      SH_FSI_BRM_INV |
+                      SH_FSI_LRS_INV |
+                      SH_FSI_OFMT(SPDIF),
+       .set_rate = fsi_set_rate,
 };
 
 static struct resource fsi_resources[] = {
@@ -592,26 +648,6 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
                .interface_type = RGB24,
                .clock_divider = 1,
                .flags = LCDC_FLAGS_DWPOL,
-               .lcd_cfg = {
-                       .name = "HDMI",
-                       /* So far only 720p is supported */
-                       .xres = 1280,
-                       .yres = 720,
-                       /*
-                        * If left and right margins are not multiples of 8,
-                        * LDHAJR will be adjusted accordingly by the LCDC
-                        * driver. Until we start using EDID, these values
-                        * might have to be adjusted for different monitors.
-                        */
-                       .left_margin = 200,
-                       .right_margin = 88,
-                       .hsync_len = 48,
-                       .upper_margin = 20,
-                       .lower_margin = 5,
-                       .vsync_len = 5,
-                       .pixclock = 13468,
-                       .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
-               },
        }
 };
 
@@ -623,7 +659,7 @@ static struct resource lcdc1_resources[] = {
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = intcs_evt2irq(0x17a0),
+               .start  = intcs_evt2irq(0x1780),
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -642,6 +678,7 @@ static struct platform_device lcdc1_device = {
 static struct sh_mobile_hdmi_info hdmi_info = {
        .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
        .lcd_dev = &lcdc1_device.dev,
+       .flags = HDMI_SND_SRC_SPDIF,
 };
 
 static struct resource hdmi_resources[] = {
@@ -704,6 +741,95 @@ static struct platform_device leds_device = {
        },
 };
 
+static struct i2c_board_info imx074_info = {
+       I2C_BOARD_INFO("imx074", 0x1a),
+};
+
+struct soc_camera_link imx074_link = {
+       .bus_id         = 0,
+       .board_info     = &imx074_info,
+       .i2c_adapter_id = 0,
+       .module_name    = "imx074",
+};
+
+static struct platform_device ap4evb_camera = {
+       .name   = "soc-camera-pdrv",
+       .id     = 0,
+       .dev    = {
+               .platform_data = &imx074_link,
+       },
+};
+
+static struct sh_csi2_client_config csi2_clients[] = {
+       {
+               .phy            = SH_CSI2_PHY_MAIN,
+               .lanes          = 3,
+               .channel        = 0,
+               .pdev           = &ap4evb_camera,
+       },
+};
+
+static struct sh_csi2_pdata csi2_info = {
+       .type           = SH_CSI2C,
+       .clients        = csi2_clients,
+       .num_clients    = ARRAY_SIZE(csi2_clients),
+       .flags          = SH_CSI2_ECC | SH_CSI2_CRC,
+};
+
+static struct resource csi2_resources[] = {
+       [0] = {
+               .name   = "CSI2",
+               .start  = 0xffc90000,
+               .end    = 0xffc90fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = intcs_evt2irq(0x17a0),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device csi2_device = {
+       .name   = "sh-mobile-csi2",
+       .id     = 0,
+       .num_resources  = ARRAY_SIZE(csi2_resources),
+       .resource       = csi2_resources,
+       .dev    = {
+               .platform_data = &csi2_info,
+       },
+};
+
+static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
+       .flags = SH_CEU_FLAG_USE_8BIT_BUS,
+       .csi2_dev = &csi2_device.dev,
+};
+
+static struct resource ceu_resources[] = {
+       [0] = {
+               .name   = "CEU",
+               .start  = 0xfe910000,
+               .end    = 0xfe91009f,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = intcs_evt2irq(0x880),
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               /* place holder for contiguous memory */
+       },
+};
+
+static struct platform_device ceu_device = {
+       .name           = "sh_mobile_ceu",
+       .id             = 0, /* "ceu0" clock */
+       .num_resources  = ARRAY_SIZE(ceu_resources),
+       .resource       = ceu_resources,
+       .dev    = {
+               .platform_data  = &sh_mobile_ceu_info,
+       },
+};
+
 static struct platform_device *ap4evb_devices[] __initdata = {
        &leds_device,
        &nor_flash_device,
@@ -716,6 +842,9 @@ static struct platform_device *ap4evb_devices[] __initdata = {
        &lcdc1_device,
        &lcdc_device,
        &hdmi_device,
+       &csi2_device,
+       &ceu_device,
+       &ap4evb_camera,
 };
 
 static int __init hdmi_init_pm_clock(void)
@@ -730,22 +859,22 @@ static int __init hdmi_init_pm_clock(void)
                goto out;
        }
 
-       ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk);
+       ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk);
        if (ret < 0) {
-               pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount);
+               pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, sh7372_pllc2_clk.usecount);
                goto out;
        }
 
-       pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk));
+       pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&sh7372_pllc2_clk));
 
-       rate = clk_round_rate(&pllc2_clk, 594000000);
+       rate = clk_round_rate(&sh7372_pllc2_clk, 594000000);
        if (rate < 0) {
                pr_err("Cannot get suitable rate: %ld\n", rate);
                ret = rate;
                goto out;
        }
 
-       ret = clk_set_rate(&pllc2_clk, rate);
+       ret = clk_set_rate(&sh7372_pllc2_clk, rate);
        if (ret < 0) {
                pr_err("Cannot set rate %ld: %d\n", rate, ret);
                goto out;
@@ -753,7 +882,7 @@ static int __init hdmi_init_pm_clock(void)
 
        pr_debug("PLLC2 set frequency %lu\n", rate);
 
-       ret = clk_set_parent(hdmi_ick, &pllc2_clk);
+       ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
        if (ret < 0) {
                pr_err("Cannot set HDMI parent: %d\n", ret);
                goto out;
@@ -767,11 +896,51 @@ out:
 
 device_initcall(hdmi_init_pm_clock);
 
+#define FSIACK_DUMMY_RATE 48000
+static int __init fsi_init_pm_clock(void)
+{
+       struct clk *fsia_ick;
+       int ret;
+
+       /*
+        * FSIACK is connected to AK4642,
+        * and the rate is depend on playing sound rate.
+        * So, set dummy rate (= 48k) here
+        */
+       ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
+       if (ret < 0) {
+               pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
+               return ret;
+       }
+
+       fsia_ick = clk_get(&fsi_device.dev, "icka");
+       if (IS_ERR(fsia_ick)) {
+               ret = PTR_ERR(fsia_ick);
+               pr_err("Cannot get FSI ICK: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
+       if (ret < 0) {
+               pr_err("Cannot set FSI-A parent: %d\n", ret);
+               goto out;
+       }
+
+       ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
+       if (ret < 0)
+               pr_err("Cannot set FSI-A rate: %d\n", ret);
+
+out:
+       clk_put(fsia_ick);
+
+       return ret;
+}
+device_initcall(fsi_init_pm_clock);
+
 /*
  * FIXME !!
  *
  * gpio_no_direction
- * gpio_pull_up
  * are quick_hack.
  *
  * current gpio frame work doesn't have
@@ -783,49 +952,37 @@ static void __init gpio_no_direction(u32 addr)
        __raw_writeb(0x00, addr);
 }
 
-static void __init gpio_pull_up(u32 addr)
-{
-       u8 data = __raw_readb(addr);
-
-       data &= 0x0F;
-       data |= 0xC0;
-       __raw_writeb(data, addr);
-}
-
 /* TouchScreen */
+#ifdef CONFIG_AP4EVB_QHD
+# define GPIO_TSC_IRQ  GPIO_FN_IRQ28_123
+# define GPIO_TSC_PORT GPIO_PORT123
+#else /* WVGA */
+# define GPIO_TSC_IRQ  GPIO_FN_IRQ7_40
+# define GPIO_TSC_PORT GPIO_PORT40
+#endif
+
 #define IRQ28  evt2irq(0x3380) /* IRQ28A */
 #define IRQ7   evt2irq(0x02e0) /* IRQ7A */
 static int ts_get_pendown_state(void)
 {
-       int val1, val2;
+       int val;
 
-       gpio_free(GPIO_FN_IRQ28_123);
-       gpio_free(GPIO_FN_IRQ7_40);
+       gpio_free(GPIO_TSC_IRQ);
 
-       gpio_request(GPIO_PORT123, NULL);
-       gpio_request(GPIO_PORT40, NULL);
+       gpio_request(GPIO_TSC_PORT, NULL);
 
-       gpio_direction_input(GPIO_PORT123);
-       gpio_direction_input(GPIO_PORT40);
+       gpio_direction_input(GPIO_TSC_PORT);
 
-       val1 = gpio_get_value(GPIO_PORT123);
-       val2 = gpio_get_value(GPIO_PORT40);
+       val = gpio_get_value(GPIO_TSC_PORT);
 
-       gpio_request(GPIO_FN_IRQ28_123, NULL);  /* for QHD */
-       gpio_request(GPIO_FN_IRQ7_40, NULL);    /* for WVGA */
+       gpio_request(GPIO_TSC_IRQ, NULL);
 
-       return val1 ^ val2;
+       return !val;
 }
 
-#define PORT40CR       0xE6051028
-#define PORT123CR      0xE605007B
 static int ts_init(void)
 {
-       gpio_request(GPIO_FN_IRQ28_123, NULL);  /* for QHD */
-       gpio_request(GPIO_FN_IRQ7_40, NULL);    /* for WVGA */
-
-       gpio_pull_up(PORT40CR);
-       gpio_pull_up(PORT123CR);
+       gpio_request(GPIO_TSC_IRQ, NULL);
 
        return 0;
 }
@@ -880,6 +1037,7 @@ static void __init ap4evb_map_io(void)
 
 #define GPIO_PORT9CR   0xE6051009
 #define GPIO_PORT10CR  0xE605100A
+#define USCCR1         0xE6058144
 static void __init ap4evb_init(void)
 {
        u32 srcr4;
@@ -950,7 +1108,7 @@ static void __init ap4evb_init(void)
        /* setup USB phy */
        __raw_writew(0x8a0a, 0xE6058130);       /* USBCR2 */
 
-       /* enable FSI2 */
+       /* enable FSI2 port A (ak4643) */
        gpio_request(GPIO_FN_FSIAIBT,   NULL);
        gpio_request(GPIO_FN_FSIAILR,   NULL);
        gpio_request(GPIO_FN_FSIAISLD,  NULL);
@@ -967,6 +1125,10 @@ static void __init ap4evb_init(void)
        gpio_request(GPIO_PORT41, NULL);
        gpio_direction_input(GPIO_PORT41);
 
+       /* setup FSI2 port B (HDMI) */
+       gpio_request(GPIO_FN_FSIBCK, NULL);
+       __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */
+
        /* set SPU2 clock to 119.6 MHz */
        clk = clk_get(NULL, "spu_clk");
        if (!IS_ERR(clk)) {
@@ -974,14 +1136,6 @@ static void __init ap4evb_init(void)
                clk_put(clk);
        }
 
-       /* change parent of FSI A */
-       clk = clk_get(NULL, "fsia_clk");
-       if (!IS_ERR(clk)) {
-               clk_register(&fsiackcr_clk);
-               clk_set_parent(clk, &fsiackcr_clk);
-               clk_put(clk);
-       }
-
        /*
         * set irq priority, to avoid sound chopping
         * when NFS rootfs is used
@@ -996,8 +1150,10 @@ static void __init ap4evb_init(void)
                                ARRAY_SIZE(i2c1_devices));
 
 #ifdef CONFIG_AP4EVB_QHD
+
        /*
-        * QHD
+        * For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and
+        * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON.
         */
 
        /* enable KEYSC */
@@ -1023,17 +1179,6 @@ static void __init ap4evb_init(void)
        lcdc_info.ch[0].interface_type          = RGB24;
        lcdc_info.ch[0].clock_divider           = 1;
        lcdc_info.ch[0].flags                   = LCDC_FLAGS_DWPOL;
-       lcdc_info.ch[0].lcd_cfg.name            = "R63302(QHD)";
-       lcdc_info.ch[0].lcd_cfg.xres            = 544;
-       lcdc_info.ch[0].lcd_cfg.yres            = 961;
-       lcdc_info.ch[0].lcd_cfg.left_margin     = 72;
-       lcdc_info.ch[0].lcd_cfg.right_margin    = 600;
-       lcdc_info.ch[0].lcd_cfg.hsync_len       = 16;
-       lcdc_info.ch[0].lcd_cfg.upper_margin    = 8;
-       lcdc_info.ch[0].lcd_cfg.lower_margin    = 8;
-       lcdc_info.ch[0].lcd_cfg.vsync_len       = 2;
-       lcdc_info.ch[0].lcd_cfg.sync            = FB_SYNC_VERT_HIGH_ACT |
-                                                 FB_SYNC_HOR_HIGH_ACT;
        lcdc_info.ch[0].lcd_size_cfg.width      = 44;
        lcdc_info.ch[0].lcd_size_cfg.height     = 79;
 
@@ -1041,8 +1186,10 @@ static void __init ap4evb_init(void)
 
 #else
        /*
-        * WVGA
+        * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and
+        * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF.
         */
+
        gpio_request(GPIO_FN_LCDD17,   NULL);
        gpio_request(GPIO_FN_LCDD16,   NULL);
        gpio_request(GPIO_FN_LCDD15,   NULL);
@@ -1074,16 +1221,6 @@ static void __init ap4evb_init(void)
        lcdc_info.ch[0].interface_type          = RGB18;
        lcdc_info.ch[0].clock_divider           = 2;
        lcdc_info.ch[0].flags                   = 0;
-       lcdc_info.ch[0].lcd_cfg.name            = "WVGA Panel";
-       lcdc_info.ch[0].lcd_cfg.xres            = 800;
-       lcdc_info.ch[0].lcd_cfg.yres            = 480;
-       lcdc_info.ch[0].lcd_cfg.left_margin     = 220;
-       lcdc_info.ch[0].lcd_cfg.right_margin    = 110;
-       lcdc_info.ch[0].lcd_cfg.hsync_len       = 70;
-       lcdc_info.ch[0].lcd_cfg.upper_margin    = 20;
-       lcdc_info.ch[0].lcd_cfg.lower_margin    = 5;
-       lcdc_info.ch[0].lcd_cfg.vsync_len       = 5;
-       lcdc_info.ch[0].lcd_cfg.sync            = 0;
        lcdc_info.ch[0].lcd_size_cfg.width      = 152;
        lcdc_info.ch[0].lcd_size_cfg.height     = 91;
 
@@ -1094,6 +1231,23 @@ static void __init ap4evb_init(void)
        i2c_register_board_info(0, &tsc_device, 1);
 #endif /* CONFIG_AP4EVB_QHD */
 
+       /* CEU */
+
+       /*
+        * TODO: reserve memory for V4L2 DMA buffers, when a suitable API
+        * becomes available
+        */
+
+       /* MIPI-CSI stuff */
+       gpio_request(GPIO_FN_VIO_CKO, NULL);
+
+       clk = clk_get(NULL, "vck1_clk");
+       if (!IS_ERR(clk)) {
+               clk_set_rate(clk, clk_round_rate(clk, 13000000));
+               clk_enable(clk);
+               clk_put(clk);
+       }
+
        sh7372_add_standard_devices();
 
        /* HDMI */
@@ -1116,7 +1270,7 @@ static void __init ap4evb_timer_init(void)
        shmobile_timer.init();
 
        /* External clock source */
-       clk_set_rate(&dv_clki_clk, 27000000);
+       clk_set_rate(&sh7372_dv_clki_clk, 27000000);
 }
 
 static struct sys_timer ap4evb_timer = {
index b6454c9f2abb07b48b01899b87fdb281153c9b2b..9f78729098f2721bdd3b46c866ea6fed1a7e08e0 100644 (file)
@@ -321,7 +321,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */
        CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */
        CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */
-       CLKDEV_CON_ID("cmt1", &mstp_clks[SYMSTP229]), /* CMT10 */
+       CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[SYMSTP229]), /* CMT10 */
        CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */
        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */
        CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */
index 759468992ad287ff3f40b2f2e92e19d99734c94a..7db31e6c6bf2085908cb66ce669238488c5aa444 100644 (file)
 #define SMSTPCR3       0xe615013c
 #define SMSTPCR4       0xe6150140
 
+#define FSIDIVA                0xFE1F8000
+#define FSIDIVB                0xFE1F8008
+
 /* Platforms must set frequency on their DV_CLKI pin */
-struct clk dv_clki_clk = {
+struct clk sh7372_dv_clki_clk = {
 };
 
 /* Fixed 32 KHz root clock from EXTALR pin */
@@ -86,9 +89,9 @@ static struct clk_ops div2_clk_ops = {
 };
 
 /* Divide dv_clki by two */
-struct clk dv_clki_div2_clk = {
+struct clk sh7372_dv_clki_div2_clk = {
        .ops            = &div2_clk_ops,
-       .parent         = &dv_clki_clk,
+       .parent         = &sh7372_dv_clki_clk,
 };
 
 /* Divide extal1 by two */
@@ -150,7 +153,7 @@ static struct clk pllc1_div2_clk = {
 static struct clk *pllc2_parent[] = {
        [0] = &extal1_div2_clk,
        [1] = &extal2_div2_clk,
-       [2] = &dv_clki_div2_clk,
+       [2] = &sh7372_dv_clki_div2_clk,
 };
 
 /* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
@@ -284,27 +287,37 @@ static struct clk_ops pllc2_clk_ops = {
        .set_parent     = pllc2_set_parent,
 };
 
-struct clk pllc2_clk = {
+struct clk sh7372_pllc2_clk = {
        .ops            = &pllc2_clk_ops,
        .parent         = &extal1_div2_clk,
        .freq_table     = pllc2_freq_table,
+       .nr_freqs       = ARRAY_SIZE(pllc2_freq_table) - 1,
        .parent_table   = pllc2_parent,
        .parent_num     = ARRAY_SIZE(pllc2_parent),
 };
 
+/* External input clock (pin name: FSIACK/FSIBCK ) */
+struct clk sh7372_fsiack_clk = {
+};
+
+struct clk sh7372_fsibck_clk = {
+};
+
 static struct clk *main_clks[] = {
-       &dv_clki_clk,
+       &sh7372_dv_clki_clk,
        &r_clk,
        &sh7372_extal1_clk,
        &sh7372_extal2_clk,
-       &dv_clki_div2_clk,
+       &sh7372_dv_clki_div2_clk,
        &extal1_div2_clk,
        &extal2_div2_clk,
        &extal2_div4_clk,
        &pllc0_clk,
        &pllc1_clk,
        &pllc1_div2_clk,
-       &pllc2_clk,
+       &sh7372_pllc2_clk,
+       &sh7372_fsiack_clk,
+       &sh7372_fsibck_clk,
 };
 
 static void div4_kick(struct clk *clk)
@@ -357,7 +370,7 @@ static struct clk div4_clks[DIV4_NR] = {
 };
 
 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
-       DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU,
+       DIV6_SUB, DIV6_SPU,
        DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
        DIV6_NR };
 
@@ -367,8 +380,6 @@ static struct clk div6_clks[DIV6_NR] = {
        [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
        [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
        [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
-       [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0),
-       [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0),
        [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
        [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
        [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
@@ -377,24 +388,137 @@ static struct clk div6_clks[DIV6_NR] = {
        [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
 };
 
-enum { DIV6_HDMI, DIV6_REPARENT_NR };
+enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
 
 /* Indices are important - they are the actual src selecting values */
 static struct clk *hdmi_parent[] = {
        [0] = &pllc1_div2_clk,
-       [1] = &pllc2_clk,
-       [2] = &dv_clki_clk,
+       [1] = &sh7372_pllc2_clk,
+       [2] = &sh7372_dv_clki_clk,
        [3] = NULL,     /* pllc2_div4 not implemented yet */
 };
 
+static struct clk *fsiackcr_parent[] = {
+       [0] = &pllc1_div2_clk,
+       [1] = &sh7372_pllc2_clk,
+       [2] = &sh7372_fsiack_clk, /* external input for FSI A */
+       [3] = NULL,     /* setting prohibited */
+};
+
+static struct clk *fsibckcr_parent[] = {
+       [0] = &pllc1_div2_clk,
+       [1] = &sh7372_pllc2_clk,
+       [2] = &sh7372_fsibck_clk, /* external input for FSI B */
+       [3] = NULL,     /* setting prohibited */
+};
+
 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
        [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
                                      hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
+       [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
+                                     fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
+       [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
+                                     fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
+};
+
+/* FSI DIV */
+static unsigned long fsidiv_recalc(struct clk *clk)
+{
+       unsigned long value;
+
+       value = __raw_readl(clk->mapping->base);
+
+       if ((value & 0x3) != 0x3)
+               return 0;
+
+       value >>= 16;
+       if (value < 2)
+               return 0;
+
+       return clk->parent->rate / value;
+}
+
+static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
+{
+       return clk_rate_div_range_round(clk, 2, 0xffff, rate);
+}
+
+static void fsidiv_disable(struct clk *clk)
+{
+       __raw_writel(0, clk->mapping->base);
+}
+
+static int fsidiv_enable(struct clk *clk)
+{
+       unsigned long value;
+
+       value  = __raw_readl(clk->mapping->base) >> 16;
+       if (value < 2) {
+               fsidiv_disable(clk);
+               return -ENOENT;
+       }
+
+       __raw_writel((value << 16) | 0x3, clk->mapping->base);
+
+       return 0;
+}
+
+static int fsidiv_set_rate(struct clk *clk,
+                          unsigned long rate, int algo_id)
+{
+       int idx;
+
+       if (clk->parent->rate == rate) {
+               fsidiv_disable(clk);
+               return 0;
+       }
+
+       idx = (clk->parent->rate / rate) & 0xffff;
+       if (idx < 2)
+               return -ENOENT;
+
+       __raw_writel(idx << 16, clk->mapping->base);
+       return fsidiv_enable(clk);
+}
+
+static struct clk_ops fsidiv_clk_ops = {
+       .recalc         = fsidiv_recalc,
+       .round_rate     = fsidiv_round_rate,
+       .set_rate       = fsidiv_set_rate,
+       .enable         = fsidiv_enable,
+       .disable        = fsidiv_disable,
+};
+
+static struct clk_mapping sh7372_fsidiva_clk_mapping = {
+       .phys   = FSIDIVA,
+       .len    = 8,
+};
+
+struct clk sh7372_fsidiva_clk = {
+       .ops            = &fsidiv_clk_ops,
+       .parent         = &div6_reparent_clks[DIV6_FSIA], /* late install */
+       .mapping        = &sh7372_fsidiva_clk_mapping,
+};
+
+static struct clk_mapping sh7372_fsidivb_clk_mapping = {
+       .phys   = FSIDIVB,
+       .len    = 8,
+};
+
+struct clk sh7372_fsidivb_clk = {
+       .ops            = &fsidiv_clk_ops,
+       .parent         = &div6_reparent_clks[DIV6_FSIB],  /* late install */
+       .mapping        = &sh7372_fsidivb_clk_mapping,
+};
+
+static struct clk *late_main_clks[] = {
+       &sh7372_fsidiva_clk,
+       &sh7372_fsidivb_clk,
 };
 
 enum { MSTP001,
        MSTP131, MSTP130,
-       MSTP129, MSTP128, MSTP127, MSTP126,
+       MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
        MSTP118, MSTP117, MSTP116,
        MSTP106, MSTP101, MSTP100,
        MSTP223,
@@ -414,6 +538,7 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
        [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
        [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
+       [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
        [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
        [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
        [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
@@ -429,7 +554,7 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
        [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
        [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
-       [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */
+       [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
        [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
        [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
        [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
@@ -445,10 +570,11 @@ static struct clk mstp_clks[MSTP_NR] = {
 
 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
 #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
 
 static struct clk_lookup lookups[] = {
        /* main clocks */
-       CLKDEV_CON_ID("dv_clki_div2_clk", &dv_clki_div2_clk),
+       CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
        CLKDEV_CON_ID("r_clk", &r_clk),
        CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
        CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
@@ -458,7 +584,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
        CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
        CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
-       CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
+       CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
 
        /* DIV4 clocks */
        CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
@@ -483,8 +609,8 @@ static struct clk_lookup lookups[] = {
        CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
        CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
        CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
-       CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]),
-       CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]),
+       CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]),
+       CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]),
        CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
        CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
        CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
@@ -501,6 +627,8 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
        CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
        CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
+       CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
+       CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
        CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
        CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
        CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
@@ -516,7 +644,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
        CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
        CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
-       CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
+       CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
        CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
        CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
@@ -531,7 +659,10 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
        CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
        CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
-       {.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]},
+
+       CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
+       CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
+       CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
 };
 
 void __init sh7372_clock_init(void)
@@ -548,11 +679,14 @@ void __init sh7372_clock_init(void)
                ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 
        if (!ret)
-               ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_NR);
+               ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
 
        if (!ret)
                ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
+       for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+               ret = clk_register(late_main_clks[k]);
+
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        if (!ret)
index e007c28cf0a8c973320e4676c05cb0b33907bb5b..f91395aeb9abadd50b13c037670d23260e841920 100644 (file)
@@ -333,7 +333,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
        CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
        CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
-       CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
+       CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
        CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */
        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
        CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */
index 5bc6bd444d7236016eac8c004f764da16a481380..2b1bb9e43ddadc8b83505b021c5ca7ae4f4704c5 100644 (file)
@@ -35,12 +35,12 @@ static inline int gpio_cansleep(unsigned gpio)
 
 static inline int gpio_to_irq(unsigned gpio)
 {
-       return -ENOSYS;
+       return __gpio_to_irq(gpio);
 }
 
 static inline int irq_to_gpio(unsigned int irq)
 {
-       return -EINVAL;
+       return -ENOSYS;
 }
 
 #endif /* CONFIG_GPIOLIB */
index 33e9700ded7e693fe4f3560dea4c1c50bcb43e98..e4f9004e710382574fcf5e23cb67339fa0f53148 100644 (file)
@@ -457,8 +457,14 @@ enum {
        SHDMA_SLAVE_SDHI2_TX,
 };
 
-extern struct clk dv_clki_clk;
-extern struct clk dv_clki_div2_clk;
-extern struct clk pllc2_clk;
+extern struct clk sh7372_extal1_clk;
+extern struct clk sh7372_extal2_clk;
+extern struct clk sh7372_dv_clki_clk;
+extern struct clk sh7372_dv_clki_div2_clk;
+extern struct clk sh7372_pllc2_clk;
+extern struct clk sh7372_fsiack_clk;
+extern struct clk sh7372_fsibck_clk;
+extern struct clk sh7372_fsidiva_clk;
+extern struct clk sh7372_fsidivb_clk;
 
 #endif /* __ASM_SH7372_H__ */
index e3551b56cd03f489cd6196887ac2edb8fff3db1c..30b2f400666af11a0097eb593b949affc818c547 100644 (file)
@@ -98,7 +98,7 @@ static struct intc_vect intca_vectors[] __initdata = {
        INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
        INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220),
        INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260),
-       INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0),
+       INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ21A, 0x32a0),
        INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0),
        INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320),
        INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360),
@@ -369,9 +369,13 @@ enum {
        INTCS,
 
        /* interrupt sources INTCS */
+
+       /* IRQ0S - IRQ31S */
        VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
        RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
        CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2,
+       /* MFI */
+       /* BBIF2 */
        VPU,
        TSIF1,
        _3DG_SGX530,
@@ -379,13 +383,17 @@ enum {
        IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
        IPMMU_IPMMUR, IPMMU_IPMMUR2,
        RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
+       /* KEYSC */
+       /* TTI20 */
        MSIOF,
        IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
        TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
        CMT0,
        TSIF0,
+       /* CMT2 */
        LMB,
        CTI,
+       /* RWDT0 */
        ICB,
        JPU_JPEG,
        LCDC,
@@ -397,11 +405,17 @@ enum {
        CSIRX,
        DSITX_DSITX0,
        DSITX_DSITX1,
+       /* SPU2 */
+       /* FSI */
+       /* FMSI */
+       /* HDMI */
        TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2,
        CMT4,
        DSITX1_DSITX1_0,
        DSITX1_DSITX1_1,
+       /* MFIS2 */
        CPORTS2R,
+       /* CEC */
        JPU6E,
 
        /* interrupt groups INTCS */
@@ -410,12 +424,15 @@ enum {
 };
 
 static struct intc_vect intcs_vectors[] = {
+       /* IRQ0S - IRQ31S */
        INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720),
        INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760),
        INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
        INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
        INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0),
        INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0),
+       /* MFI */
+       /* BBIF2 */
        INTCS_VECT(VPU, 0x980),
        INTCS_VECT(TSIF1, 0x9a0),
        INTCS_VECT(_3DG_SGX530, 0x9e0),
@@ -425,14 +442,19 @@ static struct intc_vect intcs_vectors[] = {
        INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20),
        INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
        INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
+       /* KEYSC */
+       /* TTI20 */
+       INTCS_VECT(MSIOF, 0x0d20),
        INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
        INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
        INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
        INTCS_VECT(TMU_TUNI2, 0xec0),
        INTCS_VECT(CMT0, 0xf00),
        INTCS_VECT(TSIF0, 0xf20),
+       /* CMT2 */
        INTCS_VECT(LMB, 0xf60),
        INTCS_VECT(CTI, 0x400),
+       /* RWDT0 */
        INTCS_VECT(ICB, 0x480),
        INTCS_VECT(JPU_JPEG, 0x560),
        INTCS_VECT(LCDC, 0x580),
@@ -446,12 +468,18 @@ static struct intc_vect intcs_vectors[] = {
        INTCS_VECT(CSIRX, 0x17a0),
        INTCS_VECT(DSITX_DSITX0, 0x17c0),
        INTCS_VECT(DSITX_DSITX1, 0x17e0),
+       /* SPU2 */
+       /* FSI */
+       /* FMSI */
+       /* HDMI */
        INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920),
        INTCS_VECT(TMU1_TUNI2, 0x1940),
        INTCS_VECT(CMT4, 0x1980),
        INTCS_VECT(DSITX1_DSITX1_0, 0x19a0),
        INTCS_VECT(DSITX1_DSITX1_1, 0x19c0),
+       /* MFIS2 */
        INTCS_VECT(CPORTS2R, 0x1a20),
+       /* CEC */
        INTCS_VECT(JPU6E, 0x1a80),
 
        INTC_VECT(INTCS, 0xf80),
index ec420353f8e3b3289b7d6cfa313c7089a9f8b1eb..9c265dae138a31c245c63fbaf2f87e3f5f147dbb 100644 (file)
@@ -166,12 +166,12 @@ enum {
        MSIOF2_TSYNC_MARK,      MSIOF2_TSCK_MARK,       MSIOF2_RXD_MARK,
        MSIOF2_TXD_MARK,
 
-       /* MSIOF3 */
+       /* BBIF1 */
        BBIF1_RXD_MARK,         BBIF1_TSYNC_MARK,       BBIF1_TSCK_MARK,
        BBIF1_TXD_MARK,         BBIF1_RSCK_MARK,        BBIF1_RSYNC_MARK,
        BBIF1_FLOW_MARK,        BB_RX_FLOW_N_MARK,
 
-       /* MSIOF4 */
+       /* BBIF2 */
        BBIF2_TSCK1_MARK,       BBIF2_TSYNC1_MARK,
        BBIF2_TXD1_MARK,        BBIF2_RXD_MARK,
 
@@ -976,12 +976,12 @@ static struct pinmux_gpio pinmux_gpios[] = {
        GPIO_FN(MSIOF2_TSYNC),  GPIO_FN(MSIOF2_TSCK),   GPIO_FN(MSIOF2_RXD),
        GPIO_FN(MSIOF2_TXD),
 
-       /* MSIOF3 */
+       /* BBIF1 */
        GPIO_FN(BBIF1_RXD),     GPIO_FN(BBIF1_TSYNC),   GPIO_FN(BBIF1_TSCK),
        GPIO_FN(BBIF1_TXD),     GPIO_FN(BBIF1_RSCK),    GPIO_FN(BBIF1_RSYNC),
        GPIO_FN(BBIF1_FLOW),    GPIO_FN(BB_RX_FLOW_N),
 
-       /* MSIOF4 */
+       /* BBIF2 */
        GPIO_FN(BBIF2_TSCK1),   GPIO_FN(BBIF2_TSYNC1),
        GPIO_FN(BBIF2_TXD1),    GPIO_FN(BBIF2_RXD),
 
index 3148c11a550e2fa6e28641920aab5a4930b0fe04..003008c18360eb2fcc367864c3699d6d8aec4796 100644 (file)
@@ -154,7 +154,6 @@ static struct sh_timer_config cmt10_platform_data = {
        .name = "CMT10",
        .channel_offset = 0x10,
        .timer_bit = 0,
-       .clk = "r_clk",
        .clockevent_rating = 125,
        .clocksource_rating = 125,
 };
index e26686c9d0b67b61fff64eabcecce68f0d185ea1..564a6d0be473b738d149f56bdfd775563301016f 100644 (file)
@@ -158,7 +158,6 @@ static struct sh_timer_config cmt10_platform_data = {
        .name = "CMT10",
        .channel_offset = 0x10,
        .timer_bit = 0,
-       .clk = "cmt1",
        .clockevent_rating = 125,
        .clocksource_rating = 125,
 };
@@ -186,6 +185,67 @@ static struct platform_device cmt10_device = {
        .num_resources  = ARRAY_SIZE(cmt10_resources),
 };
 
+/* TMU */
+static struct sh_timer_config tmu00_platform_data = {
+       .name = "TMU00",
+       .channel_offset = 0x4,
+       .timer_bit = 0,
+       .clockevent_rating = 200,
+};
+
+static struct resource tmu00_resources[] = {
+       [0] = {
+               .name   = "TMU00",
+               .start  = 0xfff60008,
+               .end    = 0xfff60013,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = intcs_evt2irq(0xe80), /* TMU_TUNI0 */
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device tmu00_device = {
+       .name           = "sh_tmu",
+       .id             = 0,
+       .dev = {
+               .platform_data  = &tmu00_platform_data,
+       },
+       .resource       = tmu00_resources,
+       .num_resources  = ARRAY_SIZE(tmu00_resources),
+};
+
+static struct sh_timer_config tmu01_platform_data = {
+       .name = "TMU01",
+       .channel_offset = 0x10,
+       .timer_bit = 1,
+       .clocksource_rating = 200,
+};
+
+static struct resource tmu01_resources[] = {
+       [0] = {
+               .name   = "TMU01",
+               .start  = 0xfff60014,
+               .end    = 0xfff6001f,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = intcs_evt2irq(0xea0), /* TMU_TUNI1 */
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device tmu01_device = {
+       .name           = "sh_tmu",
+       .id             = 1,
+       .dev = {
+               .platform_data  = &tmu01_platform_data,
+       },
+       .resource       = tmu01_resources,
+       .num_resources  = ARRAY_SIZE(tmu01_resources),
+};
+
 /* I2C */
 static struct resource iic0_resources[] = {
        [0] = {
@@ -419,14 +479,14 @@ static struct resource sh7372_dmae0_resources[] = {
        },
        {
                /* DMA error IRQ */
-               .start  = 246,
-               .end    = 246,
+               .start  = evt2irq(0x20c0),
+               .end    = evt2irq(0x20c0),
                .flags  = IORESOURCE_IRQ,
        },
        {
                /* IRQ for channels 0-5 */
-               .start  = 240,
-               .end    = 245,
+               .start  = evt2irq(0x2000),
+               .end    = evt2irq(0x20a0),
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -447,14 +507,14 @@ static struct resource sh7372_dmae1_resources[] = {
        },
        {
                /* DMA error IRQ */
-               .start  = 254,
-               .end    = 254,
+               .start  = evt2irq(0x21c0),
+               .end    = evt2irq(0x21c0),
                .flags  = IORESOURCE_IRQ,
        },
        {
                /* IRQ for channels 0-5 */
-               .start  = 248,
-               .end    = 253,
+               .start  = evt2irq(0x2100),
+               .end    = evt2irq(0x21a0),
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -475,14 +535,14 @@ static struct resource sh7372_dmae2_resources[] = {
        },
        {
                /* DMA error IRQ */
-               .start  = 262,
-               .end    = 262,
+               .start  = evt2irq(0x22c0),
+               .end    = evt2irq(0x22c0),
                .flags  = IORESOURCE_IRQ,
        },
        {
                /* IRQ for channels 0-5 */
-               .start  = 256,
-               .end    = 261,
+               .start  = evt2irq(0x2200),
+               .end    = evt2irq(0x22a0),
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -526,6 +586,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = {
        &scif5_device,
        &scif6_device,
        &cmt10_device,
+       &tmu00_device,
+       &tmu01_device,
+};
+
+static struct platform_device *sh7372_late_devices[] __initdata = {
        &iic0_device,
        &iic1_device,
        &dma0_device,
@@ -537,6 +602,9 @@ void __init sh7372_add_standard_devices(void)
 {
        platform_add_devices(sh7372_early_devices,
                            ARRAY_SIZE(sh7372_early_devices));
+
+       platform_add_devices(sh7372_late_devices,
+                           ARRAY_SIZE(sh7372_late_devices));
 }
 
 void __init sh7372_add_early_devices(void)
index bb4adf17dbf4613f7c388ab711b09a785470c026..575dbd6c2f1df748c5089505596b9f0b5cf35624 100644 (file)
@@ -172,7 +172,6 @@ static struct sh_timer_config cmt10_platform_data = {
        .name = "CMT10",
        .channel_offset = 0x10,
        .timer_bit = 0,
-       .clk = "r_clk",
        .clockevent_rating = 125,
        .clocksource_rating = 125,
 };
index 60acf9e708ae9d655423e46e804f509908642c04..7458fc6df5c67b466184bc6a4a317745304101ee 100644 (file)
@@ -66,7 +66,7 @@ static DEFINE_SPINLOCK(syscon_resetreg_lock);
  *  AMBA bus
  *  |
  *  +- CPU
- *  +- NANDIF NAND Flash interface
+ *  +- FSMC NANDIF NAND Flash interface
  *  +- SEMI Shared Memory interface
  *  +- ISP Image Signal Processor (U335 only)
  *  +- CDS (U335 only)
@@ -726,7 +726,7 @@ static struct clk cpu_clk = {
 };
 
 static struct clk nandif_clk = {
-       .name       = "NANDIF",
+       .name       = "FSMC",
        .parent     = &amba_clk,
        .hw_ctrld   = false,
        .reset      = true,
@@ -1259,7 +1259,7 @@ static struct clk_lookup lookups[] = {
        /* Connected directly to the AMBA bus */
        DEF_LOOKUP("amba",      &amba_clk),
        DEF_LOOKUP("cpu",       &cpu_clk),
-       DEF_LOOKUP("fsmc",      &nandif_clk),
+       DEF_LOOKUP("fsmc-nand", &nandif_clk),
        DEF_LOOKUP("semi",      &semi_clk),
 #ifdef CONFIG_MACH_U300_BS335
        DEF_LOOKUP("isp",       &isp_clk),
index ea41c236be0f78cb0e250ff8e6b4e4116339d695..aa53ee22438f55237dfa8e9917b94ac14c338bdf 100644 (file)
@@ -21,7 +21,8 @@
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/err.h>
-#include <mach/coh901318.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -30,6 +31,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <mach/coh901318.h>
 #include <mach/hardware.h>
 #include <mach/syscon.h>
 #include <mach/dma_channels.h>
@@ -285,6 +287,13 @@ static struct resource rtc_resources[] = {
  */
 static struct resource fsmc_resources[] = {
        {
+               .name  = "nand_data",
+               .start = U300_NAND_CS0_PHYS_BASE,
+               .end   = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .name  = "fsmc_regs",
                .start = U300_NAND_IF_PHYS_BASE,
                .end   = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
                .flags = IORESOURCE_MEM,
@@ -1429,11 +1438,39 @@ static struct platform_device rtc_device = {
        .resource = rtc_resources,
 };
 
-static struct platform_device fsmc_device = {
-       .name = "nandif",
+static struct mtd_partition u300_partitions[] = {
+       {
+               .name = "bootrecords",
+               .offset = 0,
+               .size = SZ_128K,
+       },
+       {
+               .name = "free",
+               .offset = SZ_128K,
+               .size = 8064 * SZ_1K,
+       },
+       {
+               .name = "platform",
+               .offset = 8192 * SZ_1K,
+               .size = 253952 * SZ_1K,
+       },
+};
+
+static struct fsmc_nand_platform_data nand_platform_data = {
+       .partitions = u300_partitions,
+       .nr_partitions = ARRAY_SIZE(u300_partitions),
+       .options = NAND_SKIP_BBTSCAN,
+       .width = FSMC_NAND_BW8,
+};
+
+static struct platform_device nand_device = {
+       .name = "fsmc-nand",
        .id = -1,
-       .num_resources = ARRAY_SIZE(fsmc_resources),
        .resource = fsmc_resources,
+       .num_resources = ARRAY_SIZE(fsmc_resources),
+       .dev = {
+               .platform_data = &nand_platform_data,
+       },
 };
 
 static struct platform_device ave_device = {
@@ -1465,7 +1502,7 @@ static struct platform_device *platform_devs[] __initdata = {
        &keypad_device,
        &rtc_device,
        &gpio_device,
-       &fsmc_device,
+       &nand_device,
        &wdog_device,
        &ave_device
 };
index 56721a0cd2aff6bfbc21fbaf7bab8fb303ef5158..8b85df4c8d8fcce5530535ffb2d91e15f25b636d 100644 (file)
 
 /* NAND Flash CS0 */
 #define U300_NAND_CS0_PHYS_BASE                0x80000000
-#define U300_NAND_CS0_VIRT_BASE                0xff040000
 
 /* NFIF */
 #define U300_NAND_IF_PHYS_BASE         0x9f800000
-#define U300_NAND_IF_VIRT_BASE         0xff030000
 
 /* AHB Peripherals */
 #define U300_AHB_PER_PHYS_BASE         0xa0000000
index edb2c0d255c2a1671cae12e6704da28e6b66cb8d..00869def54205c3291b44eafacf3afba7eb03d68 100644 (file)
@@ -67,7 +67,7 @@ static struct spi_board_info u300_spi_devices[] = {
                .bus_num        = 0, /* Only one bus on this chip */
                .chip_select    = 0,
                /* Means SPI_CS_HIGH, change if e.g low CS */
-               .mode           = SPI_MODE_1 | SPI_LSB_FIRST | SPI_LOOP,
+               .mode           = SPI_MODE_1 | SPI_LOOP,
        },
 #endif
 };
index e0fd747e447ad6e3e299e57aadcfcfbcd4241867..73fb1a551ec64338b136b73fb1548a9b87bd85e0 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 
+#include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach/map.h>
@@ -71,6 +72,46 @@ void __init ux500_init_irq(void)
 }
 
 #ifdef CONFIG_CACHE_L2X0
+static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
+{
+       /* wait for the operation to complete */
+       while (readl(reg) & mask)
+               ;
+}
+
+static inline void ux500_cache_sync(void)
+{
+       void __iomem *base = __io_address(UX500_L2CC_BASE);
+       writel(0, base + L2X0_CACHE_SYNC);
+       ux500_cache_wait(base + L2X0_CACHE_SYNC, 1);
+}
+
+/*
+ * The L2 cache cannot be turned off in the non-secure world.
+ * Dummy until a secure service is in place.
+ */
+static void ux500_l2x0_disable(void)
+{
+}
+
+/*
+ * This is only called when doing a kexec, just after turning off the L2
+ * and L1 cache, and it is surrounded by a spinlock in the generic version.
+ * However, we're not really turning off the L2 cache right now and the
+ * PL310 does not support exclusive accesses (used to implement the spinlock).
+ * So, the invalidation needs to be done without the spinlock.
+ */
+static void ux500_l2x0_inv_all(void)
+{
+       void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE);
+       uint32_t l2x0_way_mask = (1<<16) - 1;   /* Bitmask of active ways */
+
+       /* invalidate all ways */
+       writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
+       ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
+       ux500_cache_sync();
+}
+
 static int ux500_l2x0_init(void)
 {
        void __iomem *l2x0_base;
@@ -80,6 +121,10 @@ static int ux500_l2x0_init(void)
        /* 64KB way size, 8 way associativity, force WA */
        l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
 
+       /* Override invalidate function */
+       outer_cache.disable = ux500_l2x0_disable;
+       outer_cache.inv_all = ux500_l2x0_inv_all;
+
        return 0;
 }
 early_initcall(ux500_l2x0_init);
index c2e405a9e0256141d62dfad2f359bfa7bac87555..fd25ccd7272f7045b24a193f4c025a84c3bca97b 100644 (file)
@@ -54,7 +54,9 @@ static struct map_desc ct_ca9x4_io_desc[] __initdata = {
 
 static void __init ct_ca9x4_map_io(void)
 {
+#ifdef CONFIG_LOCAL_TIMERS
        twd_base = MMIO_P2V(A9_MPCORE_TWD);
+#endif
        v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
 }
 
index a0a2928ae4dd7670a1342863040791833b57dbab..4414a01e1e8a392befa91d6da826f8ab1698223c 100644 (file)
@@ -779,6 +779,14 @@ config CACHE_L2X0
        help
          This option enables the L2x0 PrimeCell.
 
+config CACHE_PL310
+       bool
+       depends on CACHE_L2X0
+       default y if CPU_V7 && !CPU_V6
+       help
+         This option enables optimisations for the PL310 cache
+         controller.
+
 config CACHE_TAUROS2
        bool "Enable the Tauros2 L2 cache controller"
        depends on (ARCH_DOVE || ARCH_MMP)
index 7148e53e6078fff5b32a5d8d87a5ce1658095ae3..1fa6f71470de52458208eecc20223921b632146d 100644 (file)
 /* FIXME: put optimal value here. Current one is just estimation */
 #define CACHE_DLIMIT   (CACHE_DSIZE * 2)
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(fa_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(fa_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -233,6 +244,7 @@ ENDPROC(fa_dma_unmap_area)
 
        .type   fa_cache_fns, #object
 ENTRY(fa_cache_fns)
+       .long   fa_flush_icache_all
        .long   fa_flush_kern_cache_all
        .long   fa_flush_user_cache_all
        .long   fa_flush_user_cache_range
index 9982eb385c0f9844d70f53d45c7377fcf5fa2887..170c9bb958666afc587e6b94c6e424f43b939a88 100644 (file)
 static void __iomem *l2x0_base;
 static DEFINE_SPINLOCK(l2x0_lock);
 static uint32_t l2x0_way_mask; /* Bitmask of active ways */
+static uint32_t l2x0_size;
 
-static inline void cache_wait(void __iomem *reg, unsigned long mask)
+static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
 {
-       /* wait for the operation to complete */
+       /* wait for cache operation by line or way to complete */
        while (readl_relaxed(reg) & mask)
                ;
 }
 
+#ifdef CONFIG_CACHE_PL310
+static inline void cache_wait(void __iomem *reg, unsigned long mask)
+{
+       /* cache operations by line are atomic on PL310 */
+}
+#else
+#define cache_wait     cache_wait_way
+#endif
+
 static inline void cache_sync(void)
 {
        void __iomem *base = l2x0_base;
@@ -103,14 +113,40 @@ static void l2x0_cache_sync(void)
        spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
-static inline void l2x0_inv_all(void)
+static void l2x0_flush_all(void)
+{
+       unsigned long flags;
+
+       /* clean all ways */
+       spin_lock_irqsave(&l2x0_lock, flags);
+       writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
+       cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
+       cache_sync();
+       spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2x0_clean_all(void)
+{
+       unsigned long flags;
+
+       /* clean all ways */
+       spin_lock_irqsave(&l2x0_lock, flags);
+       writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
+       cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
+       cache_sync();
+       spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2x0_inv_all(void)
 {
        unsigned long flags;
 
        /* invalidate all ways */
        spin_lock_irqsave(&l2x0_lock, flags);
+       /* Invalidating when L2 is enabled is a nono */
+       BUG_ON(readl(l2x0_base + L2X0_CTRL) & 1);
        writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
-       cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
+       cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
        cache_sync();
        spin_unlock_irqrestore(&l2x0_lock, flags);
 }
@@ -159,6 +195,11 @@ static void l2x0_clean_range(unsigned long start, unsigned long end)
        void __iomem *base = l2x0_base;
        unsigned long flags;
 
+       if ((end - start) >= l2x0_size) {
+               l2x0_clean_all();
+               return;
+       }
+
        spin_lock_irqsave(&l2x0_lock, flags);
        start &= ~(CACHE_LINE_SIZE - 1);
        while (start < end) {
@@ -184,6 +225,11 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
        void __iomem *base = l2x0_base;
        unsigned long flags;
 
+       if ((end - start) >= l2x0_size) {
+               l2x0_flush_all();
+               return;
+       }
+
        spin_lock_irqsave(&l2x0_lock, flags);
        start &= ~(CACHE_LINE_SIZE - 1);
        while (start < end) {
@@ -206,10 +252,20 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
        spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
+static void l2x0_disable(void)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&l2x0_lock, flags);
+       writel(0, l2x0_base + L2X0_CTRL);
+       spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
 void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 {
        __u32 aux;
        __u32 cache_id;
+       __u32 way_size = 0;
        int ways;
        const char *type;
 
@@ -243,6 +299,13 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 
        l2x0_way_mask = (1 << ways) - 1;
 
+       /*
+        * L2 cache Size =  Way size * Number of ways
+        */
+       way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
+       way_size = 1 << (way_size + 3);
+       l2x0_size = ways * way_size * SZ_1K;
+
        /*
         * Check if l2x0 controller is already enabled.
         * If you are booting from non-secure mode
@@ -263,8 +326,11 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
        outer_cache.clean_range = l2x0_clean_range;
        outer_cache.flush_range = l2x0_flush_range;
        outer_cache.sync = l2x0_cache_sync;
+       outer_cache.flush_all = l2x0_flush_all;
+       outer_cache.inv_all = l2x0_inv_all;
+       outer_cache.disable = l2x0_disable;
 
        printk(KERN_INFO "%s cache controller enabled\n", type);
-       printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
-                        ways, cache_id, aux);
+       printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
+                       ways, cache_id, aux, l2x0_size);
 }
index c2ff3c599feed47eb77d92190d29958fb95e8315..2e2bc406a18d69f93de13600732bb3d6fa329135 100644 (file)
 #include <asm/page.h>
 #include "proc-macros.S"
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v3_flush_icache_all)
+       mov     pc, lr
+ENDPROC(v3_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -122,6 +131,7 @@ ENDPROC(v3_dma_map_area)
 
        .type   v3_cache_fns, #object
 ENTRY(v3_cache_fns)
+       .long   v3_flush_icache_all
        .long   v3_flush_kern_cache_all
        .long   v3_flush_user_cache_all
        .long   v3_flush_user_cache_range
index 4810f7e3e8139ea8bed712cc4b9cea792660d99a..a8fefb523f194ab97e950af7bf1d9e906c666013 100644 (file)
 #include <asm/page.h>
 #include "proc-macros.S"
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4_flush_icache_all)
+       mov     pc, lr
+ENDPROC(v4_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -134,6 +143,7 @@ ENDPROC(v4_dma_map_area)
 
        .type   v4_cache_fns, #object
 ENTRY(v4_cache_fns)
+       .long   v4_flush_icache_all
        .long   v4_flush_kern_cache_all
        .long   v4_flush_user_cache_all
        .long   v4_flush_user_cache_range
index df8368afa102771bb99c19045abac26abb42e656..d3644db467b74af63a701a9e34d1335a0905e06d 100644 (file)
@@ -50,6 +50,17 @@ flush_base:
        .long   FLUSH_BASE
        .text
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4wb_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(v4wb_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -244,6 +255,7 @@ ENDPROC(v4wb_dma_unmap_area)
 
        .type   v4wb_cache_fns, #object
 ENTRY(v4wb_cache_fns)
+       .long   v4wb_flush_icache_all
        .long   v4wb_flush_kern_cache_all
        .long   v4wb_flush_user_cache_all
        .long   v4wb_flush_user_cache_range
index 45c70312f43bb1db9f49ae9591283d243b072ae8..49c2b66cf3dd6913b7fcdb42bcd877b8a8fa833a 100644 (file)
  */
 #define CACHE_DLIMIT   16384
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4wt_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(v4wt_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -188,6 +199,7 @@ ENDPROC(v4wt_dma_map_area)
 
        .type   v4wt_cache_fns, #object
 ENTRY(v4wt_cache_fns)
+       .long   v4wt_flush_icache_all
        .long   v4wt_flush_kern_cache_all
        .long   v4wt_flush_user_cache_all
        .long   v4wt_flush_user_cache_range
index e4dd0646e85978b89a164c40100d0561bd1005f7..ac6a36142fcd5a28084b3c669fac9e800fd65497 100644 (file)
@@ -198,7 +198,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
         * fragmentation of the DMA space, and also prevents allocations
         * smaller than a section from crossing a section boundary.
         */
-       bit = fls(size - 1) + 1;
+       bit = fls(size - 1);
        if (bit > SECTION_SHIFT)
                bit = SECTION_SHIFT;
        align = 1 << bit;
index c493d7244d3d99bee236469940fbed42c10ce476..83e59f8704261bfa1c12bd2cd21ac0c21ad17e08 100644 (file)
@@ -66,6 +66,30 @@ static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address,
        return ret;
 }
 
+#if USE_SPLIT_PTLOCKS
+/*
+ * If we are using split PTE locks, then we need to take the page
+ * lock here.  Otherwise we are using shared mm->page_table_lock
+ * which is already locked, thus cannot take it.
+ */
+static inline void do_pte_lock(spinlock_t *ptl)
+{
+       /*
+        * Use nested version here to indicate that we are already
+        * holding one similar spinlock.
+        */
+       spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);
+}
+
+static inline void do_pte_unlock(spinlock_t *ptl)
+{
+       spin_unlock(ptl);
+}
+#else /* !USE_SPLIT_PTLOCKS */
+static inline void do_pte_lock(spinlock_t *ptl) {}
+static inline void do_pte_unlock(spinlock_t *ptl) {}
+#endif /* USE_SPLIT_PTLOCKS */
+
 static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
        unsigned long pfn)
 {
@@ -90,11 +114,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
         */
        ptl = pte_lockptr(vma->vm_mm, pmd);
        pte = pte_offset_map(pmd, address);
-       spin_lock(ptl);
+       do_pte_lock(ptl);
 
        ret = do_adjust_pte(vma, address, pfn, pte);
 
-       spin_unlock(ptl);
+       do_pte_unlock(ptl);
        pte_unmap(pte);
 
        return ret;
index 7fd9b5eb177fa02c56acd3444da0e3752e702913..5164069ced42f0d0176369247fa40701292ea511 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 #include <linux/memblock.h>
+#include <linux/sort.h>
 
 #include <asm/mach-types.h>
 #include <asm/sections.h>
@@ -121,9 +122,10 @@ void show_mem(void)
        printk("%d pages swap cached\n", cached);
 }
 
-static void __init find_limits(struct meminfo *mi,
-       unsigned long *min, unsigned long *max_low, unsigned long *max_high)
+static void __init find_limits(unsigned long *min, unsigned long *max_low,
+       unsigned long *max_high)
 {
+       struct meminfo *mi = &meminfo;
        int i;
 
        *min = -1UL;
@@ -147,14 +149,13 @@ static void __init find_limits(struct meminfo *mi,
        }
 }
 
-static void __init arm_bootmem_init(struct meminfo *mi,
-       unsigned long start_pfn, unsigned long end_pfn)
+static void __init arm_bootmem_init(unsigned long start_pfn,
+       unsigned long end_pfn)
 {
        struct memblock_region *reg;
        unsigned int boot_pages;
        phys_addr_t bitmap;
        pg_data_t *pgdat;
-       int i;
 
        /*
         * Allocate the bootmem bitmap page.  This must be in a region
@@ -172,30 +173,39 @@ static void __init arm_bootmem_init(struct meminfo *mi,
        pgdat = NODE_DATA(0);
        init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
 
-       for_each_bank(i, mi) {
-               struct membank *bank = &mi->bank[i];
-               if (!bank->highmem)
-                       free_bootmem(bank_phys_start(bank), bank_phys_size(bank));
+       /* Free the lowmem regions from memblock into bootmem. */
+       for_each_memblock(memory, reg) {
+               unsigned long start = memblock_region_memory_base_pfn(reg);
+               unsigned long end = memblock_region_memory_end_pfn(reg);
+
+               if (end >= end_pfn)
+                       end = end_pfn;
+               if (start >= end)
+                       break;
+
+               free_bootmem(__pfn_to_phys(start), (end - start) << PAGE_SHIFT);
        }
 
-       /*
-        * Reserve the memblock reserved regions in bootmem.
-        */
+       /* Reserve the lowmem memblock reserved regions in bootmem. */
        for_each_memblock(reserved, reg) {
-               phys_addr_t start = memblock_region_reserved_base_pfn(reg);
-               phys_addr_t end = memblock_region_reserved_end_pfn(reg);
-               if (start >= start_pfn && end <= end_pfn)
-                       reserve_bootmem_node(pgdat, __pfn_to_phys(start),
-                                            (end - start) << PAGE_SHIFT,
-                                            BOOTMEM_DEFAULT);
+               unsigned long start = memblock_region_reserved_base_pfn(reg);
+               unsigned long end = memblock_region_reserved_end_pfn(reg);
+
+               if (end >= end_pfn)
+                       end = end_pfn;
+               if (start >= end)
+                       break;
+
+               reserve_bootmem(__pfn_to_phys(start),
+                               (end - start) << PAGE_SHIFT, BOOTMEM_DEFAULT);
        }
 }
 
-static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,
-       unsigned long max_low, unsigned long max_high)
+static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
+       unsigned long max_high)
 {
        unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
-       int i;
+       struct memblock_region *reg;
 
        /*
         * initialise the zones.
@@ -217,13 +227,20 @@ static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,
         *  holes = node_size - sum(bank_sizes)
         */
        memcpy(zhole_size, zone_size, sizeof(zhole_size));
-       for_each_bank(i, mi) {
-               int idx = 0;
+       for_each_memblock(memory, reg) {
+               unsigned long start = memblock_region_memory_base_pfn(reg);
+               unsigned long end = memblock_region_memory_end_pfn(reg);
+
+               if (start < max_low) {
+                       unsigned long low_end = min(end, max_low);
+                       zhole_size[0] -= low_end - start;
+               }
 #ifdef CONFIG_HIGHMEM
-               if (mi->bank[i].highmem)
-                       idx = ZONE_HIGHMEM;
+               if (end > max_low) {
+                       unsigned long high_start = max(start, max_low);
+                       zhole_size[ZONE_HIGHMEM] -= end - high_start;
+               }
 #endif
-               zhole_size[idx] -= bank_pfn_size(&mi->bank[i]);
        }
 
        /*
@@ -256,10 +273,19 @@ static void arm_memory_present(void)
 }
 #endif
 
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+       const struct membank *a = _a, *b = _b;
+       long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+       return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
 void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
 {
        int i;
 
+       sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+
        memblock_init();
        for (i = 0; i < mi->nr_banks; i++)
                memblock_add(mi->bank[i].start, mi->bank[i].size);
@@ -292,14 +318,13 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
 
 void __init bootmem_init(void)
 {
-       struct meminfo *mi = &meminfo;
        unsigned long min, max_low, max_high;
 
        max_low = max_high = 0;
 
-       find_limits(mi, &min, &max_low, &max_high);
+       find_limits(&min, &max_low, &max_high);
 
-       arm_bootmem_init(mi, min, max_low);
+       arm_bootmem_init(min, max_low);
 
        /*
         * Sparsemem tries to allocate bootmem in memory_present(),
@@ -317,7 +342,7 @@ void __init bootmem_init(void)
         * the sparse mem_map arrays initialized by sparse_init()
         * for memmap_init_zone(), otherwise all PFNs are invalid.
         */
-       arm_bootmem_free(mi, min, max_low, max_high);
+       arm_bootmem_free(min, max_low, max_high);
 
        high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1;
 
@@ -411,6 +436,56 @@ static void __init free_unused_memmap(struct meminfo *mi)
        }
 }
 
+static void __init free_highpages(void)
+{
+#ifdef CONFIG_HIGHMEM
+       unsigned long max_low = max_low_pfn + PHYS_PFN_OFFSET;
+       struct memblock_region *mem, *res;
+
+       /* set highmem page free */
+       for_each_memblock(memory, mem) {
+               unsigned long start = memblock_region_memory_base_pfn(mem);
+               unsigned long end = memblock_region_memory_end_pfn(mem);
+
+               /* Ignore complete lowmem entries */
+               if (end <= max_low)
+                       continue;
+
+               /* Truncate partial highmem entries */
+               if (start < max_low)
+                       start = max_low;
+
+               /* Find and exclude any reserved regions */
+               for_each_memblock(reserved, res) {
+                       unsigned long res_start, res_end;
+
+                       res_start = memblock_region_reserved_base_pfn(res);
+                       res_end = memblock_region_reserved_end_pfn(res);
+
+                       if (res_end < start)
+                               continue;
+                       if (res_start < start)
+                               res_start = start;
+                       if (res_start > end)
+                               res_start = end;
+                       if (res_end > end)
+                               res_end = end;
+                       if (res_start != start)
+                               totalhigh_pages += free_area(start, res_start,
+                                                            NULL);
+                       start = res_end;
+                       if (start == end)
+                               break;
+               }
+
+               /* And now free anything which remains */
+               if (start < end)
+                       totalhigh_pages += free_area(start, end, NULL);
+       }
+       totalram_pages += totalhigh_pages;
+#endif
+}
+
 /*
  * mem_init() marks the free areas in the mem_map and tells us how much
  * memory is free.  This is done after various parts of the system have
@@ -419,6 +494,7 @@ static void __init free_unused_memmap(struct meminfo *mi)
 void __init mem_init(void)
 {
        unsigned long reserved_pages, free_pages;
+       struct memblock_region *reg;
        int i;
 #ifdef CONFIG_HAVE_TCM
        /* These pointers are filled in on TCM detection */
@@ -439,16 +515,7 @@ void __init mem_init(void)
                                    __phys_to_pfn(__pa(swapper_pg_dir)), NULL);
 #endif
 
-#ifdef CONFIG_HIGHMEM
-       /* set highmem page free */
-       for_each_bank (i, &meminfo) {
-               unsigned long start = bank_pfn_start(&meminfo.bank[i]);
-               unsigned long end = bank_pfn_end(&meminfo.bank[i]);
-               if (start >= max_low_pfn + PHYS_PFN_OFFSET)
-                       totalhigh_pages += free_area(start, end, NULL);
-       }
-       totalram_pages += totalhigh_pages;
-#endif
+       free_highpages();
 
        reserved_pages = free_pages = 0;
 
@@ -478,9 +545,11 @@ void __init mem_init(void)
         */
        printk(KERN_INFO "Memory:");
        num_physpages = 0;
-       for (i = 0; i < meminfo.nr_banks; i++) {
-               num_physpages += bank_pfn_size(&meminfo.bank[i]);
-               printk(" %ldMB", bank_phys_size(&meminfo.bank[i]) >> 20);
+       for_each_memblock(memory, reg) {
+               unsigned long pages = memblock_region_memory_end_pfn(reg) -
+                       memblock_region_memory_base_pfn(reg);
+               num_physpages += pages;
+               printk(" %ldMB", pages >> (20 - PAGE_SHIFT));
        }
        printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
 
index c32f731d56d3db4ad51453718c5d1c43f6053f2e..72ad3e1f56cfb704e800a2e109f5eea7f66017a4 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/memblock.h>
-#include <linux/sort.h>
 #include <linux/fs.h>
 
 #include <asm/cputype.h>
@@ -265,17 +264,17 @@ static struct mem_type mem_types[] = {
                .domain    = DOMAIN_KERNEL,
        },
        [MT_MEMORY_DTCM] = {
-               .prot_pte       = L_PTE_PRESENT | L_PTE_YOUNG |
-                                 L_PTE_DIRTY | L_PTE_WRITE,
-               .prot_l1        = PMD_TYPE_TABLE,
-               .prot_sect      = PMD_TYPE_SECT | PMD_SECT_XN,
-               .domain         = DOMAIN_KERNEL,
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_WRITE,
+               .prot_l1   = PMD_TYPE_TABLE,
+               .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
+               .domain    = DOMAIN_KERNEL,
        },
        [MT_MEMORY_ITCM] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
-                               L_PTE_USER | L_PTE_EXEC,
+                               L_PTE_WRITE | L_PTE_EXEC,
                .prot_l1   = PMD_TYPE_TABLE,
-               .domain    = DOMAIN_IO,
+               .domain    = DOMAIN_KERNEL,
        },
 };
 
@@ -745,13 +744,14 @@ static int __init early_vmalloc(char *arg)
 }
 early_param("vmalloc", early_vmalloc);
 
-phys_addr_t lowmem_end_addr;
+static phys_addr_t lowmem_limit __initdata = 0;
 
 static void __init sanity_check_meminfo(void)
 {
        int i, j, highmem = 0;
 
-       lowmem_end_addr = __pa(vmalloc_min - 1) + 1;
+       lowmem_limit = __pa(vmalloc_min - 1) + 1;
+       memblock_set_current_limit(lowmem_limit);
 
        for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
                struct membank *bank = &meminfo.bank[j];
@@ -852,6 +852,7 @@ static void __init sanity_check_meminfo(void)
 static inline void prepare_page_table(void)
 {
        unsigned long addr;
+       phys_addr_t end;
 
        /*
         * Clear out all the mappings below the kernel image.
@@ -866,11 +867,18 @@ static inline void prepare_page_table(void)
        for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
                pmd_clear(pmd_off_k(addr));
 
+       /*
+        * Find the end of the first block of lowmem.
+        */
+       end = memblock.memory.regions[0].base + memblock.memory.regions[0].size;
+       if (end >= lowmem_limit)
+               end = lowmem_limit;
+
        /*
         * Clear out all the kernel space mappings, except for the first
         * memory bank, up to the end of the vmalloc region.
         */
-       for (addr = __phys_to_virt(bank_phys_end(&meminfo.bank[0]));
+       for (addr = __phys_to_virt(end);
             addr < VMALLOC_END; addr += PGDIR_SIZE)
                pmd_clear(pmd_off_k(addr));
 }
@@ -987,37 +995,28 @@ static void __init kmap_init(void)
 #endif
 }
 
-static inline void map_memory_bank(struct membank *bank)
-{
-       struct map_desc map;
-
-       map.pfn = bank_pfn_start(bank);
-       map.virtual = __phys_to_virt(bank_phys_start(bank));
-       map.length = bank_phys_size(bank);
-       map.type = MT_MEMORY;
-
-       create_mapping(&map);
-}
-
 static void __init map_lowmem(void)
 {
-       struct meminfo *mi = &meminfo;
-       int i;
+       struct memblock_region *reg;
 
        /* Map all the lowmem memory banks. */
-       for (i = 0; i < mi->nr_banks; i++) {
-               struct membank *bank = &mi->bank[i];
+       for_each_memblock(memory, reg) {
+               phys_addr_t start = reg->base;
+               phys_addr_t end = start + reg->size;
+               struct map_desc map;
+
+               if (end > lowmem_limit)
+                       end = lowmem_limit;
+               if (start >= end)
+                       break;
 
-               if (!bank->highmem)
-                       map_memory_bank(bank);
-       }
-}
+               map.pfn = __phys_to_pfn(start);
+               map.virtual = __phys_to_virt(start);
+               map.length = end - start;
+               map.type = MT_MEMORY;
 
-static int __init meminfo_cmp(const void *_a, const void *_b)
-{
-       const struct membank *a = _a, *b = _b;
-       long cmp = bank_pfn_start(a) - bank_pfn_start(b);
-       return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+               create_mapping(&map);
+       }
 }
 
 /*
@@ -1028,8 +1027,6 @@ void __init paging_init(struct machine_desc *mdesc)
 {
        void *zero_page;
 
-       sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
-
        build_mem_type_table();
        sanity_check_meminfo();
        prepare_page_table();
index a6f5f8475b96c6400a3aa26e03875a329ff771b1..bcf748d9f4e253bc34ec9a885f5d0fe4f58b16c7 100644 (file)
@@ -119,6 +119,20 @@ ENTRY(cpu_arm1020_do_idle)
 /* ================================= CACHE ================================ */
 
        .align  5
+
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1020_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+#endif
+       mov     pc, lr
+ENDPROC(arm1020_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -351,6 +365,7 @@ ENTRY(arm1020_dma_unmap_area)
 ENDPROC(arm1020_dma_unmap_area)
 
 ENTRY(arm1020_cache_fns)
+       .long   arm1020_flush_icache_all
        .long   arm1020_flush_kern_cache_all
        .long   arm1020_flush_user_cache_all
        .long   arm1020_flush_user_cache_range
index afc06b9c31332bf7dc25222855d61dcb391bc42d..ab7ec26657eaf024a7f69bf8c2603f47d88c1304 100644 (file)
@@ -119,6 +119,20 @@ ENTRY(cpu_arm1020e_do_idle)
 /* ================================= CACHE ================================ */
 
        .align  5
+
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1020e_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+#endif
+       mov     pc, lr
+ENDPROC(arm1020e_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -337,6 +351,7 @@ ENTRY(arm1020e_dma_unmap_area)
 ENDPROC(arm1020e_dma_unmap_area)
 
 ENTRY(arm1020e_cache_fns)
+       .long   arm1020e_flush_icache_all
        .long   arm1020e_flush_kern_cache_all
        .long   arm1020e_flush_user_cache_all
        .long   arm1020e_flush_user_cache_range
index 8915e0ba3fe53e1225bbb422b19f22c8a0d4c085..831c5e54e22f0e7fe795bedc4d619dae26ed9c39 100644 (file)
@@ -108,6 +108,20 @@ ENTRY(cpu_arm1022_do_idle)
 /* ================================= CACHE ================================ */
 
        .align  5
+
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1022_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+#endif
+       mov     pc, lr
+ENDPROC(arm1022_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -326,6 +340,7 @@ ENTRY(arm1022_dma_unmap_area)
 ENDPROC(arm1022_dma_unmap_area)
 
 ENTRY(arm1022_cache_fns)
+       .long   arm1022_flush_icache_all
        .long   arm1022_flush_kern_cache_all
        .long   arm1022_flush_user_cache_all
        .long   arm1022_flush_user_cache_range
index ff446c5d476f029aefb8a57da2fd4a4987e890e3..e3f7e9a166bfc6668574dc2a7518f56cee9476a6 100644 (file)
@@ -108,6 +108,20 @@ ENTRY(cpu_arm1026_do_idle)
 /* ================================= CACHE ================================ */
 
        .align  5
+
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1026_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+#endif
+       mov     pc, lr
+ENDPROC(arm1026_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -320,6 +334,7 @@ ENTRY(arm1026_dma_unmap_area)
 ENDPROC(arm1026_dma_unmap_area)
 
 ENTRY(arm1026_cache_fns)
+       .long   arm1026_flush_icache_all
        .long   arm1026_flush_kern_cache_all
        .long   arm1026_flush_user_cache_all
        .long   arm1026_flush_user_cache_range
index fecf570939f39553dcc4959a6a963a06827aadc2..6109f278a9045f4429bcd31ca9a4f8a092d3c66f 100644 (file)
@@ -109,6 +109,17 @@ ENTRY(cpu_arm920_do_idle)
 
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm920_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(arm920_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -305,6 +316,7 @@ ENTRY(arm920_dma_unmap_area)
 ENDPROC(arm920_dma_unmap_area)
 
 ENTRY(arm920_cache_fns)
+       .long   arm920_flush_icache_all
        .long   arm920_flush_kern_cache_all
        .long   arm920_flush_user_cache_all
        .long   arm920_flush_user_cache_range
index e3cbf87c9480c97e8b65086638ef6b6b72e3217c..bb2f0f46a5e6cb28f8789da35ecb7d2f0852a4b1 100644 (file)
@@ -111,6 +111,17 @@ ENTRY(cpu_arm922_do_idle)
 
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm922_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(arm922_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -307,6 +318,7 @@ ENTRY(arm922_dma_unmap_area)
 ENDPROC(arm922_dma_unmap_area)
 
 ENTRY(arm922_cache_fns)
+       .long   arm922_flush_icache_all
        .long   arm922_flush_kern_cache_all
        .long   arm922_flush_user_cache_all
        .long   arm922_flush_user_cache_range
index 572424c867b5e8560401e7cf40d895a77f140fbe..c13e01accfe2e4d38dc5e7e22d6aba32bfd0ce0a 100644 (file)
@@ -144,6 +144,17 @@ ENTRY(cpu_arm925_do_idle)
        mcr     p15, 0, r1, c1, c0, 0           @ Restore ICache enable
        mov     pc, lr
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm925_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(arm925_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -362,6 +373,7 @@ ENTRY(arm925_dma_unmap_area)
 ENDPROC(arm925_dma_unmap_area)
 
 ENTRY(arm925_cache_fns)
+       .long   arm925_flush_icache_all
        .long   arm925_flush_kern_cache_all
        .long   arm925_flush_user_cache_all
        .long   arm925_flush_user_cache_range
index 63d168b4ebe671316ff3add437c26da418dd596f..42eb4315740b1488e26192b5ff0cb07747312df5 100644 (file)
@@ -110,6 +110,17 @@ ENTRY(cpu_arm926_do_idle)
        msr     cpsr_c, r3                      @ Restore FIQ state
        mov     pc, lr
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm926_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(arm926_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -325,6 +336,7 @@ ENTRY(arm926_dma_unmap_area)
 ENDPROC(arm926_dma_unmap_area)
 
 ENTRY(arm926_cache_fns)
+       .long   arm926_flush_icache_all
        .long   arm926_flush_kern_cache_all
        .long   arm926_flush_user_cache_all
        .long   arm926_flush_user_cache_range
index f6a62822418e3573d8af5629f7f088f7ce24652d..7b11cdb9935ff4e8d635ee95a6ea09d225cdc10e 100644 (file)
@@ -67,6 +67,17 @@ ENTRY(cpu_arm940_do_idle)
        mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
        mov     pc, lr
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm940_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(arm940_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  */
@@ -254,6 +265,7 @@ ENTRY(arm940_dma_unmap_area)
 ENDPROC(arm940_dma_unmap_area)
 
 ENTRY(arm940_cache_fns)
+       .long   arm940_flush_icache_all
        .long   arm940_flush_kern_cache_all
        .long   arm940_flush_user_cache_all
        .long   arm940_flush_user_cache_range
index ea2e7f2eb95b1e6f86f4770c2e1ebca292f11f81..1a5bbf0803427b159096bfc093a5db07dc510731 100644 (file)
@@ -74,6 +74,17 @@ ENTRY(cpu_arm946_do_idle)
        mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
        mov     pc, lr
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm946_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(arm946_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  */
@@ -296,6 +307,7 @@ ENTRY(arm946_dma_unmap_area)
 ENDPROC(arm946_dma_unmap_area)
 
 ENTRY(arm946_cache_fns)
+       .long   arm946_flush_icache_all
        .long   arm946_flush_kern_cache_all
        .long   arm946_flush_user_cache_all
        .long   arm946_flush_user_cache_range
index 578da69200cfc2694a2359c18ead388dfd4a7353..b4597edbff97fe794da687178c5f23cf27e37e47 100644 (file)
@@ -123,6 +123,17 @@ ENTRY(cpu_feroceon_do_idle)
        mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
        mov     pc, lr
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(feroceon_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(feroceon_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -401,6 +412,7 @@ ENTRY(feroceon_dma_unmap_area)
 ENDPROC(feroceon_dma_unmap_area)
 
 ENTRY(feroceon_cache_fns)
+       .long   feroceon_flush_icache_all
        .long   feroceon_flush_kern_cache_all
        .long   feroceon_flush_user_cache_all
        .long   feroceon_flush_user_cache_range
@@ -412,6 +424,7 @@ ENTRY(feroceon_cache_fns)
        .long   feroceon_dma_flush_range
 
 ENTRY(feroceon_range_cache_fns)
+       .long   feroceon_flush_icache_all
        .long   feroceon_flush_kern_cache_all
        .long   feroceon_flush_user_cache_all
        .long   feroceon_flush_user_cache_range
index cad07e403044f3a2ba3b62b0812d4b37c6b4ff9f..ec26355cb7c25b8d0e574e74740569213818cd6a 100644 (file)
@@ -140,6 +140,17 @@ ENTRY(cpu_xsc3_do_idle)
 
 /* ================================= CACHE ================================ */
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(xsc3_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(xsc3_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -325,6 +336,7 @@ ENTRY(xsc3_dma_unmap_area)
 ENDPROC(xsc3_dma_unmap_area)
 
 ENTRY(xsc3_cache_fns)
+       .long   xsc3_flush_icache_all
        .long   xsc3_flush_kern_cache_all
        .long   xsc3_flush_user_cache_all
        .long   xsc3_flush_user_cache_range
index cb245edb2c2bc2e25aa355473f8ceab9dc35d493..523408c0bb38aafb69903dbd85f8584d5eef1a3a 100644 (file)
@@ -180,6 +180,17 @@ ENTRY(cpu_xscale_do_idle)
 
 /* ================================= CACHE ================================ */
 
+/*
+ *     flush_icache_all()
+ *
+ *     Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(xscale_flush_icache_all)
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mov     pc, lr
+ENDPROC(xscale_flush_icache_all)
+
 /*
  *     flush_user_cache_all()
  *
@@ -397,6 +408,7 @@ ENTRY(xscale_dma_unmap_area)
 ENDPROC(xscale_dma_unmap_area)
 
 ENTRY(xscale_cache_fns)
+       .long   xscale_flush_icache_all
        .long   xscale_flush_kern_cache_all
        .long   xscale_flush_user_cache_all
        .long   xscale_flush_user_cache_range
index 06875b4dd70fb2999da998299238aaf1e460d07b..372670952789a0e6d583ec1186721d62ba1c9085 100644 (file)
@@ -18,6 +18,7 @@ obj-$(CONFIG_MXC_USE_EPIT) += epit.o
 obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
 obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
 obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
+obj-$(CONFIG_CPU_FREQ_IMX)    += cpufreq.o
 ifdef CONFIG_SND_IMX_SOC
 obj-y += ssi-fiq.o
 obj-y += ssi-fiq-ksym.o
diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
new file mode 100644 (file)
index 0000000..039538e
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * A driver for the Freescale Semiconductor i.MXC CPUfreq module.
+ * The CPUFREQ driver is for controling CPU frequency. It allows you to change
+ * the CPU clock speed on the fly.
+ */
+
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+
+#define CLK32_FREQ     32768
+#define NANOSECOND     (1000 * 1000 * 1000)
+
+struct cpu_op *(*get_cpu_op)(int *op);
+
+static int cpu_freq_khz_min;
+static int cpu_freq_khz_max;
+
+static struct clk *cpu_clk;
+static struct cpufreq_frequency_table *imx_freq_table;
+
+static int cpu_op_nr;
+static struct cpu_op *cpu_op_tbl;
+
+static int set_cpu_freq(int freq)
+{
+       int ret = 0;
+       int org_cpu_rate;
+
+       org_cpu_rate = clk_get_rate(cpu_clk);
+       if (org_cpu_rate == freq)
+               return ret;
+
+       ret = clk_set_rate(cpu_clk, freq);
+       if (ret != 0) {
+               printk(KERN_DEBUG "cannot set CPU clock rate\n");
+               return ret;
+       }
+
+       return ret;
+}
+
+static int mxc_verify_speed(struct cpufreq_policy *policy)
+{
+       if (policy->cpu != 0)
+               return -EINVAL;
+
+       return cpufreq_frequency_table_verify(policy, imx_freq_table);
+}
+
+static unsigned int mxc_get_speed(unsigned int cpu)
+{
+       if (cpu)
+               return 0;
+
+       return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int mxc_set_target(struct cpufreq_policy *policy,
+                         unsigned int target_freq, unsigned int relation)
+{
+       struct cpufreq_freqs freqs;
+       int freq_Hz;
+       int ret = 0;
+       unsigned int index;
+
+       cpufreq_frequency_table_target(policy, imx_freq_table,
+                       target_freq, relation, &index);
+       freq_Hz = imx_freq_table[index].frequency * 1000;
+
+       freqs.old = clk_get_rate(cpu_clk) / 1000;
+       freqs.new = freq_Hz / 1000;
+       freqs.cpu = 0;
+       freqs.flags = 0;
+       cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+       ret = set_cpu_freq(freq_Hz);
+
+       cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+       return ret;
+}
+
+static int __init mxc_cpufreq_init(struct cpufreq_policy *policy)
+{
+       int ret;
+       int i;
+
+       printk(KERN_INFO "i.MXC CPU frequency driver\n");
+
+       if (policy->cpu != 0)
+               return -EINVAL;
+
+       if (!get_cpu_op)
+               return -EINVAL;
+
+       cpu_clk = clk_get(NULL, "cpu_clk");
+       if (IS_ERR(cpu_clk)) {
+               printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
+               return PTR_ERR(cpu_clk);
+       }
+
+       cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+
+       cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000;
+       cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000;
+
+       imx_freq_table = kmalloc(
+               sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1),
+                       GFP_KERNEL);
+       if (!imx_freq_table) {
+               ret = -ENOMEM;
+               goto err1;
+       }
+
+       for (i = 0; i < cpu_op_nr; i++) {
+               imx_freq_table[i].index = i;
+               imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000;
+
+               if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
+                       cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000;
+
+               if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
+                       cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000;
+       }
+
+       imx_freq_table[i].index = i;
+       imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+       policy->cur = clk_get_rate(cpu_clk) / 1000;
+       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+       policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
+       policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
+
+       /* Manual states, that PLL stabilizes in two CLK32 periods */
+       policy->cpuinfo.transition_latency = 2 * NANOSECOND / CLK32_FREQ;
+
+       ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table);
+
+       if (ret < 0) {
+               printk(KERN_ERR "%s: failed to register i.MXC CPUfreq \
+                               with error code %d\n", __func__, ret);
+               goto err;
+       }
+
+       cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu);
+       return 0;
+err:
+       kfree(imx_freq_table);
+err1:
+       clk_put(cpu_clk);
+       return ret;
+}
+
+static int mxc_cpufreq_exit(struct cpufreq_policy *policy)
+{
+       cpufreq_frequency_table_put_attr(policy->cpu);
+
+       set_cpu_freq(cpu_freq_khz_max * 1000);
+       clk_put(cpu_clk);
+       kfree(imx_freq_table);
+       return 0;
+}
+
+static struct cpufreq_driver mxc_driver = {
+       .flags = CPUFREQ_STICKY,
+       .verify = mxc_verify_speed,
+       .target = mxc_set_target,
+       .get = mxc_get_speed,
+       .init = mxc_cpufreq_init,
+       .exit = mxc_cpufreq_exit,
+       .name = "imx",
+};
+
+static int __devinit mxc_cpufreq_driver_init(void)
+{
+       return cpufreq_register_driver(&mxc_driver);
+}
+
+static void mxc_cpufreq_driver_exit(void)
+{
+       cpufreq_unregister_driver(&mxc_driver);
+}
+
+module_init(mxc_cpufreq_driver_init);
+module_exit(mxc_cpufreq_driver_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor Inc. Yong Shen <yong.shen@linaro.org>");
+MODULE_DESCRIPTION("CPUfreq driver for i.MX");
+MODULE_LICENSE("GPL");
index 404799487f1760b5eb9cec4e0636753830b54566..9aa6f3ea901253d4a827c39d2d5b752801ab01a9 100644 (file)
@@ -6,9 +6,13 @@ config IMX_HAVE_PLATFORM_FEC
        default y if ARCH_MX25 || SOC_IMX27 || ARCH_MX35 || ARCH_MX51
 
 config IMX_HAVE_PLATFORM_FLEXCAN
-       select HAVE_CAN_FLEXCAN
+       select HAVE_CAN_FLEXCAN if CAN
        bool
 
+config IMX_HAVE_PLATFORM_GPIO_KEYS
+       bool
+       default y if ARCH_MX51
+       
 config IMX_HAVE_PLATFORM_IMX_I2C
        bool
 
index 0a3c1f089413e2e2a896326612e3dd080e02818f..45aefeb283bac440421675ff039b4de427125522 100644 (file)
@@ -1,6 +1,7 @@
 obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
 obj-y += platform-imx-dma.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o
diff --git a/arch/arm/plat-mxc/devices/platform-gpio_keys.c b/arch/arm/plat-mxc/devices/platform-gpio_keys.c
new file mode 100644 (file)
index 0000000..1c53a53
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * 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 Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init imx_add_gpio_keys(
+               const struct gpio_keys_platform_data *pdata)
+{
+       return imx_add_platform_device("gpio-keys", -1, NULL,
+                0, pdata, sizeof(*pdata));
+}
index 9d38da077edb121cfbcb065322be5e7251975463..9c3e36232b5b12b58bfe2bd0ee7140a76c960de5 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
@@ -201,11 +202,42 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
        }
 }
 
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param  irq          interrupt source number
+ * @param  enable       enable as wake-up if equal to non-zero
+ * @return       This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(u32 irq, u32 enable)
+{
+       u32 gpio = irq_to_gpio(irq);
+       u32 gpio_idx = gpio & 0x1F;
+       struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
+
+       if (enable) {
+               if (port->irq_high && (gpio_idx >= 16))
+                       enable_irq_wake(port->irq_high);
+               else
+                       enable_irq_wake(port->irq);
+       } else {
+               if (port->irq_high && (gpio_idx >= 16))
+                       disable_irq_wake(port->irq_high);
+               else
+                       disable_irq_wake(port->irq);
+       }
+
+       return 0;
+}
+
 static struct irq_chip gpio_irq_chip = {
        .ack = gpio_ack_irq,
        .mask = gpio_mask_irq,
        .unmask = gpio_unmask_irq,
        .set_type = gpio_set_irq_type,
+       .set_wake = gpio_set_wake_irq,
 };
 
 static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
index 86d7575a564dba0c550e93d668fe35e0b44b1dff..8c6896fd1e5ff8415213f1c656820a08f9aabf9d 100644 (file)
@@ -29,6 +29,10 @@ struct platform_device *__init imx_add_flexcan(int id,
                resource_size_t irq,
                const struct flexcan_platform_data *pdata);
 
+#include <linux/gpio_keys.h>
+struct platform_device *__init imx_add_gpio_keys(
+               const struct gpio_keys_platform_data *pdata);
+
 #include <mach/i2c.h>
 struct imx_imx_i2c_data {
        int id;
index e46b1c2836d4c6d42a095eeae4a06ccc15f8d896..d7a41e9a26050e70f1ebd442ae126f9c7a8bf3fa 100644 (file)
@@ -45,6 +45,8 @@ typedef enum iomux_config {
                                PAD_CTL_PKE | PAD_CTL_HYS)
 #define MX51_GPIO_PAD_CTRL             (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \
                                PAD_CTL_SRE_FAST)
+#define MX51_GPIO_PAD_CTRL_2   (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
+                                       PAD_CTL_PUS_100K_UP)
 #define MX51_ECSPI_PAD_CTRL    (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
                                PAD_CTL_SRE_FAST)
 #define MX51_SDHCI_PAD_CTRL    (PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \
index 03e2afabc9fc15b662e1bc444c3ff6df4890f519..61cfe827498b2a8580351575e9a1d15211b21f1f 100644 (file)
@@ -240,7 +240,6 @@ static inline void mx31_setup_weimcs(size_t cs,
 #define MPEG4_ENC_BASE_ADDR MX31_MPEG4_ENC_BASE_ADDR
 #define MXC_INT_MPEG4_ENCODER MX31_INT_MPEG4_ENCODER
 #define MXC_INT_FIRI MX31_INT_FIRI
-#define MXC_INT_MMC_SDHC1 MX31_INT_MMC_SDHC1
 #define MXC_INT_MBX MX31_INT_MBX
 #define MXC_INT_CSPI3 MX31_INT_CSPI3
 #define MXC_INT_SIM2 MX31_INT_SIM2
index ff905cb324589f6c163aa9cd2d7996a017afe6bc..6267cff6035d56532054e6d0503a8ad32ff77047 100644 (file)
 /* these should go away */
 #define MXC_FEC_BASE_ADDR MX35_FEC_BASE_ADDR
 #define MXC_INT_OWIRE MX35_INT_OWIRE
-#define MXC_INT_MMC_SDHC2 MX35_INT_MMC_SDHC2
-#define MXC_INT_MMC_SDHC3 MX35_INT_MMC_SDHC3
 #define MXC_INT_GPU2D MX35_INT_GPU2D
 #define MXC_INT_ASRC MX35_INT_ASRC
 #define MXC_INT_USBHS MX35_INT_USBHS
index a790bf2129720c3e13a747fcf9e439229d7e4c9d..a42c7207082d589a82c51f207b79e776ddee735e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
  *
  * This program is free software; you can redistribute it and/or
@@ -20,6 +20,8 @@
 #ifndef __ASM_ARCH_MXC_H__
 #define __ASM_ARCH_MXC_H__
 
+#include <linux/types.h>
+
 #ifndef __ASM_ARCH_MXC_HARDWARE_H__
 #error "Do not include directly."
 #endif
@@ -133,6 +135,15 @@ extern unsigned int __mxc_cpu_type;
 # define cpu_is_mxc91231()     (0)
 #endif
 
+#ifndef __ASSEMBLY__
+
+struct cpu_op {
+       u32 cpu_rate;
+};
+
+extern struct cpu_op *(*get_cpu_op)(int *op);
+#endif
+
 #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
 /* These are deprecated, use mx[23][157]_setup_weimcs instead. */
 #define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10))
index 6f42a18b8aa417abc5622bf9492d9a4587111738..fc819120978dbe9e722903c95296aa6faa7a6f4e 100644 (file)
@@ -284,12 +284,14 @@ void __init omap_dsp_reserve_sdram_memblock(void)
        if (!size)
                return;
 
-       paddr = __memblock_alloc_base(size, SZ_1M, MEMBLOCK_REAL_LIMIT);
+       paddr = memblock_alloc(size, SZ_1M);
        if (!paddr) {
                pr_err("%s: failed to reserve %x bytes\n",
                                __func__, size);
                return;
        }
+       memblock_free(paddr, size);
+       memblock_remove(paddr, size);
 
        omap_dsp_phys_mempool_base = paddr;
 }
index f5c5b8da9a87f194683afa8b51ebecb39e53f302..2c2826571d45856145f7a31a416edee84b13802e 100644 (file)
@@ -1983,6 +1983,8 @@ static int omap2_dma_handle_ch(int ch)
 
        dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch));
        dma_write(1 << ch, IRQSTATUS_L0);
+       /* read back the register to flush the write */
+       dma_read(IRQSTATUS_L0);
 
        /* If the ch is not chained then chain_id will be -1 */
        if (dma_chan[ch].chain_id != -1) {
index 3ebfef72b4e700406f43131349eda135747a3304..cc99163e73fdbde0f4945a93c35cdd5830c25ac5 100644 (file)
 #ifndef __PLAT_PCIE_H
 #define __PLAT_PCIE_H
 
+struct pci_bus;
+
 u32 orion_pcie_dev_id(void __iomem *base);
 u32 orion_pcie_rev(void __iomem *base);
 int orion_pcie_link_up(void __iomem *base);
 int orion_pcie_x4_mode(void __iomem *base);
 int orion_pcie_get_local_bus_nr(void __iomem *base);
 void orion_pcie_set_local_bus_nr(void __iomem *base, int nr);
+void orion_pcie_reset(void __iomem *base);
 void orion_pcie_setup(void __iomem *base,
                      struct mbus_dram_target_info *dram);
 int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus,
index 779553a1595e938ead6a4764e84ee8d87087acb9..af2d733c50b5cf9a32ec07932a1b64131d95ca46 100644 (file)
@@ -181,11 +181,6 @@ void __init orion_pcie_setup(void __iomem *base,
        u16 cmd;
        u32 mask;
 
-       /*
-        * soft reset PCIe unit
-        */
-       orion_pcie_reset(base);
-
        /*
         * Point PCIe unit MBUS decode windows to DRAM space.
         */
index 3478eae32d8a8b8fe130e4e5c5f2c8f8a4694476..01a8448e471c8b4317452d3f4f208d64e27799bc 100644 (file)
@@ -30,15 +30,15 @@ struct pxa3xx_nand_cmdset {
 };
 
 struct pxa3xx_nand_flash {
-       const struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
-       const struct pxa3xx_nand_cmdset *cmdset;
-
-       uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
-       uint32_t page_size;     /* Page size in bytes (PAGE_SZ) */
-       uint32_t flash_width;   /* Width of Flash memory (DWIDTH_M) */
-       uint32_t dfc_width;     /* Width of flash controller(DWIDTH_C) */
-       uint32_t num_blocks;    /* Number of physical blocks in Flash */
-       uint32_t chip_id;
+       uint32_t        chip_id;
+       unsigned int    page_per_block; /* Pages per block (PG_PER_BLK) */
+       unsigned int    page_size;      /* Page size in bytes (PAGE_SZ) */
+       unsigned int    flash_width;    /* Width of Flash memory (DWIDTH_M) */
+       unsigned int    dfc_width;      /* Width of flash controller(DWIDTH_C) */
+       unsigned int    num_blocks;     /* Number of physical blocks in Flash */
+
+       struct pxa3xx_nand_cmdset *cmdset;      /* NAND command set */
+       struct pxa3xx_nand_timing *timing;      /* NAND Flash timing */
 };
 
 struct pxa3xx_nand_platform_data {
index 984bf66826d2a54773a57a316839ab346c1e6b1e..5a27b1b538f2885eab6cd6ccdfd670834607f665 100644 (file)
@@ -69,6 +69,7 @@ config S3C24XX_GPIO_EXTRA
        int
        default 128 if S3C24XX_GPIO_EXTRA128
        default 64 if S3C24XX_GPIO_EXTRA64
+       default 16 if ARCH_H1940
        default 0
 
 config S3C24XX_GPIO_EXTRA64
index 7b44d0c592b54b3e758c4bb4fa8085e6eb61a8a0..bcc43f3462725259f36573babf980e707eebbc81 100644 (file)
@@ -147,7 +147,7 @@ static struct mtd_partition smdk_default_nand_part[] = {
        [7] = {
                .name   = "S3C2410 flash partition 7",
                .offset = SZ_1M * 48,
-               .size   = SZ_16M,
+               .size   = MTDPART_SIZ_FULL,
        }
 };
 
index 4c0896f2572d1ac1494920feb5805eb65b58e7bb..24c6f5a30596b3d8206ab16d711ab202e5d99ad8 100644 (file)
@@ -74,11 +74,6 @@ static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
        return -EINVAL;
 }
 
-static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
-{
-       return IRQ_EINT8 + offset;
-}
-
 static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
        .set_config     = s3c_gpio_setcfg_s3c24xx_a,
        .get_config     = s3c_gpio_getcfg_s3c24xx_a,
@@ -87,6 +82,8 @@ static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
 struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
        .set_config     = s3c_gpio_setcfg_s3c24xx,
        .get_config     = s3c_gpio_getcfg_s3c24xx,
+       .set_pull       = s3c_gpio_setpull_1up,
+       .get_pull       = s3c_gpio_getpull_1up,
 };
 
 struct s3c_gpio_chip s3c24xx_gpios[] = {
@@ -157,12 +154,13 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
        [6] = {
                .base   = S3C2410_GPGCON,
                .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
+               .irq_base = IRQ_EINT8,
                .chip   = {
                        .base                   = S3C2410_GPG(0),
                        .owner                  = THIS_MODULE,
                        .label                  = "GPIOG",
                        .ngpio                  = 16,
-                       .to_irq                 = s3c24xx_gpiolib_bankg_toirq,
+                       .to_irq                 = samsung_gpiolib_to_irq,
                },
        }, {
                .base   = S3C2410_GPHCON,
index 25960966af7c7f1acf54c168ddc06e36ca97b91c..65dbfa8e0a860ecb27e9a804c391a23af23f0e2e 100644 (file)
@@ -32,6 +32,11 @@ config S5P_EXT_INT
          Use the external interrupts (other than GPIO interrupts.)
          Note: Do not choose this for S5P6440 and S5P6450.
 
+config S5P_GPIO_INT
+       bool
+       help
+         Common code for the GPIO interrupts (other than external interrupts.)
+
 config S5P_DEV_FIMC0
        bool
        help
index f3e917e27da870341a5d7c9d6b0c56b5964f9430..de65238a7aefc3ec423bde8ee00d65e391208543 100644 (file)
@@ -18,6 +18,9 @@ obj-y                         += cpu.o
 obj-y                          += clock.o
 obj-y                          += irq.o
 obj-$(CONFIG_S5P_EXT_INT)      += irq-eint.o
+obj-$(CONFIG_S5P_GPIO_INT)     += irq-gpioint.o
+obj-$(CONFIG_PM)               += pm.o
+obj-$(CONFIG_PM)               += irq-pm.o
 
 # devices
 
index 8aaf4e6b60c300760c443aa6fe4548fe165ff3b6..8d081d968c58ddec76c40beef9a452e5511f68f7 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/io.h>
 #include <asm/div64.h>
 
+#include <mach/regs-clock.h>
+
 #include <plat/clock.h>
 #include <plat/clock-clksrc.h>
 #include <plat/s5p-clock.h>
@@ -88,14 +90,6 @@ struct clk clk_fout_vpll = {
        .ctrlbit        = (1 << 31),
 };
 
-/* ARM clock */
-struct clk clk_arm = {
-       .name           = "armclk",
-       .id             = -1,
-       .rate           = 0,
-       .ctrlbit        = 0,
-};
-
 /* Possible clock sources for APLL Mux */
 static struct clk *clk_src_apll_list[] = {
        [0] = &clk_fin_apll,
@@ -156,6 +150,24 @@ int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
        return 0;
 }
 
+int s5p_epll_enable(struct clk *clk, int enable)
+{
+       unsigned int ctrlbit = clk->ctrlbit;
+       unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
+
+       if (enable)
+               __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
+       else
+               __raw_writel(epll_con, S5P_EPLL_CON);
+
+       return 0;
+}
+
+unsigned long s5p_epll_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
 static struct clk *s5p_clks[] __initdata = {
        &clk_ext_xtal_mux,
        &clk_48m,
@@ -165,7 +177,6 @@ static struct clk *s5p_clks[] __initdata = {
        &clk_fout_epll,
        &clk_fout_dpll,
        &clk_fout_vpll,
-       &clk_arm,
        &clk_vpll,
        &clk_xusbxti,
 };
index 3fb3a3a1746505fc376e20a13cdfe153842db8cb..ba9121c60a2a7ba919fdb1c1653c29f818ca0d9a 100644 (file)
                                                ((irq) - S5P_EINT_BASE1) : \
                                                ((irq) + 16 - S5P_EINT_BASE2))
 
+#define IRQ_EINT_BIT(x)                EINT_OFFSET(x)
+
+/* Typically only a few gpio chips require gpio interrupt support.
+   To avoid memory waste irq descriptors are allocated only for
+   S5P_GPIOINT_GROUP_COUNT chips, each with total number of
+   S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
+   to any gpio chip with the s5p_register_gpio_interrupt() function */
+#define S5P_GPIOINT_GROUP_COUNT 4
+#define S5P_GPIOINT_GROUP_SIZE 8
+#define S5P_GPIOINT_COUNT      (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
+
+/* IRQ types common for all s5p platforms */
+#define S5P_IRQ_TYPE_LEVEL_LOW         (0x00)
+#define S5P_IRQ_TYPE_LEVEL_HIGH                (0x01)
+#define S5P_IRQ_TYPE_EDGE_FALLING      (0x02)
+#define S5P_IRQ_TYPE_EDGE_RISING       (0x03)
+#define S5P_IRQ_TYPE_EDGE_BOTH         (0x04)
+
 #endif /* __ASM_PLAT_S5P_IRQS_H */
index c4ff88bf6477d2797b6ba578c768b0edadaba073..fef353d44513dee5b1f3361fc4524680391ba1ea 100644 (file)
 #ifndef __ASM_PLAT_MAP_S5P_H
 #define __ASM_PLAT_MAP_S5P_H __FILE__
 
-#define S5P_VA_CHIPID          S3C_ADDR(0x00700000)
-#define S5P_VA_GPIO            S3C_ADDR(0x00500000)
-#define S5P_VA_SYSTIMER                S3C_ADDR(0x01200000)
-#define S5P_VA_SROMC           S3C_ADDR(0x01100000)
-#define S5P_VA_SYSRAM          S3C_ADDR(0x01180000)
-
-#define S5P_VA_COMBINER_BASE   S3C_ADDR(0x00600000)
+#define S5P_VA_CHIPID          S3C_ADDR(0x02000000)
+#define S5P_VA_CMU             S3C_ADDR(0x02100000)
+#define S5P_VA_GPIO            S3C_ADDR(0x02200000)
+#define S5P_VA_GPIO1           S5P_VA_GPIO
+#define S5P_VA_GPIO2           S3C_ADDR(0x02240000)
+#define S5P_VA_GPIO3           S3C_ADDR(0x02280000)
+
+#define S5P_VA_SYSRAM          S3C_ADDR(0x02400000)
+#define S5P_VA_DMC0            S3C_ADDR(0x02440000)
+#define S5P_VA_DMC1            S3C_ADDR(0x02480000)
+#define S5P_VA_SROMC           S3C_ADDR(0x024C0000)
+
+#define S5P_VA_SYSTIMER                S3C_ADDR(0x02500000)
+#define S5P_VA_L2CC            S3C_ADDR(0x02600000)
+
+#define S5P_VA_COMBINER_BASE   S3C_ADDR(0x02700000)
 #define S5P_VA_COMBINER(x)     (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10)
 
-#define S5P_VA_COREPERI_BASE   S3C_ADDR(0x00800000)
+#define S5P_VA_COREPERI_BASE   S3C_ADDR(0x02800000)
 #define S5P_VA_COREPERI(x)     (S5P_VA_COREPERI_BASE + (x))
 #define S5P_VA_SCU             S5P_VA_COREPERI(0x0)
 #define S5P_VA_GIC_CPU         S5P_VA_COREPERI(0x100)
 #define S5P_VA_TWD             S5P_VA_COREPERI(0x600)
 #define S5P_VA_GIC_DIST                S5P_VA_COREPERI(0x1000)
 
-#define S5P_VA_L2CC            S3C_ADDR(0x00900000)
-#define S5P_VA_CMU             S3C_ADDR(0x00920000)
+#define S3C_VA_USB_HSPHY       S3C_ADDR(0x02900000)
+
+#define VA_VIC(x)              (S3C_VA_IRQ + ((x) * 0x10000))
+#define VA_VIC0                        VA_VIC(0)
+#define VA_VIC1                        VA_VIC(1)
+#define VA_VIC2                        VA_VIC(2)
+#define VA_VIC3                        VA_VIC(3)
 
 #define S5P_VA_UART(x)         (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
 #define S5P_VA_UART0           S5P_VA_UART(0)
 #define S3C_UART_OFFSET                (0x400)
 #endif
 
-#define VA_VIC(x)              (S3C_VA_IRQ + ((x) * 0x10000))
-#define VA_VIC0                        VA_VIC(0)
-#define VA_VIC1                        VA_VIC(1)
-#define VA_VIC2                        VA_VIC(2)
-#define VA_VIC3                        VA_VIC(3)
-
 #endif /* __ASM_PLAT_MAP_S5P_H */
index 17036c898409adafc0756b2064bb77e9f1e8e187..2b6dcff8ab2beb4ccf80c452d78e7ece974e0e64 100644 (file)
@@ -43,4 +43,8 @@ extern struct clksrc_sources clk_src_dpll;
 
 extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
 
+/* Common EPLL operations for S5P platform */
+extern int s5p_epll_enable(struct clk *clk, int enable);
+extern unsigned long s5p_epll_get_rate(struct clk *clk);
+
 #endif /* __ASM_PLAT_S5P_CLOCK_H */
index f36cd3327025ad1788cd6e163e94c069b4a77718..752f1a645f9dcfad3c69e7d0c5ca8ddf71dc5d45 100644 (file)
@@ -67,23 +67,23 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
 
        switch (type) {
        case IRQ_TYPE_EDGE_RISING:
-               newvalue = S5P_EXTINT_RISEEDGE;
+               newvalue = S5P_IRQ_TYPE_EDGE_RISING;
                break;
 
        case IRQ_TYPE_EDGE_FALLING:
-               newvalue = S5P_EXTINT_FALLEDGE;
+               newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
                break;
 
        case IRQ_TYPE_EDGE_BOTH:
-               newvalue = S5P_EXTINT_BOTHEDGE;
+               newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
                break;
 
        case IRQ_TYPE_LEVEL_LOW:
-               newvalue = S5P_EXTINT_LOWLEV;
+               newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
                break;
 
        case IRQ_TYPE_LEVEL_HIGH:
-               newvalue = S5P_EXTINT_HILEV;
+               newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
                break;
 
        default:
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
new file mode 100644 (file)
index 0000000..0e5dc8c
--- /dev/null
@@ -0,0 +1,237 @@
+/* linux/arch/arm/plat-s5p/irq-gpioint.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * Author: Kyungmin Park <kyungmin.park@samsung.com>
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+
+#define S5P_GPIOREG(x)                 (S5P_VA_GPIO + (x))
+
+#define GPIOINT_CON_OFFSET             0x700
+#define GPIOINT_MASK_OFFSET            0x900
+#define GPIOINT_PEND_OFFSET            0xA00
+
+static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
+
+static int s5p_gpioint_get_group(unsigned int irq)
+{
+       struct gpio_chip *chip = get_irq_data(irq);
+       struct s3c_gpio_chip *s3c_chip = container_of(chip,
+                       struct s3c_gpio_chip, chip);
+       int group;
+
+       for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++)
+               if (s3c_chip == irq_chips[group])
+                       break;
+
+       return group;
+}
+
+static int s5p_gpioint_get_offset(unsigned int irq)
+{
+       struct gpio_chip *chip = get_irq_data(irq);
+       struct s3c_gpio_chip *s3c_chip = container_of(chip,
+                       struct s3c_gpio_chip, chip);
+
+       return irq - s3c_chip->irq_base;
+}
+
+static void s5p_gpioint_ack(unsigned int irq)
+{
+       int group, offset, pend_offset;
+       unsigned int value;
+
+       group = s5p_gpioint_get_group(irq);
+       offset = s5p_gpioint_get_offset(irq);
+       pend_offset = group << 2;
+
+       value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
+       value |= 1 << offset;
+       __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
+}
+
+static void s5p_gpioint_mask(unsigned int irq)
+{
+       int group, offset, mask_offset;
+       unsigned int value;
+
+       group = s5p_gpioint_get_group(irq);
+       offset = s5p_gpioint_get_offset(irq);
+       mask_offset = group << 2;
+
+       value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+       value |= 1 << offset;
+       __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+}
+
+static void s5p_gpioint_unmask(unsigned int irq)
+{
+       int group, offset, mask_offset;
+       unsigned int value;
+
+       group = s5p_gpioint_get_group(irq);
+       offset = s5p_gpioint_get_offset(irq);
+       mask_offset = group << 2;
+
+       value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+       value &= ~(1 << offset);
+       __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+}
+
+static void s5p_gpioint_mask_ack(unsigned int irq)
+{
+       s5p_gpioint_mask(irq);
+       s5p_gpioint_ack(irq);
+}
+
+static int s5p_gpioint_set_type(unsigned int irq, unsigned int type)
+{
+       int group, offset, con_offset;
+       unsigned int value;
+
+       group = s5p_gpioint_get_group(irq);
+       offset = s5p_gpioint_get_offset(irq);
+       con_offset = group << 2;
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               type = S5P_IRQ_TYPE_EDGE_RISING;
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               type = S5P_IRQ_TYPE_EDGE_FALLING;
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+               type = S5P_IRQ_TYPE_EDGE_BOTH;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               type = S5P_IRQ_TYPE_LEVEL_HIGH;
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               type = S5P_IRQ_TYPE_LEVEL_LOW;
+               break;
+       case IRQ_TYPE_NONE:
+       default:
+               printk(KERN_WARNING "No irq type\n");
+               return -EINVAL;
+       }
+
+       value = __raw_readl(S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
+       value &= ~(0x7 << (offset * 0x4));
+       value |= (type << (offset * 0x4));
+       __raw_writel(value, S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
+
+       return 0;
+}
+
+struct irq_chip s5p_gpioint = {
+       .name           = "s5p_gpioint",
+       .ack            = s5p_gpioint_ack,
+       .mask           = s5p_gpioint_mask,
+       .mask_ack       = s5p_gpioint_mask_ack,
+       .unmask         = s5p_gpioint_unmask,
+       .set_type       = s5p_gpioint_set_type,
+};
+
+static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
+{
+       int group, offset, pend_offset, mask_offset;
+       int real_irq;
+       unsigned int pend, mask;
+
+       for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
+               pend_offset = group << 2;
+               pend = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) +
+                               pend_offset);
+               if (!pend)
+                       continue;
+
+               mask_offset = group << 2;
+               mask = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) +
+                               mask_offset);
+               pend &= ~mask;
+
+               for (offset = 0; offset < 8; offset++) {
+                       if (pend & (1 << offset)) {
+                               struct s3c_gpio_chip *chip = irq_chips[group];
+                               if (chip) {
+                                       real_irq = chip->irq_base + offset;
+                                       generic_handle_irq(real_irq);
+                               }
+                       }
+               }
+       }
+}
+
+static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
+{
+       static int used_gpioint_groups = 0;
+       static bool handler_registered = 0;
+       int irq, group = chip->group;
+       int i;
+
+       if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
+               return -ENOMEM;
+
+       chip->irq_base = S5P_GPIOINT_BASE +
+                        used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
+       used_gpioint_groups++;
+
+       if (!handler_registered) {
+               set_irq_chained_handler(IRQ_GPIOINT, s5p_gpioint_handler);
+               handler_registered = 1;
+       }
+
+       irq_chips[group] = chip;
+       for (i = 0; i < chip->chip.ngpio; i++) {
+               irq = chip->irq_base + i;
+               set_irq_chip(irq, &s5p_gpioint);
+               set_irq_data(irq, &chip->chip);
+               set_irq_handler(irq, handle_level_irq);
+               set_irq_flags(irq, IRQF_VALID);
+       }
+       return 0;
+}
+
+int __init s5p_register_gpio_interrupt(int pin)
+{
+       struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin);
+       int offset, group;
+       int ret;
+
+       if (!my_chip)
+               return -EINVAL;
+
+       offset = pin - my_chip->chip.base;
+       group = my_chip->group;
+
+       /* check if the group has been already registered */
+       if (my_chip->irq_base)
+               return my_chip->irq_base + offset;
+
+       /* register gpio group */
+       ret = s5p_gpioint_add(my_chip);
+       if (ret == 0) {
+               my_chip->chip.to_irq = samsung_gpiolib_to_irq;
+               printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
+                      group);
+               return my_chip->irq_base + offset;
+       }
+       return ret;
+}
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
new file mode 100644 (file)
index 0000000..dc33b9e
--- /dev/null
@@ -0,0 +1,93 @@
+/* linux/arch/arm/plat-s5p/irq-pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Based on arch/arm/plat-s3c24xx/irq-pm.c,
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+
+#include <plat/cpu.h>
+#include <plat/irqs.h>
+#include <plat/pm.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM,
+ * as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow     = 0x00000006L;
+unsigned long s3c_irqwake_eintallow    = 0xffffffffL;
+
+int s3c_irq_wake(unsigned int irqno, unsigned int state)
+{
+       unsigned long irqbit;
+
+       switch (irqno) {
+       case IRQ_RTC_TIC:
+       case IRQ_RTC_ALARM:
+               irqbit = 1 << (irqno + 1 - IRQ_RTC_ALARM);
+               if (!state)
+                       s3c_irqwake_intmask |= irqbit;
+               else
+                       s3c_irqwake_intmask &= ~irqbit;
+               break;
+       default:
+               return -ENOENT;
+       }
+       return 0;
+}
+
+static struct sleep_save eint_save[] = {
+       SAVE_ITEM(S5P_EINT_CON(0)),
+       SAVE_ITEM(S5P_EINT_CON(1)),
+       SAVE_ITEM(S5P_EINT_CON(2)),
+       SAVE_ITEM(S5P_EINT_CON(3)),
+
+       SAVE_ITEM(S5P_EINT_FLTCON(0)),
+       SAVE_ITEM(S5P_EINT_FLTCON(1)),
+       SAVE_ITEM(S5P_EINT_FLTCON(2)),
+       SAVE_ITEM(S5P_EINT_FLTCON(3)),
+       SAVE_ITEM(S5P_EINT_FLTCON(4)),
+       SAVE_ITEM(S5P_EINT_FLTCON(5)),
+       SAVE_ITEM(S5P_EINT_FLTCON(6)),
+       SAVE_ITEM(S5P_EINT_FLTCON(7)),
+
+       SAVE_ITEM(S5P_EINT_MASK(0)),
+       SAVE_ITEM(S5P_EINT_MASK(1)),
+       SAVE_ITEM(S5P_EINT_MASK(2)),
+       SAVE_ITEM(S5P_EINT_MASK(3)),
+};
+
+int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+{
+       s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
+
+       return 0;
+}
+
+int s3c24xx_irq_resume(struct sys_device *dev)
+{
+       s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
+
+       return 0;
+}
+
diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c
new file mode 100644 (file)
index 0000000..d592b63
--- /dev/null
@@ -0,0 +1,52 @@
+/* linux/arch/arm/plat-s5p/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * S5P Power Manager (Suspend-To-RAM) support
+ *
+ * Based on arch/arm/plat-s3c24xx/pm.c
+ * Copyright (c) 2004,2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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 <linux/suspend.h>
+#include <plat/pm.h>
+
+#define PFX "s5p pm: "
+
+/* s3c_pm_check_resume_pin
+ *
+ * check to see if the pin is configured correctly for sleep mode, and
+ * make any necessary adjustments if it is not
+*/
+
+static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
+{
+       /* nothing here yet */
+}
+
+/* s3c_pm_configure_extint
+ *
+ * configure all external interrupt pins
+*/
+
+void s3c_pm_configure_extint(void)
+{
+       /* nothing here yet */
+}
+
+void s3c_pm_restore_core(void)
+{
+       /* nothing here yet */
+}
+
+void s3c_pm_save_core(void)
+{
+       /* nothing here yet */
+}
+
index 7c0bde78116755dde5d24799b45ecedb36bb8b8b..dcd6eff4ee53840e8082ce4ae84b08a7e3cef4e8 100644 (file)
@@ -180,6 +180,31 @@ config S3C_DEV_I2C2
        help
          Compile in platform device definitions for I2C channel 2
 
+config S3C_DEV_I2C3
+       bool
+       help
+         Compile in platform device definition for I2C controller 3
+
+config S3C_DEV_I2C4
+       bool
+       help
+         Compile in platform device definition for I2C controller 4
+
+config S3C_DEV_I2C5
+       bool
+       help
+         Compile in platform device definition for I2C controller 5
+
+config S3C_DEV_I2C6
+       bool
+       help
+         Compile in platform device definition for I2C controller 6
+
+config S3C_DEV_I2C7
+       bool
+       help
+         Compile in platform device definition for I2C controller 7
+
 config S3C_DEV_FB
        bool
        help
index 4d8ff923207a9d83dafaad2b561ad7313e9aaf5a..afcce474af8e86d692a5a579387055bcf808cc3c 100644 (file)
@@ -40,6 +40,11 @@ obj-$(CONFIG_S3C_DEV_HWMON)  += dev-hwmon.o
 obj-y                          += dev-i2c0.o
 obj-$(CONFIG_S3C_DEV_I2C1)     += dev-i2c1.o
 obj-$(CONFIG_S3C_DEV_I2C2)     += dev-i2c2.o
+obj-$(CONFIG_S3C_DEV_I2C3)     += dev-i2c3.o
+obj-$(CONFIG_S3C_DEV_I2C4)     += dev-i2c4.o
+obj-$(CONFIG_S3C_DEV_I2C5)     += dev-i2c5.o
+obj-$(CONFIG_S3C_DEV_I2C6)     += dev-i2c6.o
+obj-$(CONFIG_S3C_DEV_I2C7)     += dev-i2c7.o
 obj-$(CONFIG_S3C_DEV_FB)       += dev-fb.o
 obj-y                          += dev-uart.o
 obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
index 9d2be0941410946877f042c6d36976bc93103b92..db7a65c7f127a62b93ee78ba450c6d3bbaec69a8 100644 (file)
@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
        .max_width      = 4,
        .host_caps      = (MMC_CAP_4_BIT_DATA |
                           MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
 };
 
 struct platform_device s3c_device_hsmmc0 = {
@@ -59,17 +60,20 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
 {
        struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
 
-       set->max_width = pd->max_width;
        set->cd_type = pd->cd_type;
        set->ext_cd_init = pd->ext_cd_init;
        set->ext_cd_cleanup = pd->ext_cd_cleanup;
        set->ext_cd_gpio = pd->ext_cd_gpio;
        set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
 
+       if (pd->max_width)
+               set->max_width = pd->max_width;
        if (pd->cfg_gpio)
                set->cfg_gpio = pd->cfg_gpio;
        if (pd->cfg_card)
                set->cfg_card = pd->cfg_card;
        if (pd->host_caps)
-               set->host_caps = pd->host_caps;
+               set->host_caps |= pd->host_caps;
+       if (pd->clk_type)
+               set->clk_type = pd->clk_type;
 }
index a6c8295840afdb23fa61d91815915a902dc42602..2497321f08d7ddc3a17fb3e9eedb6293cbb6df97 100644 (file)
@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
        .max_width      = 4,
        .host_caps      = (MMC_CAP_4_BIT_DATA |
                           MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
 };
 
 struct platform_device s3c_device_hsmmc1 = {
@@ -59,17 +60,20 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
 {
        struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
 
-       set->max_width = pd->max_width;
        set->cd_type = pd->cd_type;
        set->ext_cd_init = pd->ext_cd_init;
        set->ext_cd_cleanup = pd->ext_cd_cleanup;
        set->ext_cd_gpio = pd->ext_cd_gpio;
        set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
 
+       if (pd->max_width)
+               set->max_width = pd->max_width;
        if (pd->cfg_gpio)
                set->cfg_gpio = pd->cfg_gpio;
        if (pd->cfg_card)
                set->cfg_card = pd->cfg_card;
        if (pd->host_caps)
-               set->host_caps = pd->host_caps;
+               set->host_caps |= pd->host_caps;
+       if (pd->clk_type)
+               set->clk_type = pd->clk_type;
 }
index cb0d7143381a1fe06cfbc75181339548d1309c82..f60aedba417cdaea81c7d53763359a9bf0871660 100644 (file)
@@ -42,6 +42,7 @@ struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
        .max_width      = 4,
        .host_caps      = (MMC_CAP_4_BIT_DATA |
                           MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
 };
 
 struct platform_device s3c_device_hsmmc2 = {
@@ -60,17 +61,20 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
 {
        struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
 
-       set->max_width = pd->max_width;
        set->cd_type = pd->cd_type;
        set->ext_cd_init = pd->ext_cd_init;
        set->ext_cd_cleanup = pd->ext_cd_cleanup;
        set->ext_cd_gpio = pd->ext_cd_gpio;
        set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
 
+       if (pd->max_width)
+               set->max_width = pd->max_width;
        if (pd->cfg_gpio)
                set->cfg_gpio = pd->cfg_gpio;
        if (pd->cfg_card)
                set->cfg_card = pd->cfg_card;
        if (pd->host_caps)
-               set->host_caps = pd->host_caps;
+               set->host_caps |= pd->host_caps;
+       if (pd->clk_type)
+               set->clk_type = pd->clk_type;
 }
index 85aaf0f2842f8ac1e214a3ecdd8d6102b9fffc26..ede776f20e62eb6d42f29fe768f50db2c4b20202 100644 (file)
@@ -33,8 +33,8 @@ static struct resource s3c_hsmmc3_resource[] = {
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = IRQ_MMC3,
-               .end    = IRQ_MMC3,
+               .start  = IRQ_HSMMC3,
+               .end    = IRQ_HSMMC3,
                .flags  = IORESOURCE_IRQ,
        }
 };
@@ -45,6 +45,7 @@ struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
        .max_width      = 4,
        .host_caps      = (MMC_CAP_4_BIT_DATA |
                           MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+       .clk_type       = S3C_SDHCI_CLK_DIV_INTERNAL,
 };
 
 struct platform_device s3c_device_hsmmc3 = {
@@ -63,15 +64,20 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
 {
        struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
 
-       set->max_width = pd->max_width;
        set->cd_type = pd->cd_type;
        set->ext_cd_init = pd->ext_cd_init;
        set->ext_cd_cleanup = pd->ext_cd_cleanup;
        set->ext_cd_gpio = pd->ext_cd_gpio;
        set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
 
+       if (pd->max_width)
+               set->max_width = pd->max_width;
        if (pd->cfg_gpio)
                set->cfg_gpio = pd->cfg_gpio;
        if (pd->cfg_card)
                set->cfg_card = pd->cfg_card;
+       if (pd->host_caps)
+               set->host_caps |= pd->host_caps;
+       if (pd->clk_type)
+               set->clk_type = pd->clk_type;
 }
index 07036dee09e7a9e261ed5e35bc1b741d0f5d5f00..ff4ba69b683013e358c3e2221351fecc7ff9241d 100644 (file)
@@ -32,8 +32,8 @@ static struct resource s3c_i2c_resource[] = {
                .flags = IORESOURCE_MEM,
        },
        [1] = {
-               .start = IRQ_CAN0,
-               .end   = IRQ_CAN0,
+               .start = IRQ_IIC2,
+               .end   = IRQ_IIC2,
                .flags = IORESOURCE_IRQ,
        },
 };
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c
new file mode 100644 (file)
index 0000000..8586a10
--- /dev/null
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 3
+ *
+ * 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 <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+       [0] = {
+               .start  = S3C_PA_IIC3,
+               .end    = S3C_PA_IIC3 + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_IIC3,
+               .end    = IRQ_IIC3,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c_device_i2c3 = {
+       .name           = "s3c2440-i2c",
+       .id             = 3,
+       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
+       .resource       = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data3 __initdata = {
+       .flags          = 0,
+       .bus_num        = 3,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+};
+
+void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd)
+               pd = &default_i2c_data3;
+
+       npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+       if (!npd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+       else if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c3_cfg_gpio;
+
+       s3c_device_i2c3.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c
new file mode 100644 (file)
index 0000000..df2159e
--- /dev/null
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c4.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 3
+ *
+ * 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 <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+       [0] = {
+               .start  = S3C_PA_IIC4,
+               .end    = S3C_PA_IIC4 + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_IIC4,
+               .end    = IRQ_IIC4,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c_device_i2c4 = {
+       .name           = "s3c2440-i2c",
+       .id             = 4,
+       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
+       .resource       = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data4 __initdata = {
+       .flags          = 0,
+       .bus_num        = 4,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+};
+
+void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd)
+               pd = &default_i2c_data4;
+
+       npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+       if (!npd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+       else if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c4_cfg_gpio;
+
+       s3c_device_i2c4.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c
new file mode 100644 (file)
index 0000000..0499c2c
--- /dev/null
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 3
+ *
+ * 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 <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+       [0] = {
+               .start  = S3C_PA_IIC5,
+               .end    = S3C_PA_IIC5 + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_IIC5,
+               .end    = IRQ_IIC5,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c_device_i2c5 = {
+       .name           = "s3c2440-i2c",
+       .id             = 5,
+       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
+       .resource       = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data5 __initdata = {
+       .flags          = 0,
+       .bus_num        = 5,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+};
+
+void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd)
+               pd = &default_i2c_data5;
+
+       npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+       if (!npd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+       else if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c5_cfg_gpio;
+
+       s3c_device_i2c5.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c
new file mode 100644 (file)
index 0000000..4083108
--- /dev/null
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c6.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 6
+ *
+ * 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 <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+       [0] = {
+               .start  = S3C_PA_IIC6,
+               .end    = S3C_PA_IIC6 + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_IIC6,
+               .end    = IRQ_IIC6,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c_device_i2c6 = {
+       .name           = "s3c2440-i2c",
+       .id             = 6,
+       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
+       .resource       = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data6 __initdata = {
+       .flags          = 0,
+       .bus_num        = 6,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+};
+
+void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd)
+               pd = &default_i2c_data6;
+
+       npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+       if (!npd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+       else if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c6_cfg_gpio;
+
+       s3c_device_i2c6.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c
new file mode 100644 (file)
index 0000000..1182451
--- /dev/null
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c7.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 7
+ *
+ * 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 <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+       [0] = {
+               .start  = S3C_PA_IIC7,
+               .end    = S3C_PA_IIC7 + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_IIC7,
+               .end    = IRQ_IIC7,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c_device_i2c7 = {
+       .name           = "s3c2440-i2c",
+       .id             = 7,
+       .num_resources  = ARRAY_SIZE(s3c_i2c_resource),
+       .resource       = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data7 __initdata = {
+       .flags          = 0,
+       .bus_num        = 7,
+       .slave_addr     = 0x10,
+       .frequency      = 100*1000,
+       .sda_delay      = 100,
+};
+
+void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+       struct s3c2410_platform_i2c *npd;
+
+       if (!pd)
+               pd = &default_i2c_data7;
+
+       npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+       if (!npd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+       else if (!npd->cfg_gpio)
+               npd->cfg_gpio = s3c_i2c7_cfg_gpio;
+
+       s3c_device_i2c7.dev.platform_data = npd;
+}
index e3d41eaed1ffd9feed571cef0af6bf5bf0841bf2..b732b773b9aff13fcc4a661b5405618aed363756 100644 (file)
@@ -41,6 +41,37 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
 }
 EXPORT_SYMBOL(s3c_gpio_cfgpin);
 
+int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
+                         unsigned int cfg)
+{
+       int ret;
+
+       for (; nr > 0; nr--, start++) {
+               ret = s3c_gpio_cfgpin(start, cfg);
+               if (ret != 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
+
+int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
+                         unsigned int cfg, s3c_gpio_pull_t pull)
+{
+       int ret;
+
+       for (; nr > 0; nr--, start++) {
+               s3c_gpio_setpull(start, pull);
+               ret = s3c_gpio_cfgpin(start, cfg);
+               if (ret != 0)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
+
 unsigned s3c_gpio_getcfg(unsigned int pin)
 {
        struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
@@ -80,6 +111,25 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
 }
 EXPORT_SYMBOL(s3c_gpio_setpull);
 
+s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
+{
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned long flags;
+       int offset;
+       u32 pup = 0;
+
+       if (chip) {
+               offset = pin - chip->chip.base;
+
+               s3c_gpio_lock(chip, flags);
+               pup = s3c_gpio_do_getpull(chip, offset);
+               s3c_gpio_unlock(chip, flags);
+       }
+
+       return (__force s3c_gpio_pull_t)pup;
+}
+EXPORT_SYMBOL(s3c_gpio_getpull);
+
 #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
 int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
                              unsigned int off, unsigned int cfg)
index b83a83351cea9dc456c6a7e5d660ecd273c057bb..7743c4b8b2fb5e539a673c5026521ee5810c130d 100644 (file)
@@ -157,3 +157,11 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
        if (ret >= 0)
                s3c_gpiolib_track(chip);
 }
+
+int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+       struct s3c_gpio_chip *s3c_chip = container_of(chip,
+                       struct s3c_gpio_chip, chip);
+
+       return s3c_chip->irq_base + offset;
+}
index e32f9edfd4b76f53bc538ae1988ef301f5121268..7712ff6336f4f9721ff67a5b2da03c885ebc8ca1 100644 (file)
 #define S3C64XX_AC97_GPE  1
 extern void s3c64xx_ac97_setup_gpio(int);
 
+/*
+ * The machine init code calls s5p*_spdif_setup_gpio with
+ * one of these defines in order to select appropriate bank
+ * of GPIO for S/PDIF pins
+ */
+#define S5PC100_SPDIF_GPD  0
+#define S5PC100_SPDIF_GPG3 1
+extern void s5pc100_spdif_setup_gpio(int);
+
 /**
  * struct s3c_audio_pdata - common platform data for audio device drivers
  * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
index c8b94279bad101037553659e73a4886aa44148bb..2d82a6cb1444010b2a8e84000bb49d1b5a08dda3 100644 (file)
@@ -48,6 +48,11 @@ extern struct platform_device s3c_device_wdt;
 extern struct platform_device s3c_device_i2c0;
 extern struct platform_device s3c_device_i2c1;
 extern struct platform_device s3c_device_i2c2;
+extern struct platform_device s3c_device_i2c3;
+extern struct platform_device s3c_device_i2c4;
+extern struct platform_device s3c_device_i2c5;
+extern struct platform_device s3c_device_i2c6;
+extern struct platform_device s3c_device_i2c7;
 extern struct platform_device s3c_device_rtc;
 extern struct platform_device s3c_device_adc;
 extern struct platform_device s3c_device_sdi;
@@ -89,6 +94,7 @@ extern struct platform_device s5pv210_device_pcm2;
 extern struct platform_device s5pv210_device_iis0;
 extern struct platform_device s5pv210_device_iis1;
 extern struct platform_device s5pv210_device_iis2;
+extern struct platform_device s5pv210_device_spdif;
 
 extern struct platform_device s5p6442_device_pcm0;
 extern struct platform_device s5p6442_device_pcm1;
@@ -108,6 +114,7 @@ extern struct platform_device s5pc100_device_pcm1;
 extern struct platform_device s5pc100_device_iis0;
 extern struct platform_device s5pc100_device_iis1;
 extern struct platform_device s5pc100_device_iis2;
+extern struct platform_device s5pc100_device_spdif;
 
 extern struct platform_device samsung_device_keypad;
 
index 3e21c75feefa4ab2015a773d4e9cea4f8b585829..8fd65d8b5863121192fa4eff36fcd33f5413a88a 100644 (file)
@@ -42,6 +42,12 @@ static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
        return (chip->config->set_pull)(chip, off, pull);
 }
 
+static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip,
+                                                 unsigned int off)
+{
+       return chip->config->get_pull(chip, off);
+}
+
 /**
  * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
  * @chip: The gpio chip that is being configured.
index 1c6b92947c5db7e8b955ac3831214bbf556bf2bb..e4b5cf126fa9bb96ce1a765be6d3d639528de217 100644 (file)
@@ -108,6 +108,19 @@ extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
  */
 extern unsigned s3c_gpio_getcfg(unsigned int pin);
 
+/**
+ * s3c_gpio_cfgpin_range() - Change the GPIO function for configuring pin range
+ * @start: The pin number to start at
+ * @nr: The number of pins to configure from @start.
+ * @cfg: The configuration for the pin's function
+ *
+ * Call s3c_gpio_cfgpin() for the @nr pins starting at @start.
+ *
+ * @sa s3c_gpio_cfgpin.
+ */
+extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
+                                unsigned int cfg);
+
 /* Define values for the pull-{up,down} available for each gpio pin.
  *
  * These values control the state of the weak pull-{up,down} resistors
@@ -140,6 +153,31 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
 */
 extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
 
+/* configure `all` aspects of an gpio */
+
+/**
+ * s3c_gpio_cfgall_range() - configure range of gpio functtion and pull.
+ * @start: The gpio number to start at.
+ * @nr: The number of gpio to configure from @start.
+ * @cfg: The configuration to use
+ * @pull: The pull setting to use.
+ *
+ * Run s3c_gpio_cfgpin() and s3c_gpio_setpull() over the gpio range starting
+ * @gpio and running for @size.
+ *
+ * @sa s3c_gpio_cfgpin
+ * @sa s3c_gpio_setpull
+ * @sa s3c_gpio_cfgpin_range
+ */
+extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
+                                unsigned int cfg, s3c_gpio_pull_t pull);
+
+static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size,
+                                          unsigned int cfg)
+{
+       return s3c_gpio_cfgall_range(pin, size, cfg, S3C_GPIO_PULL_NONE);
+}
+
 /* Define values for the drvstr available for each gpio pin.
  *
  * These values control the value of the output signal driver strength,
@@ -169,4 +207,22 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
 */
 extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
 
+/**
+ * s5p_register_gpio_interrupt() - register interrupt support for a gpio group
+ * @pin: The pin number from the group to be registered
+ *
+ * This function registers gpio interrupt support for the group that the
+ * specified pin belongs to.
+ *
+ * The total number of gpio pins is quite large ob s5p series. Registering
+ * irq support for all of them would be a resource waste. Because of that the
+ * interrupt support for standard gpio pins is registered dynamically.
+ *
+ * It will return the irq number of the interrupt that has been registered
+ * or -ENOMEM if no more gpio interrupts can be registered. It is allowed
+ * to call this function more than once for the same gpio group (the group
+ * will be registered only once).
+ */
+extern int s5p_register_gpio_interrupt(int pin);
+
 #endif /* __PLAT_GPIO_CFG_H */
index e358c7da8480e40e7e644d1c672b82558ac2362b..13a22b8861efd58bf45f3ca4155d57aa647f320e 100644 (file)
@@ -43,6 +43,8 @@ struct s3c_gpio_cfg;
  * struct s3c_gpio_chip - wrapper for specific implementation of gpio
  * @chip: The chip structure to be exported via gpiolib.
  * @base: The base pointer to the gpio configuration registers.
+ * @group: The group register number for gpio interrupt support.
+ * @irq_base: The base irq number.
  * @config: special function and pull-resistor control information.
  * @lock: Lock for exclusive access to this gpio bank.
  * @pm_save: Save information for suspend/resume support.
@@ -63,6 +65,8 @@ struct s3c_gpio_chip {
        struct s3c_gpio_cfg     *config;
        struct s3c_gpio_pm      *pm;
        void __iomem            *base;
+       int                     irq_base;
+       int                     group;
        spinlock_t               lock;
 #ifdef CONFIG_PM
        u32                     pm_save[4];
@@ -118,6 +122,17 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
 extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
 extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
 
+
+/**
+ * samsung_gpiolib_to_irq - convert gpio pin to irq number
+ * @chip: The gpio chip that the pin belongs to.
+ * @offset: The offset of the pin in the chip.
+ *
+ * This helper returns the irq number calculated from the chip->irq_base and
+ * the provided offset.
+ */
+extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset);
+
 /* exported for core SoC support to change */
 extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
 
index 133308bf595dcf775cf29626164e33ae02dedc25..1543da8f85c1727168f7f622182940ba27ce801b 100644 (file)
@@ -55,10 +55,20 @@ struct s3c2410_platform_i2c {
 extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
 extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
 extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
 
 /* defined by architecture to configure gpio */
 extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
 extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
 extern void s3c_i2c2_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c3_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c4_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c5_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c6_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
 
 #endif /* __ASM_ARCH_IIC_H */
index 250be311c85b1b8945eaf42ba00a3d8fbefdbad5..3ffac4d2e4f07be86e014418bd0b4e3f9aa0d46e 100644 (file)
@@ -14,7 +14,7 @@
 #ifndef __ASM_PLAT_MAP_H
 #define __ASM_PLAT_MAP_H __FILE__
 
-/* Fit all our registers in at 0xF4000000 upwards, trying to use as
+/* Fit all our registers in at 0xF6000000 upwards, trying to use as
  * little of the VA space as possible so vmalloc and friends have a
  * better chance of getting memory.
  *
@@ -22,7 +22,7 @@
  * an single MOVS instruction (ie, only 8 bits of set data)
  */
 
-#define S3C_ADDR_BASE  (0xF4000000)
+#define S3C_ADDR_BASE  0xF6000000
 
 #ifndef __ASSEMBLY__
 #define S3C_ADDR(x)    ((void __iomem __force *)S3C_ADDR_BASE + (x))
diff --git a/arch/arm/plat-samsung/include/plat/nand-core.h b/arch/arm/plat-samsung/include/plat/nand-core.h
new file mode 100644 (file)
index 0000000..6de2078
--- /dev/null
@@ -0,0 +1,28 @@
+/* arch/arm/plat-samsung/include/plat/nand-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S3C -  Nand Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_NAND_CORE_H
+#define __ASM_ARCH_NAND_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_nand_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_NAND
+       s3c_device_nand.name = name;
+#endif
+}
+
+#endif /* __ASM_ARCH_NAND_CORE_H */
index 30844c263d0338013c6ea13a11627723dab2345c..85853f8c4c5dc9f1546ccd5318edd1784a47cd81 100644 (file)
@@ -28,11 +28,17 @@ enum cd_types {
        S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
 };
 
+enum clk_types {
+       S3C_SDHCI_CLK_DIV_INTERNAL,     /* use mmc internal clock divider */
+       S3C_SDHCI_CLK_DIV_EXTERNAL,     /* use external clock divider */
+};
+
 /**
  * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
  * @max_width: The maximum number of data bits supported.
  * @host_caps: Standard MMC host capabilities bit field.
  * @cd_type: Type of Card Detection method (see cd_types enum above)
+ * @clk_type: Type of clock divider method (see clk_types enum above)
  * @ext_cd_init: Initialize external card detect subsystem. Called on
  *              sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
  *              notify_func argument is a callback to the sdhci-s3c driver
@@ -59,6 +65,7 @@ struct s3c_sdhci_platdata {
        unsigned int    max_width;
        unsigned int    host_caps;
        enum cd_types   cd_type;
+       enum clk_types  clk_type;
 
        char            **clocks;       /* set of clock sources */
 
@@ -110,6 +117,10 @@ extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
 extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
 extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
 extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
+extern void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
 
 /* S3C64XX SDHCI setup */
 
@@ -288,4 +299,57 @@ static inline void s5pv210_default_sdhci3(void) { }
 
 #endif /* CONFIG_S5PV210_SETUP_SDHCI */
 
+/* S5PV310 SDHCI setup */
+#ifdef CONFIG_S5PV310_SETUP_SDHCI
+extern char *s5pv310_hsmmc_clksrcs[4];
+
+extern void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev,
+                                          void __iomem *r,
+                                          struct mmc_ios *ios,
+                                          struct mmc_card *card);
+
+static inline void s5pv310_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+       s3c_hsmmc0_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
+       s3c_hsmmc0_def_platdata.cfg_gpio = s5pv310_setup_sdhci0_cfg_gpio;
+       s3c_hsmmc0_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s5pv310_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+       s3c_hsmmc1_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
+       s3c_hsmmc1_def_platdata.cfg_gpio = s5pv310_setup_sdhci1_cfg_gpio;
+       s3c_hsmmc1_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s5pv310_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+       s3c_hsmmc2_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
+       s3c_hsmmc2_def_platdata.cfg_gpio = s5pv310_setup_sdhci2_cfg_gpio;
+       s3c_hsmmc2_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s5pv310_default_sdhci3(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC3
+       s3c_hsmmc3_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
+       s3c_hsmmc3_def_platdata.cfg_gpio = s5pv310_setup_sdhci3_cfg_gpio;
+       s3c_hsmmc3_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
+#endif
+}
+
+#else
+static inline void s5pv310_default_sdhci0(void) { }
+static inline void s5pv310_default_sdhci1(void) { }
+static inline void s5pv310_default_sdhci2(void) { }
+static inline void s5pv310_default_sdhci3(void) { }
+
+#endif /* CONFIG_S5PV310_SETUP_SDHCI */
+
 #endif /* __PLAT_S3C_SDHCI_H */
index 7df03f87fbfabfd68c681afc25e6f78d8974f0ed..96528200eb79aae3ac06928930997e86102bb18c 100644 (file)
@@ -192,7 +192,7 @@ struct s3c_gpio_pm s3c_gpio_pm_2bit = {
        .resume = s3c_gpio_pm_2bit_resume,
 };
 
-#ifdef CONFIG_ARCH_S3C64XX
+#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
 static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
 {
        chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
@@ -302,7 +302,7 @@ struct s3c_gpio_pm s3c_gpio_pm_4bit = {
        .save   = s3c_gpio_pm_4bit_save,
        .resume = s3c_gpio_pm_4bit_resume,
 };
-#endif /* CONFIG_ARCH_S3C64XX */
+#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
 
 /**
  * s3c_pm_save_gpio() - save gpio chip data for suspend
index a91305a60aed9d67126153f481351cf22cb17aac..b4ff8d74ac40d21bc0bec763e050385938530252 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
 
 #include <asm/hardware/pl330.h>
 
@@ -27,6 +29,7 @@
  * @node: To attach to the global list of DMACs.
  * @pi: PL330 configuration info for the DMAC.
  * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
+ * @clk: Pointer of DMAC operation clock.
  */
 struct s3c_pl330_dmac {
        unsigned                busy_chan;
@@ -34,6 +37,7 @@ struct s3c_pl330_dmac {
        struct list_head        node;
        struct pl330_info       *pi;
        struct kmem_cache       *kmcache;
+       struct clk              *clk;
 };
 
 /**
@@ -1072,16 +1076,25 @@ static int pl330_probe(struct platform_device *pdev)
        if (ret)
                goto probe_err4;
 
-       ret = pl330_add(pl330_info);
-       if (ret)
-               goto probe_err5;
-
        /* Allocate a new DMAC */
        s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
        if (!s3c_pl330_dmac) {
                ret = -ENOMEM;
+               goto probe_err5;
+       }
+
+       /* Get operation clock and enable it */
+       s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma");
+       if (IS_ERR(s3c_pl330_dmac->clk)) {
+               dev_err(&pdev->dev, "Cannot get operation clock.\n");
+               ret = -EINVAL;
                goto probe_err6;
        }
+       clk_enable(s3c_pl330_dmac->clk);
+
+       ret = pl330_add(pl330_info);
+       if (ret)
+               goto probe_err7;
 
        /* Hook the info */
        s3c_pl330_dmac->pi = pl330_info;
@@ -1094,7 +1107,7 @@ static int pl330_probe(struct platform_device *pdev)
 
        if (!s3c_pl330_dmac->kmcache) {
                ret = -ENOMEM;
-               goto probe_err7;
+               goto probe_err8;
        }
 
        /* Get the list of peripherals */
@@ -1120,10 +1133,13 @@ static int pl330_probe(struct platform_device *pdev)
 
        return 0;
 
+probe_err8:
+       pl330_del(pl330_info);
 probe_err7:
-       kfree(s3c_pl330_dmac);
+       clk_disable(s3c_pl330_dmac->clk);
+       clk_put(s3c_pl330_dmac->clk);
 probe_err6:
-       pl330_del(pl330_info);
+       kfree(s3c_pl330_dmac);
 probe_err5:
        free_irq(irq, pl330_info);
 probe_err4:
@@ -1188,6 +1204,10 @@ static int pl330_remove(struct platform_device *pdev)
                }
        }
 
+       /* Disable operation clock */
+       clk_disable(dmac->clk);
+       clk_put(dmac->clk);
+
        /* Remove the DMAC */
        list_del(&dmac->node);
        kfree(dmac);
index 08bc44ea688313976e6d54b6cbb679e395271159..edae461b1c545d4f02e3c91ac664ec55012b9c4c 100644 (file)
@@ -320,7 +320,7 @@ static void bfin_correct_hw_break(void)
        }
 }
 
-void kgdb_disable_hw_debug(struct pt_regs *regs)
+static void bfin_disable_hw_debug(struct pt_regs *regs)
 {
        /* Disable hardware debugging while we are in kgdb */
        bfin_write_WPIACTL(0);
@@ -406,6 +406,7 @@ struct kgdb_arch arch_kgdb_ops = {
 #endif
        .set_hw_breakpoint = bfin_set_hw_break,
        .remove_hw_breakpoint = bfin_remove_hw_break,
+       .disable_hw_break = bfin_disable_hw_debug,
        .remove_all_hw_break = bfin_remove_all_hw_break,
        .correct_hw_break = bfin_correct_hw_break,
 };
index 6b1852f7f972b80fcccc06ba0214acc321cd84e5..39e534f5a3b05fc36c46d1e58b0c581c6c307bc5 100644 (file)
@@ -618,16 +618,15 @@ pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
 }
 
 
-static int
-pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data,
-            struct vfsmount *mnt)
+static struct dentry *
+pfmfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
 {
-       return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC, mnt);
+       return mount_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC);
 }
 
 static struct file_system_type pfm_fs_type = {
        .name     = "pfmfs",
-       .get_sb   = pfmfs_get_sb,
+       .mount    = pfmfs_mount,
        .kill_sb  = kill_anon_super,
 };
 
index 4a5b284a15500f4a1a8525dab1609d34310599c0..7ef4115b8c4a59f0248df2273184ab5e2ed8f053 100644 (file)
@@ -2,7 +2,9 @@
 #define _M68K_IRQFLAGS_H
 
 #include <linux/types.h>
+#ifdef CONFIG_MMU
 #include <linux/hardirq.h>
+#endif
 #include <linux/preempt.h>
 #include <asm/thread_info.h>
 #include <asm/entry.h>
index 789f3b2de0e9bf2f63720bcc0c522c686e9c9d31..415d5484916c4d9e6ec1981e380cfe9a0f1ab4de 100644 (file)
@@ -40,5 +40,6 @@ extern unsigned long hw_timer_offset(void);
 extern irqreturn_t arch_timer_interrupt(int irq, void *dummy);
 
 extern void config_BSP(char *command, int len);
+extern void do_IRQ(int irq, struct pt_regs *fp);
 
 #endif /* _M68K_MACHDEP_H */
index cf8d0945530c4b77f42cde9421c79591efc980f1..67a2fa2caa494ff06e2550aa8cea7cf61d69f39e 100644 (file)
@@ -4,16 +4,21 @@ config MIPS
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_IDE
        select HAVE_OPROFILE
+       select HAVE_PERF_EVENTS
+       select PERF_USE_VMALLOC
        select HAVE_ARCH_KGDB
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FTRACE_MCOUNT_RECORD
+       select HAVE_C_RECORDMCOUNT
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_KPROBES
        select HAVE_KRETPROBES
        select RTC_LIB if !MACH_LOONGSON
        select GENERIC_ATOMIC64 if !64BIT
+       select HAVE_DMA_ATTRS
+       select HAVE_DMA_API_DEBUG
 
 menu "Machine selection"
 
@@ -691,6 +696,9 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
        select SWAP_IO_SPACE
        select HW_HAS_PCI
        select ARCH_SUPPORTS_MSI
+       select ZONE_DMA32
+       select USB_ARCH_HAS_OHCI
+       select USB_ARCH_HAS_EHCI
        help
          This option supports all of the Octeon reference boards from Cavium
          Networks. It builds a kernel that dynamically determines the Octeon
@@ -1334,6 +1342,57 @@ config CPU_CAVIUM_OCTEON
          can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
          Full details can be found at http://www.caviumnetworks.com.
 
+config CPU_BMIPS3300
+       bool "BMIPS3300"
+       depends on SYS_HAS_CPU_BMIPS3300
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SWAP_IO_SPACE
+       select SYS_SUPPORTS_32BIT_KERNEL
+       select WEAK_ORDERING
+       help
+         Broadcom BMIPS3300 processors.
+
+config CPU_BMIPS4350
+       bool "BMIPS4350"
+       depends on SYS_HAS_CPU_BMIPS4350
+       select CPU_SUPPORTS_32BIT_KERNEL
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SWAP_IO_SPACE
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_HOTPLUG_CPU
+       select WEAK_ORDERING
+       help
+         Broadcom BMIPS4350 ("VIPER") processors.
+
+config CPU_BMIPS4380
+       bool "BMIPS4380"
+       depends on SYS_HAS_CPU_BMIPS4380
+       select CPU_SUPPORTS_32BIT_KERNEL
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SWAP_IO_SPACE
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_HOTPLUG_CPU
+       select WEAK_ORDERING
+       help
+         Broadcom BMIPS4380 processors.
+
+config CPU_BMIPS5000
+       bool "BMIPS5000"
+       depends on SYS_HAS_CPU_BMIPS5000
+       select CPU_SUPPORTS_32BIT_KERNEL
+       select CPU_SUPPORTS_HIGHMEM
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SWAP_IO_SPACE
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_HOTPLUG_CPU
+       select WEAK_ORDERING
+       help
+         Broadcom BMIPS5000 processors.
+
 endchoice
 
 if CPU_LOONGSON2F
@@ -1452,6 +1511,18 @@ config SYS_HAS_CPU_SB1
 config SYS_HAS_CPU_CAVIUM_OCTEON
        bool
 
+config SYS_HAS_CPU_BMIPS3300
+       bool
+
+config SYS_HAS_CPU_BMIPS4350
+       bool
+
+config SYS_HAS_CPU_BMIPS4380
+       bool
+
+config SYS_HAS_CPU_BMIPS5000
+       bool
+
 #
 # CPU may reorder R->R, R->W, W->R, W->W
 # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
@@ -1928,6 +1999,14 @@ config NODES_SHIFT
        default "6"
        depends on NEED_MULTIPLE_NODES
 
+config HW_PERF_EVENTS
+       bool "Enable hardware performance counter support for perf events"
+       depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32
+       default y
+       help
+         Enable hardware performance counter support for perf events. If
+         disabled, perf events will use software events only.
+
 source "mm/Kconfig"
 
 config SMP
index 43dc279977308363e1f0aa538504b5f220cc8cb0..f437cd1fafb8cfc84b7dd97382a7995d09278c67 100644 (file)
@@ -67,6 +67,15 @@ config CMDLINE_OVERRIDE
 
          Normally, you will choose 'N' here.
 
+config DEBUG_STACKOVERFLOW
+       bool "Check for stack overflows"
+       depends on DEBUG_KERNEL
+       help
+         This option will cause messages to be printed if free stack space
+         drops below a certain limit(2GB on MIPS). The debugging option
+         provides another way to check stack overflow happened on kernel mode
+         stack usually caused by nested interruption.
+
 config DEBUG_STACK_USAGE
        bool "Enable stack utilization instrumentation"
        depends on DEBUG_KERNEL
index f4a4b663ebb3150400d5148ba25c108aac289b7d..7c1102e41fe25b917dcce6566c0bf494ceef867e 100644 (file)
@@ -48,9 +48,6 @@ ifneq ($(SUBARCH),$(ARCH))
   endif
 endif
 
-ifndef CONFIG_FUNCTION_TRACER
-cflags-y := -ffunction-sections
-endif
 ifdef CONFIG_FUNCTION_GRAPH_TRACER
   ifndef KBUILD_MCOUNT_RA_ADDRESS
     ifeq ($(call cc-option-yn,-mmcount-ra-address), y)
@@ -159,6 +156,7 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
 ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON))))
 cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
 endif
+cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
 
 cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
 cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
index c32fbb57441aceabb3627abc430755133a7164cd..425dfa5d6e12c69380b160edde7edf58477860af 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
  * Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
- * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2009-2010 Florian Fainelli <florian@openwrt.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,6 +37,16 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
        return readl(gpio_in) & (1 << gpio);
 }
 
+static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+       struct ar7_gpio_chip *gpch =
+                               container_of(chip, struct ar7_gpio_chip, chip);
+       void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0;
+       void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1;
+
+       return readl(gpio >> 5 ? gpio_in1 : gpio_in0) & (1 << (gpio & 0x1f));
+}
+
 static void ar7_gpio_set_value(struct gpio_chip *chip,
                                unsigned gpio, int value)
 {
@@ -51,6 +61,21 @@ static void ar7_gpio_set_value(struct gpio_chip *chip,
        writel(tmp, gpio_out);
 }
 
+static void titan_gpio_set_value(struct gpio_chip *chip,
+                               unsigned gpio, int value)
+{
+       struct ar7_gpio_chip *gpch =
+                               container_of(chip, struct ar7_gpio_chip, chip);
+       void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0;
+       void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1;
+       unsigned tmp;
+
+       tmp = readl(gpio >> 5 ? gpio_out1 : gpio_out0) & ~(1 << (gpio & 0x1f));
+       if (value)
+               tmp |= 1 << (gpio & 0x1f);
+       writel(tmp, gpio >> 5 ? gpio_out1 : gpio_out0);
+}
+
 static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 {
        struct ar7_gpio_chip *gpch =
@@ -62,6 +87,21 @@ static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
        return 0;
 }
 
+static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+       struct ar7_gpio_chip *gpch =
+                               container_of(chip, struct ar7_gpio_chip, chip);
+       void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
+       void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
+
+       if (gpio >= TITAN_GPIO_MAX)
+               return -EINVAL;
+
+       writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) | (1 << (gpio & 0x1f)),
+                       gpio >> 5 ? gpio_dir1 : gpio_dir0);
+       return 0;
+}
+
 static int ar7_gpio_direction_output(struct gpio_chip *chip,
                                        unsigned gpio, int value)
 {
@@ -75,6 +115,24 @@ static int ar7_gpio_direction_output(struct gpio_chip *chip,
        return 0;
 }
 
+static int titan_gpio_direction_output(struct gpio_chip *chip,
+                                       unsigned gpio, int value)
+{
+       struct ar7_gpio_chip *gpch =
+                               container_of(chip, struct ar7_gpio_chip, chip);
+       void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
+       void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
+
+       if (gpio >= TITAN_GPIO_MAX)
+               return -EINVAL;
+
+       titan_gpio_set_value(chip, gpio, value);
+       writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) & ~(1 <<
+               (gpio & 0x1f)), gpio >> 5 ? gpio_dir1 : gpio_dir0);
+
+       return 0;
+}
+
 static struct ar7_gpio_chip ar7_gpio_chip = {
        .chip = {
                .label                  = "ar7-gpio",
@@ -87,7 +145,19 @@ static struct ar7_gpio_chip ar7_gpio_chip = {
        }
 };
 
-int ar7_gpio_enable(unsigned gpio)
+static struct ar7_gpio_chip titan_gpio_chip = {
+       .chip = {
+               .label                  = "titan-gpio",
+               .direction_input        = titan_gpio_direction_input,
+               .direction_output       = titan_gpio_direction_output,
+               .set                    = titan_gpio_set_value,
+               .get                    = titan_gpio_get_value,
+               .base                   = 0,
+               .ngpio                  = TITAN_GPIO_MAX,
+       }
+};
+
+static inline int ar7_gpio_enable_ar7(unsigned gpio)
 {
        void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
 
@@ -95,9 +165,26 @@ int ar7_gpio_enable(unsigned gpio)
 
        return 0;
 }
+
+static inline int ar7_gpio_enable_titan(unsigned gpio)
+{
+       void __iomem *gpio_en0 = titan_gpio_chip.regs  + TITAN_GPIO_ENBL_0;
+       void __iomem *gpio_en1 = titan_gpio_chip.regs  + TITAN_GPIO_ENBL_1;
+
+       writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) | (1 << (gpio & 0x1f)),
+               gpio >> 5 ? gpio_en1 : gpio_en0);
+
+       return 0;
+}
+
+int ar7_gpio_enable(unsigned gpio)
+{
+       return ar7_is_titan() ? ar7_gpio_enable_titan(gpio) :
+                               ar7_gpio_enable_ar7(gpio);
+}
 EXPORT_SYMBOL(ar7_gpio_enable);
 
-int ar7_gpio_disable(unsigned gpio)
+static inline int ar7_gpio_disable_ar7(unsigned gpio)
 {
        void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
 
@@ -105,27 +192,159 @@ int ar7_gpio_disable(unsigned gpio)
 
        return 0;
 }
+
+static inline int ar7_gpio_disable_titan(unsigned gpio)
+{
+       void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
+       void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
+
+       writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) & ~(1 << (gpio & 0x1f)),
+                       gpio >> 5 ? gpio_en1 : gpio_en0);
+
+       return 0;
+}
+
+int ar7_gpio_disable(unsigned gpio)
+{
+       return ar7_is_titan() ? ar7_gpio_disable_titan(gpio) :
+                               ar7_gpio_disable_ar7(gpio);
+}
 EXPORT_SYMBOL(ar7_gpio_disable);
 
-static int __init ar7_gpio_init(void)
+struct titan_gpio_cfg {
+       u32 reg;
+       u32 shift;
+       u32 func;
+};
+
+static struct titan_gpio_cfg titan_gpio_table[] = {
+       /* reg, start bit, mux value */
+       {4, 24, 1},
+       {4, 26, 1},
+       {4, 28, 1},
+       {4, 30, 1},
+       {5, 6, 1},
+       {5, 8, 1},
+       {5, 10, 1},
+       {5, 12, 1},
+       {7, 14, 3},
+       {7, 16, 3},
+       {7, 18, 3},
+       {7, 20, 3},
+       {7, 22, 3},
+       {7, 26, 3},
+       {7, 28, 3},
+       {7, 30, 3},
+       {8, 0, 3},
+       {8, 2, 3},
+       {8, 4, 3},
+       {8, 10, 3},
+       {8, 14, 3},
+       {8, 16, 3},
+       {8, 18, 3},
+       {8, 20, 3},
+       {9, 8, 3},
+       {9, 10, 3},
+       {9, 12, 3},
+       {9, 14, 3},
+       {9, 18, 3},
+       {9, 20, 3},
+       {9, 24, 3},
+       {9, 26, 3},
+       {9, 28, 3},
+       {9, 30, 3},
+       {10, 0, 3},
+       {10, 2, 3},
+       {10, 8, 3},
+       {10, 10, 3},
+       {10, 12, 3},
+       {10, 14, 3},
+       {13, 12, 3},
+       {13, 14, 3},
+       {13, 16, 3},
+       {13, 18, 3},
+       {13, 24, 3},
+       {13, 26, 3},
+       {13, 28, 3},
+       {13, 30, 3},
+       {14, 2, 3},
+       {14, 6, 3},
+       {14, 8, 3},
+       {14, 12, 3}
+};
+
+static int titan_gpio_pinsel(unsigned gpio)
+{
+       struct titan_gpio_cfg gpio_cfg;
+       u32 mux_status, pin_sel_reg, tmp;
+       void __iomem *pin_sel = (void __iomem *)KSEG1ADDR(AR7_REGS_PINSEL);
+
+       if (gpio >= ARRAY_SIZE(titan_gpio_table))
+               return -EINVAL;
+
+       gpio_cfg = titan_gpio_table[gpio];
+       pin_sel_reg = gpio_cfg.reg - 1;
+
+       mux_status = (readl(pin_sel + pin_sel_reg) >> gpio_cfg.shift) & 0x3;
+
+       /* Check the mux status */
+       if (!((mux_status == 0) || (mux_status == gpio_cfg.func)))
+               return 0;
+
+       /* Set the pin sel value */
+       tmp = readl(pin_sel + pin_sel_reg);
+       tmp |= ((gpio_cfg.func & 0x3) << gpio_cfg.shift);
+       writel(tmp, pin_sel + pin_sel_reg);
+
+       return 0;
+}
+
+/* Perform minimal Titan GPIO configuration */
+static void titan_gpio_init(void)
+{
+       unsigned i;
+
+       for (i = 44; i < 48; i++) {
+               titan_gpio_pinsel(i);
+               ar7_gpio_enable_titan(i);
+               titan_gpio_direction_input(&titan_gpio_chip.chip, i);
+       }
+}
+
+int __init ar7_gpio_init(void)
 {
        int ret;
+       struct ar7_gpio_chip *gpch;
+       unsigned size;
+
+       if (!ar7_is_titan()) {
+               gpch = &ar7_gpio_chip;
+               size = 0x10;
+       } else {
+               gpch = &titan_gpio_chip;
+               size = 0x1f;
+       }
 
-       ar7_gpio_chip.regs = ioremap_nocache(AR7_REGS_GPIO,
+       gpch->regs = ioremap_nocache(AR7_REGS_GPIO,
                                        AR7_REGS_GPIO + 0x10);
 
-       if (!ar7_gpio_chip.regs) {
-               printk(KERN_ERR "ar7-gpio: failed to ioremap regs\n");
+       if (!gpch->regs) {
+               printk(KERN_ERR "%s: failed to ioremap regs\n",
+                                       gpch->chip.label);
                return -ENOMEM;
        }
 
-       ret = gpiochip_add(&ar7_gpio_chip.chip);
+       ret = gpiochip_add(&gpch->chip);
        if (ret) {
-               printk(KERN_ERR "ar7-gpio: failed to add gpiochip\n");
+               printk(KERN_ERR "%s: failed to add gpiochip\n",
+                                       gpch->chip.label);
                return ret;
        }
-       printk(KERN_INFO "ar7-gpio: registered %d GPIOs\n",
-                               ar7_gpio_chip.chip.ngpio);
+       printk(KERN_INFO "%s: registered %d GPIOs\n",
+                               gpch->chip.label, gpch->chip.ngpio);
+
+       if (ar7_is_titan())
+               titan_gpio_init();
+
        return ret;
 }
-arch_initcall(ar7_gpio_init);
index 0da5b2b8dd88a4a08d75b4eaf9aa3965b1af655f..7d2fab392327003311ac282483e99f0a398d2e4f 100644 (file)
@@ -357,6 +357,11 @@ static struct gpio_led default_leds[] = {
        },
 };
 
+static struct gpio_led titan_leds[] = {
+       { .name = "status", .gpio = 8, .active_low = 1, },
+       { .name = "wifi", .gpio = 13, .active_low = 1, },
+};
+
 static struct gpio_led dsl502t_leds[] = {
        {
                .name                   = "status",
@@ -495,6 +500,9 @@ static void __init detect_leds(void)
        } else if (strstr(prid, "DG834")) {
                ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds);
                ar7_led_data.leds = dg834g_leds;
+       } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
+               ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
+               ar7_led_data.leds = titan_leds;
        }
 }
 
@@ -560,6 +568,51 @@ static int __init ar7_register_uarts(void)
        return 0;
 }
 
+static void __init titan_fixup_devices(void)
+{
+       /* Set vlynq0 data */
+       vlynq_low_data.reset_bit = 15;
+       vlynq_low_data.gpio_bit = 14;
+
+       /* Set vlynq1 data */
+       vlynq_high_data.reset_bit = 16;
+       vlynq_high_data.gpio_bit = 7;
+
+       /* Set vlynq0 resources */
+       vlynq_low_res[0].start = TITAN_REGS_VLYNQ0;
+       vlynq_low_res[0].end = TITAN_REGS_VLYNQ0 + 0xff;
+       vlynq_low_res[1].start = 33;
+       vlynq_low_res[1].end = 33;
+       vlynq_low_res[2].start = 0x0c000000;
+       vlynq_low_res[2].end = 0x0fffffff;
+       vlynq_low_res[3].start = 80;
+       vlynq_low_res[3].end = 111;
+
+       /* Set vlynq1 resources */
+       vlynq_high_res[0].start = TITAN_REGS_VLYNQ1;
+       vlynq_high_res[0].end = TITAN_REGS_VLYNQ1 + 0xff;
+       vlynq_high_res[1].start = 34;
+       vlynq_high_res[1].end = 34;
+       vlynq_high_res[2].start = 0x40000000;
+       vlynq_high_res[2].end = 0x43ffffff;
+       vlynq_high_res[3].start = 112;
+       vlynq_high_res[3].end = 143;
+
+       /* Set cpmac0 data */
+       cpmac_low_data.phy_mask = 0x40000000;
+
+       /* Set cpmac1 data */
+       cpmac_high_data.phy_mask = 0x80000000;
+
+       /* Set cpmac0 resources */
+       cpmac_low_res[0].start = TITAN_REGS_MAC0;
+       cpmac_low_res[0].end = TITAN_REGS_MAC0 + 0x7ff;
+
+       /* Set cpmac1 resources */
+       cpmac_high_res[0].start = TITAN_REGS_MAC1;
+       cpmac_high_res[0].end = TITAN_REGS_MAC1 + 0x7ff;
+}
+
 static int __init ar7_register_devices(void)
 {
        void __iomem *bootcr;
@@ -574,6 +627,9 @@ static int __init ar7_register_devices(void)
        if (res)
                pr_warning("unable to register physmap-flash: %d\n", res);
 
+       if (ar7_is_titan())
+               titan_fixup_devices();
+
        ar7_device_disable(vlynq_low_data.reset_bit);
        res = platform_device_register(&vlynq_low);
        if (res)
index 52385790e5c168c70eacec3dc74feab7d755b459..23818d299127ce96434ba6c21c378ac8b35739af 100644 (file)
@@ -246,6 +246,8 @@ void __init prom_init(void)
        ar7_init_cmdline(fw_arg0, (char **)fw_arg1);
        ar7_init_env((struct env_var *)fw_arg2);
        console_config();
+
+       ar7_gpio_init();
 }
 
 #define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4)))
index 3a801d2cb6e5531ce64622c36a58e28b1263faea..f20b53e597c42fca192bc40866da920452c36cb9 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/reboot.h>
 #include <asm/mach-ar7/ar7.h>
 #include <asm/mach-ar7/prom.h>
+#include <asm/mach-ar7/gpio.h>
 
 static void ar7_machine_restart(char *command)
 {
@@ -49,6 +50,8 @@ static void ar7_machine_power_off(void)
 const char *get_system_type(void)
 {
        u16 chip_id = ar7_chip_id();
+       u16 titan_variant_id = titan_chip_id();
+
        switch (chip_id) {
        case AR7_CHIP_7100:
                return "TI AR7 (TNETD7100)";
@@ -56,6 +59,17 @@ const char *get_system_type(void)
                return "TI AR7 (TNETD7200)";
        case AR7_CHIP_7300:
                return "TI AR7 (TNETD7300)";
+       case AR7_CHIP_TITAN:
+               switch (titan_variant_id) {
+               case TITAN_CHIP_1050:
+                       return "TI AR7 (TNETV1050)";
+               case TITAN_CHIP_1055:
+                       return "TI AR7 (TNETV1055)";
+               case TITAN_CHIP_1056:
+                       return "TI AR7 (TNETV1056)";
+               case TITAN_CHIP_1060:
+                       return "TI AR7 (TNETV1060)";
+               }
        default:
                return "TI AR7 (unknown)";
        }
index cbb7caf86d77bce79656ed1aff48521552853b02..7c7e4d4486ce0d0099ab2cd92bca6d426237d2b8 100644 (file)
@@ -10,7 +10,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/cpu.h>
+#include <asm/cpu.h>
 #include <asm/cpu-info.h>
+#include <asm/mipsregs.h>
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
@@ -296,26 +298,24 @@ void __init bcm63xx_cpu_init(void)
        expected_cpu_id = 0;
 
        switch (c->cputype) {
-       /*
-        * BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c
-        */
-       case CPU_BCM3302:
-               __cpu_name[cpu] = "Broadcom BCM6338";
-               expected_cpu_id = BCM6338_CPU_ID;
-               bcm63xx_regs_base = bcm96338_regs_base;
-               bcm63xx_irqs = bcm96338_irqs;
+       case CPU_BMIPS3300:
+               if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) {
+                       expected_cpu_id = BCM6348_CPU_ID;
+                       bcm63xx_regs_base = bcm96348_regs_base;
+                       bcm63xx_irqs = bcm96348_irqs;
+               } else {
+                       __cpu_name[cpu] = "Broadcom BCM6338";
+                       expected_cpu_id = BCM6338_CPU_ID;
+                       bcm63xx_regs_base = bcm96338_regs_base;
+                       bcm63xx_irqs = bcm96338_irqs;
+               }
                break;
-       case CPU_BCM6345:
+       case CPU_BMIPS32:
                expected_cpu_id = BCM6345_CPU_ID;
                bcm63xx_regs_base = bcm96345_regs_base;
                bcm63xx_irqs = bcm96345_irqs;
                break;
-       case CPU_BCM6348:
-               expected_cpu_id = BCM6348_CPU_ID;
-               bcm63xx_regs_base = bcm96348_regs_base;
-               bcm63xx_irqs = bcm96348_irqs;
-               break;
-       case CPU_BCM6358:
+       case CPU_BMIPS4350:
                expected_cpu_id = BCM6358_CPU_ID;
                bcm63xx_regs_base = bcm96358_regs_base;
                bcm63xx_irqs = bcm96358_irqs;
index 47323ca452dcbde751536c58c9f613dd1d9d51c8..caae22858163a193b681e0adb920590d3d0bcd20 100644 (file)
@@ -3,6 +3,17 @@ config CAVIUM_OCTEON_SPECIFIC_OPTIONS
        depends on CPU_CAVIUM_OCTEON
        default "y"
 
+config CAVIUM_CN63XXP1
+       bool "Enable CN63XXP1 errata worarounds"
+       depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
+       default "n"
+       help
+         The CN63XXP1 chip requires build time workarounds to
+         function reliably, select this option to enable them.  These
+         workarounds will cause a slight decrease in performance on
+         non-CN63XXP1 hardware, so it is recommended to select "n"
+         unless it is known the workarounds are needed.
+
 config CAVIUM_OCTEON_2ND_KERNEL
        bool "Build the kernel to be used as a 2nd kernel on the same chip"
        depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
@@ -87,3 +98,15 @@ config ARCH_SPARSEMEM_ENABLE
 config CAVIUM_OCTEON_HELPER
        def_bool y
        depends on OCTEON_ETHERNET || PCI
+
+config IOMMU_HELPER
+       bool
+
+config NEED_SG_DMA_LENGTH
+       bool
+
+config SWIOTLB
+       def_bool y
+       depends on CPU_CAVIUM_OCTEON
+       select IOMMU_HELPER
+       select NEED_SG_DMA_LENGTH
index b6847c8e0ddd3784b4050b7dee6558cfd595e119..26bf71130bf8b1dd6fe1d24c8b5e336a2b30b78d 100644 (file)
@@ -4,14 +4,18 @@
  * for more details.
  *
  * Copyright (C) 2007 by Ralf Baechle
+ * Copyright (C) 2009, 2010 Cavium Networks, Inc.
  */
 #include <linux/clocksource.h>
 #include <linux/init.h>
+#include <linux/smp.h>
 
+#include <asm/cpu-info.h>
 #include <asm/time.h>
 
 #include <asm/octeon/octeon.h>
 #include <asm/octeon/cvmx-ipd-defs.h>
+#include <asm/octeon/cvmx-mio-defs.h>
 
 /*
  * Set the current core's cvmcount counter to the value of the
  * on-line.  This allows for a read from a local cpu register to
  * access a synchronized counter.
  *
+ * On CPU_CAVIUM_OCTEON2 the IPD_CLK_COUNT is scaled by rdiv/sdiv.
  */
 void octeon_init_cvmcount(void)
 {
        unsigned long flags;
        unsigned loops = 2;
+       u64 f = 0;
+       u64 rdiv = 0;
+       u64 sdiv = 0;
+       if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
+               union cvmx_mio_rst_boot rst_boot;
+               rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+               rdiv = rst_boot.s.c_mul;        /* CPU clock */
+               sdiv = rst_boot.s.pnr_mul;      /* I/O clock */
+               f = (0x8000000000000000ull / sdiv) * 2;
+       }
+
 
        /* Clobber loops so GCC will not unroll the following while loop. */
        asm("" : "+r" (loops));
@@ -33,8 +49,20 @@ void octeon_init_cvmcount(void)
         * Loop several times so we are executing from the cache,
         * which should give more deterministic timing.
         */
-       while (loops--)
-               write_c0_cvmcount(cvmx_read_csr(CVMX_IPD_CLK_COUNT));
+       while (loops--) {
+               u64 ipd_clk_count = cvmx_read_csr(CVMX_IPD_CLK_COUNT);
+               if (rdiv != 0) {
+                       ipd_clk_count *= rdiv;
+                       if (f != 0) {
+                               asm("dmultu\t%[cnt],%[f]\n\t"
+                                   "mfhi\t%[cnt]"
+                                   : [cnt] "+r" (ipd_clk_count),
+                                     [f] "=r" (f)
+                                   : : "hi", "lo");
+                       }
+               }
+               write_c0_cvmcount(ipd_clk_count);
+       }
        local_irq_restore(flags);
 }
 
@@ -77,7 +105,7 @@ unsigned long long notrace sched_clock(void)
 void __init plat_time_init(void)
 {
        clocksource_mips.rating = 300;
-       clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+       clocksource_set_clock(&clocksource_mips, octeon_get_clock_rate());
        clocksource_register(&clocksource_mips);
 }
 
index d22b5a2d64f47988659f55d2998925ff569b0711..1abb66caaa1d84459e5564fe788b0d39e61f4aeb 100644 (file)
  * Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
  * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
  * IP32 changes by Ilya.
- * Cavium Networks: Create new dma setup for Cavium Networks Octeon based on
- * the kernels original.
+ * Copyright (C) 2010 Cavium Networks, Inc.
  */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/string.h>
 #include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
 #include <linux/scatterlist.h>
+#include <linux/bootmem.h>
+#include <linux/swiotlb.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
 
-#include <linux/cache.h>
-#include <linux/io.h>
+#include <asm/bootinfo.h>
 
 #include <asm/octeon/octeon.h>
+
+#ifdef CONFIG_PCI
+#include <asm/octeon/pci-octeon.h>
 #include <asm/octeon/cvmx-npi-defs.h>
 #include <asm/octeon/cvmx-pci-defs.h>
 
-#include <dma-coherence.h>
+static dma_addr_t octeon_hole_phys_to_dma(phys_addr_t paddr)
+{
+       if (paddr >= CVMX_PCIE_BAR1_PHYS_BASE && paddr < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE))
+               return paddr - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE;
+       else
+               return paddr;
+}
 
-#ifdef CONFIG_PCI
-#include <asm/octeon/pci-octeon.h>
-#endif
+static phys_addr_t octeon_hole_dma_to_phys(dma_addr_t daddr)
+{
+       if (daddr >= CVMX_PCIE_BAR1_RC_BASE)
+               return daddr + CVMX_PCIE_BAR1_PHYS_BASE - CVMX_PCIE_BAR1_RC_BASE;
+       else
+               return daddr;
+}
+
+static dma_addr_t octeon_gen1_phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+       if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+               paddr -= 0x400000000ull;
+       return octeon_hole_phys_to_dma(paddr);
+}
 
-#define BAR2_PCI_ADDRESS 0x8000000000ul
+static phys_addr_t octeon_gen1_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+       daddr = octeon_hole_dma_to_phys(daddr);
 
-struct bar1_index_state {
-       int16_t ref_count;      /* Number of PCI mappings using this index */
-       uint16_t address_bits;  /* Upper bits of physical address. This is
-                                  shifted 22 bits */
-};
+       if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+               daddr += 0x400000000ull;
 
-#ifdef CONFIG_PCI
-static DEFINE_RAW_SPINLOCK(bar1_lock);
-static struct bar1_index_state bar1_state[32];
-#endif
+       return daddr;
+}
 
-dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size)
+static dma_addr_t octeon_big_phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
-#ifndef CONFIG_PCI
-       /* Without PCI/PCIe this function can be called for Octeon internal
-          devices such as USB. These devices all support 64bit addressing */
+       if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+               paddr -= 0x400000000ull;
+
+       /* Anything in the BAR1 hole or above goes via BAR2 */
+       if (paddr >= 0xf0000000ull)
+               paddr = OCTEON_BAR2_PCI_ADDRESS + paddr;
+
+       return paddr;
+}
+
+static phys_addr_t octeon_big_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+       if (daddr >= OCTEON_BAR2_PCI_ADDRESS)
+               daddr -= OCTEON_BAR2_PCI_ADDRESS;
+
+       if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+               daddr += 0x400000000ull;
+       return daddr;
+}
+
+static dma_addr_t octeon_small_phys_to_dma(struct device *dev,
+                                          phys_addr_t paddr)
+{
+       if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+               paddr -= 0x400000000ull;
+
+       /* Anything not in the BAR1 range goes via BAR2 */
+       if (paddr >= octeon_bar1_pci_phys && paddr < octeon_bar1_pci_phys + 0x8000000ull)
+               paddr = paddr - octeon_bar1_pci_phys;
+       else
+               paddr = OCTEON_BAR2_PCI_ADDRESS + paddr;
+
+       return paddr;
+}
+
+static phys_addr_t octeon_small_dma_to_phys(struct device *dev,
+                                           dma_addr_t daddr)
+{
+       if (daddr >= OCTEON_BAR2_PCI_ADDRESS)
+               daddr -= OCTEON_BAR2_PCI_ADDRESS;
+       else
+               daddr += octeon_bar1_pci_phys;
+
+       if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+               daddr += 0x400000000ull;
+       return daddr;
+}
+
+#endif /* CONFIG_PCI */
+
+static dma_addr_t octeon_dma_map_page(struct device *dev, struct page *page,
+       unsigned long offset, size_t size, enum dma_data_direction direction,
+       struct dma_attrs *attrs)
+{
+       dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size,
+                                           direction, attrs);
        mb();
-       return virt_to_phys(ptr);
-#else
-       unsigned long flags;
-       uint64_t dma_mask;
-       int64_t start_index;
-       dma_addr_t result = -1;
-       uint64_t physical = virt_to_phys(ptr);
-       int64_t index;
 
+       return daddr;
+}
+
+static int octeon_dma_map_sg(struct device *dev, struct scatterlist *sg,
+       int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+       int r = swiotlb_map_sg_attrs(dev, sg, nents, direction, attrs);
        mb();
-       /*
-        * Use the DMA masks to determine the allowed memory
-        * region. For us it doesn't limit the actual memory, just the
-        * address visible over PCI.  Devices with limits need to use
-        * lower indexed Bar1 entries.
-        */
-       if (dev) {
-               dma_mask = dev->coherent_dma_mask;
-               if (dev->dma_mask)
-                       dma_mask = *dev->dma_mask;
-       } else {
-               dma_mask = 0xfffffffful;
-       }
+       return r;
+}
 
-       /*
-        * Platform devices, such as the internal USB, skip all
-        * translation and use Octeon physical addresses directly.
-        */
-       if (!dev || dev->bus == &platform_bus_type)
-               return physical;
+static void octeon_dma_sync_single_for_device(struct device *dev,
+       dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
+{
+       swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
+       mb();
+}
 
-       switch (octeon_dma_bar_type) {
-       case OCTEON_DMA_BAR_TYPE_PCIE:
-               if (unlikely(physical < (16ul << 10)))
-                       panic("dma_map_single: Not allowed to map first 16KB."
-                             " It interferes with BAR0 special area\n");
-               else if ((physical + size >= (256ul << 20)) &&
-                        (physical < (512ul << 20)))
-                       panic("dma_map_single: Not allowed to map bootbus\n");
-               else if ((physical + size >= 0x400000000ull) &&
-                        physical < 0x410000000ull)
-                       panic("dma_map_single: "
-                             "Attempt to map illegal memory address 0x%llx\n",
-                             physical);
-               else if (physical >= 0x420000000ull)
-                       panic("dma_map_single: "
-                             "Attempt to map illegal memory address 0x%llx\n",
-                             physical);
-               else if (physical >= CVMX_PCIE_BAR1_PHYS_BASE &&
-                        physical + size < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE)) {
-                       result = physical - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE;
-
-                       if (((result+size-1) & dma_mask) != result+size-1)
-                               panic("dma_map_single: Attempt to map address 0x%llx-0x%llx, which can't be accessed according to the dma mask 0x%llx\n",
-                                     physical, physical+size-1, dma_mask);
-                       goto done;
-               }
-
-               /* The 2nd 256MB is mapped at 256<<20 instead of 0x410000000 */
-               if ((physical >= 0x410000000ull) && physical < 0x420000000ull)
-                       result = physical - 0x400000000ull;
-               else
-                       result = physical;
-               if (((result+size-1) & dma_mask) != result+size-1)
-                       panic("dma_map_single: Attempt to map address "
-                             "0x%llx-0x%llx, which can't be accessed "
-                             "according to the dma mask 0x%llx\n",
-                             physical, physical+size-1, dma_mask);
-               goto done;
+static void octeon_dma_sync_sg_for_device(struct device *dev,
+       struct scatterlist *sg, int nelems, enum dma_data_direction direction)
+{
+       swiotlb_sync_sg_for_device(dev, sg, nelems, direction);
+       mb();
+}
 
-       case OCTEON_DMA_BAR_TYPE_BIG:
-#ifdef CONFIG_64BIT
-               /* If the device supports 64bit addressing, then use BAR2 */
-               if (dma_mask > BAR2_PCI_ADDRESS) {
-                       result = physical + BAR2_PCI_ADDRESS;
-                       goto done;
-               }
-#endif
-               if (unlikely(physical < (4ul << 10))) {
-                       panic("dma_map_single: Not allowed to map first 4KB. "
-                             "It interferes with BAR0 special area\n");
-               } else if (physical < (256ul << 20)) {
-                       if (unlikely(physical + size > (256ul << 20)))
-                               panic("dma_map_single: Requested memory spans "
-                                     "Bar0 0:256MB and bootbus\n");
-                       result = physical;
-                       goto done;
-               } else if (unlikely(physical < (512ul << 20))) {
-                       panic("dma_map_single: Not allowed to map bootbus\n");
-               } else if (physical < (2ul << 30)) {
-                       if (unlikely(physical + size > (2ul << 30)))
-                               panic("dma_map_single: Requested memory spans "
-                                     "Bar0 512MB:2GB and BAR1\n");
-                       result = physical;
-                       goto done;
-               } else if (physical < (2ul << 30) + (128 << 20)) {
-                       /* Fall through */
-               } else if (physical <
-                          (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)) {
-                       if (unlikely
-                           (physical + size >
-                            (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)))
-                               panic("dma_map_single: Requested memory "
-                                     "extends past Bar1 (4GB-%luMB)\n",
-                                     OCTEON_PCI_BAR1_HOLE_SIZE);
-                       result = physical;
-                       goto done;
-               } else if ((physical >= 0x410000000ull) &&
-                          (physical < 0x420000000ull)) {
-                       if (unlikely(physical + size > 0x420000000ull))
-                               panic("dma_map_single: Requested memory spans "
-                                     "non existant memory\n");
-                       /* BAR0 fixed mapping 256MB:512MB ->
-                        * 16GB+256MB:16GB+512MB */
-                       result = physical - 0x400000000ull;
-                       goto done;
-               } else {
-                       /* Continued below switch statement */
-               }
-               break;
+static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
+       dma_addr_t *dma_handle, gfp_t gfp)
+{
+       void *ret;
 
-       case OCTEON_DMA_BAR_TYPE_SMALL:
-#ifdef CONFIG_64BIT
-               /* If the device supports 64bit addressing, then use BAR2 */
-               if (dma_mask > BAR2_PCI_ADDRESS) {
-                       result = physical + BAR2_PCI_ADDRESS;
-                       goto done;
-               }
+       if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
+               return ret;
+
+       /* ignore region specifiers */
+       gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+
+#ifdef CONFIG_ZONE_DMA
+       if (dev == NULL)
+               gfp |= __GFP_DMA;
+       else if (dev->coherent_dma_mask <= DMA_BIT_MASK(24))
+               gfp |= __GFP_DMA;
+       else
 #endif
-               /* Continued below switch statement */
-               break;
+#ifdef CONFIG_ZONE_DMA32
+            if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
+               gfp |= __GFP_DMA32;
+       else
+#endif
+               ;
 
-       default:
-               panic("dma_map_single: Invalid octeon_dma_bar_type\n");
-       }
+       /* Don't invoke OOM killer */
+       gfp |= __GFP_NORETRY;
 
-       /* Don't allow mapping to span multiple Bar entries. The hardware guys
-          won't guarantee that DMA across boards work */
-       if (unlikely((physical >> 22) != ((physical + size - 1) >> 22)))
-               panic("dma_map_single: "
-                     "Requested memory spans more than one Bar1 entry\n");
+       ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
 
-       if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
-               start_index = 31;
-       else if (unlikely(dma_mask < (1ul << 27)))
-               start_index = (dma_mask >> 22);
-       else
-               start_index = 31;
-
-       /* Only one processor can access the Bar register at once */
-       raw_spin_lock_irqsave(&bar1_lock, flags);
-
-       /* Look through Bar1 for existing mapping that will work */
-       for (index = start_index; index >= 0; index--) {
-               if ((bar1_state[index].address_bits == physical >> 22) &&
-                   (bar1_state[index].ref_count)) {
-                       /* An existing mapping will work, use it */
-                       bar1_state[index].ref_count++;
-                       if (unlikely(bar1_state[index].ref_count < 0))
-                               panic("dma_map_single: "
-                                     "Bar1[%d] reference count overflowed\n",
-                                     (int) index);
-                       result = (index << 22) | (physical & ((1 << 22) - 1));
-                       /* Large BAR1 is offset at 2GB */
-                       if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
-                               result += 2ul << 30;
-                       goto done_unlock;
-               }
-       }
+       mb();
 
-       /* No existing mappings, look for a free entry */
-       for (index = start_index; index >= 0; index--) {
-               if (unlikely(bar1_state[index].ref_count == 0)) {
-                       union cvmx_pci_bar1_indexx bar1_index;
-                       /* We have a free entry, use it */
-                       bar1_state[index].ref_count = 1;
-                       bar1_state[index].address_bits = physical >> 22;
-                       bar1_index.u32 = 0;
-                       /* Address bits[35:22] sent to L2C */
-                       bar1_index.s.addr_idx = physical >> 22;
-                       /* Don't put PCI accesses in L2. */
-                       bar1_index.s.ca = 1;
-                       /* Endian Swap Mode */
-                       bar1_index.s.end_swp = 1;
-                       /* Set '1' when the selected address range is valid. */
-                       bar1_index.s.addr_v = 1;
-                       octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
-                                          bar1_index.u32);
-                       /* An existing mapping will work, use it */
-                       result = (index << 22) | (physical & ((1 << 22) - 1));
-                       /* Large BAR1 is offset at 2GB */
-                       if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
-                               result += 2ul << 30;
-                       goto done_unlock;
-               }
-       }
+       return ret;
+}
 
-       pr_err("dma_map_single: "
-              "Can't find empty BAR1 index for physical mapping 0x%llx\n",
-              (unsigned long long) physical);
+static void octeon_dma_free_coherent(struct device *dev, size_t size,
+       void *vaddr, dma_addr_t dma_handle)
+{
+       int order = get_order(size);
 
-done_unlock:
-       raw_spin_unlock_irqrestore(&bar1_lock, flags);
-done:
-       pr_debug("dma_map_single 0x%llx->0x%llx\n", physical, result);
-       return result;
-#endif
+       if (dma_release_from_coherent(dev, order, vaddr))
+               return;
+
+       swiotlb_free_coherent(dev, size, vaddr, dma_handle);
 }
 
-void octeon_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
-#ifndef CONFIG_PCI
-       /*
-        * Without PCI/PCIe this function can be called for Octeon internal
-        * devices such as USB. These devices all support 64bit addressing.
-        */
-       return;
-#else
-       unsigned long flags;
-       uint64_t index;
+       return paddr;
+}
 
+static phys_addr_t octeon_unity_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+       return daddr;
+}
+
+struct octeon_dma_map_ops {
+       struct dma_map_ops dma_map_ops;
+       dma_addr_t (*phys_to_dma)(struct device *dev, phys_addr_t paddr);
+       phys_addr_t (*dma_to_phys)(struct device *dev, dma_addr_t daddr);
+};
+
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+       struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
+                                                     struct octeon_dma_map_ops,
+                                                     dma_map_ops);
+
+       return ops->phys_to_dma(dev, paddr);
+}
+EXPORT_SYMBOL(phys_to_dma);
+
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+       struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
+                                                     struct octeon_dma_map_ops,
+                                                     dma_map_ops);
+
+       return ops->dma_to_phys(dev, daddr);
+}
+EXPORT_SYMBOL(dma_to_phys);
+
+static struct octeon_dma_map_ops octeon_linear_dma_map_ops = {
+       .dma_map_ops = {
+               .alloc_coherent = octeon_dma_alloc_coherent,
+               .free_coherent = octeon_dma_free_coherent,
+               .map_page = octeon_dma_map_page,
+               .unmap_page = swiotlb_unmap_page,
+               .map_sg = octeon_dma_map_sg,
+               .unmap_sg = swiotlb_unmap_sg_attrs,
+               .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+               .sync_single_for_device = octeon_dma_sync_single_for_device,
+               .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+               .sync_sg_for_device = octeon_dma_sync_sg_for_device,
+               .mapping_error = swiotlb_dma_mapping_error,
+               .dma_supported = swiotlb_dma_supported
+       },
+       .phys_to_dma = octeon_unity_phys_to_dma,
+       .dma_to_phys = octeon_unity_dma_to_phys
+};
+
+char *octeon_swiotlb;
+
+void __init plat_swiotlb_setup(void)
+{
+       int i;
+       phys_t max_addr;
+       phys_t addr_size;
+       size_t swiotlbsize;
+       unsigned long swiotlb_nslabs;
+
+       max_addr = 0;
+       addr_size = 0;
+
+       for (i = 0 ; i < boot_mem_map.nr_map; i++) {
+               struct boot_mem_map_entry *e = &boot_mem_map.map[i];
+               if (e->type != BOOT_MEM_RAM)
+                       continue;
+
+               /* These addresses map low for PCI. */
+               if (e->addr > 0x410000000ull)
+                       continue;
+
+               addr_size += e->size;
+
+               if (max_addr < e->addr + e->size)
+                       max_addr = e->addr + e->size;
+
+       }
+
+       swiotlbsize = PAGE_SIZE;
+
+#ifdef CONFIG_PCI
        /*
-        * Platform devices, such as the internal USB, skip all
-        * translation and use Octeon physical addresses directly.
+        * For OCTEON_DMA_BAR_TYPE_SMALL, size the iotlb at 1/4 memory
+        * size to a maximum of 64MB
         */
-       if (dev->bus == &platform_bus_type)
-               return;
+       if (OCTEON_IS_MODEL(OCTEON_CN31XX)
+           || OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
+               swiotlbsize = addr_size / 4;
+               if (swiotlbsize > 64 * (1<<20))
+                       swiotlbsize = 64 * (1<<20);
+       } else if (max_addr > 0xf0000000ul) {
+               /*
+                * Otherwise only allocate a big iotlb if there is
+                * memory past the BAR1 hole.
+                */
+               swiotlbsize = 64 * (1<<20);
+       }
+#endif
+       swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
+       swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
+       swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
+
+       octeon_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
 
+       swiotlb_init_with_tbl(octeon_swiotlb, swiotlb_nslabs, 1);
+
+       mips_dma_map_ops = &octeon_linear_dma_map_ops.dma_map_ops;
+}
+
+#ifdef CONFIG_PCI
+static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = {
+       .dma_map_ops = {
+               .alloc_coherent = octeon_dma_alloc_coherent,
+               .free_coherent = octeon_dma_free_coherent,
+               .map_page = octeon_dma_map_page,
+               .unmap_page = swiotlb_unmap_page,
+               .map_sg = octeon_dma_map_sg,
+               .unmap_sg = swiotlb_unmap_sg_attrs,
+               .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+               .sync_single_for_device = octeon_dma_sync_single_for_device,
+               .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+               .sync_sg_for_device = octeon_dma_sync_sg_for_device,
+               .mapping_error = swiotlb_dma_mapping_error,
+               .dma_supported = swiotlb_dma_supported
+       },
+};
+
+struct dma_map_ops *octeon_pci_dma_map_ops;
+
+void __init octeon_pci_dma_init(void)
+{
        switch (octeon_dma_bar_type) {
        case OCTEON_DMA_BAR_TYPE_PCIE:
-               /* Nothing to do, all mappings are static */
-               goto done;
-
+               _octeon_pci_dma_map_ops.phys_to_dma = octeon_gen1_phys_to_dma;
+               _octeon_pci_dma_map_ops.dma_to_phys = octeon_gen1_dma_to_phys;
+               break;
        case OCTEON_DMA_BAR_TYPE_BIG:
-#ifdef CONFIG_64BIT
-               /* Nothing to do for addresses using BAR2 */
-               if (dma_addr >= BAR2_PCI_ADDRESS)
-                       goto done;
-#endif
-               if (unlikely(dma_addr < (4ul << 10)))
-                       panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
-                             dma_addr);
-               else if (dma_addr < (2ul << 30))
-                       /* Nothing to do for addresses using BAR0 */
-                       goto done;
-               else if (dma_addr < (2ul << 30) + (128ul << 20))
-                       /* Need to unmap, fall through */
-                       index = (dma_addr - (2ul << 30)) >> 22;
-               else if (dma_addr <
-                        (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20))
-                       goto done;      /* Nothing to do for the rest of BAR1 */
-               else
-                       panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
-                             dma_addr);
-               /* Continued below switch statement */
+               _octeon_pci_dma_map_ops.phys_to_dma = octeon_big_phys_to_dma;
+               _octeon_pci_dma_map_ops.dma_to_phys = octeon_big_dma_to_phys;
                break;
-
        case OCTEON_DMA_BAR_TYPE_SMALL:
-#ifdef CONFIG_64BIT
-               /* Nothing to do for addresses using BAR2 */
-               if (dma_addr >= BAR2_PCI_ADDRESS)
-                       goto done;
-#endif
-               index = dma_addr >> 22;
-               /* Continued below switch statement */
+               _octeon_pci_dma_map_ops.phys_to_dma = octeon_small_phys_to_dma;
+               _octeon_pci_dma_map_ops.dma_to_phys = octeon_small_dma_to_phys;
                break;
-
        default:
-               panic("dma_unmap_single: Invalid octeon_dma_bar_type\n");
+               BUG();
        }
-
-       if (unlikely(index > 31))
-               panic("dma_unmap_single: "
-                     "Attempt to unmap an invalid address (0x%llx)\n",
-                     dma_addr);
-
-       raw_spin_lock_irqsave(&bar1_lock, flags);
-       bar1_state[index].ref_count--;
-       if (bar1_state[index].ref_count == 0)
-               octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
-       else if (unlikely(bar1_state[index].ref_count < 0))
-               panic("dma_unmap_single: Bar1[%u] reference count < 0\n",
-                     (int) index);
-       raw_spin_unlock_irqrestore(&bar1_lock, flags);
-done:
-       pr_debug("dma_unmap_single 0x%llx\n", dma_addr);
-       return;
-#endif
+       octeon_pci_dma_map_ops = &_octeon_pci_dma_map_ops.dma_map_ops;
 }
+#endif /* CONFIG_PCI */
index 6abe56f1e09737055c347a2d064af2a5dc991c37..d38246e33ddb9f1eacb7f885f809db54057c5203 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
@@ -26,8 +26,8 @@
  ***********************license end**************************************/
 
 /*
- * Implementation of the Level 2 Cache (L2C) control, measurement, and
- * debugging facilities.
+ * Implementation of the Level 2 Cache (L2C) control,
+ * measurement, and debugging facilities.
  */
 
 #include <asm/octeon/cvmx.h>
  * if multiple applications or operating systems are running, then it
  * is up to the user program to coordinate between them.
  */
-static cvmx_spinlock_t cvmx_l2c_spinlock;
-
-static inline int l2_size_half(void)
-{
-       uint64_t val = cvmx_read_csr(CVMX_L2D_FUS3);
-       return !!(val & (1ull << 34));
-}
+cvmx_spinlock_t cvmx_l2c_spinlock;
 
 int cvmx_l2c_get_core_way_partition(uint32_t core)
 {
@@ -58,6 +52,9 @@ int cvmx_l2c_get_core_way_partition(uint32_t core)
        if (core >= cvmx_octeon_num_cores())
                return -1;
 
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+               return cvmx_read_csr(CVMX_L2C_WPAR_PPX(core)) & 0xffff;
+
        /*
         * Use the lower two bits of the coreNumber to determine the
         * bit offset of the UMSK[] field in the L2C_SPAR register.
@@ -71,17 +68,13 @@ int cvmx_l2c_get_core_way_partition(uint32_t core)
 
        switch (core & 0xC) {
        case 0x0:
-               return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >>
-                       field;
+               return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >> field;
        case 0x4:
-               return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >>
-                       field;
+               return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >> field;
        case 0x8:
-               return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >>
-                       field;
+               return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >> field;
        case 0xC:
-               return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >>
-                       field;
+               return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >> field;
        }
        return 0;
 }
@@ -95,48 +88,50 @@ int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask)
 
        mask &= valid_mask;
 
-       /* A UMSK setting which blocks all L2C Ways is an error. */
-       if (mask == valid_mask)
+       /* A UMSK setting which blocks all L2C Ways is an error on some chips */
+       if (mask == valid_mask && !OCTEON_IS_MODEL(OCTEON_CN63XX))
                return -1;
 
        /* Validate the core number */
        if (core >= cvmx_octeon_num_cores())
                return -1;
 
-       /* Check to make sure current mask & new mask don't block all ways */
-       if (((mask | cvmx_l2c_get_core_way_partition(core)) & valid_mask) ==
-           valid_mask)
-               return -1;
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               cvmx_write_csr(CVMX_L2C_WPAR_PPX(core), mask);
+               return 0;
+       }
 
-       /* Use the lower two bits of core to determine the bit offset of the
+       /*
+        * Use the lower two bits of core to determine the bit offset of the
         * UMSK[] field in the L2C_SPAR register.
         */
        field = (core & 0x3) * 8;
 
-       /* Assign the new mask setting to the UMSK[] field in the appropriate
+       /*
+        * Assign the new mask setting to the UMSK[] field in the appropriate
         * L2C_SPAR register based on the core_num.
         *
         */
        switch (core & 0xC) {
        case 0x0:
                cvmx_write_csr(CVMX_L2C_SPAR0,
-                              (cvmx_read_csr(CVMX_L2C_SPAR0) &
-                               ~(0xFF << field)) | mask << field);
+                              (cvmx_read_csr(CVMX_L2C_SPAR0) & ~(0xFF << field)) |
+                              mask << field);
                break;
        case 0x4:
                cvmx_write_csr(CVMX_L2C_SPAR1,
-                              (cvmx_read_csr(CVMX_L2C_SPAR1) &
-                               ~(0xFF << field)) | mask << field);
+                              (cvmx_read_csr(CVMX_L2C_SPAR1) & ~(0xFF << field)) |
+                              mask << field);
                break;
        case 0x8:
                cvmx_write_csr(CVMX_L2C_SPAR2,
-                              (cvmx_read_csr(CVMX_L2C_SPAR2) &
-                               ~(0xFF << field)) | mask << field);
+                              (cvmx_read_csr(CVMX_L2C_SPAR2) & ~(0xFF << field)) |
+                              mask << field);
                break;
        case 0xC:
                cvmx_write_csr(CVMX_L2C_SPAR3,
-                              (cvmx_read_csr(CVMX_L2C_SPAR3) &
-                               ~(0xFF << field)) | mask << field);
+                              (cvmx_read_csr(CVMX_L2C_SPAR3) & ~(0xFF << field)) |
+                              mask << field);
                break;
        }
        return 0;
@@ -146,84 +141,137 @@ int cvmx_l2c_set_hw_way_partition(uint32_t mask)
 {
        uint32_t valid_mask;
 
-       valid_mask = 0xff;
-
-       if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN38XX)) {
-               if (l2_size_half())
-                       valid_mask = 0xf;
-       } else if (l2_size_half())
-               valid_mask = 0x3;
-
+       valid_mask = (0x1 << cvmx_l2c_get_num_assoc()) - 1;
        mask &= valid_mask;
 
-       /* A UMSK setting which blocks all L2C Ways is an error. */
-       if (mask == valid_mask)
-               return -1;
-       /* Check to make sure current mask & new mask don't block all ways */
-       if (((mask | cvmx_l2c_get_hw_way_partition()) & valid_mask) ==
-           valid_mask)
+       /* A UMSK setting which blocks all L2C Ways is an error on some chips */
+       if (mask == valid_mask  && !OCTEON_IS_MODEL(OCTEON_CN63XX))
                return -1;
 
-       cvmx_write_csr(CVMX_L2C_SPAR4,
-                      (cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+               cvmx_write_csr(CVMX_L2C_WPAR_IOBX(0), mask);
+       else
+               cvmx_write_csr(CVMX_L2C_SPAR4,
+                              (cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask);
        return 0;
 }
 
 int cvmx_l2c_get_hw_way_partition(void)
 {
-       return cvmx_read_csr(CVMX_L2C_SPAR4) & (0xFF);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+               return cvmx_read_csr(CVMX_L2C_WPAR_IOBX(0)) & 0xffff;
+       else
+               return cvmx_read_csr(CVMX_L2C_SPAR4) & (0xFF);
 }
 
 void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event,
                          uint32_t clear_on_read)
 {
-       union cvmx_l2c_pfctl pfctl;
+       if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+               union cvmx_l2c_pfctl pfctl;
 
-       pfctl.u64 = cvmx_read_csr(CVMX_L2C_PFCTL);
+               pfctl.u64 = cvmx_read_csr(CVMX_L2C_PFCTL);
 
-       switch (counter) {
-       case 0:
-               pfctl.s.cnt0sel = event;
-               pfctl.s.cnt0ena = 1;
-               if (!cvmx_octeon_is_pass1())
+               switch (counter) {
+               case 0:
+                       pfctl.s.cnt0sel = event;
+                       pfctl.s.cnt0ena = 1;
                        pfctl.s.cnt0rdclr = clear_on_read;
-               break;
-       case 1:
-               pfctl.s.cnt1sel = event;
-               pfctl.s.cnt1ena = 1;
-               if (!cvmx_octeon_is_pass1())
+                       break;
+               case 1:
+                       pfctl.s.cnt1sel = event;
+                       pfctl.s.cnt1ena = 1;
                        pfctl.s.cnt1rdclr = clear_on_read;
-               break;
-       case 2:
-               pfctl.s.cnt2sel = event;
-               pfctl.s.cnt2ena = 1;
-               if (!cvmx_octeon_is_pass1())
+                       break;
+               case 2:
+                       pfctl.s.cnt2sel = event;
+                       pfctl.s.cnt2ena = 1;
                        pfctl.s.cnt2rdclr = clear_on_read;
-               break;
-       case 3:
-       default:
-               pfctl.s.cnt3sel = event;
-               pfctl.s.cnt3ena = 1;
-               if (!cvmx_octeon_is_pass1())
+                       break;
+               case 3:
+               default:
+                       pfctl.s.cnt3sel = event;
+                       pfctl.s.cnt3ena = 1;
                        pfctl.s.cnt3rdclr = clear_on_read;
-               break;
-       }
+                       break;
+               }
 
-       cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64);
+               cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64);
+       } else {
+               union cvmx_l2c_tadx_prf l2c_tadx_prf;
+               int tad;
+
+               cvmx_dprintf("L2C performance counter events are different for this chip, mapping 'event' to cvmx_l2c_tad_event_t\n");
+               if (clear_on_read)
+                       cvmx_dprintf("L2C counters don't support clear on read for this chip\n");
+
+               l2c_tadx_prf.u64 = cvmx_read_csr(CVMX_L2C_TADX_PRF(0));
+
+               switch (counter) {
+               case 0:
+                       l2c_tadx_prf.s.cnt0sel = event;
+                       break;
+               case 1:
+                       l2c_tadx_prf.s.cnt1sel = event;
+                       break;
+               case 2:
+                       l2c_tadx_prf.s.cnt2sel = event;
+                       break;
+               default:
+               case 3:
+                       l2c_tadx_prf.s.cnt3sel = event;
+                       break;
+               }
+               for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                       cvmx_write_csr(CVMX_L2C_TADX_PRF(tad),
+                                      l2c_tadx_prf.u64);
+       }
 }
 
 uint64_t cvmx_l2c_read_perf(uint32_t counter)
 {
        switch (counter) {
        case 0:
-               return cvmx_read_csr(CVMX_L2C_PFC0);
+               if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+                       return cvmx_read_csr(CVMX_L2C_PFC0);
+               else {
+                       uint64_t counter = 0;
+                       int tad;
+                       for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                               counter += cvmx_read_csr(CVMX_L2C_TADX_PFC0(tad));
+                       return counter;
+               }
        case 1:
-               return cvmx_read_csr(CVMX_L2C_PFC1);
+               if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+                       return cvmx_read_csr(CVMX_L2C_PFC1);
+               else {
+                       uint64_t counter = 0;
+                       int tad;
+                       for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                               counter += cvmx_read_csr(CVMX_L2C_TADX_PFC1(tad));
+                       return counter;
+               }
        case 2:
-               return cvmx_read_csr(CVMX_L2C_PFC2);
+               if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+                       return cvmx_read_csr(CVMX_L2C_PFC2);
+               else {
+                       uint64_t counter = 0;
+                       int tad;
+                       for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                               counter += cvmx_read_csr(CVMX_L2C_TADX_PFC2(tad));
+                       return counter;
+               }
        case 3:
        default:
-               return cvmx_read_csr(CVMX_L2C_PFC3);
+               if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+                       return cvmx_read_csr(CVMX_L2C_PFC3);
+               else {
+                       uint64_t counter = 0;
+                       int tad;
+                       for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+                               counter += cvmx_read_csr(CVMX_L2C_TADX_PFC3(tad));
+                       return counter;
+               }
        }
 }
 
@@ -240,7 +288,7 @@ static void fault_in(uint64_t addr, int len)
        volatile char dummy;
        /*
         * Adjust addr and length so we get all cache lines even for
-        * small ranges spanning two cache lines
+        * small ranges spanning two cache lines.
         */
        len += addr & CVMX_CACHE_LINE_MASK;
        addr &= ~CVMX_CACHE_LINE_MASK;
@@ -259,67 +307,100 @@ static void fault_in(uint64_t addr, int len)
 
 int cvmx_l2c_lock_line(uint64_t addr)
 {
-       int retval = 0;
-       union cvmx_l2c_dbg l2cdbg;
-       union cvmx_l2c_lckbase lckbase;
-       union cvmx_l2c_lckoff lckoff;
-       union cvmx_l2t_err l2t_err;
-       l2cdbg.u64 = 0;
-       lckbase.u64 = 0;
-       lckoff.u64 = 0;
-
-       cvmx_spinlock_lock(&cvmx_l2c_spinlock);
-
-       /* Clear l2t error bits if set */
-       l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
-       l2t_err.s.lckerr = 1;
-       l2t_err.s.lckerr2 = 1;
-       cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               int shift = CVMX_L2C_TAG_ADDR_ALIAS_SHIFT;
+               uint64_t assoc = cvmx_l2c_get_num_assoc();
+               uint64_t tag = addr >> shift;
+               uint64_t index = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, cvmx_l2c_address_to_index(addr) << CVMX_L2C_IDX_ADDR_SHIFT);
+               uint64_t way;
+               union cvmx_l2c_tadx_tag l2c_tadx_tag;
+
+               CVMX_CACHE_LCKL2(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, addr), 0);
+
+               /* Make sure we were able to lock the line */
+               for (way = 0; way < assoc; way++) {
+                       CVMX_CACHE_LTGL2I(index | (way << shift), 0);
+                       /* make sure CVMX_L2C_TADX_TAG is updated */
+                       CVMX_SYNC;
+                       l2c_tadx_tag.u64 = cvmx_read_csr(CVMX_L2C_TADX_TAG(0));
+                       if (l2c_tadx_tag.s.valid && l2c_tadx_tag.s.tag == tag)
+                               break;
+               }
 
-       addr &= ~CVMX_CACHE_LINE_MASK;
+               /* Check if a valid line is found */
+               if (way >= assoc) {
+                       /* cvmx_dprintf("ERROR: cvmx_l2c_lock_line: line not found for locking at 0x%llx address\n", (unsigned long long)addr); */
+                       return -1;
+               }
 
-       /* Set this core as debug core */
-       l2cdbg.s.ppnum = cvmx_get_core_num();
-       CVMX_SYNC;
-       cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
-       cvmx_read_csr(CVMX_L2C_DBG);
-
-       lckoff.s.lck_offset = 0;        /* Only lock 1 line at a time */
-       cvmx_write_csr(CVMX_L2C_LCKOFF, lckoff.u64);
-       cvmx_read_csr(CVMX_L2C_LCKOFF);
-
-       if (((union cvmx_l2c_cfg) (cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) {
-               int alias_shift =
-                   CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1;
-               uint64_t addr_tmp =
-                   addr ^ (addr & ((1 << alias_shift) - 1)) >>
-                   CVMX_L2_SET_BITS;
-               lckbase.s.lck_base = addr_tmp >> 7;
+               /* Check if lock bit is not set */
+               if (!l2c_tadx_tag.s.lock) {
+                       /* cvmx_dprintf("ERROR: cvmx_l2c_lock_line: Not able to lock at 0x%llx address\n", (unsigned long long)addr); */
+                       return -1;
+               }
+               return way;
        } else {
-               lckbase.s.lck_base = addr >> 7;
-       }
+               int retval = 0;
+               union cvmx_l2c_dbg l2cdbg;
+               union cvmx_l2c_lckbase lckbase;
+               union cvmx_l2c_lckoff lckoff;
+               union cvmx_l2t_err l2t_err;
 
-       lckbase.s.lck_ena = 1;
-       cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
-       cvmx_read_csr(CVMX_L2C_LCKBASE);        /* Make sure it gets there */
+               cvmx_spinlock_lock(&cvmx_l2c_spinlock);
 
-       fault_in(addr, CVMX_CACHE_LINE_SIZE);
+               l2cdbg.u64 = 0;
+               lckbase.u64 = 0;
+               lckoff.u64 = 0;
 
-       lckbase.s.lck_ena = 0;
-       cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
-       cvmx_read_csr(CVMX_L2C_LCKBASE);        /* Make sure it gets there */
+               /* Clear l2t error bits if set */
+               l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+               l2t_err.s.lckerr = 1;
+               l2t_err.s.lckerr2 = 1;
+               cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
 
-       /* Stop being debug core */
-       cvmx_write_csr(CVMX_L2C_DBG, 0);
-       cvmx_read_csr(CVMX_L2C_DBG);
+               addr &= ~CVMX_CACHE_LINE_MASK;
 
-       l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
-       if (l2t_err.s.lckerr || l2t_err.s.lckerr2)
-               retval = 1;     /* We were unable to lock the line */
+               /* Set this core as debug core */
+               l2cdbg.s.ppnum = cvmx_get_core_num();
+               CVMX_SYNC;
+               cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+               cvmx_read_csr(CVMX_L2C_DBG);
+
+               lckoff.s.lck_offset = 0; /* Only lock 1 line at a time */
+               cvmx_write_csr(CVMX_L2C_LCKOFF, lckoff.u64);
+               cvmx_read_csr(CVMX_L2C_LCKOFF);
+
+               if (((union cvmx_l2c_cfg)(cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) {
+                       int alias_shift = CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1;
+                       uint64_t addr_tmp = addr ^ (addr & ((1 << alias_shift) - 1)) >> CVMX_L2_SET_BITS;
+                       lckbase.s.lck_base = addr_tmp >> 7;
+               } else {
+                       lckbase.s.lck_base = addr >> 7;
+               }
 
-       cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+               lckbase.s.lck_ena = 1;
+               cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+               /* Make sure it gets there */
+               cvmx_read_csr(CVMX_L2C_LCKBASE);
 
-       return retval;
+               fault_in(addr, CVMX_CACHE_LINE_SIZE);
+
+               lckbase.s.lck_ena = 0;
+               cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+               /* Make sure it gets there */
+               cvmx_read_csr(CVMX_L2C_LCKBASE);
+
+               /* Stop being debug core */
+               cvmx_write_csr(CVMX_L2C_DBG, 0);
+               cvmx_read_csr(CVMX_L2C_DBG);
+
+               l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+               if (l2t_err.s.lckerr || l2t_err.s.lckerr2)
+                       retval = 1;  /* We were unable to lock the line */
+
+               cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+               return retval;
+       }
 }
 
 int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len)
@@ -336,7 +417,6 @@ int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len)
                start += CVMX_CACHE_LINE_SIZE;
                len -= CVMX_CACHE_LINE_SIZE;
        }
-
        return retval;
 }
 
@@ -344,80 +424,73 @@ void cvmx_l2c_flush(void)
 {
        uint64_t assoc, set;
        uint64_t n_assoc, n_set;
-       union cvmx_l2c_dbg l2cdbg;
-
-       cvmx_spinlock_lock(&cvmx_l2c_spinlock);
 
-       l2cdbg.u64 = 0;
-       if (!OCTEON_IS_MODEL(OCTEON_CN30XX))
-               l2cdbg.s.ppnum = cvmx_get_core_num();
-       l2cdbg.s.finv = 1;
-       n_set = CVMX_L2_SETS;
-       n_assoc = l2_size_half() ? (CVMX_L2_ASSOC / 2) : CVMX_L2_ASSOC;
-       for (set = 0; set < n_set; set++) {
-               for (assoc = 0; assoc < n_assoc; assoc++) {
-                       l2cdbg.s.set = assoc;
-                       /* Enter debug mode, and make sure all other
-                        ** writes complete before we enter debug
-                        ** mode */
-                       CVMX_SYNCW;
-                       cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
-                       cvmx_read_csr(CVMX_L2C_DBG);
-
-                       CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
-                                              (CVMX_MIPS_SPACE_XKPHYS,
-                                               set * CVMX_CACHE_LINE_SIZE), 0);
-                       CVMX_SYNCW;     /* Push STF out to L2 */
-                       /* Exit debug mode */
-                       CVMX_SYNC;
-                       cvmx_write_csr(CVMX_L2C_DBG, 0);
-                       cvmx_read_csr(CVMX_L2C_DBG);
+       n_set = cvmx_l2c_get_num_sets();
+       n_assoc = cvmx_l2c_get_num_assoc();
+
+       if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+               uint64_t address;
+               /* These may look like constants, but they aren't... */
+               int assoc_shift = CVMX_L2C_TAG_ADDR_ALIAS_SHIFT;
+               int set_shift = CVMX_L2C_IDX_ADDR_SHIFT;
+               for (set = 0; set < n_set; set++) {
+                       for (assoc = 0; assoc < n_assoc; assoc++) {
+                               address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+                                                      (assoc << assoc_shift) | (set << set_shift));
+                               CVMX_CACHE_WBIL2I(address, 0);
+                       }
                }
+       } else {
+               for (set = 0; set < n_set; set++)
+                       for (assoc = 0; assoc < n_assoc; assoc++)
+                               cvmx_l2c_flush_line(assoc, set);
        }
-
-       cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
 }
 
+
 int cvmx_l2c_unlock_line(uint64_t address)
 {
-       int assoc;
-       union cvmx_l2c_tag tag;
-       union cvmx_l2c_dbg l2cdbg;
-       uint32_t tag_addr;
 
-       uint32_t index = cvmx_l2c_address_to_index(address);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               int assoc;
+               union cvmx_l2c_tag tag;
+               uint32_t tag_addr;
+               uint32_t index = cvmx_l2c_address_to_index(address);
+
+               tag_addr = ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) & ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
+
+               /*
+                * For 63XX, we can flush a line by using the physical
+                * address directly, so finding the cache line used by
+                * the address is only required to provide the proper
+                * return value for the function.
+                */
+               for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
+                       tag = cvmx_l2c_get_tag(assoc, index);
+
+                       if (tag.s.V && (tag.s.addr == tag_addr)) {
+                               CVMX_CACHE_WBIL2(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, address), 0);
+                               return tag.s.L;
+                       }
+               }
+       } else {
+               int assoc;
+               union cvmx_l2c_tag tag;
+               uint32_t tag_addr;
 
-       cvmx_spinlock_lock(&cvmx_l2c_spinlock);
-       /* Compute portion of address that is stored in tag */
-       tag_addr =
-           ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) &
-            ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
-       for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
-               tag = cvmx_get_l2c_tag(assoc, index);
+               uint32_t index = cvmx_l2c_address_to_index(address);
 
-               if (tag.s.V && (tag.s.addr == tag_addr)) {
-                       l2cdbg.u64 = 0;
-                       l2cdbg.s.ppnum = cvmx_get_core_num();
-                       l2cdbg.s.set = assoc;
-                       l2cdbg.s.finv = 1;
+               /* Compute portion of address that is stored in tag */
+               tag_addr = ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) & ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
+               for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
+                       tag = cvmx_l2c_get_tag(assoc, index);
 
-                       CVMX_SYNC;
-                       /* Enter debug mode */
-                       cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
-                       cvmx_read_csr(CVMX_L2C_DBG);
-
-                       CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
-                                              (CVMX_MIPS_SPACE_XKPHYS,
-                                               address), 0);
-                       CVMX_SYNC;
-                       /* Exit debug mode */
-                       cvmx_write_csr(CVMX_L2C_DBG, 0);
-                       cvmx_read_csr(CVMX_L2C_DBG);
-                       cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
-                       return tag.s.L;
+                       if (tag.s.V && (tag.s.addr == tag_addr)) {
+                               cvmx_l2c_flush_line(assoc, index);
+                               return tag.s.L;
+                       }
                }
        }
-       cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
        return 0;
 }
 
@@ -445,48 +518,49 @@ union __cvmx_l2c_tag {
        uint64_t u64;
        struct cvmx_l2c_tag_cn50xx {
                uint64_t reserved:40;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:20;       /* Phys mem addr (33..14) */
        } cn50xx;
        struct cvmx_l2c_tag_cn30xx {
                uint64_t reserved:41;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:19;       /* Phys mem addr (33..15) */
        } cn30xx;
        struct cvmx_l2c_tag_cn31xx {
                uint64_t reserved:42;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:18;       /* Phys mem addr (33..16) */
        } cn31xx;
        struct cvmx_l2c_tag_cn38xx {
                uint64_t reserved:43;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:17;       /* Phys mem addr (33..17) */
        } cn38xx;
        struct cvmx_l2c_tag_cn58xx {
                uint64_t reserved:44;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:16;       /* Phys mem addr (33..18) */
        } cn58xx;
        struct cvmx_l2c_tag_cn58xx cn56xx;      /* 2048 sets */
        struct cvmx_l2c_tag_cn31xx cn52xx;      /* 512 sets */
 };
 
+
 /**
  * @INTERNAL
  * Function to read a L2C tag.  This code make the current core
@@ -503,7 +577,7 @@ union __cvmx_l2c_tag {
 static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
 {
 
-       uint64_t debug_tag_addr = (((1ULL << 63) | (index << 7)) + 96);
+       uint64_t debug_tag_addr = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, (index << 7) + 96);
        uint64_t core = cvmx_get_core_num();
        union __cvmx_l2c_tag tag_val;
        uint64_t dbg_addr = CVMX_L2C_DBG;
@@ -512,12 +586,15 @@ static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
        union cvmx_l2c_dbg debug_val;
        debug_val.u64 = 0;
        /*
-        * For low core count parts, the core number is always small enough
-        * to stay in the correct field and not set any reserved bits.
+        * For low core count parts, the core number is always small
+        * enough to stay in the correct field and not set any
+        * reserved bits.
         */
        debug_val.s.ppnum = core;
        debug_val.s.l2t = 1;
        debug_val.s.set = assoc;
+
+       local_irq_save(flags);
        /*
         * Make sure core is quiet (no prefetches, etc.) before
         * entering debug mode.
@@ -526,112 +603,139 @@ static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
        /* Flush L1 to make sure debug load misses L1 */
        CVMX_DCACHE_INVALIDATE;
 
-       local_irq_save(flags);
-
        /*
         * The following must be done in assembly as when in debug
         * mode all data loads from L2 return special debug data, not
-        * normal memory contents.  Also, interrupts must be
-        * disabled, since if an interrupt occurs while in debug mode
-        * the ISR will get debug data from all its memory reads
-        * instead of the contents of memory
+        * normal memory contents.  Also, interrupts must be disabled,
+        * since if an interrupt occurs while in debug mode the ISR
+        * will get debug data from all its memory * reads instead of
+        * the contents of memory.
         */
 
-       asm volatile (".set push              \n"
-               "        .set mips64              \n"
-               "        .set noreorder           \n"
-               /* Enter debug mode, wait for store */
-               "        sd    %[dbg_val], 0(%[dbg_addr])  \n"
-               "        ld    $0, 0(%[dbg_addr]) \n"
-               /* Read L2C tag data */
-               "        ld    %[tag_val], 0(%[tag_addr]) \n"
-               /* Exit debug mode, wait for store */
-               "        sd    $0, 0(%[dbg_addr])  \n"
-               "        ld    $0, 0(%[dbg_addr]) \n"
-               /* Invalidate dcache to discard debug data */
-               "        cache 9, 0($0) \n"
-               "        .set pop" :
-               [tag_val] "=r"(tag_val.u64) : [dbg_addr] "r"(dbg_addr),
-               [dbg_val] "r"(debug_val.u64),
-               [tag_addr] "r"(debug_tag_addr) : "memory");
+       asm volatile (
+               ".set push\n\t"
+               ".set mips64\n\t"
+               ".set noreorder\n\t"
+               "sd    %[dbg_val], 0(%[dbg_addr])\n\t"   /* Enter debug mode, wait for store */
+               "ld    $0, 0(%[dbg_addr])\n\t"
+               "ld    %[tag_val], 0(%[tag_addr])\n\t"   /* Read L2C tag data */
+               "sd    $0, 0(%[dbg_addr])\n\t"          /* Exit debug mode, wait for store */
+               "ld    $0, 0(%[dbg_addr])\n\t"
+               "cache 9, 0($0)\n\t"             /* Invalidate dcache to discard debug data */
+               ".set pop"
+               : [tag_val] "=r" (tag_val)
+               : [dbg_addr] "r" (dbg_addr), [dbg_val] "r" (debug_val), [tag_addr] "r" (debug_tag_addr)
+               : "memory");
 
        local_irq_restore(flags);
-       return tag_val;
 
+       return tag_val;
 }
 
+
 union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index)
 {
-       union __cvmx_l2c_tag tmp_tag;
        union cvmx_l2c_tag tag;
        tag.u64 = 0;
 
        if ((int)association >= cvmx_l2c_get_num_assoc()) {
-               cvmx_dprintf
-                   ("ERROR: cvmx_get_l2c_tag association out of range\n");
+               cvmx_dprintf("ERROR: cvmx_l2c_get_tag association out of range\n");
                return tag;
        }
        if ((int)index >= cvmx_l2c_get_num_sets()) {
-               cvmx_dprintf("ERROR: cvmx_get_l2c_tag "
-                            "index out of range (arg: %d, max: %d\n",
-                    index, cvmx_l2c_get_num_sets());
+               cvmx_dprintf("ERROR: cvmx_l2c_get_tag index out of range (arg: %d, max: %d)\n",
+                            (int)index, cvmx_l2c_get_num_sets());
                return tag;
        }
-       /* __read_l2_tag is intended for internal use only */
-       tmp_tag = __read_l2_tag(association, index);
-
-       /*
-        * Convert all tag structure types to generic version, as it
-        * can represent all models.
-        */
-       if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
-               tag.s.V = tmp_tag.cn58xx.V;
-               tag.s.D = tmp_tag.cn58xx.D;
-               tag.s.L = tmp_tag.cn58xx.L;
-               tag.s.U = tmp_tag.cn58xx.U;
-               tag.s.addr = tmp_tag.cn58xx.addr;
-       } else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
-               tag.s.V = tmp_tag.cn38xx.V;
-               tag.s.D = tmp_tag.cn38xx.D;
-               tag.s.L = tmp_tag.cn38xx.L;
-               tag.s.U = tmp_tag.cn38xx.U;
-               tag.s.addr = tmp_tag.cn38xx.addr;
-       } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
-                  || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
-               tag.s.V = tmp_tag.cn31xx.V;
-               tag.s.D = tmp_tag.cn31xx.D;
-               tag.s.L = tmp_tag.cn31xx.L;
-               tag.s.U = tmp_tag.cn31xx.U;
-               tag.s.addr = tmp_tag.cn31xx.addr;
-       } else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
-               tag.s.V = tmp_tag.cn30xx.V;
-               tag.s.D = tmp_tag.cn30xx.D;
-               tag.s.L = tmp_tag.cn30xx.L;
-               tag.s.U = tmp_tag.cn30xx.U;
-               tag.s.addr = tmp_tag.cn30xx.addr;
-       } else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
-               tag.s.V = tmp_tag.cn50xx.V;
-               tag.s.D = tmp_tag.cn50xx.D;
-               tag.s.L = tmp_tag.cn50xx.L;
-               tag.s.U = tmp_tag.cn50xx.U;
-               tag.s.addr = tmp_tag.cn50xx.addr;
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               union cvmx_l2c_tadx_tag l2c_tadx_tag;
+               uint64_t address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+                                               (association << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) |
+                                               (index << CVMX_L2C_IDX_ADDR_SHIFT));
+               /*
+                * Use L2 cache Index load tag cache instruction, as
+                * hardware loads the virtual tag for the L2 cache
+                * block with the contents of L2C_TAD0_TAG
+                * register.
+                */
+               CVMX_CACHE_LTGL2I(address, 0);
+               CVMX_SYNC;   /* make sure CVMX_L2C_TADX_TAG is updated */
+               l2c_tadx_tag.u64 = cvmx_read_csr(CVMX_L2C_TADX_TAG(0));
+
+               tag.s.V     = l2c_tadx_tag.s.valid;
+               tag.s.D     = l2c_tadx_tag.s.dirty;
+               tag.s.L     = l2c_tadx_tag.s.lock;
+               tag.s.U     = l2c_tadx_tag.s.use;
+               tag.s.addr  = l2c_tadx_tag.s.tag;
        } else {
-               cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+               union __cvmx_l2c_tag tmp_tag;
+               /* __read_l2_tag is intended for internal use only */
+               tmp_tag = __read_l2_tag(association, index);
+
+               /*
+                * Convert all tag structure types to generic version,
+                * as it can represent all models.
+                */
+               if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
+                       tag.s.V    = tmp_tag.cn58xx.V;
+                       tag.s.D    = tmp_tag.cn58xx.D;
+                       tag.s.L    = tmp_tag.cn58xx.L;
+                       tag.s.U    = tmp_tag.cn58xx.U;
+                       tag.s.addr = tmp_tag.cn58xx.addr;
+               } else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+                       tag.s.V    = tmp_tag.cn38xx.V;
+                       tag.s.D    = tmp_tag.cn38xx.D;
+                       tag.s.L    = tmp_tag.cn38xx.L;
+                       tag.s.U    = tmp_tag.cn38xx.U;
+                       tag.s.addr = tmp_tag.cn38xx.addr;
+               } else if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+                       tag.s.V    = tmp_tag.cn31xx.V;
+                       tag.s.D    = tmp_tag.cn31xx.D;
+                       tag.s.L    = tmp_tag.cn31xx.L;
+                       tag.s.U    = tmp_tag.cn31xx.U;
+                       tag.s.addr = tmp_tag.cn31xx.addr;
+               } else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
+                       tag.s.V    = tmp_tag.cn30xx.V;
+                       tag.s.D    = tmp_tag.cn30xx.D;
+                       tag.s.L    = tmp_tag.cn30xx.L;
+                       tag.s.U    = tmp_tag.cn30xx.U;
+                       tag.s.addr = tmp_tag.cn30xx.addr;
+               } else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+                       tag.s.V    = tmp_tag.cn50xx.V;
+                       tag.s.D    = tmp_tag.cn50xx.D;
+                       tag.s.L    = tmp_tag.cn50xx.L;
+                       tag.s.U    = tmp_tag.cn50xx.U;
+                       tag.s.addr = tmp_tag.cn50xx.addr;
+               } else {
+                       cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+               }
        }
-
        return tag;
 }
 
 uint32_t cvmx_l2c_address_to_index(uint64_t addr)
 {
        uint64_t idx = addr >> CVMX_L2C_IDX_ADDR_SHIFT;
-       union cvmx_l2c_cfg l2c_cfg;
-       l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
+       int indxalias = 0;
 
-       if (l2c_cfg.s.idxalias) {
-               idx ^=
-                   ((addr & CVMX_L2C_ALIAS_MASK) >>
-                    CVMX_L2C_TAG_ADDR_ALIAS_SHIFT);
+       if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+               union cvmx_l2c_ctl l2c_ctl;
+               l2c_ctl.u64 = cvmx_read_csr(CVMX_L2C_CTL);
+               indxalias = !l2c_ctl.s.disidxalias;
+       } else {
+               union cvmx_l2c_cfg l2c_cfg;
+               l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
+               indxalias = l2c_cfg.s.idxalias;
+       }
+
+       if (indxalias) {
+               if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+                       uint32_t a_14_12 = (idx / (CVMX_L2C_MEMBANK_SELECT_SIZE/(1<<CVMX_L2C_IDX_ADDR_SHIFT))) & 0x7;
+                       idx ^= idx / cvmx_l2c_get_num_sets();
+                       idx ^= a_14_12;
+               } else {
+                       idx ^= ((addr & CVMX_L2C_ALIAS_MASK) >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT);
+               }
        }
        idx &= CVMX_L2C_IDX_MASK;
        return idx;
@@ -652,10 +756,9 @@ int cvmx_l2c_get_set_bits(void)
        int l2_set_bits;
        if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
                l2_set_bits = 11;       /* 2048 sets */
-       else if (OCTEON_IS_MODEL(OCTEON_CN38XX))
+       else if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
                l2_set_bits = 10;       /* 1024 sets */
-       else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
-                || OCTEON_IS_MODEL(OCTEON_CN52XX))
+       else if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
                l2_set_bits = 9;        /* 512 sets */
        else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
                l2_set_bits = 8;        /* 256 sets */
@@ -666,7 +769,6 @@ int cvmx_l2c_get_set_bits(void)
                l2_set_bits = 11;       /* 2048 sets */
        }
        return l2_set_bits;
-
 }
 
 /* Return the number of sets in the L2 Cache */
@@ -682,8 +784,11 @@ int cvmx_l2c_get_num_assoc(void)
        if (OCTEON_IS_MODEL(OCTEON_CN56XX) ||
            OCTEON_IS_MODEL(OCTEON_CN52XX) ||
            OCTEON_IS_MODEL(OCTEON_CN58XX) ||
-           OCTEON_IS_MODEL(OCTEON_CN50XX) || OCTEON_IS_MODEL(OCTEON_CN38XX))
+           OCTEON_IS_MODEL(OCTEON_CN50XX) ||
+           OCTEON_IS_MODEL(OCTEON_CN38XX))
                l2_assoc = 8;
+       else if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+               l2_assoc = 16;
        else if (OCTEON_IS_MODEL(OCTEON_CN31XX) ||
                 OCTEON_IS_MODEL(OCTEON_CN30XX))
                l2_assoc = 4;
@@ -693,11 +798,42 @@ int cvmx_l2c_get_num_assoc(void)
        }
 
        /* Check to see if part of the cache is disabled */
-       if (cvmx_fuse_read(265))
-               l2_assoc = l2_assoc >> 2;
-       else if (cvmx_fuse_read(264))
-               l2_assoc = l2_assoc >> 1;
-
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               union cvmx_mio_fus_dat3 mio_fus_dat3;
+
+               mio_fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
+               /*
+                * cvmx_mio_fus_dat3.s.l2c_crip fuses map as follows
+                * <2> will be not used for 63xx
+                * <1> disables 1/2 ways
+                * <0> disables 1/4 ways
+                * They are cumulative, so for 63xx:
+                * <1> <0>
+                * 0 0 16-way 2MB cache
+                * 0 1 12-way 1.5MB cache
+                * 1 0 8-way 1MB cache
+                * 1 1 4-way 512KB cache
+                */
+
+               if (mio_fus_dat3.s.l2c_crip == 3)
+                       l2_assoc = 4;
+               else if (mio_fus_dat3.s.l2c_crip == 2)
+                       l2_assoc = 8;
+               else if (mio_fus_dat3.s.l2c_crip == 1)
+                       l2_assoc = 12;
+       } else {
+               union cvmx_l2d_fus3 val;
+               val.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
+               /*
+                * Using shifts here, as bit position names are
+                * different for each model but they all mean the
+                * same.
+                */
+               if ((val.u64 >> 35) & 0x1)
+                       l2_assoc = l2_assoc >> 2;
+               else if ((val.u64 >> 34) & 0x1)
+                       l2_assoc = l2_assoc >> 1;
+       }
        return l2_assoc;
 }
 
@@ -711,24 +847,54 @@ int cvmx_l2c_get_num_assoc(void)
  */
 void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index)
 {
-       union cvmx_l2c_dbg l2cdbg;
+       /* Check the range of the index. */
+       if (index > (uint32_t)cvmx_l2c_get_num_sets()) {
+               cvmx_dprintf("ERROR: cvmx_l2c_flush_line index out of range.\n");
+               return;
+       }
 
-       l2cdbg.u64 = 0;
-       l2cdbg.s.ppnum = cvmx_get_core_num();
-       l2cdbg.s.finv = 1;
+       /* Check the range of association. */
+       if (assoc > (uint32_t)cvmx_l2c_get_num_assoc()) {
+               cvmx_dprintf("ERROR: cvmx_l2c_flush_line association out of range.\n");
+               return;
+       }
 
-       l2cdbg.s.set = assoc;
-       /*
-        * Enter debug mode, and make sure all other writes complete
-        * before we enter debug mode.
-        */
-       asm volatile ("sync" : : : "memory");
-       cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
-       cvmx_read_csr(CVMX_L2C_DBG);
-
-       CVMX_PREPARE_FOR_STORE(((1ULL << 63) + (index) * 128), 0);
-       /* Exit debug mode */
-       asm volatile ("sync" : : : "memory");
-       cvmx_write_csr(CVMX_L2C_DBG, 0);
-       cvmx_read_csr(CVMX_L2C_DBG);
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+               uint64_t address;
+               /* Create the address based on index and association.
+                * Bits<20:17> select the way of the cache block involved in
+                *             the operation
+                * Bits<16:7> of the effect address select the index
+                */
+               address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+                               (assoc << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) |
+                               (index << CVMX_L2C_IDX_ADDR_SHIFT));
+               CVMX_CACHE_WBIL2I(address, 0);
+       } else {
+               union cvmx_l2c_dbg l2cdbg;
+
+               l2cdbg.u64 = 0;
+               if (!OCTEON_IS_MODEL(OCTEON_CN30XX))
+                       l2cdbg.s.ppnum = cvmx_get_core_num();
+               l2cdbg.s.finv = 1;
+
+               l2cdbg.s.set = assoc;
+               cvmx_spinlock_lock(&cvmx_l2c_spinlock);
+               /*
+                * Enter debug mode, and make sure all other writes
+                * complete before we enter debug mode
+                */
+               CVMX_SYNC;
+               cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+               cvmx_read_csr(CVMX_L2C_DBG);
+
+               CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+                                                   index * CVMX_CACHE_LINE_SIZE),
+                                      0);
+               /* Exit debug mode */
+               CVMX_SYNC;
+               cvmx_write_csr(CVMX_L2C_DBG, 0);
+               cvmx_read_csr(CVMX_L2C_DBG);
+               cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+       }
 }
index 62ac30eef5e8a1ff5dfac8bfdbf94e846a52b6e0..cecaf62aef32c59322553983003c34dc71a98fa0 100644 (file)
@@ -3,13 +3,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2004-2009 Cavium Networks
+ * Copyright (C) 2004-2010 Cavium Networks
  * Copyright (C) 2008 Wind River Systems
  */
 
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/i2c.h>
+#include <linux/usb.h>
+#include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
@@ -198,7 +200,7 @@ static int __init octeon_i2c_device_init(void)
                num_ports = 1;
 
        for (port = 0; port < num_ports; port++) {
-               octeon_i2c_data[port].sys_freq = octeon_get_clock_rate();
+               octeon_i2c_data[port].sys_freq = octeon_get_io_clock_rate();
                /*FIXME: should be examined. At the moment is set for 100Khz */
                octeon_i2c_data[port].i2c_freq = 100000;
 
@@ -301,6 +303,10 @@ static int __init octeon_mgmt_device_init(void)
                        ret = -ENOMEM;
                        goto out;
                }
+               /* No DMA restrictions */
+               pd->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+               pd->dev.dma_mask = &pd->dev.coherent_dma_mask;
+
                switch (port) {
                case 0:
                        mgmt_port_resource.start = OCTEON_IRQ_MII0;
@@ -332,6 +338,108 @@ out:
 }
 device_initcall(octeon_mgmt_device_init);
 
+#ifdef CONFIG_USB
+
+static int __init octeon_ehci_device_init(void)
+{
+       struct platform_device *pd;
+       int ret = 0;
+
+       struct resource usb_resources[] = {
+               {
+                       .flags  = IORESOURCE_MEM,
+               }, {
+                       .flags  = IORESOURCE_IRQ,
+               }
+       };
+
+       /* Only Octeon2 has ehci/ohci */
+       if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
+               return 0;
+
+       if (octeon_is_simulation() || usb_disabled())
+               return 0; /* No USB in the simulator. */
+
+       pd = platform_device_alloc("octeon-ehci", 0);
+       if (!pd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       usb_resources[0].start = 0x00016F0000000000ULL;
+       usb_resources[0].end = usb_resources[0].start + 0x100;
+
+       usb_resources[1].start = OCTEON_IRQ_USB0;
+       usb_resources[1].end = OCTEON_IRQ_USB0;
+
+       ret = platform_device_add_resources(pd, usb_resources,
+                                           ARRAY_SIZE(usb_resources));
+       if (ret)
+               goto fail;
+
+       ret = platform_device_add(pd);
+       if (ret)
+               goto fail;
+
+       return ret;
+fail:
+       platform_device_put(pd);
+out:
+       return ret;
+}
+device_initcall(octeon_ehci_device_init);
+
+static int __init octeon_ohci_device_init(void)
+{
+       struct platform_device *pd;
+       int ret = 0;
+
+       struct resource usb_resources[] = {
+               {
+                       .flags  = IORESOURCE_MEM,
+               }, {
+                       .flags  = IORESOURCE_IRQ,
+               }
+       };
+
+       /* Only Octeon2 has ehci/ohci */
+       if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
+               return 0;
+
+       if (octeon_is_simulation() || usb_disabled())
+               return 0; /* No USB in the simulator. */
+
+       pd = platform_device_alloc("octeon-ohci", 0);
+       if (!pd) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       usb_resources[0].start = 0x00016F0000000400ULL;
+       usb_resources[0].end = usb_resources[0].start + 0x100;
+
+       usb_resources[1].start = OCTEON_IRQ_USB0;
+       usb_resources[1].end = OCTEON_IRQ_USB0;
+
+       ret = platform_device_add_resources(pd, usb_resources,
+                                           ARRAY_SIZE(usb_resources));
+       if (ret)
+               goto fail;
+
+       ret = platform_device_add(pd);
+       if (ret)
+               goto fail;
+
+       return ret;
+fail:
+       platform_device_put(pd);
+out:
+       return ret;
+}
+device_initcall(octeon_ohci_device_init);
+
+#endif /* CONFIG_USB */
+
 MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Platform driver for Octeon SOC");
index 12dbf533b77dc2da263c4e0bfe9e4c2fa86c51d8..057f0ae88c994e6052892d4fc44620c0da7d26fa 100644 (file)
@@ -66,7 +66,7 @@ static void __init octeon_uart_set_common(struct plat_serial8250_port *p)
                /* Make simulator output fast*/
                p->uartclk = 115200 * 16;
        else
-               p->uartclk = mips_hpt_frequency;
+               p->uartclk = octeon_get_io_clock_rate();
        p->serial_in = octeon_serial_in;
        p->serial_out = octeon_serial_out;
 }
index 69197cb6c7ea106349a23ad5b81f615a8c70c614..b0c3686c96dd614abe8dac92a3a84a04818c2e7c 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <asm/octeon/octeon.h>
 #include <asm/octeon/pci-octeon.h>
+#include <asm/octeon/cvmx-mio-defs.h>
 
 #ifdef CONFIG_CAVIUM_DECODE_RSL
 extern void cvmx_interrupt_rsl_decode(void);
@@ -96,12 +97,21 @@ int octeon_is_pci_host(void)
  */
 uint64_t octeon_get_clock_rate(void)
 {
-       if (octeon_is_simulation())
-               octeon_bootinfo->eclock_hz = 6000000;
-       return octeon_bootinfo->eclock_hz;
+       struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();
+
+       return sysinfo->cpu_clock_hz;
 }
 EXPORT_SYMBOL(octeon_get_clock_rate);
 
+static u64 octeon_io_clock_rate;
+
+u64 octeon_get_io_clock_rate(void)
+{
+       return octeon_io_clock_rate;
+}
+EXPORT_SYMBOL(octeon_get_io_clock_rate);
+
+
 /**
  * Write to the LCD display connected to the bootbus. This display
  * exists on most Cavium evaluation boards. If it doesn't exist, then
@@ -346,8 +356,18 @@ void octeon_user_io_init(void)
        cvmmemctl.s.wbfltime = 0;
        /* R/W If set, do not put Istream in the L2 cache. */
        cvmmemctl.s.istrnol2 = 0;
-       /* R/W The write buffer threshold. */
-       cvmmemctl.s.wbthresh = 10;
+
+       /*
+        * R/W The write buffer threshold. As per erratum Core-14752
+        * for CN63XX, a sc/scd might fail if the write buffer is
+        * full.  Lowering WBTHRESH greatly lowers the chances of the
+        * write buffer ever being full and triggering the erratum.
+        */
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
+               cvmmemctl.s.wbthresh = 4;
+       else
+               cvmmemctl.s.wbthresh = 10;
+
        /* R/W If set, CVMSEG is available for loads/stores in
         * kernel/debug mode. */
 #if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
@@ -365,14 +385,13 @@ void octeon_user_io_init(void)
         * is max legal value. */
        cvmmemctl.s.lmemsz = CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE;
 
+       write_c0_cvmmemctl(cvmmemctl.u64);
 
        if (smp_processor_id() == 0)
                pr_notice("CVMSEG size: %d cache lines (%d bytes)\n",
                          CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
                          CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
 
-       write_c0_cvmmemctl(cvmmemctl.u64);
-
        /* Move the performance counter interrupts to IRQ 6 */
        cvmctl = read_c0_cvmctl();
        cvmctl &= ~(7 << 7);
@@ -416,6 +435,41 @@ void __init prom_init(void)
                cvmx_phys_to_ptr(octeon_boot_desc_ptr->cvmx_desc_vaddr);
        cvmx_bootmem_init(cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr));
 
+       sysinfo = cvmx_sysinfo_get();
+       memset(sysinfo, 0, sizeof(*sysinfo));
+       sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
+       sysinfo->phy_mem_desc_ptr =
+               cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
+       sysinfo->core_mask = octeon_bootinfo->core_mask;
+       sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
+       sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
+       sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
+       sysinfo->board_type = octeon_bootinfo->board_type;
+       sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
+       sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
+       memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
+              sizeof(sysinfo->mac_addr_base));
+       sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
+       memcpy(sysinfo->board_serial_number,
+              octeon_bootinfo->board_serial_number,
+              sizeof(sysinfo->board_serial_number));
+       sysinfo->compact_flash_common_base_addr =
+               octeon_bootinfo->compact_flash_common_base_addr;
+       sysinfo->compact_flash_attribute_base_addr =
+               octeon_bootinfo->compact_flash_attribute_base_addr;
+       sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
+       sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
+       sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
+
+       if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+               /* I/O clock runs at a different rate than the CPU. */
+               union cvmx_mio_rst_boot rst_boot;
+               rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+               octeon_io_clock_rate = 50000000 * rst_boot.s.pnr_mul;
+       } else {
+               octeon_io_clock_rate = sysinfo->cpu_clock_hz;
+       }
+
        /*
         * Only enable the LED controller if we're running on a CN38XX, CN58XX,
         * or CN56XX. The CN30XX and CN31XX don't have an LED controller.
@@ -479,33 +533,6 @@ void __init prom_init(void)
        }
 #endif
 
-       sysinfo = cvmx_sysinfo_get();
-       memset(sysinfo, 0, sizeof(*sysinfo));
-       sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
-       sysinfo->phy_mem_desc_ptr =
-               cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
-       sysinfo->core_mask = octeon_bootinfo->core_mask;
-       sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
-       sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
-       sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
-       sysinfo->board_type = octeon_bootinfo->board_type;
-       sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
-       sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
-       memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
-              sizeof(sysinfo->mac_addr_base));
-       sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
-       memcpy(sysinfo->board_serial_number,
-              octeon_bootinfo->board_serial_number,
-              sizeof(sysinfo->board_serial_number));
-       sysinfo->compact_flash_common_base_addr =
-               octeon_bootinfo->compact_flash_common_base_addr;
-       sysinfo->compact_flash_attribute_base_addr =
-               octeon_bootinfo->compact_flash_attribute_base_addr;
-       sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
-       sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
-       sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
-
-
        octeon_check_cpu_bist();
 
        octeon_uart = octeon_get_boot_uart();
@@ -740,6 +767,31 @@ EXPORT_SYMBOL(prom_putchar);
 
 void prom_free_prom_memory(void)
 {
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) {
+               /* Check for presence of Core-14449 fix.  */
+               u32 insn;
+               u32 *foo;
+
+               foo = &insn;
+
+               asm volatile("# before" : : : "memory");
+               prefetch(foo);
+               asm volatile(
+                       ".set push\n\t"
+                       ".set noreorder\n\t"
+                       "bal 1f\n\t"
+                       "nop\n"
+                       "1:\tlw %0,-12($31)\n\t"
+                       ".set pop\n\t"
+                       : "=r" (insn) : : "$31", "memory");
+
+               if ((insn >> 26) != 0x33)
+                       panic("No PREF instruction at Core-14449 probe point.\n");
+
+               if (((insn >> 16) & 0x1f) != 28)
+                       panic("Core-14449 WAR not in place (%04x).\n"
+                             "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).\n", insn);
+       }
 #ifdef CONFIG_CAVIUM_DECODE_RSL
        cvmx_interrupt_rsl_enable();
 
index 47d87da379f947c8a578f2a2b84e7da804f559a8..4a02fe891ab6d5909b11997d738010844f710637 100644 (file)
@@ -64,18 +64,16 @@ static __inline__ void atomic_add(int i, atomic_t * v)
        } else if (kernel_uses_llsc) {
                int temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     ll      %0, %1          # atomic_add            \n"
-               "       addu    %0, %2                                  \n"
-               "       sc      %0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       ll      %0, %1          # atomic_add    \n"
+                       "       addu    %0, %2                          \n"
+                       "       sc      %0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter));
+               } while (unlikely(!temp));
        } else {
                unsigned long flags;
 
@@ -109,18 +107,16 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
        } else if (kernel_uses_llsc) {
                int temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     ll      %0, %1          # atomic_sub            \n"
-               "       subu    %0, %2                                  \n"
-               "       sc      %0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       ll      %0, %1          # atomic_sub    \n"
+                       "       subu    %0, %2                          \n"
+                       "       sc      %0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter));
+               } while (unlikely(!temp));
        } else {
                unsigned long flags;
 
@@ -156,20 +152,19 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
        } else if (kernel_uses_llsc) {
                int temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     ll      %1, %2          # atomic_add_return     \n"
-               "       addu    %0, %1, %3                              \n"
-               "       sc      %0, %2                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       addu    %0, %1, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       ll      %1, %2  # atomic_add_return     \n"
+                       "       addu    %0, %1, %3                      \n"
+                       "       sc      %0, %2                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter)
+                       : "memory");
+               } while (unlikely(!result));
+
+               result = temp + i;
        } else {
                unsigned long flags;
 
@@ -205,23 +200,24 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
                : "memory");
+
+               result = temp - i;
        } else if (kernel_uses_llsc) {
                int temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     ll      %1, %2          # atomic_sub_return     \n"
-               "       subu    %0, %1, %3                              \n"
-               "       sc      %0, %2                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       subu    %0, %1, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       ll      %1, %2  # atomic_sub_return     \n"
+                       "       subu    %0, %1, %3                      \n"
+                       "       sc      %0, %2                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter)
+                       : "memory");
+               } while (unlikely(!result));
+
+               result = temp - i;
        } else {
                unsigned long flags;
 
@@ -279,12 +275,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
                "       bltz    %0, 1f                                  \n"
                "       sc      %0, %2                                  \n"
                "       .set    noreorder                               \n"
-               "       beqz    %0, 2f                                  \n"
+               "       beqz    %0, 1b                                  \n"
                "        subu   %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -443,18 +436,16 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
        } else if (kernel_uses_llsc) {
                long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     lld     %0, %1          # atomic64_add          \n"
-               "       daddu   %0, %2                                  \n"
-               "       scd     %0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       lld     %0, %1          # atomic64_add  \n"
+                       "       daddu   %0, %2                          \n"
+                       "       scd     %0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter));
+               } while (unlikely(!temp));
        } else {
                unsigned long flags;
 
@@ -488,18 +479,16 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
        } else if (kernel_uses_llsc) {
                long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     lld     %0, %1          # atomic64_sub          \n"
-               "       dsubu   %0, %2                                  \n"
-               "       scd     %0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       lld     %0, %1          # atomic64_sub  \n"
+                       "       dsubu   %0, %2                          \n"
+                       "       scd     %0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter));
+               } while (unlikely(!temp));
        } else {
                unsigned long flags;
 
@@ -535,20 +524,19 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
        } else if (kernel_uses_llsc) {
                long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     lld     %1, %2          # atomic64_add_return   \n"
-               "       daddu   %0, %1, %3                              \n"
-               "       scd     %0, %2                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       daddu   %0, %1, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       lld     %1, %2  # atomic64_add_return   \n"
+                       "       daddu   %0, %1, %3                      \n"
+                       "       scd     %0, %2                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter)
+                       : "memory");
+               } while (unlikely(!result));
+
+               result = temp + i;
        } else {
                unsigned long flags;
 
@@ -587,20 +575,19 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
        } else if (kernel_uses_llsc) {
                long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     lld     %1, %2          # atomic64_sub_return   \n"
-               "       dsubu   %0, %1, %3                              \n"
-               "       scd     %0, %2                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       dsubu   %0, %1, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       lld     %1, %2  # atomic64_sub_return   \n"
+                       "       dsubu   %0, %1, %3                      \n"
+                       "       scd     %0, %2                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+                       : "Ir" (i), "m" (v->counter)
+                       : "memory");
+               } while (unlikely(!result));
+
+               result = temp - i;
        } else {
                unsigned long flags;
 
@@ -658,12 +645,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
                "       bltz    %0, 1f                                  \n"
                "       scd     %0, %2                                  \n"
                "       .set    noreorder                               \n"
-               "       beqz    %0, 2f                                  \n"
+               "       beqz    %0, 1b                                  \n"
                "        dsubu  %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
index b0ce7ca2851f8fc32413e407942cc7367d6643d9..50b4ef288c53f0be1a78d9de79e40e2337a3f76d 100644 (file)
@@ -73,30 +73,26 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
                : "ir" (1UL << bit), "m" (*m));
 #ifdef CONFIG_CPU_MIPSR2
        } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
-               __asm__ __volatile__(
-               "1:     " __LL "%0, %1                  # set_bit       \n"
-               "       " __INS "%0, %4, %2, 1                          \n"
-               "       " __SC "%0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (bit), "m" (*m), "r" (~0));
+               do {
+                       __asm__ __volatile__(
+                       "       " __LL "%0, %1          # set_bit       \n"
+                       "       " __INS "%0, %3, %2, 1                  \n"
+                       "       " __SC "%0, %1                          \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (bit), "r" (~0));
+               } while (unlikely(!temp));
 #endif /* CONFIG_CPU_MIPSR2 */
        } else if (kernel_uses_llsc) {
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     " __LL "%0, %1                  # set_bit       \n"
-               "       or      %0, %2                                  \n"
-               "       " __SC  "%0, %1                                 \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (1UL << bit), "m" (*m));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1          # set_bit       \n"
+                       "       or      %0, %2                          \n"
+                       "       " __SC  "%0, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (1UL << bit));
+               } while (unlikely(!temp));
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -134,34 +130,30 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
                "       " __SC "%0, %1                                  \n"
                "       beqzl   %0, 1b                                  \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (~(1UL << bit)), "m" (*m));
+               : "=&r" (temp), "+m" (*m)
+               : "ir" (~(1UL << bit)));
 #ifdef CONFIG_CPU_MIPSR2
        } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
-               __asm__ __volatile__(
-               "1:     " __LL "%0, %1                  # clear_bit     \n"
-               "       " __INS "%0, $0, %2, 1                          \n"
-               "       " __SC "%0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (bit), "m" (*m));
+               do {
+                       __asm__ __volatile__(
+                       "       " __LL "%0, %1          # clear_bit     \n"
+                       "       " __INS "%0, $0, %2, 1                  \n"
+                       "       " __SC "%0, %1                          \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (bit));
+               } while (unlikely(!temp));
 #endif /* CONFIG_CPU_MIPSR2 */
        } else if (kernel_uses_llsc) {
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     " __LL "%0, %1                  # clear_bit     \n"
-               "       and     %0, %2                                  \n"
-               "       " __SC "%0, %1                                  \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (~(1UL << bit)), "m" (*m));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1          # clear_bit     \n"
+                       "       and     %0, %2                          \n"
+                       "       " __SC "%0, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (~(1UL << bit)));
+               } while (unlikely(!temp));
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -213,24 +205,22 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
                "       " __SC  "%0, %1                         \n"
                "       beqzl   %0, 1b                          \n"
                "       .set    mips0                           \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (1UL << bit), "m" (*m));
+               : "=&r" (temp), "+m" (*m)
+               : "ir" (1UL << bit));
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    mips3                           \n"
-               "1:     " __LL "%0, %1          # change_bit    \n"
-               "       xor     %0, %2                          \n"
-               "       " __SC  "%0, %1                         \n"
-               "       beqz    %0, 2f                          \n"
-               "       .subsection 2                           \n"
-               "2:     b       1b                              \n"
-               "       .previous                               \n"
-               "       .set    mips0                           \n"
-               : "=&r" (temp), "=m" (*m)
-               : "ir" (1UL << bit), "m" (*m));
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1          # change_bit    \n"
+                       "       xor     %0, %2                          \n"
+                       "       " __SC  "%0, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m)
+                       : "ir" (1UL << bit));
+               } while (unlikely(!temp));
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -272,30 +262,26 @@ static inline int test_and_set_bit(unsigned long nr,
                "       beqzl   %2, 1b                                  \n"
                "       and     %2, %0, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
+               : "=&r" (temp), "+m" (*m), "=&r" (res)
+               : "r" (1UL << bit)
                : "memory");
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noreorder                               \n"
-               "       .set    mips3                                   \n"
-               "1:     " __LL "%0, %1          # test_and_set_bit      \n"
-               "       or      %2, %0, %3                              \n"
-               "       " __SC  "%2, %1                                 \n"
-               "       beqz    %2, 2f                                  \n"
-               "        and    %2, %0, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "        nop                                            \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1  # test_and_set_bit      \n"
+                       "       or      %2, %0, %3                      \n"
+                       "       " __SC  "%2, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "r" (1UL << bit)
+                       : "memory");
+               } while (unlikely(!res));
+
+               res = temp & (1UL << bit);
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -340,30 +326,26 @@ static inline int test_and_set_bit_lock(unsigned long nr,
                "       beqzl   %2, 1b                                  \n"
                "       and     %2, %0, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
+               : "=&r" (temp), "+m" (*m), "=&r" (res)
+               : "r" (1UL << bit)
                : "memory");
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noreorder                               \n"
-               "       .set    mips3                                   \n"
-               "1:     " __LL "%0, %1          # test_and_set_bit      \n"
-               "       or      %2, %0, %3                              \n"
-               "       " __SC  "%2, %1                                 \n"
-               "       beqz    %2, 2f                                  \n"
-               "        and    %2, %0, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "        nop                                            \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL "%0, %1  # test_and_set_bit      \n"
+                       "       or      %2, %0, %3                      \n"
+                       "       " __SC  "%2, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "r" (1UL << bit)
+                       : "memory");
+               } while (unlikely(!res));
+
+               res = temp & (1UL << bit);
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -410,49 +392,43 @@ static inline int test_and_clear_bit(unsigned long nr,
                "       beqzl   %2, 1b                                  \n"
                "       and     %2, %0, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
+               : "=&r" (temp), "+m" (*m), "=&r" (res)
+               : "r" (1UL << bit)
                : "memory");
 #ifdef CONFIG_CPU_MIPSR2
        } else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "1:     " __LL  "%0, %1         # test_and_clear_bit    \n"
-               "       " __EXT "%2, %0, %3, 1                          \n"
-               "       " __INS "%0, $0, %3, 1                          \n"
-               "       " __SC  "%0, %1                                 \n"
-               "       beqz    %0, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "ir" (bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       " __LL  "%0, %1 # test_and_clear_bit    \n"
+                       "       " __EXT "%2, %0, %3, 1                  \n"
+                       "       " __INS "%0, $0, %3, 1                  \n"
+                       "       " __SC  "%0, %1                         \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "ir" (bit)
+                       : "memory");
+               } while (unlikely(!temp));
 #endif
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noreorder                               \n"
-               "       .set    mips3                                   \n"
-               "1:     " __LL  "%0, %1         # test_and_clear_bit    \n"
-               "       or      %2, %0, %3                              \n"
-               "       xor     %2, %3                                  \n"
-               "       " __SC  "%2, %1                                 \n"
-               "       beqz    %2, 2f                                  \n"
-               "        and    %2, %0, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "        nop                                            \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL  "%0, %1 # test_and_clear_bit    \n"
+                       "       or      %2, %0, %3                      \n"
+                       "       xor     %2, %3                          \n"
+                       "       " __SC  "%2, %1                         \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "r" (1UL << bit)
+                       : "memory");
+               } while (unlikely(!res));
+
+               res = temp & (1UL << bit);
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
@@ -499,30 +475,26 @@ static inline int test_and_change_bit(unsigned long nr,
                "       beqzl   %2, 1b                                  \n"
                "       and     %2, %0, %3                              \n"
                "       .set    mips0                                   \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
+               : "=&r" (temp), "+m" (*m), "=&r" (res)
+               : "r" (1UL << bit)
                : "memory");
        } else if (kernel_uses_llsc) {
                unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
                unsigned long temp;
 
-               __asm__ __volatile__(
-               "       .set    push                                    \n"
-               "       .set    noreorder                               \n"
-               "       .set    mips3                                   \n"
-               "1:     " __LL  "%0, %1         # test_and_change_bit   \n"
-               "       xor     %2, %0, %3                              \n"
-               "       " __SC  "\t%2, %1                               \n"
-               "       beqz    %2, 2f                                  \n"
-               "        and    %2, %0, %3                              \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "        nop                                            \n"
-               "       .previous                                       \n"
-               "       .set    pop                                     \n"
-               : "=&r" (temp), "=m" (*m), "=&r" (res)
-               : "r" (1UL << bit), "m" (*m)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       " __LL  "%0, %1 # test_and_change_bit   \n"
+                       "       xor     %2, %0, %3                      \n"
+                       "       " __SC  "\t%2, %1                       \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (temp), "+m" (*m), "=&r" (res)
+                       : "r" (1UL << bit)
+                       : "memory");
+               } while (unlikely(!res));
+
+               res = temp & (1UL << bit);
        } else {
                volatile unsigned long *a = addr;
                unsigned long mask;
index 15a8ef0707c695538fa5463d1ac05893e91f55b4..35cd1bab69c3c23d81015da791d2e7609526d962 100644 (file)
@@ -125,4 +125,16 @@ extern unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
  */
 extern void plat_mem_setup(void);
 
+#ifdef CONFIG_SWIOTLB
+/*
+ * Optional platform hook to call swiotlb_setup().
+ */
+extern void plat_swiotlb_setup(void);
+
+#else
+
+static inline void plat_swiotlb_setup(void) {}
+
+#endif /* CONFIG_SWIOTLB */
+
 #endif /* _ASM_BOOTINFO_H */
index 2d28017e95d0756d1c1117847a5ff4811dffcea1..d8d1c2805ac71c7c67b4e1043d15e4e072845f78 100644 (file)
                "       move    $1, %z4                         \n"     \
                "       .set    mips3                           \n"     \
                "       " st "  $1, %1                          \n"     \
-               "       beqz    $1, 3f                          \n"     \
-               "2:                                             \n"     \
-               "       .subsection 2                           \n"     \
-               "3:     b       1b                              \n"     \
-               "       .previous                               \n"     \
+               "       beqz    $1, 1b                          \n"     \
                "       .set    pop                             \n"     \
+               "2:                                             \n"     \
                : "=&r" (__ret), "=R" (*m)                              \
                : "R" (*m), "Jr" (old), "Jr" (new)                      \
                : "memory");                                            \
index b201a8f5b127898ff645cfe0da800158a3b6595d..06d59dcbe24310a92669983231a51e3aad34d324 100644 (file)
  * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
  */
 
-#define PRID_IMP_BCM4710       0x4000
-#define PRID_IMP_BCM3302       0x9000
-#define PRID_IMP_BCM6338       0x9000
-#define PRID_IMP_BCM6345       0x8000
-#define PRID_IMP_BCM6348       0x9100
-#define PRID_IMP_BCM4350       0xA000
-#define PRID_REV_BCM6358       0x0010
-#define PRID_REV_BCM6368       0x0030
+#define PRID_IMP_BMIPS4KC      0x4000
+#define PRID_IMP_BMIPS32       0x8000
+#define PRID_IMP_BMIPS3300     0x9000
+#define PRID_IMP_BMIPS3300_ALT 0x9100
+#define PRID_IMP_BMIPS3300_BUG 0x0000
+#define PRID_IMP_BMIPS43XX     0xa000
+#define PRID_IMP_BMIPS5000     0x5a00
+
+#define PRID_REV_BMIPS4380_LO  0x0040
+#define PRID_REV_BMIPS4380_HI  0x006f
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
 #define PRID_IMP_CAVIUM_CN56XX 0x0400
 #define PRID_IMP_CAVIUM_CN50XX 0x0600
 #define PRID_IMP_CAVIUM_CN52XX 0x0700
+#define PRID_IMP_CAVIUM_CN63XX 0x9000
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
@@ -223,15 +226,14 @@ enum cpu_type_enum {
         * MIPS32 class processors
         */
        CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
-       CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
-       CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358,
-       CPU_JZRISC,
+       CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
+       CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC,
 
        /*
         * MIPS64 class processors
         */
        CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
-       CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
+       CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
 
        CPU_LAST
 };
index 06746c5e80993d45b234cc047b22de19f6b7ffe4..c94fafba9e62fe238c5554e6910fb08820e83ed3 100644 (file)
@@ -3,4 +3,17 @@
  *
  * This file is released under the GPLv2
  */
-#include <asm-generic/device.h>
+#ifndef _ASM_MIPS_DEVICE_H
+#define _ASM_MIPS_DEVICE_H
+
+struct dma_map_ops;
+
+struct dev_archdata {
+       /* DMA operations on that device */
+       struct dma_map_ops *dma_ops;
+};
+
+struct pdev_archdata {
+};
+
+#endif /* _ASM_MIPS_DEVICE_H*/
index 18fbf7af8e93c2fa182b4906a66dfa25c3e17d00..655f849bd08d8767e81f6846ce205ce40e487980 100644 (file)
@@ -5,51 +5,41 @@
 #include <asm/cache.h>
 #include <asm-generic/dma-coherent.h>
 
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
-                          dma_addr_t *dma_handle, gfp_t flag);
+#include <dma-coherence.h>
 
-void dma_free_noncoherent(struct device *dev, size_t size,
-                        void *vaddr, dma_addr_t dma_handle);
+extern struct dma_map_ops *mips_dma_map_ops;
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
-                          dma_addr_t *dma_handle, gfp_t flag);
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+       if (dev && dev->archdata.dma_ops)
+               return dev->archdata.dma_ops;
+       else
+               return mips_dma_map_ops;
+}
 
-void dma_free_coherent(struct device *dev, size_t size,
-                        void *vaddr, dma_addr_t dma_handle);
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+       if (!dev->dma_mask)
+               return 0;
 
-extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-       enum dma_data_direction direction);
-extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
-       size_t size, enum dma_data_direction direction);
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-       enum dma_data_direction direction);
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
-       unsigned long offset, size_t size, enum dma_data_direction direction);
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-       size_t size, enum dma_data_direction direction)
+       return addr + size <= *dev->dma_mask;
+}
+
+static inline void dma_mark_clean(void *addr, size_t size) {}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline int dma_supported(struct device *dev, u64 mask)
 {
-       dma_unmap_single(dev, dma_address, size, direction);
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       return ops->dma_supported(dev, mask);
 }
 
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-       int nhwentries, enum dma_data_direction direction);
-extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_for_device(struct device *dev,
-       dma_addr_t dma_handle, size_t size, enum dma_data_direction direction);
-extern void dma_sync_single_range_for_cpu(struct device *dev,
-       dma_addr_t dma_handle, unsigned long offset, size_t size,
-       enum dma_data_direction direction);
-extern void dma_sync_single_range_for_device(struct device *dev,
-       dma_addr_t dma_handle, unsigned long offset, size_t size,
-       enum dma_data_direction direction);
-extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-       int nelems, enum dma_data_direction direction);
-extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
-       int nelems, enum dma_data_direction direction);
-extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
-extern int dma_supported(struct device *dev, u64 mask);
+static inline int dma_mapping_error(struct device *dev, u64 mask)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+       return ops->mapping_error(dev, mask);
+}
 
 static inline int
 dma_set_mask(struct device *dev, u64 mask)
@@ -65,4 +55,34 @@ dma_set_mask(struct device *dev, u64 mask)
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
               enum dma_data_direction direction);
 
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+                                      dma_addr_t *dma_handle, gfp_t gfp)
+{
+       void *ret;
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       ret = ops->alloc_coherent(dev, size, dma_handle, gfp);
+
+       debug_dma_alloc_coherent(dev, size, *dma_handle, ret);
+
+       return ret;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+                                    void *vaddr, dma_addr_t dma_handle)
+{
+       struct dma_map_ops *ops = get_dma_ops(dev);
+
+       ops->free_coherent(dev, size, vaddr, dma_handle);
+
+       debug_dma_free_coherent(dev, size, vaddr, dma_handle);
+}
+
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+                          dma_addr_t *dma_handle, gfp_t flag);
+
+void dma_free_noncoherent(struct device *dev, size_t size,
+                        void *vaddr, dma_addr_t dma_handle);
+
 #endif /* _ASM_DMA_MAPPING_H */
index 1353c81065d1808d252d97b339fe34a052cca480..2d47da62d5a7d25dec4c4361c15e2170770158ee 100644 (file)
 #define MAX_DMA_ADDRESS                (PAGE_OFFSET + 0x01000000)
 #endif
 #define MAX_DMA_PFN            PFN_DOWN(virt_to_phys((void *)MAX_DMA_ADDRESS))
+
+#ifndef MAX_DMA32_PFN
 #define MAX_DMA32_PFN          (1UL << (32 - PAGE_SHIFT))
+#endif
 
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE   0x00    /* 8 bit slave DMA, channels 0..3 */
index bdcdef02d147c6e014d86eb6748c7cd7c0628c9e..fffc8307a80a31e11424cc0996ec749ad5f1a0c4 100644 (file)
@@ -117,7 +117,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
 
 #define local_cmpxchg(l, o, n) \
        ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
-#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
+#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
 
 /**
  * local_add_unless - add unless the number is a given value
index 483ffea9ecb1de05bd6bcfacae3ce850d29c9b71..7919d76186bf1b78dca75c62e1fc41f731fc6ebb 100644 (file)
@@ -39,6 +39,7 @@
 #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_PINSEL (AR7_REGS_BASE + 0x160C)
 #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 UR8_REGS_WDT   (AR7_REGS_BASE + 0x0b00)
 #define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00)
 
+/* Titan registers */
+#define TITAN_REGS_ESWITCH_BASE        (0x08640000)
+#define TITAN_REGS_MAC0                (TITAN_REGS_ESWITCH_BASE)
+#define TITAN_REGS_MAC1                (TITAN_REGS_ESWITCH_BASE + 0x0800)
+#define TITAN_REGS_MDIO                (TITAN_REGS_ESWITCH_BASE + 0x02000)
+#define TITAN_REGS_VLYNQ0      (AR7_REGS_BASE + 0x1c00)
+#define TITAN_REGS_VLYNQ1      (AR7_REGS_BASE + 0x1300)
+
 #define AR7_RESET_PERIPHERAL   0x0
 #define AR7_RESET_SOFTWARE     0x4
 #define AR7_RESET_STATUS       0x8
 #define AR7_RESET_BIT_MDIO     22
 #define AR7_RESET_BIT_EPHY     26
 
+#define TITAN_RESET_BIT_EPHY1  28
+
 /* GPIO control registers */
 #define AR7_GPIO_INPUT 0x0
 #define AR7_GPIO_OUTPUT        0x4
 #define AR7_GPIO_DIR   0x8
 #define AR7_GPIO_ENABLE        0xc
+#define TITAN_GPIO_INPUT_0     0x0
+#define TITAN_GPIO_INPUT_1     0x4
+#define TITAN_GPIO_OUTPUT_0    0x8
+#define TITAN_GPIO_OUTPUT_1    0xc
+#define TITAN_GPIO_DIR_0       0x10
+#define TITAN_GPIO_DIR_1       0x14
+#define TITAN_GPIO_ENBL_0      0x18
+#define TITAN_GPIO_ENBL_1      0x1c
 
 #define AR7_CHIP_7100  0x18
 #define AR7_CHIP_7200  0x2b
 #define AR7_CHIP_7300  0x05
+#define AR7_CHIP_TITAN 0x07
+#define TITAN_CHIP_1050        0x0f
+#define TITAN_CHIP_1055        0x0e
+#define TITAN_CHIP_1056        0x0d
+#define TITAN_CHIP_1060        0x07
 
 /* Interrupts */
 #define AR7_IRQ_UART0  15
@@ -95,14 +119,29 @@ struct plat_dsl_data {
 
 extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock;
 
+static inline int ar7_is_titan(void)
+{
+       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x24)) & 0xffff) ==
+               AR7_CHIP_TITAN;
+}
+
 static inline u16 ar7_chip_id(void)
 {
-       return readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff;
+       return ar7_is_titan() ? AR7_CHIP_TITAN : (readl((void *)
+               KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff);
+}
+
+static inline u16 titan_chip_id(void)
+{
+       unsigned int val = readl((void *)KSEG1ADDR(AR7_REGS_GPIO +
+                                               TITAN_GPIO_INPUT_1));
+       return ((val >> 12) & 0x0f);
 }
 
 static inline u8 ar7_chip_rev(void)
 {
-       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) & 0xff;
+       return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + (ar7_is_titan() ? 0x24 :
+               0x14))) >> 16) & 0xff;
 }
 
 struct clk {
@@ -161,4 +200,8 @@ static inline void ar7_device_off(u32 bit)
        msleep(20);
 }
 
+int __init ar7_gpio_init(void);
+
+int __init ar7_gpio_init(void);
+
 #endif /* __AR7_H__ */
index abc317c0372eb183b4e2782705a4ea4eba11a6b2..c177cd1eed2588671d34d5a8d6fd74fb7123cfe4 100644 (file)
@@ -22,7 +22,8 @@
 #include <asm/mach-ar7/ar7.h>
 
 #define AR7_GPIO_MAX 32
-#define NR_BUILTIN_GPIO AR7_GPIO_MAX
+#define TITAN_GPIO_MAX 51
+#define NR_BUILTIN_GPIO TITAN_GPIO_MAX
 
 #define gpio_to_irq(gpio)      -1
 
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
new file mode 100644 (file)
index 0000000..5325084
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef __BCM963XX_TAG_H
+#define __BCM963XX_TAG_H
+
+#define TAGVER_LEN             4       /* Length of Tag Version */
+#define TAGLAYOUT_LEN          4       /* Length of FlashLayoutVer */
+#define SIG1_LEN               20      /* Company Signature 1 Length */
+#define SIG2_LEN               14      /* Company Signature 2 Lenght */
+#define BOARDID_LEN            16      /* Length of BoardId */
+#define ENDIANFLAG_LEN         2       /* Endian Flag Length */
+#define CHIPID_LEN             6       /* Chip Id Length */
+#define IMAGE_LEN              10      /* Length of Length Field */
+#define ADDRESS_LEN            12      /* Length of Address field */
+#define DUALFLAG_LEN           2       /* Dual Image flag Length */
+#define INACTIVEFLAG_LEN       2       /* Inactie Flag Length */
+#define RSASIG_LEN             20      /* Length of RSA Signature in tag */
+#define TAGINFO1_LEN           30      /* Length of vendor information field1 in tag */
+#define FLASHLAYOUTVER_LEN     4       /* Length of Flash Layout Version String tag */
+#define TAGINFO2_LEN           16      /* Length of vendor information field2 in tag */
+#define CRC_LEN                        4       /* Length of CRC in bytes */
+#define ALTTAGINFO_LEN         54      /* Alternate length for vendor information; Pirelli */
+
+#define NUM_PIRELLI            2
+#define IMAGETAG_CRC_START     0xFFFFFFFF
+
+#define PIRELLI_BOARDS { \
+       "AGPF-S0", \
+       "DWV-S0", \
+}
+
+/*
+ * The broadcom firmware assumes the rootfs starts the image,
+ * therefore uses the rootfs start (flash_image_address)
+ * to determine where to flash the image.  Since we have the kernel first
+ * we have to give it the kernel address, but the crc uses the length
+ * associated with this address (root_length), which is added to the kernel
+ * length (kernel_length) to determine the length of image to flash and thus
+ * needs to be rootfs + deadcode (jffs2 EOF marker)
+*/
+
+struct bcm_tag {
+       /* 0-3: Version of the image tag */
+       char tag_version[TAGVER_LEN];
+       /* 4-23: Company Line 1 */
+       char sig_1[SIG1_LEN];
+       /*  24-37: Company Line 2 */
+       char sig_2[SIG2_LEN];
+       /* 38-43: Chip this image is for */
+       char chip_id[CHIPID_LEN];
+       /* 44-59: Board name */
+       char board_id[BOARDID_LEN];
+       /* 60-61: Map endianness -- 1 BE 0 LE */
+       char big_endian[ENDIANFLAG_LEN];
+       /* 62-71: Total length of image */
+       char total_length[IMAGE_LEN];
+       /* 72-83: Address in memory of CFE */
+       char cfe__address[ADDRESS_LEN];
+       /* 84-93: Size of CFE */
+       char cfe_length[IMAGE_LEN];
+       /* 94-105: Address in memory of image start
+        * (kernel for OpenWRT, rootfs for stock firmware)
+        */
+       char flash_image_start[ADDRESS_LEN];
+       /* 106-115: Size of rootfs */
+       char root_length[IMAGE_LEN];
+       /* 116-127: Address in memory of kernel */
+       char kernel_address[ADDRESS_LEN];
+       /* 128-137: Size of kernel */
+       char kernel_length[IMAGE_LEN];
+       /* 138-139: Unused at the moment */
+       char dual_image[DUALFLAG_LEN];
+       /* 140-141: Unused at the moment */
+       char inactive_flag[INACTIVEFLAG_LEN];
+       /* 142-161: RSA Signature (not used; some vendors may use this) */
+       char rsa_signature[RSASIG_LEN];
+       /* 162-191: Compilation and related information (not used in OpenWrt) */
+       char information1[TAGINFO1_LEN];
+       /* 192-195: Version flash layout */
+       char flash_layout_ver[FLASHLAYOUTVER_LEN];
+       /* 196-199: kernel+rootfs CRC32 */
+       char fskernel_crc[CRC_LEN];
+       /* 200-215: Unused except on Alice Gate where is is information */
+       char information2[TAGINFO2_LEN];
+       /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
+       char image_crc[CRC_LEN];
+       /* 220-223: CRC32 of rootfs partition */
+       char rootfs_crc[CRC_LEN];
+       /* 224-227: CRC32 of kernel partition */
+       char kernel_crc[CRC_LEN];
+       /* 228-235: Unused at present */
+       char reserved1[8];
+       /* 236-239: CRC32 of header excluding tagVersion */
+       char header_crc[CRC_LEN];
+       /* 240-255: Unused at present */
+       char reserved2[16];
+};
+
+#endif /* __BCM63XX_TAG_H */
index b952fc7215e204463174d30608eff1e9a5bcba00..0d5a42b5f47abb4091d3257270b72f80ed1fe3ce 100644 (file)
@@ -59,7 +59,7 @@
 #define cpu_has_veic           0
 #define cpu_hwrena_impl_bits   0xc0000000
 
-#define kernel_uses_smartmips_rixi (cpu_data[0].cputype == CPU_CAVIUM_OCTEON_PLUS)
+#define kernel_uses_smartmips_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
 
 #define ARCH_HAS_IRQ_PER_CPU   1
 #define ARCH_HAS_SPINLOCK_PREFETCH 1
@@ -81,4 +81,10 @@ static inline int octeon_has_saa(void)
        return id >= 0x000d0300;
 }
 
+/*
+ * The last 256MB are reserved for device to device mappings and the
+ * BAR1 hole.
+ */
+#define MAX_DMA32_PFN (((1ULL << 32) - (1ULL << 28)) >> PAGE_SHIFT)
+
 #endif
index 17d579471ec408fc2ab302e89a15953eac22f21f..be8fb4240cece35c234b14f43cd65a26b16a0988 100644 (file)
 
 struct device;
 
-dma_addr_t octeon_map_dma_mem(struct device *, void *, size_t);
-void octeon_unmap_dma_mem(struct device *, dma_addr_t);
+extern void octeon_pci_dma_init(void);
 
 static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
        size_t size)
 {
-       return octeon_map_dma_mem(dev, addr, size);
+       BUG();
 }
 
 static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
        struct page *page)
 {
-       return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE);
+       BUG();
 }
 
 static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
        dma_addr_t dma_addr)
 {
-       return dma_addr;
+       BUG();
 }
 
 static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
        size_t size, enum dma_data_direction direction)
 {
-       octeon_unmap_dma_mem(dev, dma_addr);
+       BUG();
 }
 
 static inline int plat_dma_supported(struct device *dev, u64 mask)
 {
-       return 1;
+       BUG();
 }
 
 static inline void plat_extra_sync_for_device(struct device *dev)
 {
-       mb();
+       BUG();
 }
 
 static inline int plat_device_is_coherent(struct device *dev)
@@ -60,7 +59,14 @@ static inline int plat_device_is_coherent(struct device *dev)
 static inline int plat_dma_mapping_error(struct device *dev,
                                         dma_addr_t dma_addr)
 {
-       return dma_addr == -1;
+       BUG();
 }
 
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
+
+struct dma_map_ops;
+extern struct dma_map_ops *octeon_pci_dma_map_ops;
+extern char *octeon_swiotlb;
+
 #endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */
index d3d04018a8586945eead0fcc2da6a2e9e50ed1a6..016d0989b141355e9205c55a18be9b573e5875df 100644 (file)
@@ -26,14 +26,15 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
        return pa;
 }
 
-static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+       struct page *page)
 {
        dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page));
 
        return pa;
 }
 
-static unsigned long plat_dma_addr_to_phys(struct device *dev,
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
        dma_addr_t dma_addr)
 {
        return dma_addr & ~(0xffUL << 56);
index 37855955b313310a3cdc4ef531b989d54388ff6b..c8fb5aacf50a412eb89e0397f5a55b73655ce8d3 100644 (file)
@@ -37,7 +37,8 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
        return pa;
 }
 
-static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+       struct page *page)
 {
        dma_addr_t pa;
 
@@ -50,7 +51,7 @@ static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
 }
 
 /* This is almost certainly wrong but it's what dma-ip32.c used to use  */
-static unsigned long plat_dma_addr_to_phys(struct device *dev,
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
        dma_addr_t dma_addr)
 {
        unsigned long addr = dma_addr & RAM_OFFSET_MASK;
index f93aee59454a041416ef5054a3efe9e647211037..302101b54acb1e72d47ec080b71f126d44b7c9c0 100644 (file)
 
 struct device;
 
-static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
 {
        return vdma_alloc(virt_to_phys(addr), size);
 }
 
-static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+       struct page *page)
 {
        return vdma_alloc(page_to_phys(page), PAGE_SIZE);
 }
 
-static unsigned long plat_dma_addr_to_phys(struct device *dev,
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
        dma_addr_t dma_addr)
 {
        return vdma_log2phys(dma_addr);
 }
 
-static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
        size_t size, enum dma_data_direction direction)
 {
        vdma_free(dma_addr);
index 335474c155f6e6187aa19ce49527712ca954c8fb..4d9870975382be738893a92bcb2a68ca96fe3181 100644 (file)
@@ -1040,6 +1040,12 @@ do {                                                                     \
 #define read_c0_dtaglo()       __read_32bit_c0_register($28, 2)
 #define write_c0_dtaglo(val)   __write_32bit_c0_register($28, 2, val)
 
+#define read_c0_ddatalo()      __read_32bit_c0_register($28, 3)
+#define write_c0_ddatalo(val)  __write_32bit_c0_register($28, 3, val)
+
+#define read_c0_staglo()       __read_32bit_c0_register($28, 4)
+#define write_c0_staglo(val)   __write_32bit_c0_register($28, 4, val)
+
 #define read_c0_taghi()                __read_32bit_c0_register($29, 0)
 #define write_c0_taghi(val)    __write_32bit_c0_register($29, 0, val)
 
@@ -1082,6 +1088,51 @@ do {                                                                     \
 #define read_octeon_c0_dcacheerr()     __read_64bit_c0_register($27, 1)
 #define write_octeon_c0_dcacheerr(val) __write_64bit_c0_register($27, 1, val)
 
+/* BMIPS3300 */
+#define read_c0_brcm_config_0()                __read_32bit_c0_register($22, 0)
+#define write_c0_brcm_config_0(val)    __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_brcm_bus_pll()         __read_32bit_c0_register($22, 4)
+#define write_c0_brcm_bus_pll(val)     __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_brcm_reset()           __read_32bit_c0_register($22, 5)
+#define write_c0_brcm_reset(val)       __write_32bit_c0_register($22, 5, val)
+
+/* BMIPS4380 */
+#define read_c0_brcm_cmt_intr()                __read_32bit_c0_register($22, 1)
+#define write_c0_brcm_cmt_intr(val)    __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_brcm_cmt_ctrl()                __read_32bit_c0_register($22, 2)
+#define write_c0_brcm_cmt_ctrl(val)    __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_brcm_cmt_local()       __read_32bit_c0_register($22, 3)
+#define write_c0_brcm_cmt_local(val)   __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_brcm_config_1()                __read_32bit_c0_register($22, 5)
+#define write_c0_brcm_config_1(val)    __write_32bit_c0_register($22, 5, val)
+
+#define read_c0_brcm_cbr()             __read_32bit_c0_register($22, 6)
+#define write_c0_brcm_cbr(val)         __write_32bit_c0_register($22, 6, val)
+
+/* BMIPS5000 */
+#define read_c0_brcm_config()          __read_32bit_c0_register($22, 0)
+#define write_c0_brcm_config(val)      __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_brcm_mode()            __read_32bit_c0_register($22, 1)
+#define write_c0_brcm_mode(val)                __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_brcm_action()          __read_32bit_c0_register($22, 2)
+#define write_c0_brcm_action(val)      __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_brcm_edsp()            __read_32bit_c0_register($22, 3)
+#define write_c0_brcm_edsp(val)                __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_brcm_bootvec()         __read_32bit_c0_register($22, 4)
+#define write_c0_brcm_bootvec(val)     __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_brcm_sleepcount()      __read_32bit_c0_register($22, 7)
+#define write_c0_brcm_sleepcount(val)  __write_32bit_c0_register($22, 7, val)
+
 /*
  * Macros to access the floating point coprocessor control registers
  */
index ec94b9ab7be1f485b54bf03d1722fff5fb43d1f1..30d68f2365e0621624aefa12fdb910f88413ff6d 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_AGL_DEFS_H__
 #define __CVMX_AGL_DEFS_H__
 
-#define CVMX_AGL_GMX_BAD_REG \
-        CVMX_ADD_IO_SEG(0x00011800E0000518ull)
-#define CVMX_AGL_GMX_BIST \
-        CVMX_ADD_IO_SEG(0x00011800E0000400ull)
-#define CVMX_AGL_GMX_DRV_CTL \
-        CVMX_ADD_IO_SEG(0x00011800E00007F0ull)
-#define CVMX_AGL_GMX_INF_MODE \
-        CVMX_ADD_IO_SEG(0x00011800E00007F8ull)
-#define CVMX_AGL_GMX_PRTX_CFG(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000010ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000180ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000188ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000190ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000198ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00001A0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00001A8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000108ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000100ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_DECISION(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000040ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000020ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000018ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000030ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000028ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_IFG(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000058ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_INT_EN(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000008ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_INT_REG(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000000ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_JABBER(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000038ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000068ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000050ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000088ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000098ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000A8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000B8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000080ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000C0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000090ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000A0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00000B0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000048ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_RX_BP_DROPX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000420ull + (((offset) & 1) * 8))
-#define CVMX_AGL_GMX_RX_BP_OFFX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000460ull + (((offset) & 1) * 8))
-#define CVMX_AGL_GMX_RX_BP_ONX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000440ull + (((offset) & 1) * 8))
-#define CVMX_AGL_GMX_RX_PRT_INFO \
-        CVMX_ADD_IO_SEG(0x00011800E00004E8ull)
-#define CVMX_AGL_GMX_RX_TX_STATUS \
-        CVMX_ADD_IO_SEG(0x00011800E00007E8ull)
-#define CVMX_AGL_GMX_SMACX(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000230ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_STAT_BP \
-        CVMX_ADD_IO_SEG(0x00011800E0000520ull)
-#define CVMX_AGL_GMX_TXX_APPEND(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000218ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000270ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000240ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000248ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000238ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000258ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000260ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000250ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT0(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000280ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT1(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000288ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT2(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000290ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT3(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000298ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT4(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002A0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT5(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002A8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT6(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002B0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT7(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002B8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT8(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002C0ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STAT9(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E00002C8ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000268ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TXX_THRESH(offset) \
-        CVMX_ADD_IO_SEG(0x00011800E0000210ull + (((offset) & 1) * 2048))
-#define CVMX_AGL_GMX_TX_BP \
-        CVMX_ADD_IO_SEG(0x00011800E00004D0ull)
-#define CVMX_AGL_GMX_TX_COL_ATTEMPT \
-        CVMX_ADD_IO_SEG(0x00011800E0000498ull)
-#define CVMX_AGL_GMX_TX_IFG \
-        CVMX_ADD_IO_SEG(0x00011800E0000488ull)
-#define CVMX_AGL_GMX_TX_INT_EN \
-        CVMX_ADD_IO_SEG(0x00011800E0000508ull)
-#define CVMX_AGL_GMX_TX_INT_REG \
-        CVMX_ADD_IO_SEG(0x00011800E0000500ull)
-#define CVMX_AGL_GMX_TX_JAM \
-        CVMX_ADD_IO_SEG(0x00011800E0000490ull)
-#define CVMX_AGL_GMX_TX_LFSR \
-        CVMX_ADD_IO_SEG(0x00011800E00004F8ull)
-#define CVMX_AGL_GMX_TX_OVR_BP \
-        CVMX_ADD_IO_SEG(0x00011800E00004C8ull)
-#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC \
-        CVMX_ADD_IO_SEG(0x00011800E00004A0ull)
-#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE \
-        CVMX_ADD_IO_SEG(0x00011800E00004A8ull)
+#define CVMX_AGL_GMX_BAD_REG (CVMX_ADD_IO_SEG(0x00011800E0000518ull))
+#define CVMX_AGL_GMX_BIST (CVMX_ADD_IO_SEG(0x00011800E0000400ull))
+#define CVMX_AGL_GMX_DRV_CTL (CVMX_ADD_IO_SEG(0x00011800E00007F0ull))
+#define CVMX_AGL_GMX_INF_MODE (CVMX_ADD_IO_SEG(0x00011800E00007F8ull))
+#define CVMX_AGL_GMX_PRTX_CFG(offset) (CVMX_ADD_IO_SEG(0x00011800E0000010ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) (CVMX_ADD_IO_SEG(0x00011800E0000180ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) (CVMX_ADD_IO_SEG(0x00011800E0000188ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) (CVMX_ADD_IO_SEG(0x00011800E0000190ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) (CVMX_ADD_IO_SEG(0x00011800E0000198ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) (CVMX_ADD_IO_SEG(0x00011800E00001A0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) (CVMX_ADD_IO_SEG(0x00011800E00001A8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) (CVMX_ADD_IO_SEG(0x00011800E0000108ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000100ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_DECISION(offset) (CVMX_ADD_IO_SEG(0x00011800E0000040ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) (CVMX_ADD_IO_SEG(0x00011800E0000020ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000018ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000030ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) (CVMX_ADD_IO_SEG(0x00011800E0000028ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_IFG(offset) (CVMX_ADD_IO_SEG(0x00011800E0000058ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_INT_EN(offset) (CVMX_ADD_IO_SEG(0x00011800E0000008ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_INT_REG(offset) (CVMX_ADD_IO_SEG(0x00011800E0000000ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_JABBER(offset) (CVMX_ADD_IO_SEG(0x00011800E0000038ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) (CVMX_ADD_IO_SEG(0x00011800E0000068ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_RX_INBND(offset) (CVMX_ADD_IO_SEG(0x00011800E0000060ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000050ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) (CVMX_ADD_IO_SEG(0x00011800E0000088ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000098ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) (CVMX_ADD_IO_SEG(0x00011800E00000A8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) (CVMX_ADD_IO_SEG(0x00011800E00000B8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) (CVMX_ADD_IO_SEG(0x00011800E0000080ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) (CVMX_ADD_IO_SEG(0x00011800E00000C0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000090ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) (CVMX_ADD_IO_SEG(0x00011800E00000A0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) (CVMX_ADD_IO_SEG(0x00011800E00000B0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) (CVMX_ADD_IO_SEG(0x00011800E0000048ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RX_BP_DROPX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000420ull) + ((offset) & 1) * 8)
+#define CVMX_AGL_GMX_RX_BP_OFFX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000460ull) + ((offset) & 1) * 8)
+#define CVMX_AGL_GMX_RX_BP_ONX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000440ull) + ((offset) & 1) * 8)
+#define CVMX_AGL_GMX_RX_PRT_INFO (CVMX_ADD_IO_SEG(0x00011800E00004E8ull))
+#define CVMX_AGL_GMX_RX_TX_STATUS (CVMX_ADD_IO_SEG(0x00011800E00007E8ull))
+#define CVMX_AGL_GMX_SMACX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000230ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_STAT_BP (CVMX_ADD_IO_SEG(0x00011800E0000520ull))
+#define CVMX_AGL_GMX_TXX_APPEND(offset) (CVMX_ADD_IO_SEG(0x00011800E0000218ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_CLK(offset) (CVMX_ADD_IO_SEG(0x00011800E0000208ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000270ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) (CVMX_ADD_IO_SEG(0x00011800E0000240ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000248ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) (CVMX_ADD_IO_SEG(0x00011800E0000238ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) (CVMX_ADD_IO_SEG(0x00011800E0000258ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) (CVMX_ADD_IO_SEG(0x00011800E0000260ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) (CVMX_ADD_IO_SEG(0x00011800E0000250ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT0(offset) (CVMX_ADD_IO_SEG(0x00011800E0000280ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT1(offset) (CVMX_ADD_IO_SEG(0x00011800E0000288ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT2(offset) (CVMX_ADD_IO_SEG(0x00011800E0000290ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT3(offset) (CVMX_ADD_IO_SEG(0x00011800E0000298ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT4(offset) (CVMX_ADD_IO_SEG(0x00011800E00002A0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT5(offset) (CVMX_ADD_IO_SEG(0x00011800E00002A8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT6(offset) (CVMX_ADD_IO_SEG(0x00011800E00002B0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT7(offset) (CVMX_ADD_IO_SEG(0x00011800E00002B8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT8(offset) (CVMX_ADD_IO_SEG(0x00011800E00002C0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT9(offset) (CVMX_ADD_IO_SEG(0x00011800E00002C8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000268ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_THRESH(offset) (CVMX_ADD_IO_SEG(0x00011800E0000210ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TX_BP (CVMX_ADD_IO_SEG(0x00011800E00004D0ull))
+#define CVMX_AGL_GMX_TX_COL_ATTEMPT (CVMX_ADD_IO_SEG(0x00011800E0000498ull))
+#define CVMX_AGL_GMX_TX_IFG (CVMX_ADD_IO_SEG(0x00011800E0000488ull))
+#define CVMX_AGL_GMX_TX_INT_EN (CVMX_ADD_IO_SEG(0x00011800E0000508ull))
+#define CVMX_AGL_GMX_TX_INT_REG (CVMX_ADD_IO_SEG(0x00011800E0000500ull))
+#define CVMX_AGL_GMX_TX_JAM (CVMX_ADD_IO_SEG(0x00011800E0000490ull))
+#define CVMX_AGL_GMX_TX_LFSR (CVMX_ADD_IO_SEG(0x00011800E00004F8ull))
+#define CVMX_AGL_GMX_TX_OVR_BP (CVMX_ADD_IO_SEG(0x00011800E00004C8ull))
+#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC (CVMX_ADD_IO_SEG(0x00011800E00004A0ull))
+#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE (CVMX_ADD_IO_SEG(0x00011800E00004A8ull))
+#define CVMX_AGL_PRTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0002000ull) + ((offset) & 1) * 8)
 
 union cvmx_agl_gmx_bad_reg {
        uint64_t u64;
        struct cvmx_agl_gmx_bad_reg_s {
+               uint64_t reserved_38_63:26;
+               uint64_t txpsh1:1;
+               uint64_t txpop1:1;
+               uint64_t ovrflw1:1;
+               uint64_t txpsh:1;
+               uint64_t txpop:1;
+               uint64_t ovrflw:1;
+               uint64_t reserved_27_31:5;
+               uint64_t statovr:1;
+               uint64_t reserved_24_25:2;
+               uint64_t loststat:2;
+               uint64_t reserved_4_21:18;
+               uint64_t out_ovr:2;
+               uint64_t reserved_0_1:2;
+       } s;
+       struct cvmx_agl_gmx_bad_reg_cn52xx {
                uint64_t reserved_38_63:26;
                uint64_t txpsh1:1;
                uint64_t txpop1:1;
@@ -188,9 +136,8 @@ union cvmx_agl_gmx_bad_reg {
                uint64_t reserved_4_21:18;
                uint64_t out_ovr:2;
                uint64_t reserved_0_1:2;
-       } s;
-       struct cvmx_agl_gmx_bad_reg_s cn52xx;
-       struct cvmx_agl_gmx_bad_reg_s cn52xxp1;
+       } cn52xx;
+       struct cvmx_agl_gmx_bad_reg_cn52xx cn52xxp1;
        struct cvmx_agl_gmx_bad_reg_cn56xx {
                uint64_t reserved_35_63:29;
                uint64_t txpsh:1;
@@ -205,18 +152,25 @@ union cvmx_agl_gmx_bad_reg {
                uint64_t reserved_0_1:2;
        } cn56xx;
        struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1;
+       struct cvmx_agl_gmx_bad_reg_s cn63xx;
+       struct cvmx_agl_gmx_bad_reg_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_bist {
        uint64_t u64;
        struct cvmx_agl_gmx_bist_s {
+               uint64_t reserved_25_63:39;
+               uint64_t status:25;
+       } s;
+       struct cvmx_agl_gmx_bist_cn52xx {
                uint64_t reserved_10_63:54;
                uint64_t status:10;
-       } s;
-       struct cvmx_agl_gmx_bist_s cn52xx;
-       struct cvmx_agl_gmx_bist_s cn52xxp1;
-       struct cvmx_agl_gmx_bist_s cn56xx;
-       struct cvmx_agl_gmx_bist_s cn56xxp1;
+       } cn52xx;
+       struct cvmx_agl_gmx_bist_cn52xx cn52xxp1;
+       struct cvmx_agl_gmx_bist_cn52xx cn56xx;
+       struct cvmx_agl_gmx_bist_cn52xx cn56xxp1;
+       struct cvmx_agl_gmx_bist_s cn63xx;
+       struct cvmx_agl_gmx_bist_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_drv_ctl {
@@ -264,7 +218,13 @@ union cvmx_agl_gmx_inf_mode {
 union cvmx_agl_gmx_prtx_cfg {
        uint64_t u64;
        struct cvmx_agl_gmx_prtx_cfg_s {
-               uint64_t reserved_6_63:58;
+               uint64_t reserved_14_63:50;
+               uint64_t tx_idle:1;
+               uint64_t rx_idle:1;
+               uint64_t reserved_9_11:3;
+               uint64_t speed_msb:1;
+               uint64_t reserved_7_7:1;
+               uint64_t burst:1;
                uint64_t tx_en:1;
                uint64_t rx_en:1;
                uint64_t slottime:1;
@@ -272,10 +232,20 @@ union cvmx_agl_gmx_prtx_cfg {
                uint64_t speed:1;
                uint64_t en:1;
        } s;
-       struct cvmx_agl_gmx_prtx_cfg_s cn52xx;
-       struct cvmx_agl_gmx_prtx_cfg_s cn52xxp1;
-       struct cvmx_agl_gmx_prtx_cfg_s cn56xx;
-       struct cvmx_agl_gmx_prtx_cfg_s cn56xxp1;
+       struct cvmx_agl_gmx_prtx_cfg_cn52xx {
+               uint64_t reserved_6_63:58;
+               uint64_t tx_en:1;
+               uint64_t rx_en:1;
+               uint64_t slottime:1;
+               uint64_t duplex:1;
+               uint64_t speed:1;
+               uint64_t en:1;
+       } cn52xx;
+       struct cvmx_agl_gmx_prtx_cfg_cn52xx cn52xxp1;
+       struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xx;
+       struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xxp1;
+       struct cvmx_agl_gmx_prtx_cfg_s cn63xx;
+       struct cvmx_agl_gmx_prtx_cfg_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam0 {
@@ -287,6 +257,8 @@ union cvmx_agl_gmx_rxx_adr_cam0 {
        struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx;
        struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xx;
+       struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam1 {
@@ -298,6 +270,8 @@ union cvmx_agl_gmx_rxx_adr_cam1 {
        struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx;
        struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xx;
+       struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam2 {
@@ -309,6 +283,8 @@ union cvmx_agl_gmx_rxx_adr_cam2 {
        struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx;
        struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xx;
+       struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam3 {
@@ -320,6 +296,8 @@ union cvmx_agl_gmx_rxx_adr_cam3 {
        struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx;
        struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xx;
+       struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam4 {
@@ -331,6 +309,8 @@ union cvmx_agl_gmx_rxx_adr_cam4 {
        struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx;
        struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xx;
+       struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam5 {
@@ -342,6 +322,8 @@ union cvmx_agl_gmx_rxx_adr_cam5 {
        struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx;
        struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xx;
+       struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam_en {
@@ -354,6 +336,8 @@ union cvmx_agl_gmx_rxx_adr_cam_en {
        struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx;
        struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xx;
+       struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_ctl {
@@ -368,6 +352,8 @@ union cvmx_agl_gmx_rxx_adr_ctl {
        struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx;
        struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xx;
+       struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_decision {
@@ -380,11 +366,26 @@ union cvmx_agl_gmx_rxx_decision {
        struct cvmx_agl_gmx_rxx_decision_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_decision_s cn56xx;
        struct cvmx_agl_gmx_rxx_decision_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_decision_s cn63xx;
+       struct cvmx_agl_gmx_rxx_decision_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_frm_chk {
        uint64_t u64;
        struct cvmx_agl_gmx_rxx_frm_chk_s {
+               uint64_t reserved_10_63:54;
+               uint64_t niberr:1;
+               uint64_t skperr:1;
+               uint64_t rcverr:1;
+               uint64_t lenerr:1;
+               uint64_t alnerr:1;
+               uint64_t fcserr:1;
+               uint64_t jabber:1;
+               uint64_t maxerr:1;
+               uint64_t carext:1;
+               uint64_t minerr:1;
+       } s;
+       struct cvmx_agl_gmx_rxx_frm_chk_cn52xx {
                uint64_t reserved_9_63:55;
                uint64_t skperr:1;
                uint64_t rcverr:1;
@@ -395,17 +396,21 @@ union cvmx_agl_gmx_rxx_frm_chk {
                uint64_t maxerr:1;
                uint64_t reserved_1_1:1;
                uint64_t minerr:1;
-       } s;
-       struct cvmx_agl_gmx_rxx_frm_chk_s cn52xx;
-       struct cvmx_agl_gmx_rxx_frm_chk_s cn52xxp1;
-       struct cvmx_agl_gmx_rxx_frm_chk_s cn56xx;
-       struct cvmx_agl_gmx_rxx_frm_chk_s cn56xxp1;
+       } cn52xx;
+       struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn52xxp1;
+       struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xx;
+       struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xxp1;
+       struct cvmx_agl_gmx_rxx_frm_chk_s cn63xx;
+       struct cvmx_agl_gmx_rxx_frm_chk_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_frm_ctl {
        uint64_t u64;
        struct cvmx_agl_gmx_rxx_frm_ctl_s {
-               uint64_t reserved_10_63:54;
+               uint64_t reserved_13_63:51;
+               uint64_t ptp_mode:1;
+               uint64_t reserved_11_11:1;
+               uint64_t null_dis:1;
                uint64_t pre_align:1;
                uint64_t pad_len:1;
                uint64_t vlan_len:1;
@@ -417,10 +422,24 @@ union cvmx_agl_gmx_rxx_frm_ctl {
                uint64_t pre_strp:1;
                uint64_t pre_chk:1;
        } s;
-       struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xx;
-       struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xxp1;
-       struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xx;
-       struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx {
+               uint64_t reserved_10_63:54;
+               uint64_t pre_align:1;
+               uint64_t pad_len:1;
+               uint64_t vlan_len:1;
+               uint64_t pre_free:1;
+               uint64_t ctl_smac:1;
+               uint64_t ctl_mcst:1;
+               uint64_t ctl_bck:1;
+               uint64_t ctl_drp:1;
+               uint64_t pre_strp:1;
+               uint64_t pre_chk:1;
+       } cn52xx;
+       struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn52xxp1;
+       struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xx;
+       struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xxp1;
+       struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xx;
+       struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_frm_max {
@@ -433,6 +452,8 @@ union cvmx_agl_gmx_rxx_frm_max {
        struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_frm_max_s cn56xx;
        struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_frm_max_s cn63xx;
+       struct cvmx_agl_gmx_rxx_frm_max_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_frm_min {
@@ -445,6 +466,8 @@ union cvmx_agl_gmx_rxx_frm_min {
        struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_frm_min_s cn56xx;
        struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_frm_min_s cn63xx;
+       struct cvmx_agl_gmx_rxx_frm_min_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_ifg {
@@ -457,11 +480,36 @@ union cvmx_agl_gmx_rxx_ifg {
        struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_ifg_s cn56xx;
        struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_ifg_s cn63xx;
+       struct cvmx_agl_gmx_rxx_ifg_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_int_en {
        uint64_t u64;
        struct cvmx_agl_gmx_rxx_int_en_s {
+               uint64_t reserved_20_63:44;
+               uint64_t pause_drp:1;
+               uint64_t phy_dupx:1;
+               uint64_t phy_spd:1;
+               uint64_t phy_link:1;
+               uint64_t ifgerr:1;
+               uint64_t coldet:1;
+               uint64_t falerr:1;
+               uint64_t rsverr:1;
+               uint64_t pcterr:1;
+               uint64_t ovrerr:1;
+               uint64_t niberr:1;
+               uint64_t skperr:1;
+               uint64_t rcverr:1;
+               uint64_t lenerr:1;
+               uint64_t alnerr:1;
+               uint64_t fcserr:1;
+               uint64_t jabber:1;
+               uint64_t maxerr:1;
+               uint64_t carext:1;
+               uint64_t minerr:1;
+       } s;
+       struct cvmx_agl_gmx_rxx_int_en_cn52xx {
                uint64_t reserved_20_63:44;
                uint64_t pause_drp:1;
                uint64_t reserved_16_18:3;
@@ -481,16 +529,40 @@ union cvmx_agl_gmx_rxx_int_en {
                uint64_t maxerr:1;
                uint64_t reserved_1_1:1;
                uint64_t minerr:1;
-       } s;
-       struct cvmx_agl_gmx_rxx_int_en_s cn52xx;
-       struct cvmx_agl_gmx_rxx_int_en_s cn52xxp1;
-       struct cvmx_agl_gmx_rxx_int_en_s cn56xx;
-       struct cvmx_agl_gmx_rxx_int_en_s cn56xxp1;
+       } cn52xx;
+       struct cvmx_agl_gmx_rxx_int_en_cn52xx cn52xxp1;
+       struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xx;
+       struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xxp1;
+       struct cvmx_agl_gmx_rxx_int_en_s cn63xx;
+       struct cvmx_agl_gmx_rxx_int_en_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_int_reg {
        uint64_t u64;
        struct cvmx_agl_gmx_rxx_int_reg_s {
+               uint64_t reserved_20_63:44;
+               uint64_t pause_drp:1;
+               uint64_t phy_dupx:1;
+               uint64_t phy_spd:1;
+               uint64_t phy_link:1;
+               uint64_t ifgerr:1;
+               uint64_t coldet:1;
+               uint64_t falerr:1;
+               uint64_t rsverr:1;
+               uint64_t pcterr:1;
+               uint64_t ovrerr:1;
+               uint64_t niberr:1;
+               uint64_t skperr:1;
+               uint64_t rcverr:1;
+               uint64_t lenerr:1;
+               uint64_t alnerr:1;
+               uint64_t fcserr:1;
+               uint64_t jabber:1;
+               uint64_t maxerr:1;
+               uint64_t carext:1;
+               uint64_t minerr:1;
+       } s;
+       struct cvmx_agl_gmx_rxx_int_reg_cn52xx {
                uint64_t reserved_20_63:44;
                uint64_t pause_drp:1;
                uint64_t reserved_16_18:3;
@@ -510,11 +582,12 @@ union cvmx_agl_gmx_rxx_int_reg {
                uint64_t maxerr:1;
                uint64_t reserved_1_1:1;
                uint64_t minerr:1;
-       } s;
-       struct cvmx_agl_gmx_rxx_int_reg_s cn52xx;
-       struct cvmx_agl_gmx_rxx_int_reg_s cn52xxp1;
-       struct cvmx_agl_gmx_rxx_int_reg_s cn56xx;
-       struct cvmx_agl_gmx_rxx_int_reg_s cn56xxp1;
+       } cn52xx;
+       struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn52xxp1;
+       struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xx;
+       struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xxp1;
+       struct cvmx_agl_gmx_rxx_int_reg_s cn63xx;
+       struct cvmx_agl_gmx_rxx_int_reg_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_jabber {
@@ -527,6 +600,8 @@ union cvmx_agl_gmx_rxx_jabber {
        struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_jabber_s cn56xx;
        struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_jabber_s cn63xx;
+       struct cvmx_agl_gmx_rxx_jabber_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_pause_drop_time {
@@ -539,6 +614,20 @@ union cvmx_agl_gmx_rxx_pause_drop_time {
        struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx;
        struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xx;
+       struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_rx_inbnd {
+       uint64_t u64;
+       struct cvmx_agl_gmx_rxx_rx_inbnd_s {
+               uint64_t reserved_4_63:60;
+               uint64_t duplex:1;
+               uint64_t speed:2;
+               uint64_t status:1;
+       } s;
+       struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xx;
+       struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_ctl {
@@ -551,6 +640,8 @@ union cvmx_agl_gmx_rxx_stats_ctl {
        struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_octs {
@@ -563,6 +654,8 @@ union cvmx_agl_gmx_rxx_stats_octs {
        struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_octs_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_octs_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_octs_ctl {
@@ -575,6 +668,8 @@ union cvmx_agl_gmx_rxx_stats_octs_ctl {
        struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_octs_dmac {
@@ -587,6 +682,8 @@ union cvmx_agl_gmx_rxx_stats_octs_dmac {
        struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_octs_drp {
@@ -599,6 +696,8 @@ union cvmx_agl_gmx_rxx_stats_octs_drp {
        struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts {
@@ -611,6 +710,8 @@ union cvmx_agl_gmx_rxx_stats_pkts {
        struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts_bad {
@@ -623,6 +724,8 @@ union cvmx_agl_gmx_rxx_stats_pkts_bad {
        struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts_ctl {
@@ -635,6 +738,8 @@ union cvmx_agl_gmx_rxx_stats_pkts_ctl {
        struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts_dmac {
@@ -647,6 +752,8 @@ union cvmx_agl_gmx_rxx_stats_pkts_dmac {
        struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts_drp {
@@ -659,6 +766,8 @@ union cvmx_agl_gmx_rxx_stats_pkts_drp {
        struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx;
        struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xx;
+       struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rxx_udd_skp {
@@ -673,6 +782,8 @@ union cvmx_agl_gmx_rxx_udd_skp {
        struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1;
        struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx;
        struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1;
+       struct cvmx_agl_gmx_rxx_udd_skp_s cn63xx;
+       struct cvmx_agl_gmx_rxx_udd_skp_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rx_bp_dropx {
@@ -685,6 +796,8 @@ union cvmx_agl_gmx_rx_bp_dropx {
        struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1;
        struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx;
        struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1;
+       struct cvmx_agl_gmx_rx_bp_dropx_s cn63xx;
+       struct cvmx_agl_gmx_rx_bp_dropx_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rx_bp_offx {
@@ -697,6 +810,8 @@ union cvmx_agl_gmx_rx_bp_offx {
        struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1;
        struct cvmx_agl_gmx_rx_bp_offx_s cn56xx;
        struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1;
+       struct cvmx_agl_gmx_rx_bp_offx_s cn63xx;
+       struct cvmx_agl_gmx_rx_bp_offx_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rx_bp_onx {
@@ -709,6 +824,8 @@ union cvmx_agl_gmx_rx_bp_onx {
        struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1;
        struct cvmx_agl_gmx_rx_bp_onx_s cn56xx;
        struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1;
+       struct cvmx_agl_gmx_rx_bp_onx_s cn63xx;
+       struct cvmx_agl_gmx_rx_bp_onx_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rx_prt_info {
@@ -728,6 +845,8 @@ union cvmx_agl_gmx_rx_prt_info {
                uint64_t commit:1;
        } cn56xx;
        struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1;
+       struct cvmx_agl_gmx_rx_prt_info_s cn63xx;
+       struct cvmx_agl_gmx_rx_prt_info_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_rx_tx_status {
@@ -747,6 +866,8 @@ union cvmx_agl_gmx_rx_tx_status {
                uint64_t rx:1;
        } cn56xx;
        struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1;
+       struct cvmx_agl_gmx_rx_tx_status_s cn63xx;
+       struct cvmx_agl_gmx_rx_tx_status_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_smacx {
@@ -759,6 +880,8 @@ union cvmx_agl_gmx_smacx {
        struct cvmx_agl_gmx_smacx_s cn52xxp1;
        struct cvmx_agl_gmx_smacx_s cn56xx;
        struct cvmx_agl_gmx_smacx_s cn56xxp1;
+       struct cvmx_agl_gmx_smacx_s cn63xx;
+       struct cvmx_agl_gmx_smacx_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_stat_bp {
@@ -772,6 +895,8 @@ union cvmx_agl_gmx_stat_bp {
        struct cvmx_agl_gmx_stat_bp_s cn52xxp1;
        struct cvmx_agl_gmx_stat_bp_s cn56xx;
        struct cvmx_agl_gmx_stat_bp_s cn56xxp1;
+       struct cvmx_agl_gmx_stat_bp_s cn63xx;
+       struct cvmx_agl_gmx_stat_bp_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_append {
@@ -787,6 +912,18 @@ union cvmx_agl_gmx_txx_append {
        struct cvmx_agl_gmx_txx_append_s cn52xxp1;
        struct cvmx_agl_gmx_txx_append_s cn56xx;
        struct cvmx_agl_gmx_txx_append_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_append_s cn63xx;
+       struct cvmx_agl_gmx_txx_append_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_clk {
+       uint64_t u64;
+       struct cvmx_agl_gmx_txx_clk_s {
+               uint64_t reserved_6_63:58;
+               uint64_t clk_cnt:6;
+       } s;
+       struct cvmx_agl_gmx_txx_clk_s cn63xx;
+       struct cvmx_agl_gmx_txx_clk_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_ctl {
@@ -800,6 +937,8 @@ union cvmx_agl_gmx_txx_ctl {
        struct cvmx_agl_gmx_txx_ctl_s cn52xxp1;
        struct cvmx_agl_gmx_txx_ctl_s cn56xx;
        struct cvmx_agl_gmx_txx_ctl_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_ctl_s cn63xx;
+       struct cvmx_agl_gmx_txx_ctl_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_min_pkt {
@@ -812,6 +951,8 @@ union cvmx_agl_gmx_txx_min_pkt {
        struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1;
        struct cvmx_agl_gmx_txx_min_pkt_s cn56xx;
        struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_min_pkt_s cn63xx;
+       struct cvmx_agl_gmx_txx_min_pkt_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_pause_pkt_interval {
@@ -824,6 +965,8 @@ union cvmx_agl_gmx_txx_pause_pkt_interval {
        struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1;
        struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx;
        struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xx;
+       struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_pause_pkt_time {
@@ -836,6 +979,8 @@ union cvmx_agl_gmx_txx_pause_pkt_time {
        struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1;
        struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx;
        struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xx;
+       struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_pause_togo {
@@ -848,6 +993,8 @@ union cvmx_agl_gmx_txx_pause_togo {
        struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1;
        struct cvmx_agl_gmx_txx_pause_togo_s cn56xx;
        struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_pause_togo_s cn63xx;
+       struct cvmx_agl_gmx_txx_pause_togo_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_pause_zero {
@@ -860,6 +1007,8 @@ union cvmx_agl_gmx_txx_pause_zero {
        struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1;
        struct cvmx_agl_gmx_txx_pause_zero_s cn56xx;
        struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_pause_zero_s cn63xx;
+       struct cvmx_agl_gmx_txx_pause_zero_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_soft_pause {
@@ -872,6 +1021,8 @@ union cvmx_agl_gmx_txx_soft_pause {
        struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1;
        struct cvmx_agl_gmx_txx_soft_pause_s cn56xx;
        struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_soft_pause_s cn63xx;
+       struct cvmx_agl_gmx_txx_soft_pause_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat0 {
@@ -884,6 +1035,8 @@ union cvmx_agl_gmx_txx_stat0 {
        struct cvmx_agl_gmx_txx_stat0_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat0_s cn56xx;
        struct cvmx_agl_gmx_txx_stat0_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat0_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat0_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat1 {
@@ -896,6 +1049,8 @@ union cvmx_agl_gmx_txx_stat1 {
        struct cvmx_agl_gmx_txx_stat1_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat1_s cn56xx;
        struct cvmx_agl_gmx_txx_stat1_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat1_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat1_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat2 {
@@ -908,6 +1063,8 @@ union cvmx_agl_gmx_txx_stat2 {
        struct cvmx_agl_gmx_txx_stat2_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat2_s cn56xx;
        struct cvmx_agl_gmx_txx_stat2_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat2_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat2_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat3 {
@@ -920,6 +1077,8 @@ union cvmx_agl_gmx_txx_stat3 {
        struct cvmx_agl_gmx_txx_stat3_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat3_s cn56xx;
        struct cvmx_agl_gmx_txx_stat3_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat3_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat3_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat4 {
@@ -932,6 +1091,8 @@ union cvmx_agl_gmx_txx_stat4 {
        struct cvmx_agl_gmx_txx_stat4_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat4_s cn56xx;
        struct cvmx_agl_gmx_txx_stat4_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat4_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat4_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat5 {
@@ -944,6 +1105,8 @@ union cvmx_agl_gmx_txx_stat5 {
        struct cvmx_agl_gmx_txx_stat5_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat5_s cn56xx;
        struct cvmx_agl_gmx_txx_stat5_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat5_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat5_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat6 {
@@ -956,6 +1119,8 @@ union cvmx_agl_gmx_txx_stat6 {
        struct cvmx_agl_gmx_txx_stat6_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat6_s cn56xx;
        struct cvmx_agl_gmx_txx_stat6_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat6_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat6_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat7 {
@@ -968,6 +1133,8 @@ union cvmx_agl_gmx_txx_stat7 {
        struct cvmx_agl_gmx_txx_stat7_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat7_s cn56xx;
        struct cvmx_agl_gmx_txx_stat7_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat7_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat7_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat8 {
@@ -980,6 +1147,8 @@ union cvmx_agl_gmx_txx_stat8 {
        struct cvmx_agl_gmx_txx_stat8_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat8_s cn56xx;
        struct cvmx_agl_gmx_txx_stat8_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat8_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat8_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat9 {
@@ -992,6 +1161,8 @@ union cvmx_agl_gmx_txx_stat9 {
        struct cvmx_agl_gmx_txx_stat9_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stat9_s cn56xx;
        struct cvmx_agl_gmx_txx_stat9_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stat9_s cn63xx;
+       struct cvmx_agl_gmx_txx_stat9_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_stats_ctl {
@@ -1004,6 +1175,8 @@ union cvmx_agl_gmx_txx_stats_ctl {
        struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1;
        struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx;
        struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_stats_ctl_s cn63xx;
+       struct cvmx_agl_gmx_txx_stats_ctl_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_txx_thresh {
@@ -1016,6 +1189,8 @@ union cvmx_agl_gmx_txx_thresh {
        struct cvmx_agl_gmx_txx_thresh_s cn52xxp1;
        struct cvmx_agl_gmx_txx_thresh_s cn56xx;
        struct cvmx_agl_gmx_txx_thresh_s cn56xxp1;
+       struct cvmx_agl_gmx_txx_thresh_s cn63xx;
+       struct cvmx_agl_gmx_txx_thresh_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_bp {
@@ -1031,6 +1206,8 @@ union cvmx_agl_gmx_tx_bp {
                uint64_t bp:1;
        } cn56xx;
        struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1;
+       struct cvmx_agl_gmx_tx_bp_s cn63xx;
+       struct cvmx_agl_gmx_tx_bp_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_col_attempt {
@@ -1043,6 +1220,8 @@ union cvmx_agl_gmx_tx_col_attempt {
        struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1;
        struct cvmx_agl_gmx_tx_col_attempt_s cn56xx;
        struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1;
+       struct cvmx_agl_gmx_tx_col_attempt_s cn63xx;
+       struct cvmx_agl_gmx_tx_col_attempt_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_ifg {
@@ -1056,12 +1235,16 @@ union cvmx_agl_gmx_tx_ifg {
        struct cvmx_agl_gmx_tx_ifg_s cn52xxp1;
        struct cvmx_agl_gmx_tx_ifg_s cn56xx;
        struct cvmx_agl_gmx_tx_ifg_s cn56xxp1;
+       struct cvmx_agl_gmx_tx_ifg_s cn63xx;
+       struct cvmx_agl_gmx_tx_ifg_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_int_en {
        uint64_t u64;
        struct cvmx_agl_gmx_tx_int_en_s {
-               uint64_t reserved_18_63:46;
+               uint64_t reserved_22_63:42;
+               uint64_t ptp_lost:2;
+               uint64_t reserved_18_19:2;
                uint64_t late_col:2;
                uint64_t reserved_14_15:2;
                uint64_t xsdef:2;
@@ -1072,8 +1255,19 @@ union cvmx_agl_gmx_tx_int_en {
                uint64_t reserved_1_1:1;
                uint64_t pko_nxa:1;
        } s;
-       struct cvmx_agl_gmx_tx_int_en_s cn52xx;
-       struct cvmx_agl_gmx_tx_int_en_s cn52xxp1;
+       struct cvmx_agl_gmx_tx_int_en_cn52xx {
+               uint64_t reserved_18_63:46;
+               uint64_t late_col:2;
+               uint64_t reserved_14_15:2;
+               uint64_t xsdef:2;
+               uint64_t reserved_10_11:2;
+               uint64_t xscol:2;
+               uint64_t reserved_4_7:4;
+               uint64_t undflw:2;
+               uint64_t reserved_1_1:1;
+               uint64_t pko_nxa:1;
+       } cn52xx;
+       struct cvmx_agl_gmx_tx_int_en_cn52xx cn52xxp1;
        struct cvmx_agl_gmx_tx_int_en_cn56xx {
                uint64_t reserved_17_63:47;
                uint64_t late_col:1;
@@ -1087,12 +1281,16 @@ union cvmx_agl_gmx_tx_int_en {
                uint64_t pko_nxa:1;
        } cn56xx;
        struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1;
+       struct cvmx_agl_gmx_tx_int_en_s cn63xx;
+       struct cvmx_agl_gmx_tx_int_en_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_int_reg {
        uint64_t u64;
        struct cvmx_agl_gmx_tx_int_reg_s {
-               uint64_t reserved_18_63:46;
+               uint64_t reserved_22_63:42;
+               uint64_t ptp_lost:2;
+               uint64_t reserved_18_19:2;
                uint64_t late_col:2;
                uint64_t reserved_14_15:2;
                uint64_t xsdef:2;
@@ -1103,8 +1301,19 @@ union cvmx_agl_gmx_tx_int_reg {
                uint64_t reserved_1_1:1;
                uint64_t pko_nxa:1;
        } s;
-       struct cvmx_agl_gmx_tx_int_reg_s cn52xx;
-       struct cvmx_agl_gmx_tx_int_reg_s cn52xxp1;
+       struct cvmx_agl_gmx_tx_int_reg_cn52xx {
+               uint64_t reserved_18_63:46;
+               uint64_t late_col:2;
+               uint64_t reserved_14_15:2;
+               uint64_t xsdef:2;
+               uint64_t reserved_10_11:2;
+               uint64_t xscol:2;
+               uint64_t reserved_4_7:4;
+               uint64_t undflw:2;
+               uint64_t reserved_1_1:1;
+               uint64_t pko_nxa:1;
+       } cn52xx;
+       struct cvmx_agl_gmx_tx_int_reg_cn52xx cn52xxp1;
        struct cvmx_agl_gmx_tx_int_reg_cn56xx {
                uint64_t reserved_17_63:47;
                uint64_t late_col:1;
@@ -1118,6 +1327,8 @@ union cvmx_agl_gmx_tx_int_reg {
                uint64_t pko_nxa:1;
        } cn56xx;
        struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1;
+       struct cvmx_agl_gmx_tx_int_reg_s cn63xx;
+       struct cvmx_agl_gmx_tx_int_reg_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_jam {
@@ -1130,6 +1341,8 @@ union cvmx_agl_gmx_tx_jam {
        struct cvmx_agl_gmx_tx_jam_s cn52xxp1;
        struct cvmx_agl_gmx_tx_jam_s cn56xx;
        struct cvmx_agl_gmx_tx_jam_s cn56xxp1;
+       struct cvmx_agl_gmx_tx_jam_s cn63xx;
+       struct cvmx_agl_gmx_tx_jam_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_lfsr {
@@ -1142,6 +1355,8 @@ union cvmx_agl_gmx_tx_lfsr {
        struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1;
        struct cvmx_agl_gmx_tx_lfsr_s cn56xx;
        struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1;
+       struct cvmx_agl_gmx_tx_lfsr_s cn63xx;
+       struct cvmx_agl_gmx_tx_lfsr_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_ovr_bp {
@@ -1165,6 +1380,8 @@ union cvmx_agl_gmx_tx_ovr_bp {
                uint64_t ign_full:1;
        } cn56xx;
        struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1;
+       struct cvmx_agl_gmx_tx_ovr_bp_s cn63xx;
+       struct cvmx_agl_gmx_tx_ovr_bp_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_pause_pkt_dmac {
@@ -1177,6 +1394,8 @@ union cvmx_agl_gmx_tx_pause_pkt_dmac {
        struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1;
        struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx;
        struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1;
+       struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xx;
+       struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xxp1;
 };
 
 union cvmx_agl_gmx_tx_pause_pkt_type {
@@ -1189,6 +1408,39 @@ union cvmx_agl_gmx_tx_pause_pkt_type {
        struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1;
        struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx;
        struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1;
+       struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xx;
+       struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xxp1;
+};
+
+union cvmx_agl_prtx_ctl {
+       uint64_t u64;
+       struct cvmx_agl_prtx_ctl_s {
+               uint64_t drv_byp:1;
+               uint64_t reserved_62_62:1;
+               uint64_t cmp_pctl:6;
+               uint64_t reserved_54_55:2;
+               uint64_t cmp_nctl:6;
+               uint64_t reserved_46_47:2;
+               uint64_t drv_pctl:6;
+               uint64_t reserved_38_39:2;
+               uint64_t drv_nctl:6;
+               uint64_t reserved_29_31:3;
+               uint64_t clk_set:5;
+               uint64_t clkrx_byp:1;
+               uint64_t reserved_21_22:2;
+               uint64_t clkrx_set:5;
+               uint64_t clktx_byp:1;
+               uint64_t reserved_13_14:2;
+               uint64_t clktx_set:5;
+               uint64_t reserved_5_7:3;
+               uint64_t dllrst:1;
+               uint64_t comp:1;
+               uint64_t enable:1;
+               uint64_t clkrst:1;
+               uint64_t mode:1;
+       } s;
+       struct cvmx_agl_prtx_ctl_s cn63xx;
+       struct cvmx_agl_prtx_ctl_s cn63xxp1;
 };
 
 #endif
index b21d3fc1ef91516447de5370d54a36fbacd7388d..5de5de95311bd80acc4a52497e4d4ea0b5e19230 100644 (file)
 #define CVMX_DCACHE_INVALIDATE \
        { CVMX_SYNC; asm volatile ("cache 9, 0($0)" : : ); }
 
+#define CVMX_CACHE(op, address, offset)                                        \
+       asm volatile ("cache " CVMX_TMP_STR(op) ", " CVMX_TMP_STR(offset) "(%[rbase])" \
+               : : [rbase] "d" (address) )
+/* fetch and lock the state. */
+#define CVMX_CACHE_LCKL2(address, offset) CVMX_CACHE(31, address, offset)
+/* unlock the state. */
+#define CVMX_CACHE_WBIL2(address, offset) CVMX_CACHE(23, address, offset)
+/* invalidate the cache block and clear the USED bits for the block */
+#define CVMX_CACHE_WBIL2I(address, offset) CVMX_CACHE(3, address, offset)
+/* load virtual tag and data for the L2 cache block into L2C_TAD0_TAG register */
+#define CVMX_CACHE_LTGL2I(address, offset) CVMX_CACHE(7, address, offset)
 
 #define CVMX_POP(result, input) \
        asm ("pop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
index f8f05b7764b731fe5f153c0935645ebdacec100d..27cead370411f7e7f5d7f7e8db4eb7f41c4a06d1 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_CIU_DEFS_H__
 #define __CVMX_CIU_DEFS_H__
 
-#define CVMX_CIU_BIST \
-        CVMX_ADD_IO_SEG(0x0001070000000730ull)
-#define CVMX_CIU_DINT \
-        CVMX_ADD_IO_SEG(0x0001070000000720ull)
-#define CVMX_CIU_FUSE \
-        CVMX_ADD_IO_SEG(0x0001070000000728ull)
-#define CVMX_CIU_GSTOP \
-        CVMX_ADD_IO_SEG(0x0001070000000710ull)
-#define CVMX_CIU_INTX_EN0(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000200ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN0_W1C(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000002200ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN0_W1S(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000006200ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN1(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000208ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN1_W1C(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000002208ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN1_W1S(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000006208ull + (((offset) & 63) * 16))
-#define CVMX_CIU_INTX_EN4_0(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000C80ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_0_W1C(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000002C80ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_0_W1S(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000006C80ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_1(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000C88ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_1_W1C(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000002C88ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_EN4_1_W1S(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000006C88ull + (((offset) & 15) * 16))
-#define CVMX_CIU_INTX_SUM0(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000000ull + (((offset) & 63) * 8))
-#define CVMX_CIU_INTX_SUM4(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000C00ull + (((offset) & 15) * 8))
-#define CVMX_CIU_INT_SUM1 \
-        CVMX_ADD_IO_SEG(0x0001070000000108ull)
-#define CVMX_CIU_MBOX_CLRX(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000680ull + (((offset) & 15) * 8))
-#define CVMX_CIU_MBOX_SETX(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000600ull + (((offset) & 15) * 8))
-#define CVMX_CIU_NMI \
-        CVMX_ADD_IO_SEG(0x0001070000000718ull)
-#define CVMX_CIU_PCI_INTA \
-        CVMX_ADD_IO_SEG(0x0001070000000750ull)
-#define CVMX_CIU_PP_DBG \
-        CVMX_ADD_IO_SEG(0x0001070000000708ull)
-#define CVMX_CIU_PP_POKEX(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000580ull + (((offset) & 15) * 8))
-#define CVMX_CIU_PP_RST \
-        CVMX_ADD_IO_SEG(0x0001070000000700ull)
-#define CVMX_CIU_QLM_DCOK \
-        CVMX_ADD_IO_SEG(0x0001070000000760ull)
-#define CVMX_CIU_QLM_JTGC \
-        CVMX_ADD_IO_SEG(0x0001070000000768ull)
-#define CVMX_CIU_QLM_JTGD \
-        CVMX_ADD_IO_SEG(0x0001070000000770ull)
-#define CVMX_CIU_SOFT_BIST \
-        CVMX_ADD_IO_SEG(0x0001070000000738ull)
-#define CVMX_CIU_SOFT_PRST \
-        CVMX_ADD_IO_SEG(0x0001070000000748ull)
-#define CVMX_CIU_SOFT_PRST1 \
-        CVMX_ADD_IO_SEG(0x0001070000000758ull)
-#define CVMX_CIU_SOFT_RST \
-        CVMX_ADD_IO_SEG(0x0001070000000740ull)
-#define CVMX_CIU_TIMX(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000480ull + (((offset) & 3) * 8))
-#define CVMX_CIU_WDOGX(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000500ull + (((offset) & 15) * 8))
+#define CVMX_CIU_BIST (CVMX_ADD_IO_SEG(0x0001070000000730ull))
+#define CVMX_CIU_BLOCK_INT (CVMX_ADD_IO_SEG(0x00010700000007C0ull))
+#define CVMX_CIU_DINT (CVMX_ADD_IO_SEG(0x0001070000000720ull))
+#define CVMX_CIU_FUSE (CVMX_ADD_IO_SEG(0x0001070000000728ull))
+#define CVMX_CIU_GSTOP (CVMX_ADD_IO_SEG(0x0001070000000710ull))
+#define CVMX_CIU_INT33_SUM0 (CVMX_ADD_IO_SEG(0x0001070000000110ull))
+#define CVMX_CIU_INTX_EN0(offset) (CVMX_ADD_IO_SEG(0x0001070000000200ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN0_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002200ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN0_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006200ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN1(offset) (CVMX_ADD_IO_SEG(0x0001070000000208ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN1_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002208ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN1_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006208ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN4_0(offset) (CVMX_ADD_IO_SEG(0x0001070000000C80ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_0_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002C80ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_0_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006C80ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_1(offset) (CVMX_ADD_IO_SEG(0x0001070000000C88ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_1_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002C88ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_1_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006C88ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_SUM0(offset) (CVMX_ADD_IO_SEG(0x0001070000000000ull) + ((offset) & 63) * 8)
+#define CVMX_CIU_INTX_SUM4(offset) (CVMX_ADD_IO_SEG(0x0001070000000C00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_INT_DBG_SEL (CVMX_ADD_IO_SEG(0x00010700000007D0ull))
+#define CVMX_CIU_INT_SUM1 (CVMX_ADD_IO_SEG(0x0001070000000108ull))
+#define CVMX_CIU_MBOX_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001070000000680ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_MBOX_SETX(offset) (CVMX_ADD_IO_SEG(0x0001070000000600ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_NMI (CVMX_ADD_IO_SEG(0x0001070000000718ull))
+#define CVMX_CIU_PCI_INTA (CVMX_ADD_IO_SEG(0x0001070000000750ull))
+#define CVMX_CIU_PP_DBG (CVMX_ADD_IO_SEG(0x0001070000000708ull))
+#define CVMX_CIU_PP_POKEX(offset) (CVMX_ADD_IO_SEG(0x0001070000000580ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_PP_RST (CVMX_ADD_IO_SEG(0x0001070000000700ull))
+#define CVMX_CIU_QLM0 (CVMX_ADD_IO_SEG(0x0001070000000780ull))
+#define CVMX_CIU_QLM1 (CVMX_ADD_IO_SEG(0x0001070000000788ull))
+#define CVMX_CIU_QLM2 (CVMX_ADD_IO_SEG(0x0001070000000790ull))
+#define CVMX_CIU_QLM_DCOK (CVMX_ADD_IO_SEG(0x0001070000000760ull))
+#define CVMX_CIU_QLM_JTGC (CVMX_ADD_IO_SEG(0x0001070000000768ull))
+#define CVMX_CIU_QLM_JTGD (CVMX_ADD_IO_SEG(0x0001070000000770ull))
+#define CVMX_CIU_SOFT_BIST (CVMX_ADD_IO_SEG(0x0001070000000738ull))
+#define CVMX_CIU_SOFT_PRST (CVMX_ADD_IO_SEG(0x0001070000000748ull))
+#define CVMX_CIU_SOFT_PRST1 (CVMX_ADD_IO_SEG(0x0001070000000758ull))
+#define CVMX_CIU_SOFT_RST (CVMX_ADD_IO_SEG(0x0001070000000740ull))
+#define CVMX_CIU_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001070000000480ull) + ((offset) & 3) * 8)
+#define CVMX_CIU_WDOGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000500ull) + ((offset) & 15) * 8)
 
 union cvmx_ciu_bist {
        uint64_t u64;
        struct cvmx_ciu_bist_s {
+               uint64_t reserved_5_63:59;
+               uint64_t bist:5;
+       } s;
+       struct cvmx_ciu_bist_cn30xx {
                uint64_t reserved_4_63:60;
                uint64_t bist:4;
-       } s;
-       struct cvmx_ciu_bist_s cn30xx;
-       struct cvmx_ciu_bist_s cn31xx;
-       struct cvmx_ciu_bist_s cn38xx;
-       struct cvmx_ciu_bist_s cn38xxp2;
+       } cn30xx;
+       struct cvmx_ciu_bist_cn30xx cn31xx;
+       struct cvmx_ciu_bist_cn30xx cn38xx;
+       struct cvmx_ciu_bist_cn30xx cn38xxp2;
        struct cvmx_ciu_bist_cn50xx {
                uint64_t reserved_2_63:62;
                uint64_t bist:2;
@@ -118,10 +92,57 @@ union cvmx_ciu_bist {
                uint64_t bist:3;
        } cn52xx;
        struct cvmx_ciu_bist_cn52xx cn52xxp1;
-       struct cvmx_ciu_bist_s cn56xx;
-       struct cvmx_ciu_bist_s cn56xxp1;
-       struct cvmx_ciu_bist_s cn58xx;
-       struct cvmx_ciu_bist_s cn58xxp1;
+       struct cvmx_ciu_bist_cn30xx cn56xx;
+       struct cvmx_ciu_bist_cn30xx cn56xxp1;
+       struct cvmx_ciu_bist_cn30xx cn58xx;
+       struct cvmx_ciu_bist_cn30xx cn58xxp1;
+       struct cvmx_ciu_bist_s cn63xx;
+       struct cvmx_ciu_bist_s cn63xxp1;
+};
+
+union cvmx_ciu_block_int {
+       uint64_t u64;
+       struct cvmx_ciu_block_int_s {
+               uint64_t reserved_43_63:21;
+               uint64_t ptp:1;
+               uint64_t dpi:1;
+               uint64_t dfm:1;
+               uint64_t reserved_34_39:6;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t reserved_31_31:1;
+               uint64_t iob:1;
+               uint64_t reserved_29_29:1;
+               uint64_t agl:1;
+               uint64_t reserved_27_27:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t reserved_23_24:2;
+               uint64_t asxpcs0:1;
+               uint64_t reserved_21_21:1;
+               uint64_t pip:1;
+               uint64_t reserved_18_19:2;
+               uint64_t lmc0:1;
+               uint64_t l2c:1;
+               uint64_t reserved_15_15:1;
+               uint64_t rad:1;
+               uint64_t usb:1;
+               uint64_t pow:1;
+               uint64_t tim:1;
+               uint64_t pko:1;
+               uint64_t ipd:1;
+               uint64_t reserved_8_8:1;
+               uint64_t zip:1;
+               uint64_t dfa:1;
+               uint64_t fpa:1;
+               uint64_t key:1;
+               uint64_t sli:1;
+               uint64_t reserved_2_2:1;
+               uint64_t gmx0:1;
+               uint64_t mio:1;
+       } s;
+       struct cvmx_ciu_block_int_s cn63xx;
+       struct cvmx_ciu_block_int_s cn63xxp1;
 };
 
 union cvmx_ciu_dint {
@@ -153,6 +174,11 @@ union cvmx_ciu_dint {
        struct cvmx_ciu_dint_cn56xx cn56xxp1;
        struct cvmx_ciu_dint_s cn58xx;
        struct cvmx_ciu_dint_s cn58xxp1;
+       struct cvmx_ciu_dint_cn63xx {
+               uint64_t reserved_6_63:58;
+               uint64_t dint:6;
+       } cn63xx;
+       struct cvmx_ciu_dint_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_fuse {
@@ -184,6 +210,11 @@ union cvmx_ciu_fuse {
        struct cvmx_ciu_fuse_cn56xx cn56xxp1;
        struct cvmx_ciu_fuse_s cn58xx;
        struct cvmx_ciu_fuse_s cn58xxp1;
+       struct cvmx_ciu_fuse_cn63xx {
+               uint64_t reserved_6_63:58;
+               uint64_t fuse:6;
+       } cn63xx;
+       struct cvmx_ciu_fuse_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_gstop {
@@ -203,6 +234,8 @@ union cvmx_ciu_gstop {
        struct cvmx_ciu_gstop_s cn56xxp1;
        struct cvmx_ciu_gstop_s cn58xx;
        struct cvmx_ciu_gstop_s cn58xxp1;
+       struct cvmx_ciu_gstop_s cn63xx;
+       struct cvmx_ciu_gstop_s cn63xxp1;
 };
 
 union cvmx_ciu_intx_en0 {
@@ -343,6 +376,8 @@ union cvmx_ciu_intx_en0 {
        struct cvmx_ciu_intx_en0_cn56xx cn56xxp1;
        struct cvmx_ciu_intx_en0_cn38xx cn58xx;
        struct cvmx_ciu_intx_en0_cn38xx cn58xxp1;
+       struct cvmx_ciu_intx_en0_cn52xx cn63xx;
+       struct cvmx_ciu_intx_en0_cn52xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en0_w1c {
@@ -412,6 +447,8 @@ union cvmx_ciu_intx_en0_w1c {
                uint64_t gpio:16;
                uint64_t workq:16;
        } cn58xx;
+       struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xx;
+       struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en0_w1s {
@@ -481,12 +518,42 @@ union cvmx_ciu_intx_en0_w1s {
                uint64_t gpio:16;
                uint64_t workq:16;
        } cn58xx;
+       struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xx;
+       struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en1 {
        uint64_t u64;
        struct cvmx_ciu_intx_en1_s {
-               uint64_t reserved_20_63:44;
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
                uint64_t nand:1;
                uint64_t mii1:1;
                uint64_t usb1:1;
@@ -531,12 +598,76 @@ union cvmx_ciu_intx_en1 {
        struct cvmx_ciu_intx_en1_cn56xx cn56xxp1;
        struct cvmx_ciu_intx_en1_cn38xx cn58xx;
        struct cvmx_ciu_intx_en1_cn38xx cn58xxp1;
+       struct cvmx_ciu_intx_en1_cn63xx {
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
+               uint64_t nand:1;
+               uint64_t mii1:1;
+               uint64_t reserved_6_17:12;
+               uint64_t wdog:6;
+       } cn63xx;
+       struct cvmx_ciu_intx_en1_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en1_w1c {
        uint64_t u64;
        struct cvmx_ciu_intx_en1_w1c_s {
-               uint64_t reserved_20_63:44;
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
                uint64_t nand:1;
                uint64_t mii1:1;
                uint64_t usb1:1;
@@ -560,12 +691,76 @@ union cvmx_ciu_intx_en1_w1c {
                uint64_t reserved_16_63:48;
                uint64_t wdog:16;
        } cn58xx;
+       struct cvmx_ciu_intx_en1_w1c_cn63xx {
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
+               uint64_t nand:1;
+               uint64_t mii1:1;
+               uint64_t reserved_6_17:12;
+               uint64_t wdog:6;
+       } cn63xx;
+       struct cvmx_ciu_intx_en1_w1c_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en1_w1s {
        uint64_t u64;
        struct cvmx_ciu_intx_en1_w1s_s {
-               uint64_t reserved_20_63:44;
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
                uint64_t nand:1;
                uint64_t mii1:1;
                uint64_t usb1:1;
@@ -589,6 +784,42 @@ union cvmx_ciu_intx_en1_w1s {
                uint64_t reserved_16_63:48;
                uint64_t wdog:16;
        } cn58xx;
+       struct cvmx_ciu_intx_en1_w1s_cn63xx {
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
+               uint64_t nand:1;
+               uint64_t mii1:1;
+               uint64_t reserved_6_17:12;
+               uint64_t wdog:6;
+       } cn63xx;
+       struct cvmx_ciu_intx_en1_w1s_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en4_0 {
@@ -705,6 +936,8 @@ union cvmx_ciu_intx_en4_0 {
                uint64_t workq:16;
        } cn58xx;
        struct cvmx_ciu_intx_en4_0_cn58xx cn58xxp1;
+       struct cvmx_ciu_intx_en4_0_cn52xx cn63xx;
+       struct cvmx_ciu_intx_en4_0_cn52xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en4_0_w1c {
@@ -774,6 +1007,8 @@ union cvmx_ciu_intx_en4_0_w1c {
                uint64_t gpio:16;
                uint64_t workq:16;
        } cn58xx;
+       struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xx;
+       struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en4_0_w1s {
@@ -843,12 +1078,42 @@ union cvmx_ciu_intx_en4_0_w1s {
                uint64_t gpio:16;
                uint64_t workq:16;
        } cn58xx;
+       struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xx;
+       struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en4_1 {
        uint64_t u64;
        struct cvmx_ciu_intx_en4_1_s {
-               uint64_t reserved_20_63:44;
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
                uint64_t nand:1;
                uint64_t mii1:1;
                uint64_t usb1:1;
@@ -886,12 +1151,76 @@ union cvmx_ciu_intx_en4_1 {
                uint64_t wdog:16;
        } cn58xx;
        struct cvmx_ciu_intx_en4_1_cn58xx cn58xxp1;
+       struct cvmx_ciu_intx_en4_1_cn63xx {
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
+               uint64_t nand:1;
+               uint64_t mii1:1;
+               uint64_t reserved_6_17:12;
+               uint64_t wdog:6;
+       } cn63xx;
+       struct cvmx_ciu_intx_en4_1_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en4_1_w1c {
        uint64_t u64;
        struct cvmx_ciu_intx_en4_1_w1c_s {
-               uint64_t reserved_20_63:44;
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
                uint64_t nand:1;
                uint64_t mii1:1;
                uint64_t usb1:1;
@@ -915,12 +1244,76 @@ union cvmx_ciu_intx_en4_1_w1c {
                uint64_t reserved_16_63:48;
                uint64_t wdog:16;
        } cn58xx;
+       struct cvmx_ciu_intx_en4_1_w1c_cn63xx {
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
+               uint64_t nand:1;
+               uint64_t mii1:1;
+               uint64_t reserved_6_17:12;
+               uint64_t wdog:6;
+       } cn63xx;
+       struct cvmx_ciu_intx_en4_1_w1c_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_en4_1_w1s {
        uint64_t u64;
        struct cvmx_ciu_intx_en4_1_w1s_s {
-               uint64_t reserved_20_63:44;
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
                uint64_t nand:1;
                uint64_t mii1:1;
                uint64_t usb1:1;
@@ -944,6 +1337,42 @@ union cvmx_ciu_intx_en4_1_w1s {
                uint64_t reserved_16_63:48;
                uint64_t wdog:16;
        } cn58xx;
+       struct cvmx_ciu_intx_en4_1_w1s_cn63xx {
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
+               uint64_t nand:1;
+               uint64_t mii1:1;
+               uint64_t reserved_6_17:12;
+               uint64_t wdog:6;
+       } cn63xx;
+       struct cvmx_ciu_intx_en4_1_w1s_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_sum0 {
@@ -1084,6 +1513,8 @@ union cvmx_ciu_intx_sum0 {
        struct cvmx_ciu_intx_sum0_cn56xx cn56xxp1;
        struct cvmx_ciu_intx_sum0_cn38xx cn58xx;
        struct cvmx_ciu_intx_sum0_cn38xx cn58xxp1;
+       struct cvmx_ciu_intx_sum0_cn52xx cn63xx;
+       struct cvmx_ciu_intx_sum0_cn52xx cn63xxp1;
 };
 
 union cvmx_ciu_intx_sum4 {
@@ -1200,12 +1631,85 @@ union cvmx_ciu_intx_sum4 {
                uint64_t workq:16;
        } cn58xx;
        struct cvmx_ciu_intx_sum4_cn58xx cn58xxp1;
+       struct cvmx_ciu_intx_sum4_cn52xx cn63xx;
+       struct cvmx_ciu_intx_sum4_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_int33_sum0 {
+       uint64_t u64;
+       struct cvmx_ciu_int33_sum0_s {
+               uint64_t bootdma:1;
+               uint64_t mii:1;
+               uint64_t ipdppthr:1;
+               uint64_t powiq:1;
+               uint64_t twsi2:1;
+               uint64_t reserved_57_58:2;
+               uint64_t usb:1;
+               uint64_t timer:4;
+               uint64_t reserved_51_51:1;
+               uint64_t ipd_drp:1;
+               uint64_t reserved_49_49:1;
+               uint64_t gmx_drp:1;
+               uint64_t trace:1;
+               uint64_t rml:1;
+               uint64_t twsi:1;
+               uint64_t wdog_sum:1;
+               uint64_t pci_msi:4;
+               uint64_t pci_int:4;
+               uint64_t uart:2;
+               uint64_t mbox:2;
+               uint64_t gpio:16;
+               uint64_t workq:16;
+       } s;
+       struct cvmx_ciu_int33_sum0_s cn63xx;
+       struct cvmx_ciu_int33_sum0_s cn63xxp1;
+};
+
+union cvmx_ciu_int_dbg_sel {
+       uint64_t u64;
+       struct cvmx_ciu_int_dbg_sel_s {
+               uint64_t reserved_19_63:45;
+               uint64_t sel:3;
+               uint64_t reserved_10_15:6;
+               uint64_t irq:2;
+               uint64_t reserved_3_7:5;
+               uint64_t pp:3;
+       } s;
+       struct cvmx_ciu_int_dbg_sel_s cn63xx;
 };
 
 union cvmx_ciu_int_sum1 {
        uint64_t u64;
        struct cvmx_ciu_int_sum1_s {
-               uint64_t reserved_20_63:44;
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
                uint64_t nand:1;
                uint64_t mii1:1;
                uint64_t usb1:1;
@@ -1250,6 +1754,42 @@ union cvmx_ciu_int_sum1 {
        struct cvmx_ciu_int_sum1_cn56xx cn56xxp1;
        struct cvmx_ciu_int_sum1_cn38xx cn58xx;
        struct cvmx_ciu_int_sum1_cn38xx cn58xxp1;
+       struct cvmx_ciu_int_sum1_cn63xx {
+               uint64_t rst:1;
+               uint64_t reserved_57_62:6;
+               uint64_t dfm:1;
+               uint64_t reserved_53_55:3;
+               uint64_t lmc0:1;
+               uint64_t srio1:1;
+               uint64_t srio0:1;
+               uint64_t pem1:1;
+               uint64_t pem0:1;
+               uint64_t ptp:1;
+               uint64_t agl:1;
+               uint64_t reserved_37_45:9;
+               uint64_t agx0:1;
+               uint64_t dpi:1;
+               uint64_t sli:1;
+               uint64_t usb:1;
+               uint64_t dfa:1;
+               uint64_t key:1;
+               uint64_t rad:1;
+               uint64_t tim:1;
+               uint64_t zip:1;
+               uint64_t pko:1;
+               uint64_t pip:1;
+               uint64_t ipd:1;
+               uint64_t l2c:1;
+               uint64_t pow:1;
+               uint64_t fpa:1;
+               uint64_t iob:1;
+               uint64_t mio:1;
+               uint64_t nand:1;
+               uint64_t mii1:1;
+               uint64_t reserved_6_17:12;
+               uint64_t wdog:6;
+       } cn63xx;
+       struct cvmx_ciu_int_sum1_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_mbox_clrx {
@@ -1269,6 +1809,8 @@ union cvmx_ciu_mbox_clrx {
        struct cvmx_ciu_mbox_clrx_s cn56xxp1;
        struct cvmx_ciu_mbox_clrx_s cn58xx;
        struct cvmx_ciu_mbox_clrx_s cn58xxp1;
+       struct cvmx_ciu_mbox_clrx_s cn63xx;
+       struct cvmx_ciu_mbox_clrx_s cn63xxp1;
 };
 
 union cvmx_ciu_mbox_setx {
@@ -1288,6 +1830,8 @@ union cvmx_ciu_mbox_setx {
        struct cvmx_ciu_mbox_setx_s cn56xxp1;
        struct cvmx_ciu_mbox_setx_s cn58xx;
        struct cvmx_ciu_mbox_setx_s cn58xxp1;
+       struct cvmx_ciu_mbox_setx_s cn63xx;
+       struct cvmx_ciu_mbox_setx_s cn63xxp1;
 };
 
 union cvmx_ciu_nmi {
@@ -1319,6 +1863,11 @@ union cvmx_ciu_nmi {
        struct cvmx_ciu_nmi_cn56xx cn56xxp1;
        struct cvmx_ciu_nmi_s cn58xx;
        struct cvmx_ciu_nmi_s cn58xxp1;
+       struct cvmx_ciu_nmi_cn63xx {
+               uint64_t reserved_6_63:58;
+               uint64_t nmi:6;
+       } cn63xx;
+       struct cvmx_ciu_nmi_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_pci_inta {
@@ -1338,6 +1887,8 @@ union cvmx_ciu_pci_inta {
        struct cvmx_ciu_pci_inta_s cn56xxp1;
        struct cvmx_ciu_pci_inta_s cn58xx;
        struct cvmx_ciu_pci_inta_s cn58xxp1;
+       struct cvmx_ciu_pci_inta_s cn63xx;
+       struct cvmx_ciu_pci_inta_s cn63xxp1;
 };
 
 union cvmx_ciu_pp_dbg {
@@ -1369,12 +1920,17 @@ union cvmx_ciu_pp_dbg {
        struct cvmx_ciu_pp_dbg_cn56xx cn56xxp1;
        struct cvmx_ciu_pp_dbg_s cn58xx;
        struct cvmx_ciu_pp_dbg_s cn58xxp1;
+       struct cvmx_ciu_pp_dbg_cn63xx {
+               uint64_t reserved_6_63:58;
+               uint64_t ppdbg:6;
+       } cn63xx;
+       struct cvmx_ciu_pp_dbg_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_pp_pokex {
        uint64_t u64;
        struct cvmx_ciu_pp_pokex_s {
-               uint64_t reserved_0_63:64;
+               uint64_t poke:64;
        } s;
        struct cvmx_ciu_pp_pokex_s cn30xx;
        struct cvmx_ciu_pp_pokex_s cn31xx;
@@ -1387,6 +1943,8 @@ union cvmx_ciu_pp_pokex {
        struct cvmx_ciu_pp_pokex_s cn56xxp1;
        struct cvmx_ciu_pp_pokex_s cn58xx;
        struct cvmx_ciu_pp_pokex_s cn58xxp1;
+       struct cvmx_ciu_pp_pokex_s cn63xx;
+       struct cvmx_ciu_pp_pokex_s cn63xxp1;
 };
 
 union cvmx_ciu_pp_rst {
@@ -1422,6 +1980,97 @@ union cvmx_ciu_pp_rst {
        struct cvmx_ciu_pp_rst_cn56xx cn56xxp1;
        struct cvmx_ciu_pp_rst_s cn58xx;
        struct cvmx_ciu_pp_rst_s cn58xxp1;
+       struct cvmx_ciu_pp_rst_cn63xx {
+               uint64_t reserved_6_63:58;
+               uint64_t rst:5;
+               uint64_t rst0:1;
+       } cn63xx;
+       struct cvmx_ciu_pp_rst_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_qlm0 {
+       uint64_t u64;
+       struct cvmx_ciu_qlm0_s {
+               uint64_t g2bypass:1;
+               uint64_t reserved_53_62:10;
+               uint64_t g2deemph:5;
+               uint64_t reserved_45_47:3;
+               uint64_t g2margin:5;
+               uint64_t reserved_32_39:8;
+               uint64_t txbypass:1;
+               uint64_t reserved_21_30:10;
+               uint64_t txdeemph:5;
+               uint64_t reserved_13_15:3;
+               uint64_t txmargin:5;
+               uint64_t reserved_4_7:4;
+               uint64_t lane_en:4;
+       } s;
+       struct cvmx_ciu_qlm0_s cn63xx;
+       struct cvmx_ciu_qlm0_cn63xxp1 {
+               uint64_t reserved_32_63:32;
+               uint64_t txbypass:1;
+               uint64_t reserved_20_30:11;
+               uint64_t txdeemph:4;
+               uint64_t reserved_13_15:3;
+               uint64_t txmargin:5;
+               uint64_t reserved_4_7:4;
+               uint64_t lane_en:4;
+       } cn63xxp1;
+};
+
+union cvmx_ciu_qlm1 {
+       uint64_t u64;
+       struct cvmx_ciu_qlm1_s {
+               uint64_t g2bypass:1;
+               uint64_t reserved_53_62:10;
+               uint64_t g2deemph:5;
+               uint64_t reserved_45_47:3;
+               uint64_t g2margin:5;
+               uint64_t reserved_32_39:8;
+               uint64_t txbypass:1;
+               uint64_t reserved_21_30:10;
+               uint64_t txdeemph:5;
+               uint64_t reserved_13_15:3;
+               uint64_t txmargin:5;
+               uint64_t reserved_4_7:4;
+               uint64_t lane_en:4;
+       } s;
+       struct cvmx_ciu_qlm1_s cn63xx;
+       struct cvmx_ciu_qlm1_cn63xxp1 {
+               uint64_t reserved_32_63:32;
+               uint64_t txbypass:1;
+               uint64_t reserved_20_30:11;
+               uint64_t txdeemph:4;
+               uint64_t reserved_13_15:3;
+               uint64_t txmargin:5;
+               uint64_t reserved_4_7:4;
+               uint64_t lane_en:4;
+       } cn63xxp1;
+};
+
+union cvmx_ciu_qlm2 {
+       uint64_t u64;
+       struct cvmx_ciu_qlm2_s {
+               uint64_t reserved_32_63:32;
+               uint64_t txbypass:1;
+               uint64_t reserved_21_30:10;
+               uint64_t txdeemph:5;
+               uint64_t reserved_13_15:3;
+               uint64_t txmargin:5;
+               uint64_t reserved_4_7:4;
+               uint64_t lane_en:4;
+       } s;
+       struct cvmx_ciu_qlm2_s cn63xx;
+       struct cvmx_ciu_qlm2_cn63xxp1 {
+               uint64_t reserved_32_63:32;
+               uint64_t txbypass:1;
+               uint64_t reserved_20_30:11;
+               uint64_t txdeemph:4;
+               uint64_t reserved_13_15:3;
+               uint64_t txmargin:5;
+               uint64_t reserved_4_7:4;
+               uint64_t lane_en:4;
+       } cn63xxp1;
 };
 
 union cvmx_ciu_qlm_dcok {
@@ -1459,6 +2108,15 @@ union cvmx_ciu_qlm_jtgc {
        struct cvmx_ciu_qlm_jtgc_cn52xx cn52xxp1;
        struct cvmx_ciu_qlm_jtgc_s cn56xx;
        struct cvmx_ciu_qlm_jtgc_s cn56xxp1;
+       struct cvmx_ciu_qlm_jtgc_cn63xx {
+               uint64_t reserved_11_63:53;
+               uint64_t clk_div:3;
+               uint64_t reserved_6_7:2;
+               uint64_t mux_sel:2;
+               uint64_t reserved_3_3:1;
+               uint64_t bypass:3;
+       } cn63xx;
+       struct cvmx_ciu_qlm_jtgc_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_qlm_jtgd {
@@ -1493,6 +2151,17 @@ union cvmx_ciu_qlm_jtgd {
                uint64_t shft_cnt:5;
                uint64_t shft_reg:32;
        } cn56xxp1;
+       struct cvmx_ciu_qlm_jtgd_cn63xx {
+               uint64_t capture:1;
+               uint64_t shift:1;
+               uint64_t update:1;
+               uint64_t reserved_43_60:18;
+               uint64_t select:3;
+               uint64_t reserved_37_39:3;
+               uint64_t shft_cnt:5;
+               uint64_t shft_reg:32;
+       } cn63xx;
+       struct cvmx_ciu_qlm_jtgd_cn63xx cn63xxp1;
 };
 
 union cvmx_ciu_soft_bist {
@@ -1512,6 +2181,8 @@ union cvmx_ciu_soft_bist {
        struct cvmx_ciu_soft_bist_s cn56xxp1;
        struct cvmx_ciu_soft_bist_s cn58xx;
        struct cvmx_ciu_soft_bist_s cn58xxp1;
+       struct cvmx_ciu_soft_bist_s cn63xx;
+       struct cvmx_ciu_soft_bist_s cn63xxp1;
 };
 
 union cvmx_ciu_soft_prst {
@@ -1536,6 +2207,8 @@ union cvmx_ciu_soft_prst {
        struct cvmx_ciu_soft_prst_cn52xx cn56xxp1;
        struct cvmx_ciu_soft_prst_s cn58xx;
        struct cvmx_ciu_soft_prst_s cn58xxp1;
+       struct cvmx_ciu_soft_prst_cn52xx cn63xx;
+       struct cvmx_ciu_soft_prst_cn52xx cn63xxp1;
 };
 
 union cvmx_ciu_soft_prst1 {
@@ -1548,6 +2221,8 @@ union cvmx_ciu_soft_prst1 {
        struct cvmx_ciu_soft_prst1_s cn52xxp1;
        struct cvmx_ciu_soft_prst1_s cn56xx;
        struct cvmx_ciu_soft_prst1_s cn56xxp1;
+       struct cvmx_ciu_soft_prst1_s cn63xx;
+       struct cvmx_ciu_soft_prst1_s cn63xxp1;
 };
 
 union cvmx_ciu_soft_rst {
@@ -1567,6 +2242,8 @@ union cvmx_ciu_soft_rst {
        struct cvmx_ciu_soft_rst_s cn56xxp1;
        struct cvmx_ciu_soft_rst_s cn58xx;
        struct cvmx_ciu_soft_rst_s cn58xxp1;
+       struct cvmx_ciu_soft_rst_s cn63xx;
+       struct cvmx_ciu_soft_rst_s cn63xxp1;
 };
 
 union cvmx_ciu_timx {
@@ -1587,6 +2264,8 @@ union cvmx_ciu_timx {
        struct cvmx_ciu_timx_s cn56xxp1;
        struct cvmx_ciu_timx_s cn58xx;
        struct cvmx_ciu_timx_s cn58xxp1;
+       struct cvmx_ciu_timx_s cn63xx;
+       struct cvmx_ciu_timx_s cn63xxp1;
 };
 
 union cvmx_ciu_wdogx {
@@ -1611,6 +2290,8 @@ union cvmx_ciu_wdogx {
        struct cvmx_ciu_wdogx_s cn56xxp1;
        struct cvmx_ciu_wdogx_s cn58xx;
        struct cvmx_ciu_wdogx_s cn58xxp1;
+       struct cvmx_ciu_wdogx_s cn63xx;
+       struct cvmx_ciu_wdogx_s cn63xxp1;
 };
 
 #endif
index 5fdd6ba48a05b5ecf7d69ba5d850031d6770f3c4..395564e8d1f08d9b4b6db48d25a87c95e297d941 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_GPIO_DEFS_H__
 #define __CVMX_GPIO_DEFS_H__
 
-#define CVMX_GPIO_BIT_CFGX(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000800ull + (((offset) & 15) * 8))
-#define CVMX_GPIO_BOOT_ENA \
-        CVMX_ADD_IO_SEG(0x00010700000008A8ull)
-#define CVMX_GPIO_CLK_GENX(offset) \
-        CVMX_ADD_IO_SEG(0x00010700000008C0ull + (((offset) & 3) * 8))
-#define CVMX_GPIO_DBG_ENA \
-        CVMX_ADD_IO_SEG(0x00010700000008A0ull)
-#define CVMX_GPIO_INT_CLR \
-        CVMX_ADD_IO_SEG(0x0001070000000898ull)
-#define CVMX_GPIO_RX_DAT \
-        CVMX_ADD_IO_SEG(0x0001070000000880ull)
-#define CVMX_GPIO_TX_CLR \
-        CVMX_ADD_IO_SEG(0x0001070000000890ull)
-#define CVMX_GPIO_TX_SET \
-        CVMX_ADD_IO_SEG(0x0001070000000888ull)
-#define CVMX_GPIO_XBIT_CFGX(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000000900ull + (((offset) & 31) * 8) - 8 * 16)
+#define CVMX_GPIO_BIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000800ull) + ((offset) & 15) * 8)
+#define CVMX_GPIO_BOOT_ENA (CVMX_ADD_IO_SEG(0x00010700000008A8ull))
+#define CVMX_GPIO_CLK_GENX(offset) (CVMX_ADD_IO_SEG(0x00010700000008C0ull) + ((offset) & 3) * 8)
+#define CVMX_GPIO_CLK_QLMX(offset) (CVMX_ADD_IO_SEG(0x00010700000008E0ull) + ((offset) & 1) * 8)
+#define CVMX_GPIO_DBG_ENA (CVMX_ADD_IO_SEG(0x00010700000008A0ull))
+#define CVMX_GPIO_INT_CLR (CVMX_ADD_IO_SEG(0x0001070000000898ull))
+#define CVMX_GPIO_RX_DAT (CVMX_ADD_IO_SEG(0x0001070000000880ull))
+#define CVMX_GPIO_TX_CLR (CVMX_ADD_IO_SEG(0x0001070000000890ull))
+#define CVMX_GPIO_TX_SET (CVMX_ADD_IO_SEG(0x0001070000000888ull))
+#define CVMX_GPIO_XBIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000900ull) + ((offset) & 31) * 8 - 8*16)
 
 union cvmx_gpio_bit_cfgx {
        uint64_t u64;
        struct cvmx_gpio_bit_cfgx_s {
-               uint64_t reserved_15_63:49;
+               uint64_t reserved_17_63:47;
+               uint64_t synce_sel:2;
                uint64_t clk_gen:1;
                uint64_t clk_sel:2;
                uint64_t fil_sel:4;
@@ -73,12 +66,24 @@ union cvmx_gpio_bit_cfgx {
        struct cvmx_gpio_bit_cfgx_cn30xx cn38xx;
        struct cvmx_gpio_bit_cfgx_cn30xx cn38xxp2;
        struct cvmx_gpio_bit_cfgx_cn30xx cn50xx;
-       struct cvmx_gpio_bit_cfgx_s cn52xx;
-       struct cvmx_gpio_bit_cfgx_s cn52xxp1;
-       struct cvmx_gpio_bit_cfgx_s cn56xx;
-       struct cvmx_gpio_bit_cfgx_s cn56xxp1;
+       struct cvmx_gpio_bit_cfgx_cn52xx {
+               uint64_t reserved_15_63:49;
+               uint64_t clk_gen:1;
+               uint64_t clk_sel:2;
+               uint64_t fil_sel:4;
+               uint64_t fil_cnt:4;
+               uint64_t int_type:1;
+               uint64_t int_en:1;
+               uint64_t rx_xor:1;
+               uint64_t tx_oe:1;
+       } cn52xx;
+       struct cvmx_gpio_bit_cfgx_cn52xx cn52xxp1;
+       struct cvmx_gpio_bit_cfgx_cn52xx cn56xx;
+       struct cvmx_gpio_bit_cfgx_cn52xx cn56xxp1;
        struct cvmx_gpio_bit_cfgx_cn30xx cn58xx;
        struct cvmx_gpio_bit_cfgx_cn30xx cn58xxp1;
+       struct cvmx_gpio_bit_cfgx_s cn63xx;
+       struct cvmx_gpio_bit_cfgx_s cn63xxp1;
 };
 
 union cvmx_gpio_boot_ena {
@@ -103,6 +108,19 @@ union cvmx_gpio_clk_genx {
        struct cvmx_gpio_clk_genx_s cn52xxp1;
        struct cvmx_gpio_clk_genx_s cn56xx;
        struct cvmx_gpio_clk_genx_s cn56xxp1;
+       struct cvmx_gpio_clk_genx_s cn63xx;
+       struct cvmx_gpio_clk_genx_s cn63xxp1;
+};
+
+union cvmx_gpio_clk_qlmx {
+       uint64_t u64;
+       struct cvmx_gpio_clk_qlmx_s {
+               uint64_t reserved_3_63:61;
+               uint64_t div:1;
+               uint64_t lane_sel:2;
+       } s;
+       struct cvmx_gpio_clk_qlmx_s cn63xx;
+       struct cvmx_gpio_clk_qlmx_s cn63xxp1;
 };
 
 union cvmx_gpio_dbg_ena {
@@ -133,6 +151,8 @@ union cvmx_gpio_int_clr {
        struct cvmx_gpio_int_clr_s cn56xxp1;
        struct cvmx_gpio_int_clr_s cn58xx;
        struct cvmx_gpio_int_clr_s cn58xxp1;
+       struct cvmx_gpio_int_clr_s cn63xx;
+       struct cvmx_gpio_int_clr_s cn63xxp1;
 };
 
 union cvmx_gpio_rx_dat {
@@ -155,6 +175,8 @@ union cvmx_gpio_rx_dat {
        struct cvmx_gpio_rx_dat_cn38xx cn56xxp1;
        struct cvmx_gpio_rx_dat_cn38xx cn58xx;
        struct cvmx_gpio_rx_dat_cn38xx cn58xxp1;
+       struct cvmx_gpio_rx_dat_cn38xx cn63xx;
+       struct cvmx_gpio_rx_dat_cn38xx cn63xxp1;
 };
 
 union cvmx_gpio_tx_clr {
@@ -177,6 +199,8 @@ union cvmx_gpio_tx_clr {
        struct cvmx_gpio_tx_clr_cn38xx cn56xxp1;
        struct cvmx_gpio_tx_clr_cn38xx cn58xx;
        struct cvmx_gpio_tx_clr_cn38xx cn58xxp1;
+       struct cvmx_gpio_tx_clr_cn38xx cn63xx;
+       struct cvmx_gpio_tx_clr_cn38xx cn63xxp1;
 };
 
 union cvmx_gpio_tx_set {
@@ -199,6 +223,8 @@ union cvmx_gpio_tx_set {
        struct cvmx_gpio_tx_set_cn38xx cn56xxp1;
        struct cvmx_gpio_tx_set_cn38xx cn58xx;
        struct cvmx_gpio_tx_set_cn38xx cn58xxp1;
+       struct cvmx_gpio_tx_set_cn38xx cn63xx;
+       struct cvmx_gpio_tx_set_cn38xx cn63xxp1;
 };
 
 union cvmx_gpio_xbit_cfgx {
index 0ee36baec5000f508627a4bae5e0e5411506d42e..d7d856c2483d5fcb53e847f055d816440fc54f97 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_IOB_DEFS_H__
 #define __CVMX_IOB_DEFS_H__
 
-#define CVMX_IOB_BIST_STATUS \
-        CVMX_ADD_IO_SEG(0x00011800F00007F8ull)
-#define CVMX_IOB_CTL_STATUS \
-        CVMX_ADD_IO_SEG(0x00011800F0000050ull)
-#define CVMX_IOB_DWB_PRI_CNT \
-        CVMX_ADD_IO_SEG(0x00011800F0000028ull)
-#define CVMX_IOB_FAU_TIMEOUT \
-        CVMX_ADD_IO_SEG(0x00011800F0000000ull)
-#define CVMX_IOB_I2C_PRI_CNT \
-        CVMX_ADD_IO_SEG(0x00011800F0000010ull)
-#define CVMX_IOB_INB_CONTROL_MATCH \
-        CVMX_ADD_IO_SEG(0x00011800F0000078ull)
-#define CVMX_IOB_INB_CONTROL_MATCH_ENB \
-        CVMX_ADD_IO_SEG(0x00011800F0000088ull)
-#define CVMX_IOB_INB_DATA_MATCH \
-        CVMX_ADD_IO_SEG(0x00011800F0000070ull)
-#define CVMX_IOB_INB_DATA_MATCH_ENB \
-        CVMX_ADD_IO_SEG(0x00011800F0000080ull)
-#define CVMX_IOB_INT_ENB \
-        CVMX_ADD_IO_SEG(0x00011800F0000060ull)
-#define CVMX_IOB_INT_SUM \
-        CVMX_ADD_IO_SEG(0x00011800F0000058ull)
-#define CVMX_IOB_N2C_L2C_PRI_CNT \
-        CVMX_ADD_IO_SEG(0x00011800F0000020ull)
-#define CVMX_IOB_N2C_RSP_PRI_CNT \
-        CVMX_ADD_IO_SEG(0x00011800F0000008ull)
-#define CVMX_IOB_OUTB_COM_PRI_CNT \
-        CVMX_ADD_IO_SEG(0x00011800F0000040ull)
-#define CVMX_IOB_OUTB_CONTROL_MATCH \
-        CVMX_ADD_IO_SEG(0x00011800F0000098ull)
-#define CVMX_IOB_OUTB_CONTROL_MATCH_ENB \
-        CVMX_ADD_IO_SEG(0x00011800F00000A8ull)
-#define CVMX_IOB_OUTB_DATA_MATCH \
-        CVMX_ADD_IO_SEG(0x00011800F0000090ull)
-#define CVMX_IOB_OUTB_DATA_MATCH_ENB \
-        CVMX_ADD_IO_SEG(0x00011800F00000A0ull)
-#define CVMX_IOB_OUTB_FPA_PRI_CNT \
-        CVMX_ADD_IO_SEG(0x00011800F0000048ull)
-#define CVMX_IOB_OUTB_REQ_PRI_CNT \
-        CVMX_ADD_IO_SEG(0x00011800F0000038ull)
-#define CVMX_IOB_P2C_REQ_PRI_CNT \
-        CVMX_ADD_IO_SEG(0x00011800F0000018ull)
-#define CVMX_IOB_PKT_ERR \
-        CVMX_ADD_IO_SEG(0x00011800F0000068ull)
+#define CVMX_IOB_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011800F00007F8ull))
+#define CVMX_IOB_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011800F0000050ull))
+#define CVMX_IOB_DWB_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000028ull))
+#define CVMX_IOB_FAU_TIMEOUT (CVMX_ADD_IO_SEG(0x00011800F0000000ull))
+#define CVMX_IOB_I2C_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000010ull))
+#define CVMX_IOB_INB_CONTROL_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000078ull))
+#define CVMX_IOB_INB_CONTROL_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F0000088ull))
+#define CVMX_IOB_INB_DATA_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000070ull))
+#define CVMX_IOB_INB_DATA_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F0000080ull))
+#define CVMX_IOB_INT_ENB (CVMX_ADD_IO_SEG(0x00011800F0000060ull))
+#define CVMX_IOB_INT_SUM (CVMX_ADD_IO_SEG(0x00011800F0000058ull))
+#define CVMX_IOB_N2C_L2C_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000020ull))
+#define CVMX_IOB_N2C_RSP_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000008ull))
+#define CVMX_IOB_OUTB_COM_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000040ull))
+#define CVMX_IOB_OUTB_CONTROL_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000098ull))
+#define CVMX_IOB_OUTB_CONTROL_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F00000A8ull))
+#define CVMX_IOB_OUTB_DATA_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000090ull))
+#define CVMX_IOB_OUTB_DATA_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F00000A0ull))
+#define CVMX_IOB_OUTB_FPA_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000048ull))
+#define CVMX_IOB_OUTB_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000038ull))
+#define CVMX_IOB_P2C_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000018ull))
+#define CVMX_IOB_PKT_ERR (CVMX_ADD_IO_SEG(0x00011800F0000068ull))
+#define CVMX_IOB_TO_CMB_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00000B0ull))
 
 union cvmx_iob_bist_status {
        uint64_t u64;
        struct cvmx_iob_bist_status_s {
-               uint64_t reserved_18_63:46;
+               uint64_t reserved_23_63:41;
+               uint64_t xmdfif:1;
+               uint64_t xmcfif:1;
+               uint64_t iorfif:1;
+               uint64_t rsdfif:1;
+               uint64_t iocfif:1;
                uint64_t icnrcb:1;
                uint64_t icr0:1;
                uint64_t icr1:1;
@@ -96,40 +80,81 @@ union cvmx_iob_bist_status {
                uint64_t ibd:1;
                uint64_t icd:1;
        } s;
-       struct cvmx_iob_bist_status_s cn30xx;
-       struct cvmx_iob_bist_status_s cn31xx;
-       struct cvmx_iob_bist_status_s cn38xx;
-       struct cvmx_iob_bist_status_s cn38xxp2;
-       struct cvmx_iob_bist_status_s cn50xx;
-       struct cvmx_iob_bist_status_s cn52xx;
-       struct cvmx_iob_bist_status_s cn52xxp1;
-       struct cvmx_iob_bist_status_s cn56xx;
-       struct cvmx_iob_bist_status_s cn56xxp1;
-       struct cvmx_iob_bist_status_s cn58xx;
-       struct cvmx_iob_bist_status_s cn58xxp1;
+       struct cvmx_iob_bist_status_cn30xx {
+               uint64_t reserved_18_63:46;
+               uint64_t icnrcb:1;
+               uint64_t icr0:1;
+               uint64_t icr1:1;
+               uint64_t icnr1:1;
+               uint64_t icnr0:1;
+               uint64_t ibdr0:1;
+               uint64_t ibdr1:1;
+               uint64_t ibr0:1;
+               uint64_t ibr1:1;
+               uint64_t icnrt:1;
+               uint64_t ibrq0:1;
+               uint64_t ibrq1:1;
+               uint64_t icrn0:1;
+               uint64_t icrn1:1;
+               uint64_t icrp0:1;
+               uint64_t icrp1:1;
+               uint64_t ibd:1;
+               uint64_t icd:1;
+       } cn30xx;
+       struct cvmx_iob_bist_status_cn30xx cn31xx;
+       struct cvmx_iob_bist_status_cn30xx cn38xx;
+       struct cvmx_iob_bist_status_cn30xx cn38xxp2;
+       struct cvmx_iob_bist_status_cn30xx cn50xx;
+       struct cvmx_iob_bist_status_cn30xx cn52xx;
+       struct cvmx_iob_bist_status_cn30xx cn52xxp1;
+       struct cvmx_iob_bist_status_cn30xx cn56xx;
+       struct cvmx_iob_bist_status_cn30xx cn56xxp1;
+       struct cvmx_iob_bist_status_cn30xx cn58xx;
+       struct cvmx_iob_bist_status_cn30xx cn58xxp1;
+       struct cvmx_iob_bist_status_s cn63xx;
+       struct cvmx_iob_bist_status_s cn63xxp1;
 };
 
 union cvmx_iob_ctl_status {
        uint64_t u64;
        struct cvmx_iob_ctl_status_s {
-               uint64_t reserved_5_63:59;
+               uint64_t reserved_10_63:54;
+               uint64_t xmc_per:4;
+               uint64_t rr_mode:1;
                uint64_t outb_mat:1;
                uint64_t inb_mat:1;
                uint64_t pko_enb:1;
                uint64_t dwb_enb:1;
                uint64_t fau_end:1;
        } s;
-       struct cvmx_iob_ctl_status_s cn30xx;
-       struct cvmx_iob_ctl_status_s cn31xx;
-       struct cvmx_iob_ctl_status_s cn38xx;
-       struct cvmx_iob_ctl_status_s cn38xxp2;
-       struct cvmx_iob_ctl_status_s cn50xx;
-       struct cvmx_iob_ctl_status_s cn52xx;
-       struct cvmx_iob_ctl_status_s cn52xxp1;
-       struct cvmx_iob_ctl_status_s cn56xx;
-       struct cvmx_iob_ctl_status_s cn56xxp1;
-       struct cvmx_iob_ctl_status_s cn58xx;
-       struct cvmx_iob_ctl_status_s cn58xxp1;
+       struct cvmx_iob_ctl_status_cn30xx {
+               uint64_t reserved_5_63:59;
+               uint64_t outb_mat:1;
+               uint64_t inb_mat:1;
+               uint64_t pko_enb:1;
+               uint64_t dwb_enb:1;
+               uint64_t fau_end:1;
+       } cn30xx;
+       struct cvmx_iob_ctl_status_cn30xx cn31xx;
+       struct cvmx_iob_ctl_status_cn30xx cn38xx;
+       struct cvmx_iob_ctl_status_cn30xx cn38xxp2;
+       struct cvmx_iob_ctl_status_cn30xx cn50xx;
+       struct cvmx_iob_ctl_status_cn52xx {
+               uint64_t reserved_6_63:58;
+               uint64_t rr_mode:1;
+               uint64_t outb_mat:1;
+               uint64_t inb_mat:1;
+               uint64_t pko_enb:1;
+               uint64_t dwb_enb:1;
+               uint64_t fau_end:1;
+       } cn52xx;
+       struct cvmx_iob_ctl_status_cn30xx cn52xxp1;
+       struct cvmx_iob_ctl_status_cn30xx cn56xx;
+       struct cvmx_iob_ctl_status_cn30xx cn56xxp1;
+       struct cvmx_iob_ctl_status_cn30xx cn58xx;
+       struct cvmx_iob_ctl_status_cn30xx cn58xxp1;
+       struct cvmx_iob_ctl_status_s cn63xx;
+       struct cvmx_iob_ctl_status_s cn63xxp1;
 };
 
 union cvmx_iob_dwb_pri_cnt {
@@ -147,6 +172,8 @@ union cvmx_iob_dwb_pri_cnt {
        struct cvmx_iob_dwb_pri_cnt_s cn56xxp1;
        struct cvmx_iob_dwb_pri_cnt_s cn58xx;
        struct cvmx_iob_dwb_pri_cnt_s cn58xxp1;
+       struct cvmx_iob_dwb_pri_cnt_s cn63xx;
+       struct cvmx_iob_dwb_pri_cnt_s cn63xxp1;
 };
 
 union cvmx_iob_fau_timeout {
@@ -167,6 +194,8 @@ union cvmx_iob_fau_timeout {
        struct cvmx_iob_fau_timeout_s cn56xxp1;
        struct cvmx_iob_fau_timeout_s cn58xx;
        struct cvmx_iob_fau_timeout_s cn58xxp1;
+       struct cvmx_iob_fau_timeout_s cn63xx;
+       struct cvmx_iob_fau_timeout_s cn63xxp1;
 };
 
 union cvmx_iob_i2c_pri_cnt {
@@ -184,6 +213,8 @@ union cvmx_iob_i2c_pri_cnt {
        struct cvmx_iob_i2c_pri_cnt_s cn56xxp1;
        struct cvmx_iob_i2c_pri_cnt_s cn58xx;
        struct cvmx_iob_i2c_pri_cnt_s cn58xxp1;
+       struct cvmx_iob_i2c_pri_cnt_s cn63xx;
+       struct cvmx_iob_i2c_pri_cnt_s cn63xxp1;
 };
 
 union cvmx_iob_inb_control_match {
@@ -206,6 +237,8 @@ union cvmx_iob_inb_control_match {
        struct cvmx_iob_inb_control_match_s cn56xxp1;
        struct cvmx_iob_inb_control_match_s cn58xx;
        struct cvmx_iob_inb_control_match_s cn58xxp1;
+       struct cvmx_iob_inb_control_match_s cn63xx;
+       struct cvmx_iob_inb_control_match_s cn63xxp1;
 };
 
 union cvmx_iob_inb_control_match_enb {
@@ -228,6 +261,8 @@ union cvmx_iob_inb_control_match_enb {
        struct cvmx_iob_inb_control_match_enb_s cn56xxp1;
        struct cvmx_iob_inb_control_match_enb_s cn58xx;
        struct cvmx_iob_inb_control_match_enb_s cn58xxp1;
+       struct cvmx_iob_inb_control_match_enb_s cn63xx;
+       struct cvmx_iob_inb_control_match_enb_s cn63xxp1;
 };
 
 union cvmx_iob_inb_data_match {
@@ -246,6 +281,8 @@ union cvmx_iob_inb_data_match {
        struct cvmx_iob_inb_data_match_s cn56xxp1;
        struct cvmx_iob_inb_data_match_s cn58xx;
        struct cvmx_iob_inb_data_match_s cn58xxp1;
+       struct cvmx_iob_inb_data_match_s cn63xx;
+       struct cvmx_iob_inb_data_match_s cn63xxp1;
 };
 
 union cvmx_iob_inb_data_match_enb {
@@ -264,6 +301,8 @@ union cvmx_iob_inb_data_match_enb {
        struct cvmx_iob_inb_data_match_enb_s cn56xxp1;
        struct cvmx_iob_inb_data_match_enb_s cn58xx;
        struct cvmx_iob_inb_data_match_enb_s cn58xxp1;
+       struct cvmx_iob_inb_data_match_enb_s cn63xx;
+       struct cvmx_iob_inb_data_match_enb_s cn63xxp1;
 };
 
 union cvmx_iob_int_enb {
@@ -294,6 +333,8 @@ union cvmx_iob_int_enb {
        struct cvmx_iob_int_enb_s cn56xxp1;
        struct cvmx_iob_int_enb_s cn58xx;
        struct cvmx_iob_int_enb_s cn58xxp1;
+       struct cvmx_iob_int_enb_s cn63xx;
+       struct cvmx_iob_int_enb_s cn63xxp1;
 };
 
 union cvmx_iob_int_sum {
@@ -324,6 +365,8 @@ union cvmx_iob_int_sum {
        struct cvmx_iob_int_sum_s cn56xxp1;
        struct cvmx_iob_int_sum_s cn58xx;
        struct cvmx_iob_int_sum_s cn58xxp1;
+       struct cvmx_iob_int_sum_s cn63xx;
+       struct cvmx_iob_int_sum_s cn63xxp1;
 };
 
 union cvmx_iob_n2c_l2c_pri_cnt {
@@ -341,6 +384,8 @@ union cvmx_iob_n2c_l2c_pri_cnt {
        struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xxp1;
        struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xx;
        struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xxp1;
+       struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xx;
+       struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xxp1;
 };
 
 union cvmx_iob_n2c_rsp_pri_cnt {
@@ -358,6 +403,8 @@ union cvmx_iob_n2c_rsp_pri_cnt {
        struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xxp1;
        struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xx;
        struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xxp1;
+       struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xx;
+       struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xxp1;
 };
 
 union cvmx_iob_outb_com_pri_cnt {
@@ -375,6 +422,8 @@ union cvmx_iob_outb_com_pri_cnt {
        struct cvmx_iob_outb_com_pri_cnt_s cn56xxp1;
        struct cvmx_iob_outb_com_pri_cnt_s cn58xx;
        struct cvmx_iob_outb_com_pri_cnt_s cn58xxp1;
+       struct cvmx_iob_outb_com_pri_cnt_s cn63xx;
+       struct cvmx_iob_outb_com_pri_cnt_s cn63xxp1;
 };
 
 union cvmx_iob_outb_control_match {
@@ -397,6 +446,8 @@ union cvmx_iob_outb_control_match {
        struct cvmx_iob_outb_control_match_s cn56xxp1;
        struct cvmx_iob_outb_control_match_s cn58xx;
        struct cvmx_iob_outb_control_match_s cn58xxp1;
+       struct cvmx_iob_outb_control_match_s cn63xx;
+       struct cvmx_iob_outb_control_match_s cn63xxp1;
 };
 
 union cvmx_iob_outb_control_match_enb {
@@ -419,6 +470,8 @@ union cvmx_iob_outb_control_match_enb {
        struct cvmx_iob_outb_control_match_enb_s cn56xxp1;
        struct cvmx_iob_outb_control_match_enb_s cn58xx;
        struct cvmx_iob_outb_control_match_enb_s cn58xxp1;
+       struct cvmx_iob_outb_control_match_enb_s cn63xx;
+       struct cvmx_iob_outb_control_match_enb_s cn63xxp1;
 };
 
 union cvmx_iob_outb_data_match {
@@ -437,6 +490,8 @@ union cvmx_iob_outb_data_match {
        struct cvmx_iob_outb_data_match_s cn56xxp1;
        struct cvmx_iob_outb_data_match_s cn58xx;
        struct cvmx_iob_outb_data_match_s cn58xxp1;
+       struct cvmx_iob_outb_data_match_s cn63xx;
+       struct cvmx_iob_outb_data_match_s cn63xxp1;
 };
 
 union cvmx_iob_outb_data_match_enb {
@@ -455,6 +510,8 @@ union cvmx_iob_outb_data_match_enb {
        struct cvmx_iob_outb_data_match_enb_s cn56xxp1;
        struct cvmx_iob_outb_data_match_enb_s cn58xx;
        struct cvmx_iob_outb_data_match_enb_s cn58xxp1;
+       struct cvmx_iob_outb_data_match_enb_s cn63xx;
+       struct cvmx_iob_outb_data_match_enb_s cn63xxp1;
 };
 
 union cvmx_iob_outb_fpa_pri_cnt {
@@ -472,6 +529,8 @@ union cvmx_iob_outb_fpa_pri_cnt {
        struct cvmx_iob_outb_fpa_pri_cnt_s cn56xxp1;
        struct cvmx_iob_outb_fpa_pri_cnt_s cn58xx;
        struct cvmx_iob_outb_fpa_pri_cnt_s cn58xxp1;
+       struct cvmx_iob_outb_fpa_pri_cnt_s cn63xx;
+       struct cvmx_iob_outb_fpa_pri_cnt_s cn63xxp1;
 };
 
 union cvmx_iob_outb_req_pri_cnt {
@@ -489,6 +548,8 @@ union cvmx_iob_outb_req_pri_cnt {
        struct cvmx_iob_outb_req_pri_cnt_s cn56xxp1;
        struct cvmx_iob_outb_req_pri_cnt_s cn58xx;
        struct cvmx_iob_outb_req_pri_cnt_s cn58xxp1;
+       struct cvmx_iob_outb_req_pri_cnt_s cn63xx;
+       struct cvmx_iob_outb_req_pri_cnt_s cn63xxp1;
 };
 
 union cvmx_iob_p2c_req_pri_cnt {
@@ -506,25 +567,46 @@ union cvmx_iob_p2c_req_pri_cnt {
        struct cvmx_iob_p2c_req_pri_cnt_s cn56xxp1;
        struct cvmx_iob_p2c_req_pri_cnt_s cn58xx;
        struct cvmx_iob_p2c_req_pri_cnt_s cn58xxp1;
+       struct cvmx_iob_p2c_req_pri_cnt_s cn63xx;
+       struct cvmx_iob_p2c_req_pri_cnt_s cn63xxp1;
 };
 
 union cvmx_iob_pkt_err {
        uint64_t u64;
        struct cvmx_iob_pkt_err_s {
+               uint64_t reserved_12_63:52;
+               uint64_t vport:6;
+               uint64_t port:6;
+       } s;
+       struct cvmx_iob_pkt_err_cn30xx {
                uint64_t reserved_6_63:58;
                uint64_t port:6;
+       } cn30xx;
+       struct cvmx_iob_pkt_err_cn30xx cn31xx;
+       struct cvmx_iob_pkt_err_cn30xx cn38xx;
+       struct cvmx_iob_pkt_err_cn30xx cn38xxp2;
+       struct cvmx_iob_pkt_err_cn30xx cn50xx;
+       struct cvmx_iob_pkt_err_cn30xx cn52xx;
+       struct cvmx_iob_pkt_err_cn30xx cn52xxp1;
+       struct cvmx_iob_pkt_err_cn30xx cn56xx;
+       struct cvmx_iob_pkt_err_cn30xx cn56xxp1;
+       struct cvmx_iob_pkt_err_cn30xx cn58xx;
+       struct cvmx_iob_pkt_err_cn30xx cn58xxp1;
+       struct cvmx_iob_pkt_err_s cn63xx;
+       struct cvmx_iob_pkt_err_s cn63xxp1;
+};
+
+union cvmx_iob_to_cmb_credits {
+       uint64_t u64;
+       struct cvmx_iob_to_cmb_credits_s {
+               uint64_t reserved_9_63:55;
+               uint64_t pko_rd:3;
+               uint64_t ncb_rd:3;
+               uint64_t ncb_wr:3;
        } s;
-       struct cvmx_iob_pkt_err_s cn30xx;
-       struct cvmx_iob_pkt_err_s cn31xx;
-       struct cvmx_iob_pkt_err_s cn38xx;
-       struct cvmx_iob_pkt_err_s cn38xxp2;
-       struct cvmx_iob_pkt_err_s cn50xx;
-       struct cvmx_iob_pkt_err_s cn52xx;
-       struct cvmx_iob_pkt_err_s cn52xxp1;
-       struct cvmx_iob_pkt_err_s cn56xx;
-       struct cvmx_iob_pkt_err_s cn56xxp1;
-       struct cvmx_iob_pkt_err_s cn58xx;
-       struct cvmx_iob_pkt_err_s cn58xxp1;
+       struct cvmx_iob_to_cmb_credits_s cn52xx;
+       struct cvmx_iob_to_cmb_credits_s cn63xx;
+       struct cvmx_iob_to_cmb_credits_s cn63xxp1;
 };
 
 #endif
index f8b8fc657d2ce816a3b2267cce8d62159e08980f..e0a5bfe88d040ef7a14ce342727d79bde2166812 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_IPD_DEFS_H__
 #define __CVMX_IPD_DEFS_H__
 
-#define CVMX_IPD_1ST_MBUFF_SKIP \
-        CVMX_ADD_IO_SEG(0x00014F0000000000ull)
-#define CVMX_IPD_1st_NEXT_PTR_BACK \
-        CVMX_ADD_IO_SEG(0x00014F0000000150ull)
-#define CVMX_IPD_2nd_NEXT_PTR_BACK \
-        CVMX_ADD_IO_SEG(0x00014F0000000158ull)
-#define CVMX_IPD_BIST_STATUS \
-        CVMX_ADD_IO_SEG(0x00014F00000007F8ull)
-#define CVMX_IPD_BP_PRT_RED_END \
-        CVMX_ADD_IO_SEG(0x00014F0000000328ull)
-#define CVMX_IPD_CLK_COUNT \
-        CVMX_ADD_IO_SEG(0x00014F0000000338ull)
-#define CVMX_IPD_CTL_STATUS \
-        CVMX_ADD_IO_SEG(0x00014F0000000018ull)
-#define CVMX_IPD_INT_ENB \
-        CVMX_ADD_IO_SEG(0x00014F0000000160ull)
-#define CVMX_IPD_INT_SUM \
-        CVMX_ADD_IO_SEG(0x00014F0000000168ull)
-#define CVMX_IPD_NOT_1ST_MBUFF_SKIP \
-        CVMX_ADD_IO_SEG(0x00014F0000000008ull)
-#define CVMX_IPD_PACKET_MBUFF_SIZE \
-        CVMX_ADD_IO_SEG(0x00014F0000000010ull)
-#define CVMX_IPD_PKT_PTR_VALID \
-        CVMX_ADD_IO_SEG(0x00014F0000000358ull)
-#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) \
-        CVMX_ADD_IO_SEG(0x00014F0000000028ull + (((offset) & 63) * 8))
-#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) \
-        CVMX_ADD_IO_SEG(0x00014F0000000368ull + (((offset) & 63) * 8) - 8 * 36)
-#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) \
-        CVMX_ADD_IO_SEG(0x00014F0000000388ull + (((offset) & 63) * 8) - 8 * 36)
-#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) \
-        CVMX_ADD_IO_SEG(0x00014F00000001B8ull + (((offset) & 63) * 8))
-#define CVMX_IPD_PORT_QOS_INTX(offset) \
-        CVMX_ADD_IO_SEG(0x00014F0000000808ull + (((offset) & 7) * 8))
-#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) \
-        CVMX_ADD_IO_SEG(0x00014F0000000848ull + (((offset) & 7) * 8))
-#define CVMX_IPD_PORT_QOS_X_CNT(offset) \
-        CVMX_ADD_IO_SEG(0x00014F0000000888ull + (((offset) & 511) * 8))
-#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL \
-        CVMX_ADD_IO_SEG(0x00014F0000000348ull)
-#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL \
-        CVMX_ADD_IO_SEG(0x00014F0000000350ull)
-#define CVMX_IPD_PTR_COUNT \
-        CVMX_ADD_IO_SEG(0x00014F0000000320ull)
-#define CVMX_IPD_PWP_PTR_FIFO_CTL \
-        CVMX_ADD_IO_SEG(0x00014F0000000340ull)
-#define CVMX_IPD_QOS0_RED_MARKS \
-        CVMX_ADD_IO_SEG(0x00014F0000000178ull)
-#define CVMX_IPD_QOS1_RED_MARKS \
-        CVMX_ADD_IO_SEG(0x00014F0000000180ull)
-#define CVMX_IPD_QOS2_RED_MARKS \
-        CVMX_ADD_IO_SEG(0x00014F0000000188ull)
-#define CVMX_IPD_QOS3_RED_MARKS \
-        CVMX_ADD_IO_SEG(0x00014F0000000190ull)
-#define CVMX_IPD_QOS4_RED_MARKS \
-        CVMX_ADD_IO_SEG(0x00014F0000000198ull)
-#define CVMX_IPD_QOS5_RED_MARKS \
-        CVMX_ADD_IO_SEG(0x00014F00000001A0ull)
-#define CVMX_IPD_QOS6_RED_MARKS \
-        CVMX_ADD_IO_SEG(0x00014F00000001A8ull)
-#define CVMX_IPD_QOS7_RED_MARKS \
-        CVMX_ADD_IO_SEG(0x00014F00000001B0ull)
-#define CVMX_IPD_QOSX_RED_MARKS(offset) \
-        CVMX_ADD_IO_SEG(0x00014F0000000178ull + (((offset) & 7) * 8))
-#define CVMX_IPD_QUE0_FREE_PAGE_CNT \
-        CVMX_ADD_IO_SEG(0x00014F0000000330ull)
-#define CVMX_IPD_RED_PORT_ENABLE \
-        CVMX_ADD_IO_SEG(0x00014F00000002D8ull)
-#define CVMX_IPD_RED_PORT_ENABLE2 \
-        CVMX_ADD_IO_SEG(0x00014F00000003A8ull)
-#define CVMX_IPD_RED_QUE0_PARAM \
-        CVMX_ADD_IO_SEG(0x00014F00000002E0ull)
-#define CVMX_IPD_RED_QUE1_PARAM \
-        CVMX_ADD_IO_SEG(0x00014F00000002E8ull)
-#define CVMX_IPD_RED_QUE2_PARAM \
-        CVMX_ADD_IO_SEG(0x00014F00000002F0ull)
-#define CVMX_IPD_RED_QUE3_PARAM \
-        CVMX_ADD_IO_SEG(0x00014F00000002F8ull)
-#define CVMX_IPD_RED_QUE4_PARAM \
-        CVMX_ADD_IO_SEG(0x00014F0000000300ull)
-#define CVMX_IPD_RED_QUE5_PARAM \
-        CVMX_ADD_IO_SEG(0x00014F0000000308ull)
-#define CVMX_IPD_RED_QUE6_PARAM \
-        CVMX_ADD_IO_SEG(0x00014F0000000310ull)
-#define CVMX_IPD_RED_QUE7_PARAM \
-        CVMX_ADD_IO_SEG(0x00014F0000000318ull)
-#define CVMX_IPD_RED_QUEX_PARAM(offset) \
-        CVMX_ADD_IO_SEG(0x00014F00000002E0ull + (((offset) & 7) * 8))
-#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT \
-        CVMX_ADD_IO_SEG(0x00014F0000000148ull)
-#define CVMX_IPD_SUB_PORT_FCS \
-        CVMX_ADD_IO_SEG(0x00014F0000000170ull)
-#define CVMX_IPD_SUB_PORT_QOS_CNT \
-        CVMX_ADD_IO_SEG(0x00014F0000000800ull)
-#define CVMX_IPD_WQE_FPA_QUEUE \
-        CVMX_ADD_IO_SEG(0x00014F0000000020ull)
-#define CVMX_IPD_WQE_PTR_VALID \
-        CVMX_ADD_IO_SEG(0x00014F0000000360ull)
+#define CVMX_IPD_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000000ull))
+#define CVMX_IPD_1st_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000150ull))
+#define CVMX_IPD_2nd_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000158ull))
+#define CVMX_IPD_BIST_STATUS (CVMX_ADD_IO_SEG(0x00014F00000007F8ull))
+#define CVMX_IPD_BP_PRT_RED_END (CVMX_ADD_IO_SEG(0x00014F0000000328ull))
+#define CVMX_IPD_CLK_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000338ull))
+#define CVMX_IPD_CTL_STATUS (CVMX_ADD_IO_SEG(0x00014F0000000018ull))
+#define CVMX_IPD_INT_ENB (CVMX_ADD_IO_SEG(0x00014F0000000160ull))
+#define CVMX_IPD_INT_SUM (CVMX_ADD_IO_SEG(0x00014F0000000168ull))
+#define CVMX_IPD_NOT_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000008ull))
+#define CVMX_IPD_PACKET_MBUFF_SIZE (CVMX_ADD_IO_SEG(0x00014F0000000010ull))
+#define CVMX_IPD_PKT_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000358ull))
+#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000028ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) (CVMX_ADD_IO_SEG(0x00014F0000000368ull) + ((offset) & 63) * 8 - 8*36)
+#define CVMX_IPD_PORTX_BP_PAGE_CNT3(offset) (CVMX_ADD_IO_SEG(0x00014F00000003D0ull) + ((offset) & 63) * 8 - 8*40)
+#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000388ull) + ((offset) & 63) * 8 - 8*36)
+#define CVMX_IPD_PORT_BP_COUNTERS3_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000003B0ull) + ((offset) & 63) * 8 - 8*40)
+#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000001B8ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_PORT_QOS_INTX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000808ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000848ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_PORT_QOS_X_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000888ull) + ((offset) & 511) * 8)
+#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000348ull))
+#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000350ull))
+#define CVMX_IPD_PTR_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000320ull))
+#define CVMX_IPD_PWP_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000340ull))
+#define CVMX_IPD_QOS0_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(0)
+#define CVMX_IPD_QOS1_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(1)
+#define CVMX_IPD_QOS2_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(2)
+#define CVMX_IPD_QOS3_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(3)
+#define CVMX_IPD_QOS4_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(4)
+#define CVMX_IPD_QOS5_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(5)
+#define CVMX_IPD_QOS6_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(6)
+#define CVMX_IPD_QOS7_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(7)
+#define CVMX_IPD_QOSX_RED_MARKS(offset) (CVMX_ADD_IO_SEG(0x00014F0000000178ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_QUE0_FREE_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000330ull))
+#define CVMX_IPD_RED_PORT_ENABLE (CVMX_ADD_IO_SEG(0x00014F00000002D8ull))
+#define CVMX_IPD_RED_PORT_ENABLE2 (CVMX_ADD_IO_SEG(0x00014F00000003A8ull))
+#define CVMX_IPD_RED_QUE0_PARAM CVMX_IPD_RED_QUEX_PARAM(0)
+#define CVMX_IPD_RED_QUE1_PARAM CVMX_IPD_RED_QUEX_PARAM(1)
+#define CVMX_IPD_RED_QUE2_PARAM CVMX_IPD_RED_QUEX_PARAM(2)
+#define CVMX_IPD_RED_QUE3_PARAM CVMX_IPD_RED_QUEX_PARAM(3)
+#define CVMX_IPD_RED_QUE4_PARAM CVMX_IPD_RED_QUEX_PARAM(4)
+#define CVMX_IPD_RED_QUE5_PARAM CVMX_IPD_RED_QUEX_PARAM(5)
+#define CVMX_IPD_RED_QUE6_PARAM CVMX_IPD_RED_QUEX_PARAM(6)
+#define CVMX_IPD_RED_QUE7_PARAM CVMX_IPD_RED_QUEX_PARAM(7)
+#define CVMX_IPD_RED_QUEX_PARAM(offset) (CVMX_ADD_IO_SEG(0x00014F00000002E0ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000148ull))
+#define CVMX_IPD_SUB_PORT_FCS (CVMX_ADD_IO_SEG(0x00014F0000000170ull))
+#define CVMX_IPD_SUB_PORT_QOS_CNT (CVMX_ADD_IO_SEG(0x00014F0000000800ull))
+#define CVMX_IPD_WQE_FPA_QUEUE (CVMX_ADD_IO_SEG(0x00014F0000000020ull))
+#define CVMX_IPD_WQE_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000360ull))
 
 union cvmx_ipd_1st_mbuff_skip {
        uint64_t u64;
@@ -144,6 +97,8 @@ union cvmx_ipd_1st_mbuff_skip {
        struct cvmx_ipd_1st_mbuff_skip_s cn56xxp1;
        struct cvmx_ipd_1st_mbuff_skip_s cn58xx;
        struct cvmx_ipd_1st_mbuff_skip_s cn58xxp1;
+       struct cvmx_ipd_1st_mbuff_skip_s cn63xx;
+       struct cvmx_ipd_1st_mbuff_skip_s cn63xxp1;
 };
 
 union cvmx_ipd_1st_next_ptr_back {
@@ -163,6 +118,8 @@ union cvmx_ipd_1st_next_ptr_back {
        struct cvmx_ipd_1st_next_ptr_back_s cn56xxp1;
        struct cvmx_ipd_1st_next_ptr_back_s cn58xx;
        struct cvmx_ipd_1st_next_ptr_back_s cn58xxp1;
+       struct cvmx_ipd_1st_next_ptr_back_s cn63xx;
+       struct cvmx_ipd_1st_next_ptr_back_s cn63xxp1;
 };
 
 union cvmx_ipd_2nd_next_ptr_back {
@@ -182,6 +139,8 @@ union cvmx_ipd_2nd_next_ptr_back {
        struct cvmx_ipd_2nd_next_ptr_back_s cn56xxp1;
        struct cvmx_ipd_2nd_next_ptr_back_s cn58xx;
        struct cvmx_ipd_2nd_next_ptr_back_s cn58xxp1;
+       struct cvmx_ipd_2nd_next_ptr_back_s cn63xx;
+       struct cvmx_ipd_2nd_next_ptr_back_s cn63xxp1;
 };
 
 union cvmx_ipd_bist_status {
@@ -236,13 +195,15 @@ union cvmx_ipd_bist_status {
        struct cvmx_ipd_bist_status_s cn56xxp1;
        struct cvmx_ipd_bist_status_cn30xx cn58xx;
        struct cvmx_ipd_bist_status_cn30xx cn58xxp1;
+       struct cvmx_ipd_bist_status_s cn63xx;
+       struct cvmx_ipd_bist_status_s cn63xxp1;
 };
 
 union cvmx_ipd_bp_prt_red_end {
        uint64_t u64;
        struct cvmx_ipd_bp_prt_red_end_s {
-               uint64_t reserved_40_63:24;
-               uint64_t prt_enb:40;
+               uint64_t reserved_44_63:20;
+               uint64_t prt_enb:44;
        } s;
        struct cvmx_ipd_bp_prt_red_end_cn30xx {
                uint64_t reserved_36_63:28;
@@ -252,12 +213,17 @@ union cvmx_ipd_bp_prt_red_end {
        struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xx;
        struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xxp2;
        struct cvmx_ipd_bp_prt_red_end_cn30xx cn50xx;
-       struct cvmx_ipd_bp_prt_red_end_s cn52xx;
-       struct cvmx_ipd_bp_prt_red_end_s cn52xxp1;
-       struct cvmx_ipd_bp_prt_red_end_s cn56xx;
-       struct cvmx_ipd_bp_prt_red_end_s cn56xxp1;
+       struct cvmx_ipd_bp_prt_red_end_cn52xx {
+               uint64_t reserved_40_63:24;
+               uint64_t prt_enb:40;
+       } cn52xx;
+       struct cvmx_ipd_bp_prt_red_end_cn52xx cn52xxp1;
+       struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xx;
+       struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xxp1;
        struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xx;
        struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xxp1;
+       struct cvmx_ipd_bp_prt_red_end_s cn63xx;
+       struct cvmx_ipd_bp_prt_red_end_s cn63xxp1;
 };
 
 union cvmx_ipd_clk_count {
@@ -276,12 +242,17 @@ union cvmx_ipd_clk_count {
        struct cvmx_ipd_clk_count_s cn56xxp1;
        struct cvmx_ipd_clk_count_s cn58xx;
        struct cvmx_ipd_clk_count_s cn58xxp1;
+       struct cvmx_ipd_clk_count_s cn63xx;
+       struct cvmx_ipd_clk_count_s cn63xxp1;
 };
 
 union cvmx_ipd_ctl_status {
        uint64_t u64;
        struct cvmx_ipd_ctl_status_s {
-               uint64_t reserved_15_63:49;
+               uint64_t reserved_18_63:46;
+               uint64_t use_sop:1;
+               uint64_t rst_done:1;
+               uint64_t clken:1;
                uint64_t no_wptr:1;
                uint64_t pq_apkt:1;
                uint64_t pq_nabuf:1;
@@ -322,11 +293,27 @@ union cvmx_ipd_ctl_status {
                uint64_t opc_mode:2;
                uint64_t ipd_en:1;
        } cn38xxp2;
-       struct cvmx_ipd_ctl_status_s cn50xx;
-       struct cvmx_ipd_ctl_status_s cn52xx;
-       struct cvmx_ipd_ctl_status_s cn52xxp1;
-       struct cvmx_ipd_ctl_status_s cn56xx;
-       struct cvmx_ipd_ctl_status_s cn56xxp1;
+       struct cvmx_ipd_ctl_status_cn50xx {
+               uint64_t reserved_15_63:49;
+               uint64_t no_wptr:1;
+               uint64_t pq_apkt:1;
+               uint64_t pq_nabuf:1;
+               uint64_t ipd_full:1;
+               uint64_t pkt_off:1;
+               uint64_t len_m8:1;
+               uint64_t reset:1;
+               uint64_t addpkt:1;
+               uint64_t naddbuf:1;
+               uint64_t pkt_lend:1;
+               uint64_t wqe_lend:1;
+               uint64_t pbp_en:1;
+               uint64_t opc_mode:2;
+               uint64_t ipd_en:1;
+       } cn50xx;
+       struct cvmx_ipd_ctl_status_cn50xx cn52xx;
+       struct cvmx_ipd_ctl_status_cn50xx cn52xxp1;
+       struct cvmx_ipd_ctl_status_cn50xx cn56xx;
+       struct cvmx_ipd_ctl_status_cn50xx cn56xxp1;
        struct cvmx_ipd_ctl_status_cn58xx {
                uint64_t reserved_12_63:52;
                uint64_t ipd_full:1;
@@ -342,6 +329,25 @@ union cvmx_ipd_ctl_status {
                uint64_t ipd_en:1;
        } cn58xx;
        struct cvmx_ipd_ctl_status_cn58xx cn58xxp1;
+       struct cvmx_ipd_ctl_status_s cn63xx;
+       struct cvmx_ipd_ctl_status_cn63xxp1 {
+               uint64_t reserved_16_63:48;
+               uint64_t clken:1;
+               uint64_t no_wptr:1;
+               uint64_t pq_apkt:1;
+               uint64_t pq_nabuf:1;
+               uint64_t ipd_full:1;
+               uint64_t pkt_off:1;
+               uint64_t len_m8:1;
+               uint64_t reset:1;
+               uint64_t addpkt:1;
+               uint64_t naddbuf:1;
+               uint64_t pkt_lend:1;
+               uint64_t wqe_lend:1;
+               uint64_t pbp_en:1;
+               uint64_t opc_mode:2;
+               uint64_t ipd_en:1;
+       } cn63xxp1;
 };
 
 union cvmx_ipd_int_enb {
@@ -391,6 +397,8 @@ union cvmx_ipd_int_enb {
        struct cvmx_ipd_int_enb_s cn56xxp1;
        struct cvmx_ipd_int_enb_cn38xx cn58xx;
        struct cvmx_ipd_int_enb_cn38xx cn58xxp1;
+       struct cvmx_ipd_int_enb_s cn63xx;
+       struct cvmx_ipd_int_enb_s cn63xxp1;
 };
 
 union cvmx_ipd_int_sum {
@@ -440,6 +448,8 @@ union cvmx_ipd_int_sum {
        struct cvmx_ipd_int_sum_s cn56xxp1;
        struct cvmx_ipd_int_sum_cn38xx cn58xx;
        struct cvmx_ipd_int_sum_cn38xx cn58xxp1;
+       struct cvmx_ipd_int_sum_s cn63xx;
+       struct cvmx_ipd_int_sum_s cn63xxp1;
 };
 
 union cvmx_ipd_not_1st_mbuff_skip {
@@ -459,6 +469,8 @@ union cvmx_ipd_not_1st_mbuff_skip {
        struct cvmx_ipd_not_1st_mbuff_skip_s cn56xxp1;
        struct cvmx_ipd_not_1st_mbuff_skip_s cn58xx;
        struct cvmx_ipd_not_1st_mbuff_skip_s cn58xxp1;
+       struct cvmx_ipd_not_1st_mbuff_skip_s cn63xx;
+       struct cvmx_ipd_not_1st_mbuff_skip_s cn63xxp1;
 };
 
 union cvmx_ipd_packet_mbuff_size {
@@ -478,6 +490,8 @@ union cvmx_ipd_packet_mbuff_size {
        struct cvmx_ipd_packet_mbuff_size_s cn56xxp1;
        struct cvmx_ipd_packet_mbuff_size_s cn58xx;
        struct cvmx_ipd_packet_mbuff_size_s cn58xxp1;
+       struct cvmx_ipd_packet_mbuff_size_s cn63xx;
+       struct cvmx_ipd_packet_mbuff_size_s cn63xxp1;
 };
 
 union cvmx_ipd_pkt_ptr_valid {
@@ -496,6 +510,8 @@ union cvmx_ipd_pkt_ptr_valid {
        struct cvmx_ipd_pkt_ptr_valid_s cn56xxp1;
        struct cvmx_ipd_pkt_ptr_valid_s cn58xx;
        struct cvmx_ipd_pkt_ptr_valid_s cn58xxp1;
+       struct cvmx_ipd_pkt_ptr_valid_s cn63xx;
+       struct cvmx_ipd_pkt_ptr_valid_s cn63xxp1;
 };
 
 union cvmx_ipd_portx_bp_page_cnt {
@@ -516,6 +532,8 @@ union cvmx_ipd_portx_bp_page_cnt {
        struct cvmx_ipd_portx_bp_page_cnt_s cn56xxp1;
        struct cvmx_ipd_portx_bp_page_cnt_s cn58xx;
        struct cvmx_ipd_portx_bp_page_cnt_s cn58xxp1;
+       struct cvmx_ipd_portx_bp_page_cnt_s cn63xx;
+       struct cvmx_ipd_portx_bp_page_cnt_s cn63xxp1;
 };
 
 union cvmx_ipd_portx_bp_page_cnt2 {
@@ -529,6 +547,19 @@ union cvmx_ipd_portx_bp_page_cnt2 {
        struct cvmx_ipd_portx_bp_page_cnt2_s cn52xxp1;
        struct cvmx_ipd_portx_bp_page_cnt2_s cn56xx;
        struct cvmx_ipd_portx_bp_page_cnt2_s cn56xxp1;
+       struct cvmx_ipd_portx_bp_page_cnt2_s cn63xx;
+       struct cvmx_ipd_portx_bp_page_cnt2_s cn63xxp1;
+};
+
+union cvmx_ipd_portx_bp_page_cnt3 {
+       uint64_t u64;
+       struct cvmx_ipd_portx_bp_page_cnt3_s {
+               uint64_t reserved_18_63:46;
+               uint64_t bp_enb:1;
+               uint64_t page_cnt:17;
+       } s;
+       struct cvmx_ipd_portx_bp_page_cnt3_s cn63xx;
+       struct cvmx_ipd_portx_bp_page_cnt3_s cn63xxp1;
 };
 
 union cvmx_ipd_port_bp_counters2_pairx {
@@ -541,6 +572,18 @@ union cvmx_ipd_port_bp_counters2_pairx {
        struct cvmx_ipd_port_bp_counters2_pairx_s cn52xxp1;
        struct cvmx_ipd_port_bp_counters2_pairx_s cn56xx;
        struct cvmx_ipd_port_bp_counters2_pairx_s cn56xxp1;
+       struct cvmx_ipd_port_bp_counters2_pairx_s cn63xx;
+       struct cvmx_ipd_port_bp_counters2_pairx_s cn63xxp1;
+};
+
+union cvmx_ipd_port_bp_counters3_pairx {
+       uint64_t u64;
+       struct cvmx_ipd_port_bp_counters3_pairx_s {
+               uint64_t reserved_25_63:39;
+               uint64_t cnt_val:25;
+       } s;
+       struct cvmx_ipd_port_bp_counters3_pairx_s cn63xx;
+       struct cvmx_ipd_port_bp_counters3_pairx_s cn63xxp1;
 };
 
 union cvmx_ipd_port_bp_counters_pairx {
@@ -560,6 +603,8 @@ union cvmx_ipd_port_bp_counters_pairx {
        struct cvmx_ipd_port_bp_counters_pairx_s cn56xxp1;
        struct cvmx_ipd_port_bp_counters_pairx_s cn58xx;
        struct cvmx_ipd_port_bp_counters_pairx_s cn58xxp1;
+       struct cvmx_ipd_port_bp_counters_pairx_s cn63xx;
+       struct cvmx_ipd_port_bp_counters_pairx_s cn63xxp1;
 };
 
 union cvmx_ipd_port_qos_x_cnt {
@@ -572,6 +617,8 @@ union cvmx_ipd_port_qos_x_cnt {
        struct cvmx_ipd_port_qos_x_cnt_s cn52xxp1;
        struct cvmx_ipd_port_qos_x_cnt_s cn56xx;
        struct cvmx_ipd_port_qos_x_cnt_s cn56xxp1;
+       struct cvmx_ipd_port_qos_x_cnt_s cn63xx;
+       struct cvmx_ipd_port_qos_x_cnt_s cn63xxp1;
 };
 
 union cvmx_ipd_port_qos_intx {
@@ -583,6 +630,8 @@ union cvmx_ipd_port_qos_intx {
        struct cvmx_ipd_port_qos_intx_s cn52xxp1;
        struct cvmx_ipd_port_qos_intx_s cn56xx;
        struct cvmx_ipd_port_qos_intx_s cn56xxp1;
+       struct cvmx_ipd_port_qos_intx_s cn63xx;
+       struct cvmx_ipd_port_qos_intx_s cn63xxp1;
 };
 
 union cvmx_ipd_port_qos_int_enbx {
@@ -594,6 +643,8 @@ union cvmx_ipd_port_qos_int_enbx {
        struct cvmx_ipd_port_qos_int_enbx_s cn52xxp1;
        struct cvmx_ipd_port_qos_int_enbx_s cn56xx;
        struct cvmx_ipd_port_qos_int_enbx_s cn56xxp1;
+       struct cvmx_ipd_port_qos_int_enbx_s cn63xx;
+       struct cvmx_ipd_port_qos_int_enbx_s cn63xxp1;
 };
 
 union cvmx_ipd_prc_hold_ptr_fifo_ctl {
@@ -616,6 +667,8 @@ union cvmx_ipd_prc_hold_ptr_fifo_ctl {
        struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xxp1;
        struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xx;
        struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xxp1;
+       struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xx;
+       struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xxp1;
 };
 
 union cvmx_ipd_prc_port_ptr_fifo_ctl {
@@ -637,6 +690,8 @@ union cvmx_ipd_prc_port_ptr_fifo_ctl {
        struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xxp1;
        struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xx;
        struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xxp1;
+       struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xx;
+       struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xxp1;
 };
 
 union cvmx_ipd_ptr_count {
@@ -660,6 +715,8 @@ union cvmx_ipd_ptr_count {
        struct cvmx_ipd_ptr_count_s cn56xxp1;
        struct cvmx_ipd_ptr_count_s cn58xx;
        struct cvmx_ipd_ptr_count_s cn58xxp1;
+       struct cvmx_ipd_ptr_count_s cn63xx;
+       struct cvmx_ipd_ptr_count_s cn63xxp1;
 };
 
 union cvmx_ipd_pwp_ptr_fifo_ctl {
@@ -683,6 +740,8 @@ union cvmx_ipd_pwp_ptr_fifo_ctl {
        struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xxp1;
        struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xx;
        struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xxp1;
+       struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xx;
+       struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xxp1;
 };
 
 union cvmx_ipd_qosx_red_marks {
@@ -702,6 +761,8 @@ union cvmx_ipd_qosx_red_marks {
        struct cvmx_ipd_qosx_red_marks_s cn56xxp1;
        struct cvmx_ipd_qosx_red_marks_s cn58xx;
        struct cvmx_ipd_qosx_red_marks_s cn58xxp1;
+       struct cvmx_ipd_qosx_red_marks_s cn63xx;
+       struct cvmx_ipd_qosx_red_marks_s cn63xxp1;
 };
 
 union cvmx_ipd_que0_free_page_cnt {
@@ -721,6 +782,8 @@ union cvmx_ipd_que0_free_page_cnt {
        struct cvmx_ipd_que0_free_page_cnt_s cn56xxp1;
        struct cvmx_ipd_que0_free_page_cnt_s cn58xx;
        struct cvmx_ipd_que0_free_page_cnt_s cn58xxp1;
+       struct cvmx_ipd_que0_free_page_cnt_s cn63xx;
+       struct cvmx_ipd_que0_free_page_cnt_s cn63xxp1;
 };
 
 union cvmx_ipd_red_port_enable {
@@ -741,18 +804,25 @@ union cvmx_ipd_red_port_enable {
        struct cvmx_ipd_red_port_enable_s cn56xxp1;
        struct cvmx_ipd_red_port_enable_s cn58xx;
        struct cvmx_ipd_red_port_enable_s cn58xxp1;
+       struct cvmx_ipd_red_port_enable_s cn63xx;
+       struct cvmx_ipd_red_port_enable_s cn63xxp1;
 };
 
 union cvmx_ipd_red_port_enable2 {
        uint64_t u64;
        struct cvmx_ipd_red_port_enable2_s {
+               uint64_t reserved_8_63:56;
+               uint64_t prt_enb:8;
+       } s;
+       struct cvmx_ipd_red_port_enable2_cn52xx {
                uint64_t reserved_4_63:60;
                uint64_t prt_enb:4;
-       } s;
-       struct cvmx_ipd_red_port_enable2_s cn52xx;
-       struct cvmx_ipd_red_port_enable2_s cn52xxp1;
-       struct cvmx_ipd_red_port_enable2_s cn56xx;
-       struct cvmx_ipd_red_port_enable2_s cn56xxp1;
+       } cn52xx;
+       struct cvmx_ipd_red_port_enable2_cn52xx cn52xxp1;
+       struct cvmx_ipd_red_port_enable2_cn52xx cn56xx;
+       struct cvmx_ipd_red_port_enable2_cn52xx cn56xxp1;
+       struct cvmx_ipd_red_port_enable2_s cn63xx;
+       struct cvmx_ipd_red_port_enable2_s cn63xxp1;
 };
 
 union cvmx_ipd_red_quex_param {
@@ -775,6 +845,8 @@ union cvmx_ipd_red_quex_param {
        struct cvmx_ipd_red_quex_param_s cn56xxp1;
        struct cvmx_ipd_red_quex_param_s cn58xx;
        struct cvmx_ipd_red_quex_param_s cn58xxp1;
+       struct cvmx_ipd_red_quex_param_s cn63xx;
+       struct cvmx_ipd_red_quex_param_s cn63xxp1;
 };
 
 union cvmx_ipd_sub_port_bp_page_cnt {
@@ -795,6 +867,8 @@ union cvmx_ipd_sub_port_bp_page_cnt {
        struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xxp1;
        struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xx;
        struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xxp1;
+       struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xx;
+       struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xxp1;
 };
 
 union cvmx_ipd_sub_port_fcs {
@@ -822,6 +896,8 @@ union cvmx_ipd_sub_port_fcs {
        struct cvmx_ipd_sub_port_fcs_s cn56xxp1;
        struct cvmx_ipd_sub_port_fcs_cn38xx cn58xx;
        struct cvmx_ipd_sub_port_fcs_cn38xx cn58xxp1;
+       struct cvmx_ipd_sub_port_fcs_s cn63xx;
+       struct cvmx_ipd_sub_port_fcs_s cn63xxp1;
 };
 
 union cvmx_ipd_sub_port_qos_cnt {
@@ -835,6 +911,8 @@ union cvmx_ipd_sub_port_qos_cnt {
        struct cvmx_ipd_sub_port_qos_cnt_s cn52xxp1;
        struct cvmx_ipd_sub_port_qos_cnt_s cn56xx;
        struct cvmx_ipd_sub_port_qos_cnt_s cn56xxp1;
+       struct cvmx_ipd_sub_port_qos_cnt_s cn63xx;
+       struct cvmx_ipd_sub_port_qos_cnt_s cn63xxp1;
 };
 
 union cvmx_ipd_wqe_fpa_queue {
@@ -854,6 +932,8 @@ union cvmx_ipd_wqe_fpa_queue {
        struct cvmx_ipd_wqe_fpa_queue_s cn56xxp1;
        struct cvmx_ipd_wqe_fpa_queue_s cn58xx;
        struct cvmx_ipd_wqe_fpa_queue_s cn58xxp1;
+       struct cvmx_ipd_wqe_fpa_queue_s cn63xx;
+       struct cvmx_ipd_wqe_fpa_queue_s cn63xxp1;
 };
 
 union cvmx_ipd_wqe_ptr_valid {
@@ -872,6 +952,8 @@ union cvmx_ipd_wqe_ptr_valid {
        struct cvmx_ipd_wqe_ptr_valid_s cn56xxp1;
        struct cvmx_ipd_wqe_ptr_valid_s cn58xx;
        struct cvmx_ipd_wqe_ptr_valid_s cn58xxp1;
+       struct cvmx_ipd_wqe_ptr_valid_s cn63xx;
+       struct cvmx_ipd_wqe_ptr_valid_s cn63xxp1;
 };
 
 #endif
index 337583842b51e2b7d34f5d98a22dfa364df24160..7a50a0beb472aa495f8eb1fe321ccc17862253e3 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_L2C_DEFS_H__
 #define __CVMX_L2C_DEFS_H__
 
-#define CVMX_L2C_BST0 \
-        CVMX_ADD_IO_SEG(0x00011800800007F8ull)
-#define CVMX_L2C_BST1 \
-        CVMX_ADD_IO_SEG(0x00011800800007F0ull)
-#define CVMX_L2C_BST2 \
-        CVMX_ADD_IO_SEG(0x00011800800007E8ull)
-#define CVMX_L2C_CFG \
-        CVMX_ADD_IO_SEG(0x0001180080000000ull)
-#define CVMX_L2C_DBG \
-        CVMX_ADD_IO_SEG(0x0001180080000030ull)
-#define CVMX_L2C_DUT \
-        CVMX_ADD_IO_SEG(0x0001180080000050ull)
-#define CVMX_L2C_GRPWRR0 \
-        CVMX_ADD_IO_SEG(0x00011800800000C8ull)
-#define CVMX_L2C_GRPWRR1 \
-        CVMX_ADD_IO_SEG(0x00011800800000D0ull)
-#define CVMX_L2C_INT_EN \
-        CVMX_ADD_IO_SEG(0x0001180080000100ull)
-#define CVMX_L2C_INT_STAT \
-        CVMX_ADD_IO_SEG(0x00011800800000F8ull)
-#define CVMX_L2C_LCKBASE \
-        CVMX_ADD_IO_SEG(0x0001180080000058ull)
-#define CVMX_L2C_LCKOFF \
-        CVMX_ADD_IO_SEG(0x0001180080000060ull)
-#define CVMX_L2C_LFB0 \
-        CVMX_ADD_IO_SEG(0x0001180080000038ull)
-#define CVMX_L2C_LFB1 \
-        CVMX_ADD_IO_SEG(0x0001180080000040ull)
-#define CVMX_L2C_LFB2 \
-        CVMX_ADD_IO_SEG(0x0001180080000048ull)
-#define CVMX_L2C_LFB3 \
-        CVMX_ADD_IO_SEG(0x00011800800000B8ull)
-#define CVMX_L2C_OOB \
-        CVMX_ADD_IO_SEG(0x00011800800000D8ull)
-#define CVMX_L2C_OOB1 \
-        CVMX_ADD_IO_SEG(0x00011800800000E0ull)
-#define CVMX_L2C_OOB2 \
-        CVMX_ADD_IO_SEG(0x00011800800000E8ull)
-#define CVMX_L2C_OOB3 \
-        CVMX_ADD_IO_SEG(0x00011800800000F0ull)
-#define CVMX_L2C_PFC0 \
-        CVMX_ADD_IO_SEG(0x0001180080000098ull)
-#define CVMX_L2C_PFC1 \
-        CVMX_ADD_IO_SEG(0x00011800800000A0ull)
-#define CVMX_L2C_PFC2 \
-        CVMX_ADD_IO_SEG(0x00011800800000A8ull)
-#define CVMX_L2C_PFC3 \
-        CVMX_ADD_IO_SEG(0x00011800800000B0ull)
-#define CVMX_L2C_PFCTL \
-        CVMX_ADD_IO_SEG(0x0001180080000090ull)
-#define CVMX_L2C_PFCX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180080000098ull + (((offset) & 3) * 8))
-#define CVMX_L2C_PPGRP \
-        CVMX_ADD_IO_SEG(0x00011800800000C0ull)
-#define CVMX_L2C_SPAR0 \
-        CVMX_ADD_IO_SEG(0x0001180080000068ull)
-#define CVMX_L2C_SPAR1 \
-        CVMX_ADD_IO_SEG(0x0001180080000070ull)
-#define CVMX_L2C_SPAR2 \
-        CVMX_ADD_IO_SEG(0x0001180080000078ull)
-#define CVMX_L2C_SPAR3 \
-        CVMX_ADD_IO_SEG(0x0001180080000080ull)
-#define CVMX_L2C_SPAR4 \
-        CVMX_ADD_IO_SEG(0x0001180080000088ull)
+#define CVMX_L2C_BIG_CTL (CVMX_ADD_IO_SEG(0x0001180080800030ull))
+#define CVMX_L2C_BST (CVMX_ADD_IO_SEG(0x00011800808007F8ull))
+#define CVMX_L2C_BST0 (CVMX_ADD_IO_SEG(0x00011800800007F8ull))
+#define CVMX_L2C_BST1 (CVMX_ADD_IO_SEG(0x00011800800007F0ull))
+#define CVMX_L2C_BST2 (CVMX_ADD_IO_SEG(0x00011800800007E8ull))
+#define CVMX_L2C_BST_MEMX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F8ull))
+#define CVMX_L2C_BST_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F0ull))
+#define CVMX_L2C_BST_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F8ull))
+#define CVMX_L2C_CFG (CVMX_ADD_IO_SEG(0x0001180080000000ull))
+#define CVMX_L2C_COP0_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080940000ull) + ((offset) & 16383) * 8)
+#define CVMX_L2C_CTL (CVMX_ADD_IO_SEG(0x0001180080800000ull))
+#define CVMX_L2C_DBG (CVMX_ADD_IO_SEG(0x0001180080000030ull))
+#define CVMX_L2C_DUT (CVMX_ADD_IO_SEG(0x0001180080000050ull))
+#define CVMX_L2C_DUT_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080E00000ull) + ((offset) & 2047) * 8)
+#define CVMX_L2C_ERR_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E0ull))
+#define CVMX_L2C_ERR_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E8ull))
+#define CVMX_L2C_ERR_VBFX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F0ull))
+#define CVMX_L2C_ERR_XMC (CVMX_ADD_IO_SEG(0x00011800808007D8ull))
+#define CVMX_L2C_GRPWRR0 (CVMX_ADD_IO_SEG(0x00011800800000C8ull))
+#define CVMX_L2C_GRPWRR1 (CVMX_ADD_IO_SEG(0x00011800800000D0ull))
+#define CVMX_L2C_INT_EN (CVMX_ADD_IO_SEG(0x0001180080000100ull))
+#define CVMX_L2C_INT_ENA (CVMX_ADD_IO_SEG(0x0001180080800020ull))
+#define CVMX_L2C_INT_REG (CVMX_ADD_IO_SEG(0x0001180080800018ull))
+#define CVMX_L2C_INT_STAT (CVMX_ADD_IO_SEG(0x00011800800000F8ull))
+#define CVMX_L2C_IOCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800420ull))
+#define CVMX_L2C_IORX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800428ull))
+#define CVMX_L2C_LCKBASE (CVMX_ADD_IO_SEG(0x0001180080000058ull))
+#define CVMX_L2C_LCKOFF (CVMX_ADD_IO_SEG(0x0001180080000060ull))
+#define CVMX_L2C_LFB0 (CVMX_ADD_IO_SEG(0x0001180080000038ull))
+#define CVMX_L2C_LFB1 (CVMX_ADD_IO_SEG(0x0001180080000040ull))
+#define CVMX_L2C_LFB2 (CVMX_ADD_IO_SEG(0x0001180080000048ull))
+#define CVMX_L2C_LFB3 (CVMX_ADD_IO_SEG(0x00011800800000B8ull))
+#define CVMX_L2C_OOB (CVMX_ADD_IO_SEG(0x00011800800000D8ull))
+#define CVMX_L2C_OOB1 (CVMX_ADD_IO_SEG(0x00011800800000E0ull))
+#define CVMX_L2C_OOB2 (CVMX_ADD_IO_SEG(0x00011800800000E8ull))
+#define CVMX_L2C_OOB3 (CVMX_ADD_IO_SEG(0x00011800800000F0ull))
+#define CVMX_L2C_PFC0 CVMX_L2C_PFCX(0)
+#define CVMX_L2C_PFC1 CVMX_L2C_PFCX(1)
+#define CVMX_L2C_PFC2 CVMX_L2C_PFCX(2)
+#define CVMX_L2C_PFC3 CVMX_L2C_PFCX(3)
+#define CVMX_L2C_PFCTL (CVMX_ADD_IO_SEG(0x0001180080000090ull))
+#define CVMX_L2C_PFCX(offset) (CVMX_ADD_IO_SEG(0x0001180080000098ull) + ((offset) & 3) * 8)
+#define CVMX_L2C_PPGRP (CVMX_ADD_IO_SEG(0x00011800800000C0ull))
+#define CVMX_L2C_QOS_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080880200ull))
+#define CVMX_L2C_QOS_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080880000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_QOS_WGT (CVMX_ADD_IO_SEG(0x0001180080800008ull))
+#define CVMX_L2C_RSCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800410ull))
+#define CVMX_L2C_RSDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800418ull))
+#define CVMX_L2C_SPAR0 (CVMX_ADD_IO_SEG(0x0001180080000068ull))
+#define CVMX_L2C_SPAR1 (CVMX_ADD_IO_SEG(0x0001180080000070ull))
+#define CVMX_L2C_SPAR2 (CVMX_ADD_IO_SEG(0x0001180080000078ull))
+#define CVMX_L2C_SPAR3 (CVMX_ADD_IO_SEG(0x0001180080000080ull))
+#define CVMX_L2C_SPAR4 (CVMX_ADD_IO_SEG(0x0001180080000088ull))
+#define CVMX_L2C_TADX_ECC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00018ull))
+#define CVMX_L2C_TADX_ECC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00020ull))
+#define CVMX_L2C_TADX_IEN(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00000ull))
+#define CVMX_L2C_TADX_INT(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00028ull))
+#define CVMX_L2C_TADX_PFC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00400ull))
+#define CVMX_L2C_TADX_PFC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00408ull))
+#define CVMX_L2C_TADX_PFC2(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00410ull))
+#define CVMX_L2C_TADX_PFC3(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00418ull))
+#define CVMX_L2C_TADX_PRF(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00008ull))
+#define CVMX_L2C_TADX_TAG(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00010ull))
+#define CVMX_L2C_VER_ID (CVMX_ADD_IO_SEG(0x00011800808007E0ull))
+#define CVMX_L2C_VER_IOB (CVMX_ADD_IO_SEG(0x00011800808007F0ull))
+#define CVMX_L2C_VER_MSC (CVMX_ADD_IO_SEG(0x00011800808007D0ull))
+#define CVMX_L2C_VER_PP (CVMX_ADD_IO_SEG(0x00011800808007E8ull))
+#define CVMX_L2C_VIRTID_IOBX(block_id) (CVMX_ADD_IO_SEG(0x00011800808C0200ull))
+#define CVMX_L2C_VIRTID_PPX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_VRT_CTL (CVMX_ADD_IO_SEG(0x0001180080800010ull))
+#define CVMX_L2C_VRT_MEMX(offset) (CVMX_ADD_IO_SEG(0x0001180080900000ull) + ((offset) & 1023) * 8)
+#define CVMX_L2C_WPAR_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080840200ull))
+#define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_XMCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800400ull))
+#define CVMX_L2C_XMC_CMD (CVMX_ADD_IO_SEG(0x0001180080800028ull))
+#define CVMX_L2C_XMDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800408ull))
+
+union cvmx_l2c_big_ctl {
+       uint64_t u64;
+       struct cvmx_l2c_big_ctl_s {
+               uint64_t reserved_8_63:56;
+               uint64_t maxdram:4;
+               uint64_t reserved_1_3:3;
+               uint64_t disable:1;
+       } s;
+       struct cvmx_l2c_big_ctl_s cn63xx;
+};
+
+union cvmx_l2c_bst {
+       uint64_t u64;
+       struct cvmx_l2c_bst_s {
+               uint64_t reserved_38_63:26;
+               uint64_t dutfl:6;
+               uint64_t reserved_17_31:15;
+               uint64_t ioccmdfl:1;
+               uint64_t reserved_13_15:3;
+               uint64_t iocdatfl:1;
+               uint64_t reserved_9_11:3;
+               uint64_t dutresfl:1;
+               uint64_t reserved_5_7:3;
+               uint64_t vrtfl:1;
+               uint64_t reserved_1_3:3;
+               uint64_t tdffl:1;
+       } s;
+       struct cvmx_l2c_bst_s cn63xx;
+       struct cvmx_l2c_bst_s cn63xxp1;
+};
 
 union cvmx_l2c_bst0 {
        uint64_t u64;
@@ -253,6 +296,48 @@ union cvmx_l2c_bst2 {
        struct cvmx_l2c_bst2_cn56xx cn58xxp1;
 };
 
+union cvmx_l2c_bst_memx {
+       uint64_t u64;
+       struct cvmx_l2c_bst_memx_s {
+               uint64_t start_bist:1;
+               uint64_t clear_bist:1;
+               uint64_t reserved_5_61:57;
+               uint64_t rdffl:1;
+               uint64_t vbffl:4;
+       } s;
+       struct cvmx_l2c_bst_memx_s cn63xx;
+       struct cvmx_l2c_bst_memx_s cn63xxp1;
+};
+
+union cvmx_l2c_bst_tdtx {
+       uint64_t u64;
+       struct cvmx_l2c_bst_tdtx_s {
+               uint64_t reserved_32_63:32;
+               uint64_t fbfrspfl:8;
+               uint64_t sbffl:8;
+               uint64_t fbffl:8;
+               uint64_t l2dfl:8;
+       } s;
+       struct cvmx_l2c_bst_tdtx_s cn63xx;
+       struct cvmx_l2c_bst_tdtx_cn63xxp1 {
+               uint64_t reserved_24_63:40;
+               uint64_t sbffl:8;
+               uint64_t fbffl:8;
+               uint64_t l2dfl:8;
+       } cn63xxp1;
+};
+
+union cvmx_l2c_bst_ttgx {
+       uint64_t u64;
+       struct cvmx_l2c_bst_ttgx_s {
+               uint64_t reserved_17_63:47;
+               uint64_t lrufl:1;
+               uint64_t tagfl:16;
+       } s;
+       struct cvmx_l2c_bst_ttgx_s cn63xx;
+       struct cvmx_l2c_bst_ttgx_s cn63xxp1;
+};
+
 union cvmx_l2c_cfg {
        uint64_t u64;
        struct cvmx_l2c_cfg_s {
@@ -333,6 +418,49 @@ union cvmx_l2c_cfg {
        } cn58xxp1;
 };
 
+union cvmx_l2c_cop0_mapx {
+       uint64_t u64;
+       struct cvmx_l2c_cop0_mapx_s {
+               uint64_t data:64;
+       } s;
+       struct cvmx_l2c_cop0_mapx_s cn63xx;
+       struct cvmx_l2c_cop0_mapx_s cn63xxp1;
+};
+
+union cvmx_l2c_ctl {
+       uint64_t u64;
+       struct cvmx_l2c_ctl_s {
+               uint64_t reserved_28_63:36;
+               uint64_t disstgl2i:1;
+               uint64_t l2dfsbe:1;
+               uint64_t l2dfdbe:1;
+               uint64_t discclk:1;
+               uint64_t maxvab:4;
+               uint64_t maxlfb:4;
+               uint64_t rsp_arb_mode:1;
+               uint64_t xmc_arb_mode:1;
+               uint64_t ef_ena:1;
+               uint64_t ef_cnt:7;
+               uint64_t vab_thresh:4;
+               uint64_t disecc:1;
+               uint64_t disidxalias:1;
+       } s;
+       struct cvmx_l2c_ctl_s cn63xx;
+       struct cvmx_l2c_ctl_cn63xxp1 {
+               uint64_t reserved_25_63:39;
+               uint64_t discclk:1;
+               uint64_t maxvab:4;
+               uint64_t maxlfb:4;
+               uint64_t rsp_arb_mode:1;
+               uint64_t xmc_arb_mode:1;
+               uint64_t ef_ena:1;
+               uint64_t ef_cnt:7;
+               uint64_t vab_thresh:4;
+               uint64_t disecc:1;
+               uint64_t disidxalias:1;
+       } cn63xxp1;
+};
+
 union cvmx_l2c_dbg {
        uint64_t u64;
        struct cvmx_l2c_dbg_s {
@@ -349,7 +477,9 @@ union cvmx_l2c_dbg {
                uint64_t reserved_13_63:51;
                uint64_t lfb_enum:2;
                uint64_t lfb_dmp:1;
-               uint64_t reserved_5_9:5;
+               uint64_t reserved_7_9:3;
+               uint64_t ppnum:1;
+               uint64_t reserved_5_5:1;
                uint64_t set:2;
                uint64_t finv:1;
                uint64_t l2d:1;
@@ -420,6 +550,79 @@ union cvmx_l2c_dut {
        struct cvmx_l2c_dut_s cn58xxp1;
 };
 
+union cvmx_l2c_dut_mapx {
+       uint64_t u64;
+       struct cvmx_l2c_dut_mapx_s {
+               uint64_t reserved_38_63:26;
+               uint64_t tag:28;
+               uint64_t reserved_1_9:9;
+               uint64_t valid:1;
+       } s;
+       struct cvmx_l2c_dut_mapx_s cn63xx;
+       struct cvmx_l2c_dut_mapx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_tdtx {
+       uint64_t u64;
+       struct cvmx_l2c_err_tdtx_s {
+               uint64_t dbe:1;
+               uint64_t sbe:1;
+               uint64_t vdbe:1;
+               uint64_t vsbe:1;
+               uint64_t syn:10;
+               uint64_t reserved_21_49:29;
+               uint64_t wayidx:17;
+               uint64_t reserved_2_3:2;
+               uint64_t type:2;
+       } s;
+       struct cvmx_l2c_err_tdtx_s cn63xx;
+       struct cvmx_l2c_err_tdtx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_ttgx {
+       uint64_t u64;
+       struct cvmx_l2c_err_ttgx_s {
+               uint64_t dbe:1;
+               uint64_t sbe:1;
+               uint64_t noway:1;
+               uint64_t reserved_56_60:5;
+               uint64_t syn:6;
+               uint64_t reserved_21_49:29;
+               uint64_t wayidx:14;
+               uint64_t reserved_2_6:5;
+               uint64_t type:2;
+       } s;
+       struct cvmx_l2c_err_ttgx_s cn63xx;
+       struct cvmx_l2c_err_ttgx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_vbfx {
+       uint64_t u64;
+       struct cvmx_l2c_err_vbfx_s {
+               uint64_t reserved_62_63:2;
+               uint64_t vdbe:1;
+               uint64_t vsbe:1;
+               uint64_t vsyn:10;
+               uint64_t reserved_2_49:48;
+               uint64_t type:2;
+       } s;
+       struct cvmx_l2c_err_vbfx_s cn63xx;
+       struct cvmx_l2c_err_vbfx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_xmc {
+       uint64_t u64;
+       struct cvmx_l2c_err_xmc_s {
+               uint64_t cmd:6;
+               uint64_t reserved_52_57:6;
+               uint64_t sid:4;
+               uint64_t reserved_38_47:10;
+               uint64_t addr:38;
+       } s;
+       struct cvmx_l2c_err_xmc_s cn63xx;
+       struct cvmx_l2c_err_xmc_s cn63xxp1;
+};
+
 union cvmx_l2c_grpwrr0 {
        uint64_t u64;
        struct cvmx_l2c_grpwrr0_s {
@@ -464,6 +667,60 @@ union cvmx_l2c_int_en {
        struct cvmx_l2c_int_en_s cn56xxp1;
 };
 
+union cvmx_l2c_int_ena {
+       uint64_t u64;
+       struct cvmx_l2c_int_ena_s {
+               uint64_t reserved_8_63:56;
+               uint64_t bigrd:1;
+               uint64_t bigwr:1;
+               uint64_t vrtpe:1;
+               uint64_t vrtadrng:1;
+               uint64_t vrtidrng:1;
+               uint64_t vrtwr:1;
+               uint64_t holewr:1;
+               uint64_t holerd:1;
+       } s;
+       struct cvmx_l2c_int_ena_s cn63xx;
+       struct cvmx_l2c_int_ena_cn63xxp1 {
+               uint64_t reserved_6_63:58;
+               uint64_t vrtpe:1;
+               uint64_t vrtadrng:1;
+               uint64_t vrtidrng:1;
+               uint64_t vrtwr:1;
+               uint64_t holewr:1;
+               uint64_t holerd:1;
+       } cn63xxp1;
+};
+
+union cvmx_l2c_int_reg {
+       uint64_t u64;
+       struct cvmx_l2c_int_reg_s {
+               uint64_t reserved_17_63:47;
+               uint64_t tad0:1;
+               uint64_t reserved_8_15:8;
+               uint64_t bigrd:1;
+               uint64_t bigwr:1;
+               uint64_t vrtpe:1;
+               uint64_t vrtadrng:1;
+               uint64_t vrtidrng:1;
+               uint64_t vrtwr:1;
+               uint64_t holewr:1;
+               uint64_t holerd:1;
+       } s;
+       struct cvmx_l2c_int_reg_s cn63xx;
+       struct cvmx_l2c_int_reg_cn63xxp1 {
+               uint64_t reserved_17_63:47;
+               uint64_t tad0:1;
+               uint64_t reserved_6_15:10;
+               uint64_t vrtpe:1;
+               uint64_t vrtadrng:1;
+               uint64_t vrtidrng:1;
+               uint64_t vrtwr:1;
+               uint64_t holewr:1;
+               uint64_t holerd:1;
+       } cn63xxp1;
+};
+
 union cvmx_l2c_int_stat {
        uint64_t u64;
        struct cvmx_l2c_int_stat_s {
@@ -484,6 +741,24 @@ union cvmx_l2c_int_stat {
        struct cvmx_l2c_int_stat_s cn56xxp1;
 };
 
+union cvmx_l2c_iocx_pfc {
+       uint64_t u64;
+       struct cvmx_l2c_iocx_pfc_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_iocx_pfc_s cn63xx;
+       struct cvmx_l2c_iocx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_iorx_pfc {
+       uint64_t u64;
+       struct cvmx_l2c_iorx_pfc_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_iorx_pfc_s cn63xx;
+       struct cvmx_l2c_iorx_pfc_s cn63xxp1;
+};
+
 union cvmx_l2c_lckbase {
        uint64_t u64;
        struct cvmx_l2c_lckbase_s {
@@ -855,6 +1130,59 @@ union cvmx_l2c_ppgrp {
        struct cvmx_l2c_ppgrp_s cn56xxp1;
 };
 
+union cvmx_l2c_qos_iobx {
+       uint64_t u64;
+       struct cvmx_l2c_qos_iobx_s {
+               uint64_t reserved_6_63:58;
+               uint64_t dwblvl:2;
+               uint64_t reserved_2_3:2;
+               uint64_t lvl:2;
+       } s;
+       struct cvmx_l2c_qos_iobx_s cn63xx;
+       struct cvmx_l2c_qos_iobx_s cn63xxp1;
+};
+
+union cvmx_l2c_qos_ppx {
+       uint64_t u64;
+       struct cvmx_l2c_qos_ppx_s {
+               uint64_t reserved_2_63:62;
+               uint64_t lvl:2;
+       } s;
+       struct cvmx_l2c_qos_ppx_s cn63xx;
+       struct cvmx_l2c_qos_ppx_s cn63xxp1;
+};
+
+union cvmx_l2c_qos_wgt {
+       uint64_t u64;
+       struct cvmx_l2c_qos_wgt_s {
+               uint64_t reserved_32_63:32;
+               uint64_t wgt3:8;
+               uint64_t wgt2:8;
+               uint64_t wgt1:8;
+               uint64_t wgt0:8;
+       } s;
+       struct cvmx_l2c_qos_wgt_s cn63xx;
+       struct cvmx_l2c_qos_wgt_s cn63xxp1;
+};
+
+union cvmx_l2c_rscx_pfc {
+       uint64_t u64;
+       struct cvmx_l2c_rscx_pfc_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_rscx_pfc_s cn63xx;
+       struct cvmx_l2c_rscx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_rsdx_pfc {
+       uint64_t u64;
+       struct cvmx_l2c_rsdx_pfc_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_rsdx_pfc_s cn63xx;
+       struct cvmx_l2c_rsdx_pfc_s cn63xxp1;
+};
+
 union cvmx_l2c_spar0 {
        uint64_t u64;
        struct cvmx_l2c_spar0_s {
@@ -960,4 +1288,282 @@ union cvmx_l2c_spar4 {
        struct cvmx_l2c_spar4_s cn58xxp1;
 };
 
+union cvmx_l2c_tadx_ecc0 {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_ecc0_s {
+               uint64_t reserved_58_63:6;
+               uint64_t ow3ecc:10;
+               uint64_t reserved_42_47:6;
+               uint64_t ow2ecc:10;
+               uint64_t reserved_26_31:6;
+               uint64_t ow1ecc:10;
+               uint64_t reserved_10_15:6;
+               uint64_t ow0ecc:10;
+       } s;
+       struct cvmx_l2c_tadx_ecc0_s cn63xx;
+       struct cvmx_l2c_tadx_ecc0_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_ecc1 {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_ecc1_s {
+               uint64_t reserved_58_63:6;
+               uint64_t ow7ecc:10;
+               uint64_t reserved_42_47:6;
+               uint64_t ow6ecc:10;
+               uint64_t reserved_26_31:6;
+               uint64_t ow5ecc:10;
+               uint64_t reserved_10_15:6;
+               uint64_t ow4ecc:10;
+       } s;
+       struct cvmx_l2c_tadx_ecc1_s cn63xx;
+       struct cvmx_l2c_tadx_ecc1_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_ien {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_ien_s {
+               uint64_t reserved_9_63:55;
+               uint64_t wrdislmc:1;
+               uint64_t rddislmc:1;
+               uint64_t noway:1;
+               uint64_t vbfdbe:1;
+               uint64_t vbfsbe:1;
+               uint64_t tagdbe:1;
+               uint64_t tagsbe:1;
+               uint64_t l2ddbe:1;
+               uint64_t l2dsbe:1;
+       } s;
+       struct cvmx_l2c_tadx_ien_s cn63xx;
+       struct cvmx_l2c_tadx_ien_cn63xxp1 {
+               uint64_t reserved_7_63:57;
+               uint64_t noway:1;
+               uint64_t vbfdbe:1;
+               uint64_t vbfsbe:1;
+               uint64_t tagdbe:1;
+               uint64_t tagsbe:1;
+               uint64_t l2ddbe:1;
+               uint64_t l2dsbe:1;
+       } cn63xxp1;
+};
+
+union cvmx_l2c_tadx_int {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_int_s {
+               uint64_t reserved_9_63:55;
+               uint64_t wrdislmc:1;
+               uint64_t rddislmc:1;
+               uint64_t noway:1;
+               uint64_t vbfdbe:1;
+               uint64_t vbfsbe:1;
+               uint64_t tagdbe:1;
+               uint64_t tagsbe:1;
+               uint64_t l2ddbe:1;
+               uint64_t l2dsbe:1;
+       } s;
+       struct cvmx_l2c_tadx_int_s cn63xx;
+};
+
+union cvmx_l2c_tadx_pfc0 {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_pfc0_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_tadx_pfc0_s cn63xx;
+       struct cvmx_l2c_tadx_pfc0_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_pfc1 {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_pfc1_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_tadx_pfc1_s cn63xx;
+       struct cvmx_l2c_tadx_pfc1_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_pfc2 {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_pfc2_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_tadx_pfc2_s cn63xx;
+       struct cvmx_l2c_tadx_pfc2_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_pfc3 {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_pfc3_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_tadx_pfc3_s cn63xx;
+       struct cvmx_l2c_tadx_pfc3_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_prf {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_prf_s {
+               uint64_t reserved_32_63:32;
+               uint64_t cnt3sel:8;
+               uint64_t cnt2sel:8;
+               uint64_t cnt1sel:8;
+               uint64_t cnt0sel:8;
+       } s;
+       struct cvmx_l2c_tadx_prf_s cn63xx;
+       struct cvmx_l2c_tadx_prf_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_tag {
+       uint64_t u64;
+       struct cvmx_l2c_tadx_tag_s {
+               uint64_t reserved_46_63:18;
+               uint64_t ecc:6;
+               uint64_t reserved_36_39:4;
+               uint64_t tag:19;
+               uint64_t reserved_4_16:13;
+               uint64_t use:1;
+               uint64_t valid:1;
+               uint64_t dirty:1;
+               uint64_t lock:1;
+       } s;
+       struct cvmx_l2c_tadx_tag_s cn63xx;
+       struct cvmx_l2c_tadx_tag_s cn63xxp1;
+};
+
+union cvmx_l2c_ver_id {
+       uint64_t u64;
+       struct cvmx_l2c_ver_id_s {
+               uint64_t mask:64;
+       } s;
+       struct cvmx_l2c_ver_id_s cn63xx;
+       struct cvmx_l2c_ver_id_s cn63xxp1;
+};
+
+union cvmx_l2c_ver_iob {
+       uint64_t u64;
+       struct cvmx_l2c_ver_iob_s {
+               uint64_t reserved_1_63:63;
+               uint64_t mask:1;
+       } s;
+       struct cvmx_l2c_ver_iob_s cn63xx;
+       struct cvmx_l2c_ver_iob_s cn63xxp1;
+};
+
+union cvmx_l2c_ver_msc {
+       uint64_t u64;
+       struct cvmx_l2c_ver_msc_s {
+               uint64_t reserved_2_63:62;
+               uint64_t invl2:1;
+               uint64_t dwb:1;
+       } s;
+       struct cvmx_l2c_ver_msc_s cn63xx;
+};
+
+union cvmx_l2c_ver_pp {
+       uint64_t u64;
+       struct cvmx_l2c_ver_pp_s {
+               uint64_t reserved_6_63:58;
+               uint64_t mask:6;
+       } s;
+       struct cvmx_l2c_ver_pp_s cn63xx;
+       struct cvmx_l2c_ver_pp_s cn63xxp1;
+};
+
+union cvmx_l2c_virtid_iobx {
+       uint64_t u64;
+       struct cvmx_l2c_virtid_iobx_s {
+               uint64_t reserved_14_63:50;
+               uint64_t dwbid:6;
+               uint64_t reserved_6_7:2;
+               uint64_t id:6;
+       } s;
+       struct cvmx_l2c_virtid_iobx_s cn63xx;
+       struct cvmx_l2c_virtid_iobx_s cn63xxp1;
+};
+
+union cvmx_l2c_virtid_ppx {
+       uint64_t u64;
+       struct cvmx_l2c_virtid_ppx_s {
+               uint64_t reserved_6_63:58;
+               uint64_t id:6;
+       } s;
+       struct cvmx_l2c_virtid_ppx_s cn63xx;
+       struct cvmx_l2c_virtid_ppx_s cn63xxp1;
+};
+
+union cvmx_l2c_vrt_ctl {
+       uint64_t u64;
+       struct cvmx_l2c_vrt_ctl_s {
+               uint64_t reserved_9_63:55;
+               uint64_t ooberr:1;
+               uint64_t reserved_7_7:1;
+               uint64_t memsz:3;
+               uint64_t numid:3;
+               uint64_t enable:1;
+       } s;
+       struct cvmx_l2c_vrt_ctl_s cn63xx;
+       struct cvmx_l2c_vrt_ctl_s cn63xxp1;
+};
+
+union cvmx_l2c_vrt_memx {
+       uint64_t u64;
+       struct cvmx_l2c_vrt_memx_s {
+               uint64_t reserved_36_63:28;
+               uint64_t parity:4;
+               uint64_t data:32;
+       } s;
+       struct cvmx_l2c_vrt_memx_s cn63xx;
+       struct cvmx_l2c_vrt_memx_s cn63xxp1;
+};
+
+union cvmx_l2c_wpar_iobx {
+       uint64_t u64;
+       struct cvmx_l2c_wpar_iobx_s {
+               uint64_t reserved_16_63:48;
+               uint64_t mask:16;
+       } s;
+       struct cvmx_l2c_wpar_iobx_s cn63xx;
+       struct cvmx_l2c_wpar_iobx_s cn63xxp1;
+};
+
+union cvmx_l2c_wpar_ppx {
+       uint64_t u64;
+       struct cvmx_l2c_wpar_ppx_s {
+               uint64_t reserved_16_63:48;
+               uint64_t mask:16;
+       } s;
+       struct cvmx_l2c_wpar_ppx_s cn63xx;
+       struct cvmx_l2c_wpar_ppx_s cn63xxp1;
+};
+
+union cvmx_l2c_xmcx_pfc {
+       uint64_t u64;
+       struct cvmx_l2c_xmcx_pfc_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_xmcx_pfc_s cn63xx;
+       struct cvmx_l2c_xmcx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_xmc_cmd {
+       uint64_t u64;
+       struct cvmx_l2c_xmc_cmd_s {
+               uint64_t inuse:1;
+               uint64_t cmd:6;
+               uint64_t reserved_38_56:19;
+               uint64_t addr:38;
+       } s;
+       struct cvmx_l2c_xmc_cmd_s cn63xx;
+       struct cvmx_l2c_xmc_cmd_s cn63xxp1;
+};
+
+union cvmx_l2c_xmdx_pfc {
+       uint64_t u64;
+       struct cvmx_l2c_xmdx_pfc_s {
+               uint64_t count:64;
+       } s;
+       struct cvmx_l2c_xmdx_pfc_s cn63xx;
+       struct cvmx_l2c_xmdx_pfc_s cn63xxp1;
+};
+
 #endif
index 2a8c0902ea505fe00b52c92efc0508d09afe2180..0b32c5b118e2b907abc8d7f83ebc00afb4d24875 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
@@ -26,7 +26,6 @@
  ***********************license end**************************************/
 
 /*
- *
  * Interface to the Level 2 Cache (L2C) control, measurement, and debugging
  * facilities.
  */
 #ifndef __CVMX_L2C_H__
 #define __CVMX_L2C_H__
 
-/* Deprecated macro, use function */
-#define CVMX_L2_ASSOC     cvmx_l2c_get_num_assoc()
-
-/* Deprecated macro, use function */
-#define CVMX_L2_SET_BITS  cvmx_l2c_get_set_bits()
+#define CVMX_L2_ASSOC     cvmx_l2c_get_num_assoc()   /* Deprecated macro, use function */
+#define CVMX_L2_SET_BITS  cvmx_l2c_get_set_bits()    /* Deprecated macro, use function */
+#define CVMX_L2_SETS      cvmx_l2c_get_num_sets()    /* Deprecated macro, use function */
 
-/* Deprecated macro, use function */
-#define CVMX_L2_SETS      cvmx_l2c_get_num_sets()
 
 #define CVMX_L2C_IDX_ADDR_SHIFT 7  /* based on 128 byte cache line size */
 #define CVMX_L2C_IDX_MASK       (cvmx_l2c_get_num_sets() - 1)
 
 /* Defines for index aliasing computations */
-#define CVMX_L2C_TAG_ADDR_ALIAS_SHIFT \
-       (CVMX_L2C_IDX_ADDR_SHIFT + cvmx_l2c_get_set_bits())
+#define CVMX_L2C_TAG_ADDR_ALIAS_SHIFT (CVMX_L2C_IDX_ADDR_SHIFT + cvmx_l2c_get_set_bits())
+#define CVMX_L2C_ALIAS_MASK (CVMX_L2C_IDX_MASK << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT)
+#define CVMX_L2C_MEMBANK_SELECT_SIZE  4096
 
-#define CVMX_L2C_ALIAS_MASK \
-       (CVMX_L2C_IDX_MASK << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT)
+/* Defines for Virtualizations, valid only from Octeon II onwards. */
+#define CVMX_L2C_VRT_MAX_VIRTID_ALLOWED ((OCTEON_IS_MODEL(OCTEON_CN63XX)) ? 64 : 0)
+#define CVMX_L2C_VRT_MAX_MEMSZ_ALLOWED ((OCTEON_IS_MODEL(OCTEON_CN63XX)) ? 32 : 0)
 
 union cvmx_l2c_tag {
        uint64_t u64;
        struct {
                uint64_t reserved:28;
-               uint64_t V:1;   /* Line valid */
-               uint64_t D:1;   /* Line dirty */
-               uint64_t L:1;   /* Line locked */
-               uint64_t U:1;   /* Use, LRU eviction */
+               uint64_t V:1;           /* Line valid */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t L:1;           /* Line locked */
+               uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:32;       /* Phys mem (not all bits valid) */
        } s;
 };
 
+/* Number of L2C Tag-and-data sections (TADs) that are connected to LMC. */
+#define CVMX_L2C_TADS  1
+
   /* L2C Performance Counter events. */
 enum cvmx_l2c_event {
-       CVMX_L2C_EVENT_CYCLES = 0,
-       CVMX_L2C_EVENT_INSTRUCTION_MISS = 1,
-       CVMX_L2C_EVENT_INSTRUCTION_HIT = 2,
-       CVMX_L2C_EVENT_DATA_MISS = 3,
-       CVMX_L2C_EVENT_DATA_HIT = 4,
-       CVMX_L2C_EVENT_MISS = 5,
-       CVMX_L2C_EVENT_HIT = 6,
-       CVMX_L2C_EVENT_VICTIM_HIT = 7,
-       CVMX_L2C_EVENT_INDEX_CONFLICT = 8,
-       CVMX_L2C_EVENT_TAG_PROBE = 9,
-       CVMX_L2C_EVENT_TAG_UPDATE = 10,
-       CVMX_L2C_EVENT_TAG_COMPLETE = 11,
-       CVMX_L2C_EVENT_TAG_DIRTY = 12,
-       CVMX_L2C_EVENT_DATA_STORE_NOP = 13,
-       CVMX_L2C_EVENT_DATA_STORE_READ = 14,
+       CVMX_L2C_EVENT_CYCLES           =  0,
+       CVMX_L2C_EVENT_INSTRUCTION_MISS =  1,
+       CVMX_L2C_EVENT_INSTRUCTION_HIT  =  2,
+       CVMX_L2C_EVENT_DATA_MISS        =  3,
+       CVMX_L2C_EVENT_DATA_HIT         =  4,
+       CVMX_L2C_EVENT_MISS             =  5,
+       CVMX_L2C_EVENT_HIT              =  6,
+       CVMX_L2C_EVENT_VICTIM_HIT       =  7,
+       CVMX_L2C_EVENT_INDEX_CONFLICT   =  8,
+       CVMX_L2C_EVENT_TAG_PROBE        =  9,
+       CVMX_L2C_EVENT_TAG_UPDATE       = 10,
+       CVMX_L2C_EVENT_TAG_COMPLETE     = 11,
+       CVMX_L2C_EVENT_TAG_DIRTY        = 12,
+       CVMX_L2C_EVENT_DATA_STORE_NOP   = 13,
+       CVMX_L2C_EVENT_DATA_STORE_READ  = 14,
        CVMX_L2C_EVENT_DATA_STORE_WRITE = 15,
-       CVMX_L2C_EVENT_FILL_DATA_VALID = 16,
-       CVMX_L2C_EVENT_WRITE_REQUEST = 17,
-       CVMX_L2C_EVENT_READ_REQUEST = 18,
+       CVMX_L2C_EVENT_FILL_DATA_VALID  = 16,
+       CVMX_L2C_EVENT_WRITE_REQUEST    = 17,
+       CVMX_L2C_EVENT_READ_REQUEST     = 18,
        CVMX_L2C_EVENT_WRITE_DATA_VALID = 19,
-       CVMX_L2C_EVENT_XMC_NOP = 20,
-       CVMX_L2C_EVENT_XMC_LDT = 21,
-       CVMX_L2C_EVENT_XMC_LDI = 22,
-       CVMX_L2C_EVENT_XMC_LDD = 23,
-       CVMX_L2C_EVENT_XMC_STF = 24,
-       CVMX_L2C_EVENT_XMC_STT = 25,
-       CVMX_L2C_EVENT_XMC_STP = 26,
-       CVMX_L2C_EVENT_XMC_STC = 27,
-       CVMX_L2C_EVENT_XMC_DWB = 28,
-       CVMX_L2C_EVENT_XMC_PL2 = 29,
-       CVMX_L2C_EVENT_XMC_PSL1 = 30,
-       CVMX_L2C_EVENT_XMC_IOBLD = 31,
-       CVMX_L2C_EVENT_XMC_IOBST = 32,
-       CVMX_L2C_EVENT_XMC_IOBDMA = 33,
-       CVMX_L2C_EVENT_XMC_IOBRSP = 34,
-       CVMX_L2C_EVENT_XMC_BUS_VALID = 35,
-       CVMX_L2C_EVENT_XMC_MEM_DATA = 36,
-       CVMX_L2C_EVENT_XMC_REFL_DATA = 37,
-       CVMX_L2C_EVENT_XMC_IOBRSP_DATA = 38,
-       CVMX_L2C_EVENT_RSC_NOP = 39,
-       CVMX_L2C_EVENT_RSC_STDN = 40,
-       CVMX_L2C_EVENT_RSC_FILL = 41,
-       CVMX_L2C_EVENT_RSC_REFL = 42,
-       CVMX_L2C_EVENT_RSC_STIN = 43,
-       CVMX_L2C_EVENT_RSC_SCIN = 44,
-       CVMX_L2C_EVENT_RSC_SCFL = 45,
-       CVMX_L2C_EVENT_RSC_SCDN = 46,
-       CVMX_L2C_EVENT_RSC_DATA_VALID = 47,
-       CVMX_L2C_EVENT_RSC_VALID_FILL = 48,
-       CVMX_L2C_EVENT_RSC_VALID_STRSP = 49,
-       CVMX_L2C_EVENT_RSC_VALID_REFL = 50,
-       CVMX_L2C_EVENT_LRF_REQ = 51,
-       CVMX_L2C_EVENT_DT_RD_ALLOC = 52,
-       CVMX_L2C_EVENT_DT_WR_INVAL = 53
+       CVMX_L2C_EVENT_XMC_NOP          = 20,
+       CVMX_L2C_EVENT_XMC_LDT          = 21,
+       CVMX_L2C_EVENT_XMC_LDI          = 22,
+       CVMX_L2C_EVENT_XMC_LDD          = 23,
+       CVMX_L2C_EVENT_XMC_STF          = 24,
+       CVMX_L2C_EVENT_XMC_STT          = 25,
+       CVMX_L2C_EVENT_XMC_STP          = 26,
+       CVMX_L2C_EVENT_XMC_STC          = 27,
+       CVMX_L2C_EVENT_XMC_DWB          = 28,
+       CVMX_L2C_EVENT_XMC_PL2          = 29,
+       CVMX_L2C_EVENT_XMC_PSL1         = 30,
+       CVMX_L2C_EVENT_XMC_IOBLD        = 31,
+       CVMX_L2C_EVENT_XMC_IOBST        = 32,
+       CVMX_L2C_EVENT_XMC_IOBDMA       = 33,
+       CVMX_L2C_EVENT_XMC_IOBRSP       = 34,
+       CVMX_L2C_EVENT_XMC_BUS_VALID    = 35,
+       CVMX_L2C_EVENT_XMC_MEM_DATA     = 36,
+       CVMX_L2C_EVENT_XMC_REFL_DATA    = 37,
+       CVMX_L2C_EVENT_XMC_IOBRSP_DATA  = 38,
+       CVMX_L2C_EVENT_RSC_NOP          = 39,
+       CVMX_L2C_EVENT_RSC_STDN         = 40,
+       CVMX_L2C_EVENT_RSC_FILL         = 41,
+       CVMX_L2C_EVENT_RSC_REFL         = 42,
+       CVMX_L2C_EVENT_RSC_STIN         = 43,
+       CVMX_L2C_EVENT_RSC_SCIN         = 44,
+       CVMX_L2C_EVENT_RSC_SCFL         = 45,
+       CVMX_L2C_EVENT_RSC_SCDN         = 46,
+       CVMX_L2C_EVENT_RSC_DATA_VALID   = 47,
+       CVMX_L2C_EVENT_RSC_VALID_FILL   = 48,
+       CVMX_L2C_EVENT_RSC_VALID_STRSP  = 49,
+       CVMX_L2C_EVENT_RSC_VALID_REFL   = 50,
+       CVMX_L2C_EVENT_LRF_REQ          = 51,
+       CVMX_L2C_EVENT_DT_RD_ALLOC      = 52,
+       CVMX_L2C_EVENT_DT_WR_INVAL      = 53,
+       CVMX_L2C_EVENT_MAX
+};
+
+/* L2C Performance Counter events for Octeon2. */
+enum cvmx_l2c_tad_event {
+       CVMX_L2C_TAD_EVENT_NONE          = 0,
+       CVMX_L2C_TAD_EVENT_TAG_HIT       = 1,
+       CVMX_L2C_TAD_EVENT_TAG_MISS      = 2,
+       CVMX_L2C_TAD_EVENT_TAG_NOALLOC   = 3,
+       CVMX_L2C_TAD_EVENT_TAG_VICTIM    = 4,
+       CVMX_L2C_TAD_EVENT_SC_FAIL       = 5,
+       CVMX_L2C_TAD_EVENT_SC_PASS       = 6,
+       CVMX_L2C_TAD_EVENT_LFB_VALID     = 7,
+       CVMX_L2C_TAD_EVENT_LFB_WAIT_LFB  = 8,
+       CVMX_L2C_TAD_EVENT_LFB_WAIT_VAB  = 9,
+       CVMX_L2C_TAD_EVENT_QUAD0_INDEX   = 128,
+       CVMX_L2C_TAD_EVENT_QUAD0_READ    = 129,
+       CVMX_L2C_TAD_EVENT_QUAD0_BANK    = 130,
+       CVMX_L2C_TAD_EVENT_QUAD0_WDAT    = 131,
+       CVMX_L2C_TAD_EVENT_QUAD1_INDEX   = 144,
+       CVMX_L2C_TAD_EVENT_QUAD1_READ    = 145,
+       CVMX_L2C_TAD_EVENT_QUAD1_BANK    = 146,
+       CVMX_L2C_TAD_EVENT_QUAD1_WDAT    = 147,
+       CVMX_L2C_TAD_EVENT_QUAD2_INDEX   = 160,
+       CVMX_L2C_TAD_EVENT_QUAD2_READ    = 161,
+       CVMX_L2C_TAD_EVENT_QUAD2_BANK    = 162,
+       CVMX_L2C_TAD_EVENT_QUAD2_WDAT    = 163,
+       CVMX_L2C_TAD_EVENT_QUAD3_INDEX   = 176,
+       CVMX_L2C_TAD_EVENT_QUAD3_READ    = 177,
+       CVMX_L2C_TAD_EVENT_QUAD3_BANK    = 178,
+       CVMX_L2C_TAD_EVENT_QUAD3_WDAT    = 179,
+       CVMX_L2C_TAD_EVENT_MAX
 };
 
 /**
@@ -132,10 +164,10 @@ enum cvmx_l2c_event {
  * @clear_on_read:  When asserted, any read of the performance counter
  *                       clears the counter.
  *
- * The routine does not clear the counter.
+ * @note The routine does not clear the counter.
  */
-void cvmx_l2c_config_perf(uint32_t counter,
-                         enum cvmx_l2c_event event, uint32_t clear_on_read);
+void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event, uint32_t clear_on_read);
+
 /**
  * Read the given L2 Cache performance counter. The counter must be configured
  * before reading, but this routine does not enforce this requirement.
@@ -160,18 +192,18 @@ int cvmx_l2c_get_core_way_partition(uint32_t core);
 /**
  * Partitions the L2 cache for a core
  *
- * @core:  The core that the partitioning applies to.
+ * @core: The core that the partitioning applies to.
+ * @mask: The partitioning of the ways expressed as a binary
+ *             mask. A 0 bit allows the core to evict cache lines from
+ *             a way, while a 1 bit blocks the core from evicting any
+ *             lines from that way. There must be at least one allowed
+ *             way (0 bit) in the mask.
  *
- * @mask: The partitioning of the ways expressed as a binary mask. A 0
- *        bit allows the core to evict cache lines from a way, while a
- *        1 bit blocks the core from evicting any lines from that
- *        way. There must be at least one allowed way (0 bit) in the
- *        mask.
- *
- * If any ways are blocked for all cores and the HW blocks, then those
- * ways will never have any cache lines evicted from them.  All cores
- * and the hardware blocks are free to read from all ways regardless
- * of the partitioning.
+
+ * @note If any ways are blocked for all cores and the HW blocks, then
+ *       those ways will never have any cache lines evicted from them.
+ *       All cores and the hardware blocks are free to read from all
+ *       ways regardless of the partitioning.
  */
 int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask);
 
@@ -187,19 +219,21 @@ int cvmx_l2c_get_hw_way_partition(void);
 /**
  * Partitions the L2 cache for the hardware blocks.
  *
- * @mask: The partitioning of the ways expressed as a binary mask. A 0
- *        bit allows the core to evict cache lines from a way, while a
- *        1 bit blocks the core from evicting any lines from that
- *        way. There must be at least one allowed way (0 bit) in the
- *        mask.
+ * @mask: The partitioning of the ways expressed as a binary
+ *             mask. A 0 bit allows the core to evict cache lines from
+ *             a way, while a 1 bit blocks the core from evicting any
+ *             lines from that way. There must be at least one allowed
+ *             way (0 bit) in the mask.
  *
- * If any ways are blocked for all cores and the HW blocks, then those
- * ways will never have any cache lines evicted from them.  All cores
- * and the hardware blocks are free to read from all ways regardless
- * of the partitioning.
+
+ * @note If any ways are blocked for all cores and the HW blocks, then
+ *       those ways will never have any cache lines evicted from them.
+ *       All cores and the hardware blocks are free to read from all
+ *       ways regardless of the partitioning.
  */
 int cvmx_l2c_set_hw_way_partition(uint32_t mask);
 
+
 /**
  * Locks a line in the L2 cache at the specified physical address
  *
@@ -263,13 +297,14 @@ int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len);
  */
 union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index);
 
-/* Wrapper around deprecated old function name */
-static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association,
-                                             uint32_t index)
+/* Wrapper providing a deprecated old function name */
+static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association, uint32_t index) __attribute__((deprecated));
+static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association, uint32_t index)
 {
        return cvmx_l2c_get_tag(association, index);
 }
 
+
 /**
  * Returns the cache index for a given physical address
  *
index d7102d455e1b19e476e7fb66cff571dbc57e7416..60543e0e77fc270475fac1cbb7a659f37824ecc3 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_L2D_DEFS_H__
 #define __CVMX_L2D_DEFS_H__
 
-#define CVMX_L2D_BST0 \
-        CVMX_ADD_IO_SEG(0x0001180080000780ull)
-#define CVMX_L2D_BST1 \
-        CVMX_ADD_IO_SEG(0x0001180080000788ull)
-#define CVMX_L2D_BST2 \
-        CVMX_ADD_IO_SEG(0x0001180080000790ull)
-#define CVMX_L2D_BST3 \
-        CVMX_ADD_IO_SEG(0x0001180080000798ull)
-#define CVMX_L2D_ERR \
-        CVMX_ADD_IO_SEG(0x0001180080000010ull)
-#define CVMX_L2D_FADR \
-        CVMX_ADD_IO_SEG(0x0001180080000018ull)
-#define CVMX_L2D_FSYN0 \
-        CVMX_ADD_IO_SEG(0x0001180080000020ull)
-#define CVMX_L2D_FSYN1 \
-        CVMX_ADD_IO_SEG(0x0001180080000028ull)
-#define CVMX_L2D_FUS0 \
-        CVMX_ADD_IO_SEG(0x00011800800007A0ull)
-#define CVMX_L2D_FUS1 \
-        CVMX_ADD_IO_SEG(0x00011800800007A8ull)
-#define CVMX_L2D_FUS2 \
-        CVMX_ADD_IO_SEG(0x00011800800007B0ull)
-#define CVMX_L2D_FUS3 \
-        CVMX_ADD_IO_SEG(0x00011800800007B8ull)
+#define CVMX_L2D_BST0 (CVMX_ADD_IO_SEG(0x0001180080000780ull))
+#define CVMX_L2D_BST1 (CVMX_ADD_IO_SEG(0x0001180080000788ull))
+#define CVMX_L2D_BST2 (CVMX_ADD_IO_SEG(0x0001180080000790ull))
+#define CVMX_L2D_BST3 (CVMX_ADD_IO_SEG(0x0001180080000798ull))
+#define CVMX_L2D_ERR (CVMX_ADD_IO_SEG(0x0001180080000010ull))
+#define CVMX_L2D_FADR (CVMX_ADD_IO_SEG(0x0001180080000018ull))
+#define CVMX_L2D_FSYN0 (CVMX_ADD_IO_SEG(0x0001180080000020ull))
+#define CVMX_L2D_FSYN1 (CVMX_ADD_IO_SEG(0x0001180080000028ull))
+#define CVMX_L2D_FUS0 (CVMX_ADD_IO_SEG(0x00011800800007A0ull))
+#define CVMX_L2D_FUS1 (CVMX_ADD_IO_SEG(0x00011800800007A8ull))
+#define CVMX_L2D_FUS2 (CVMX_ADD_IO_SEG(0x00011800800007B0ull))
+#define CVMX_L2D_FUS3 (CVMX_ADD_IO_SEG(0x00011800800007B8ull))
 
 union cvmx_l2d_bst0 {
        uint64_t u64;
index 2639a3f5ffc207118180d47a525b4e8e4284cc0e..873968f55eeb08ade79ae054cced219254f57cfc 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
@@ -28,8 +28,7 @@
 #ifndef __CVMX_L2T_DEFS_H__
 #define __CVMX_L2T_DEFS_H__
 
-#define CVMX_L2T_ERR \
-        CVMX_ADD_IO_SEG(0x0001180080000008ull)
+#define CVMX_L2T_ERR (CVMX_ADD_IO_SEG(0x0001180080000008ull))
 
 union cvmx_l2t_err {
        uint64_t u64;
index 16f174a4dadf664b2a67a03fcf6025c5b74cd3c5..e25173bb8bb7d4a8d800280a015f752ea4501a73 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_LED_DEFS_H__
 #define __CVMX_LED_DEFS_H__
 
-#define CVMX_LED_BLINK \
-        CVMX_ADD_IO_SEG(0x0001180000001A48ull)
-#define CVMX_LED_CLK_PHASE \
-        CVMX_ADD_IO_SEG(0x0001180000001A08ull)
-#define CVMX_LED_CYLON \
-        CVMX_ADD_IO_SEG(0x0001180000001AF8ull)
-#define CVMX_LED_DBG \
-        CVMX_ADD_IO_SEG(0x0001180000001A18ull)
-#define CVMX_LED_EN \
-        CVMX_ADD_IO_SEG(0x0001180000001A00ull)
-#define CVMX_LED_POLARITY \
-        CVMX_ADD_IO_SEG(0x0001180000001A50ull)
-#define CVMX_LED_PRT \
-        CVMX_ADD_IO_SEG(0x0001180000001A10ull)
-#define CVMX_LED_PRT_FMT \
-        CVMX_ADD_IO_SEG(0x0001180000001A30ull)
-#define CVMX_LED_PRT_STATUSX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001A80ull + (((offset) & 7) * 8))
-#define CVMX_LED_UDD_CNTX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001A20ull + (((offset) & 1) * 8))
-#define CVMX_LED_UDD_DATX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001A38ull + (((offset) & 1) * 8))
-#define CVMX_LED_UDD_DAT_CLRX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001AC8ull + (((offset) & 1) * 16))
-#define CVMX_LED_UDD_DAT_SETX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001AC0ull + (((offset) & 1) * 16))
+#define CVMX_LED_BLINK (CVMX_ADD_IO_SEG(0x0001180000001A48ull))
+#define CVMX_LED_CLK_PHASE (CVMX_ADD_IO_SEG(0x0001180000001A08ull))
+#define CVMX_LED_CYLON (CVMX_ADD_IO_SEG(0x0001180000001AF8ull))
+#define CVMX_LED_DBG (CVMX_ADD_IO_SEG(0x0001180000001A18ull))
+#define CVMX_LED_EN (CVMX_ADD_IO_SEG(0x0001180000001A00ull))
+#define CVMX_LED_POLARITY (CVMX_ADD_IO_SEG(0x0001180000001A50ull))
+#define CVMX_LED_PRT (CVMX_ADD_IO_SEG(0x0001180000001A10ull))
+#define CVMX_LED_PRT_FMT (CVMX_ADD_IO_SEG(0x0001180000001A30ull))
+#define CVMX_LED_PRT_STATUSX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A80ull) + ((offset) & 7) * 8)
+#define CVMX_LED_UDD_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A20ull) + ((offset) & 1) * 8)
+#define CVMX_LED_UDD_DATX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A38ull) + ((offset) & 1) * 8)
+#define CVMX_LED_UDD_DAT_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001180000001AC8ull) + ((offset) & 1) * 16)
+#define CVMX_LED_UDD_DAT_SETX(offset) (CVMX_ADD_IO_SEG(0x0001180000001AC0ull) + ((offset) & 1) * 16)
 
 union cvmx_led_blink {
        uint64_t u64;
index 6555f05309887967f04e8040b8725c683b492912..52b14a333ad44ada1b25b3bfc0e0475743fa4e23 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_MIO_DEFS_H__
 #define __CVMX_MIO_DEFS_H__
 
-#define CVMX_MIO_BOOT_BIST_STAT \
-        CVMX_ADD_IO_SEG(0x00011800000000F8ull)
-#define CVMX_MIO_BOOT_COMP \
-        CVMX_ADD_IO_SEG(0x00011800000000B8ull)
-#define CVMX_MIO_BOOT_DMA_CFGX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000100ull + (((offset) & 3) * 8))
-#define CVMX_MIO_BOOT_DMA_INTX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000138ull + (((offset) & 3) * 8))
-#define CVMX_MIO_BOOT_DMA_INT_ENX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000150ull + (((offset) & 3) * 8))
-#define CVMX_MIO_BOOT_DMA_TIMX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000120ull + (((offset) & 3) * 8))
-#define CVMX_MIO_BOOT_ERR \
-        CVMX_ADD_IO_SEG(0x00011800000000A0ull)
-#define CVMX_MIO_BOOT_INT \
-        CVMX_ADD_IO_SEG(0x00011800000000A8ull)
-#define CVMX_MIO_BOOT_LOC_ADR \
-        CVMX_ADD_IO_SEG(0x0001180000000090ull)
-#define CVMX_MIO_BOOT_LOC_CFGX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000080ull + (((offset) & 1) * 8))
-#define CVMX_MIO_BOOT_LOC_DAT \
-        CVMX_ADD_IO_SEG(0x0001180000000098ull)
-#define CVMX_MIO_BOOT_PIN_DEFS \
-        CVMX_ADD_IO_SEG(0x00011800000000C0ull)
-#define CVMX_MIO_BOOT_REG_CFGX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000000ull + (((offset) & 7) * 8))
-#define CVMX_MIO_BOOT_REG_TIMX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000040ull + (((offset) & 7) * 8))
-#define CVMX_MIO_BOOT_THR \
-        CVMX_ADD_IO_SEG(0x00011800000000B0ull)
-#define CVMX_MIO_FUS_BNK_DATX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001520ull + (((offset) & 3) * 8))
-#define CVMX_MIO_FUS_DAT0 \
-        CVMX_ADD_IO_SEG(0x0001180000001400ull)
-#define CVMX_MIO_FUS_DAT1 \
-        CVMX_ADD_IO_SEG(0x0001180000001408ull)
-#define CVMX_MIO_FUS_DAT2 \
-        CVMX_ADD_IO_SEG(0x0001180000001410ull)
-#define CVMX_MIO_FUS_DAT3 \
-        CVMX_ADD_IO_SEG(0x0001180000001418ull)
-#define CVMX_MIO_FUS_EMA \
-        CVMX_ADD_IO_SEG(0x0001180000001550ull)
-#define CVMX_MIO_FUS_PDF \
-        CVMX_ADD_IO_SEG(0x0001180000001420ull)
-#define CVMX_MIO_FUS_PLL \
-        CVMX_ADD_IO_SEG(0x0001180000001580ull)
-#define CVMX_MIO_FUS_PROG \
-        CVMX_ADD_IO_SEG(0x0001180000001510ull)
-#define CVMX_MIO_FUS_PROG_TIMES \
-        CVMX_ADD_IO_SEG(0x0001180000001518ull)
-#define CVMX_MIO_FUS_RCMD \
-        CVMX_ADD_IO_SEG(0x0001180000001500ull)
-#define CVMX_MIO_FUS_SPR_REPAIR_RES \
-        CVMX_ADD_IO_SEG(0x0001180000001548ull)
-#define CVMX_MIO_FUS_SPR_REPAIR_SUM \
-        CVMX_ADD_IO_SEG(0x0001180000001540ull)
-#define CVMX_MIO_FUS_UNLOCK \
-        CVMX_ADD_IO_SEG(0x0001180000001578ull)
-#define CVMX_MIO_FUS_WADR \
-        CVMX_ADD_IO_SEG(0x0001180000001508ull)
-#define CVMX_MIO_NDF_DMA_CFG \
-        CVMX_ADD_IO_SEG(0x0001180000000168ull)
-#define CVMX_MIO_NDF_DMA_INT \
-        CVMX_ADD_IO_SEG(0x0001180000000170ull)
-#define CVMX_MIO_NDF_DMA_INT_EN \
-        CVMX_ADD_IO_SEG(0x0001180000000178ull)
-#define CVMX_MIO_PLL_CTL \
-        CVMX_ADD_IO_SEG(0x0001180000001448ull)
-#define CVMX_MIO_PLL_SETTING \
-        CVMX_ADD_IO_SEG(0x0001180000001440ull)
-#define CVMX_MIO_TWSX_INT(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001010ull + (((offset) & 1) * 512))
-#define CVMX_MIO_TWSX_SW_TWSI(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001000ull + (((offset) & 1) * 512))
-#define CVMX_MIO_TWSX_SW_TWSI_EXT(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001018ull + (((offset) & 1) * 512))
-#define CVMX_MIO_TWSX_TWSI_SW(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001008ull + (((offset) & 1) * 512))
-#define CVMX_MIO_UART2_DLH \
-        CVMX_ADD_IO_SEG(0x0001180000000488ull)
-#define CVMX_MIO_UART2_DLL \
-        CVMX_ADD_IO_SEG(0x0001180000000480ull)
-#define CVMX_MIO_UART2_FAR \
-        CVMX_ADD_IO_SEG(0x0001180000000520ull)
-#define CVMX_MIO_UART2_FCR \
-        CVMX_ADD_IO_SEG(0x0001180000000450ull)
-#define CVMX_MIO_UART2_HTX \
-        CVMX_ADD_IO_SEG(0x0001180000000708ull)
-#define CVMX_MIO_UART2_IER \
-        CVMX_ADD_IO_SEG(0x0001180000000408ull)
-#define CVMX_MIO_UART2_IIR \
-        CVMX_ADD_IO_SEG(0x0001180000000410ull)
-#define CVMX_MIO_UART2_LCR \
-        CVMX_ADD_IO_SEG(0x0001180000000418ull)
-#define CVMX_MIO_UART2_LSR \
-        CVMX_ADD_IO_SEG(0x0001180000000428ull)
-#define CVMX_MIO_UART2_MCR \
-        CVMX_ADD_IO_SEG(0x0001180000000420ull)
-#define CVMX_MIO_UART2_MSR \
-        CVMX_ADD_IO_SEG(0x0001180000000430ull)
-#define CVMX_MIO_UART2_RBR \
-        CVMX_ADD_IO_SEG(0x0001180000000400ull)
-#define CVMX_MIO_UART2_RFL \
-        CVMX_ADD_IO_SEG(0x0001180000000608ull)
-#define CVMX_MIO_UART2_RFW \
-        CVMX_ADD_IO_SEG(0x0001180000000530ull)
-#define CVMX_MIO_UART2_SBCR \
-        CVMX_ADD_IO_SEG(0x0001180000000620ull)
-#define CVMX_MIO_UART2_SCR \
-        CVMX_ADD_IO_SEG(0x0001180000000438ull)
-#define CVMX_MIO_UART2_SFE \
-        CVMX_ADD_IO_SEG(0x0001180000000630ull)
-#define CVMX_MIO_UART2_SRR \
-        CVMX_ADD_IO_SEG(0x0001180000000610ull)
-#define CVMX_MIO_UART2_SRT \
-        CVMX_ADD_IO_SEG(0x0001180000000638ull)
-#define CVMX_MIO_UART2_SRTS \
-        CVMX_ADD_IO_SEG(0x0001180000000618ull)
-#define CVMX_MIO_UART2_STT \
-        CVMX_ADD_IO_SEG(0x0001180000000700ull)
-#define CVMX_MIO_UART2_TFL \
-        CVMX_ADD_IO_SEG(0x0001180000000600ull)
-#define CVMX_MIO_UART2_TFR \
-        CVMX_ADD_IO_SEG(0x0001180000000528ull)
-#define CVMX_MIO_UART2_THR \
-        CVMX_ADD_IO_SEG(0x0001180000000440ull)
-#define CVMX_MIO_UART2_USR \
-        CVMX_ADD_IO_SEG(0x0001180000000538ull)
-#define CVMX_MIO_UARTX_DLH(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000888ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_DLL(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000880ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_FAR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000920ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_FCR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000850ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_HTX(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000B08ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_IER(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000808ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_IIR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000810ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_LCR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000818ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_LSR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000828ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_MCR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000820ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_MSR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000830ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_RBR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000800ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_RFL(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000A08ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_RFW(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000930ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SBCR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000A20ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SCR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000838ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SFE(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000A30ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SRR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000A10ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SRT(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000A38ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_SRTS(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000A18ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_STT(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000B00ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_TFL(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000A00ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_TFR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000928ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_THR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000840ull + (((offset) & 1) * 1024))
-#define CVMX_MIO_UARTX_USR(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000000938ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_BOOT_BIST_STAT (CVMX_ADD_IO_SEG(0x00011800000000F8ull))
+#define CVMX_MIO_BOOT_COMP (CVMX_ADD_IO_SEG(0x00011800000000B8ull))
+#define CVMX_MIO_BOOT_DMA_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000100ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_DMA_INTX(offset) (CVMX_ADD_IO_SEG(0x0001180000000138ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_DMA_INT_ENX(offset) (CVMX_ADD_IO_SEG(0x0001180000000150ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_DMA_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001180000000120ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_ERR (CVMX_ADD_IO_SEG(0x00011800000000A0ull))
+#define CVMX_MIO_BOOT_INT (CVMX_ADD_IO_SEG(0x00011800000000A8ull))
+#define CVMX_MIO_BOOT_LOC_ADR (CVMX_ADD_IO_SEG(0x0001180000000090ull))
+#define CVMX_MIO_BOOT_LOC_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000080ull) + ((offset) & 1) * 8)
+#define CVMX_MIO_BOOT_LOC_DAT (CVMX_ADD_IO_SEG(0x0001180000000098ull))
+#define CVMX_MIO_BOOT_PIN_DEFS (CVMX_ADD_IO_SEG(0x00011800000000C0ull))
+#define CVMX_MIO_BOOT_REG_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000000ull) + ((offset) & 7) * 8)
+#define CVMX_MIO_BOOT_REG_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001180000000040ull) + ((offset) & 7) * 8)
+#define CVMX_MIO_BOOT_THR (CVMX_ADD_IO_SEG(0x00011800000000B0ull))
+#define CVMX_MIO_FUS_BNK_DATX(offset) (CVMX_ADD_IO_SEG(0x0001180000001520ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_FUS_DAT0 (CVMX_ADD_IO_SEG(0x0001180000001400ull))
+#define CVMX_MIO_FUS_DAT1 (CVMX_ADD_IO_SEG(0x0001180000001408ull))
+#define CVMX_MIO_FUS_DAT2 (CVMX_ADD_IO_SEG(0x0001180000001410ull))
+#define CVMX_MIO_FUS_DAT3 (CVMX_ADD_IO_SEG(0x0001180000001418ull))
+#define CVMX_MIO_FUS_EMA (CVMX_ADD_IO_SEG(0x0001180000001550ull))
+#define CVMX_MIO_FUS_PDF (CVMX_ADD_IO_SEG(0x0001180000001420ull))
+#define CVMX_MIO_FUS_PLL (CVMX_ADD_IO_SEG(0x0001180000001580ull))
+#define CVMX_MIO_FUS_PROG (CVMX_ADD_IO_SEG(0x0001180000001510ull))
+#define CVMX_MIO_FUS_PROG_TIMES (CVMX_ADD_IO_SEG(0x0001180000001518ull))
+#define CVMX_MIO_FUS_RCMD (CVMX_ADD_IO_SEG(0x0001180000001500ull))
+#define CVMX_MIO_FUS_READ_TIMES (CVMX_ADD_IO_SEG(0x0001180000001570ull))
+#define CVMX_MIO_FUS_REPAIR_RES0 (CVMX_ADD_IO_SEG(0x0001180000001558ull))
+#define CVMX_MIO_FUS_REPAIR_RES1 (CVMX_ADD_IO_SEG(0x0001180000001560ull))
+#define CVMX_MIO_FUS_REPAIR_RES2 (CVMX_ADD_IO_SEG(0x0001180000001568ull))
+#define CVMX_MIO_FUS_SPR_REPAIR_RES (CVMX_ADD_IO_SEG(0x0001180000001548ull))
+#define CVMX_MIO_FUS_SPR_REPAIR_SUM (CVMX_ADD_IO_SEG(0x0001180000001540ull))
+#define CVMX_MIO_FUS_UNLOCK (CVMX_ADD_IO_SEG(0x0001180000001578ull))
+#define CVMX_MIO_FUS_WADR (CVMX_ADD_IO_SEG(0x0001180000001508ull))
+#define CVMX_MIO_GPIO_COMP (CVMX_ADD_IO_SEG(0x00011800000000C8ull))
+#define CVMX_MIO_NDF_DMA_CFG (CVMX_ADD_IO_SEG(0x0001180000000168ull))
+#define CVMX_MIO_NDF_DMA_INT (CVMX_ADD_IO_SEG(0x0001180000000170ull))
+#define CVMX_MIO_NDF_DMA_INT_EN (CVMX_ADD_IO_SEG(0x0001180000000178ull))
+#define CVMX_MIO_PLL_CTL (CVMX_ADD_IO_SEG(0x0001180000001448ull))
+#define CVMX_MIO_PLL_SETTING (CVMX_ADD_IO_SEG(0x0001180000001440ull))
+#define CVMX_MIO_PTP_CLOCK_CFG (CVMX_ADD_IO_SEG(0x0001070000000F00ull))
+#define CVMX_MIO_PTP_CLOCK_COMP (CVMX_ADD_IO_SEG(0x0001070000000F18ull))
+#define CVMX_MIO_PTP_CLOCK_HI (CVMX_ADD_IO_SEG(0x0001070000000F10ull))
+#define CVMX_MIO_PTP_CLOCK_LO (CVMX_ADD_IO_SEG(0x0001070000000F08ull))
+#define CVMX_MIO_PTP_EVT_CNT (CVMX_ADD_IO_SEG(0x0001070000000F28ull))
+#define CVMX_MIO_PTP_TIMESTAMP (CVMX_ADD_IO_SEG(0x0001070000000F20ull))
+#define CVMX_MIO_RST_BOOT (CVMX_ADD_IO_SEG(0x0001180000001600ull))
+#define CVMX_MIO_RST_CFG (CVMX_ADD_IO_SEG(0x0001180000001610ull))
+#define CVMX_MIO_RST_CTLX(offset) (CVMX_ADD_IO_SEG(0x0001180000001618ull) + ((offset) & 1) * 8)
+#define CVMX_MIO_RST_DELAY (CVMX_ADD_IO_SEG(0x0001180000001608ull))
+#define CVMX_MIO_RST_INT (CVMX_ADD_IO_SEG(0x0001180000001628ull))
+#define CVMX_MIO_RST_INT_EN (CVMX_ADD_IO_SEG(0x0001180000001630ull))
+#define CVMX_MIO_TWSX_INT(offset) (CVMX_ADD_IO_SEG(0x0001180000001010ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_TWSX_SW_TWSI(offset) (CVMX_ADD_IO_SEG(0x0001180000001000ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_TWSX_SW_TWSI_EXT(offset) (CVMX_ADD_IO_SEG(0x0001180000001018ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_TWSX_TWSI_SW(offset) (CVMX_ADD_IO_SEG(0x0001180000001008ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_UART2_DLH (CVMX_ADD_IO_SEG(0x0001180000000488ull))
+#define CVMX_MIO_UART2_DLL (CVMX_ADD_IO_SEG(0x0001180000000480ull))
+#define CVMX_MIO_UART2_FAR (CVMX_ADD_IO_SEG(0x0001180000000520ull))
+#define CVMX_MIO_UART2_FCR (CVMX_ADD_IO_SEG(0x0001180000000450ull))
+#define CVMX_MIO_UART2_HTX (CVMX_ADD_IO_SEG(0x0001180000000708ull))
+#define CVMX_MIO_UART2_IER (CVMX_ADD_IO_SEG(0x0001180000000408ull))
+#define CVMX_MIO_UART2_IIR (CVMX_ADD_IO_SEG(0x0001180000000410ull))
+#define CVMX_MIO_UART2_LCR (CVMX_ADD_IO_SEG(0x0001180000000418ull))
+#define CVMX_MIO_UART2_LSR (CVMX_ADD_IO_SEG(0x0001180000000428ull))
+#define CVMX_MIO_UART2_MCR (CVMX_ADD_IO_SEG(0x0001180000000420ull))
+#define CVMX_MIO_UART2_MSR (CVMX_ADD_IO_SEG(0x0001180000000430ull))
+#define CVMX_MIO_UART2_RBR (CVMX_ADD_IO_SEG(0x0001180000000400ull))
+#define CVMX_MIO_UART2_RFL (CVMX_ADD_IO_SEG(0x0001180000000608ull))
+#define CVMX_MIO_UART2_RFW (CVMX_ADD_IO_SEG(0x0001180000000530ull))
+#define CVMX_MIO_UART2_SBCR (CVMX_ADD_IO_SEG(0x0001180000000620ull))
+#define CVMX_MIO_UART2_SCR (CVMX_ADD_IO_SEG(0x0001180000000438ull))
+#define CVMX_MIO_UART2_SFE (CVMX_ADD_IO_SEG(0x0001180000000630ull))
+#define CVMX_MIO_UART2_SRR (CVMX_ADD_IO_SEG(0x0001180000000610ull))
+#define CVMX_MIO_UART2_SRT (CVMX_ADD_IO_SEG(0x0001180000000638ull))
+#define CVMX_MIO_UART2_SRTS (CVMX_ADD_IO_SEG(0x0001180000000618ull))
+#define CVMX_MIO_UART2_STT (CVMX_ADD_IO_SEG(0x0001180000000700ull))
+#define CVMX_MIO_UART2_TFL (CVMX_ADD_IO_SEG(0x0001180000000600ull))
+#define CVMX_MIO_UART2_TFR (CVMX_ADD_IO_SEG(0x0001180000000528ull))
+#define CVMX_MIO_UART2_THR (CVMX_ADD_IO_SEG(0x0001180000000440ull))
+#define CVMX_MIO_UART2_USR (CVMX_ADD_IO_SEG(0x0001180000000538ull))
+#define CVMX_MIO_UARTX_DLH(offset) (CVMX_ADD_IO_SEG(0x0001180000000888ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_DLL(offset) (CVMX_ADD_IO_SEG(0x0001180000000880ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_FAR(offset) (CVMX_ADD_IO_SEG(0x0001180000000920ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_FCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000850ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_HTX(offset) (CVMX_ADD_IO_SEG(0x0001180000000B08ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_IER(offset) (CVMX_ADD_IO_SEG(0x0001180000000808ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_IIR(offset) (CVMX_ADD_IO_SEG(0x0001180000000810ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_LCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000818ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_LSR(offset) (CVMX_ADD_IO_SEG(0x0001180000000828ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_MCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000820ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_MSR(offset) (CVMX_ADD_IO_SEG(0x0001180000000830ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_RBR(offset) (CVMX_ADD_IO_SEG(0x0001180000000800ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_RFL(offset) (CVMX_ADD_IO_SEG(0x0001180000000A08ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_RFW(offset) (CVMX_ADD_IO_SEG(0x0001180000000930ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SBCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000A20ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000838ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SFE(offset) (CVMX_ADD_IO_SEG(0x0001180000000A30ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SRR(offset) (CVMX_ADD_IO_SEG(0x0001180000000A10ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SRT(offset) (CVMX_ADD_IO_SEG(0x0001180000000A38ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SRTS(offset) (CVMX_ADD_IO_SEG(0x0001180000000A18ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_STT(offset) (CVMX_ADD_IO_SEG(0x0001180000000B00ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_TFL(offset) (CVMX_ADD_IO_SEG(0x0001180000000A00ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_TFR(offset) (CVMX_ADD_IO_SEG(0x0001180000000928ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_THR(offset) (CVMX_ADD_IO_SEG(0x0001180000000840ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_USR(offset) (CVMX_ADD_IO_SEG(0x0001180000000938ull) + ((offset) & 1) * 1024)
 
 union cvmx_mio_boot_bist_stat {
        uint64_t u64;
        struct cvmx_mio_boot_bist_stat_s {
-               uint64_t reserved_2_63:62;
-               uint64_t loc:1;
-               uint64_t ncbi:1;
+               uint64_t reserved_0_63:64;
        } s;
        struct cvmx_mio_boot_bist_stat_cn30xx {
                uint64_t reserved_4_63:60;
@@ -257,20 +183,33 @@ union cvmx_mio_boot_bist_stat {
        struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xxp1;
        struct cvmx_mio_boot_bist_stat_cn38xx cn58xx;
        struct cvmx_mio_boot_bist_stat_cn38xx cn58xxp1;
+       struct cvmx_mio_boot_bist_stat_cn63xx {
+               uint64_t reserved_9_63:55;
+               uint64_t stat:9;
+       } cn63xx;
+       struct cvmx_mio_boot_bist_stat_cn63xx cn63xxp1;
 };
 
 union cvmx_mio_boot_comp {
        uint64_t u64;
        struct cvmx_mio_boot_comp_s {
+               uint64_t reserved_0_63:64;
+       } s;
+       struct cvmx_mio_boot_comp_cn50xx {
                uint64_t reserved_10_63:54;
                uint64_t pctl:5;
                uint64_t nctl:5;
-       } s;
-       struct cvmx_mio_boot_comp_s cn50xx;
-       struct cvmx_mio_boot_comp_s cn52xx;
-       struct cvmx_mio_boot_comp_s cn52xxp1;
-       struct cvmx_mio_boot_comp_s cn56xx;
-       struct cvmx_mio_boot_comp_s cn56xxp1;
+       } cn50xx;
+       struct cvmx_mio_boot_comp_cn50xx cn52xx;
+       struct cvmx_mio_boot_comp_cn50xx cn52xxp1;
+       struct cvmx_mio_boot_comp_cn50xx cn56xx;
+       struct cvmx_mio_boot_comp_cn50xx cn56xxp1;
+       struct cvmx_mio_boot_comp_cn63xx {
+               uint64_t reserved_12_63:52;
+               uint64_t pctl:6;
+               uint64_t nctl:6;
+       } cn63xx;
+       struct cvmx_mio_boot_comp_cn63xx cn63xxp1;
 };
 
 union cvmx_mio_boot_dma_cfgx {
@@ -291,6 +230,8 @@ union cvmx_mio_boot_dma_cfgx {
        struct cvmx_mio_boot_dma_cfgx_s cn52xxp1;
        struct cvmx_mio_boot_dma_cfgx_s cn56xx;
        struct cvmx_mio_boot_dma_cfgx_s cn56xxp1;
+       struct cvmx_mio_boot_dma_cfgx_s cn63xx;
+       struct cvmx_mio_boot_dma_cfgx_s cn63xxp1;
 };
 
 union cvmx_mio_boot_dma_intx {
@@ -304,6 +245,8 @@ union cvmx_mio_boot_dma_intx {
        struct cvmx_mio_boot_dma_intx_s cn52xxp1;
        struct cvmx_mio_boot_dma_intx_s cn56xx;
        struct cvmx_mio_boot_dma_intx_s cn56xxp1;
+       struct cvmx_mio_boot_dma_intx_s cn63xx;
+       struct cvmx_mio_boot_dma_intx_s cn63xxp1;
 };
 
 union cvmx_mio_boot_dma_int_enx {
@@ -317,6 +260,8 @@ union cvmx_mio_boot_dma_int_enx {
        struct cvmx_mio_boot_dma_int_enx_s cn52xxp1;
        struct cvmx_mio_boot_dma_int_enx_s cn56xx;
        struct cvmx_mio_boot_dma_int_enx_s cn56xxp1;
+       struct cvmx_mio_boot_dma_int_enx_s cn63xx;
+       struct cvmx_mio_boot_dma_int_enx_s cn63xxp1;
 };
 
 union cvmx_mio_boot_dma_timx {
@@ -342,6 +287,8 @@ union cvmx_mio_boot_dma_timx {
        struct cvmx_mio_boot_dma_timx_s cn52xxp1;
        struct cvmx_mio_boot_dma_timx_s cn56xx;
        struct cvmx_mio_boot_dma_timx_s cn56xxp1;
+       struct cvmx_mio_boot_dma_timx_s cn63xx;
+       struct cvmx_mio_boot_dma_timx_s cn63xxp1;
 };
 
 union cvmx_mio_boot_err {
@@ -362,6 +309,8 @@ union cvmx_mio_boot_err {
        struct cvmx_mio_boot_err_s cn56xxp1;
        struct cvmx_mio_boot_err_s cn58xx;
        struct cvmx_mio_boot_err_s cn58xxp1;
+       struct cvmx_mio_boot_err_s cn63xx;
+       struct cvmx_mio_boot_err_s cn63xxp1;
 };
 
 union cvmx_mio_boot_int {
@@ -382,6 +331,8 @@ union cvmx_mio_boot_int {
        struct cvmx_mio_boot_int_s cn56xxp1;
        struct cvmx_mio_boot_int_s cn58xx;
        struct cvmx_mio_boot_int_s cn58xxp1;
+       struct cvmx_mio_boot_int_s cn63xx;
+       struct cvmx_mio_boot_int_s cn63xxp1;
 };
 
 union cvmx_mio_boot_loc_adr {
@@ -402,6 +353,8 @@ union cvmx_mio_boot_loc_adr {
        struct cvmx_mio_boot_loc_adr_s cn56xxp1;
        struct cvmx_mio_boot_loc_adr_s cn58xx;
        struct cvmx_mio_boot_loc_adr_s cn58xxp1;
+       struct cvmx_mio_boot_loc_adr_s cn63xx;
+       struct cvmx_mio_boot_loc_adr_s cn63xxp1;
 };
 
 union cvmx_mio_boot_loc_cfgx {
@@ -424,6 +377,8 @@ union cvmx_mio_boot_loc_cfgx {
        struct cvmx_mio_boot_loc_cfgx_s cn56xxp1;
        struct cvmx_mio_boot_loc_cfgx_s cn58xx;
        struct cvmx_mio_boot_loc_cfgx_s cn58xxp1;
+       struct cvmx_mio_boot_loc_cfgx_s cn63xx;
+       struct cvmx_mio_boot_loc_cfgx_s cn63xxp1;
 };
 
 union cvmx_mio_boot_loc_dat {
@@ -442,6 +397,8 @@ union cvmx_mio_boot_loc_dat {
        struct cvmx_mio_boot_loc_dat_s cn56xxp1;
        struct cvmx_mio_boot_loc_dat_s cn58xx;
        struct cvmx_mio_boot_loc_dat_s cn58xxp1;
+       struct cvmx_mio_boot_loc_dat_s cn63xx;
+       struct cvmx_mio_boot_loc_dat_s cn63xxp1;
 };
 
 union cvmx_mio_boot_pin_defs {
@@ -478,6 +435,8 @@ union cvmx_mio_boot_pin_defs {
                uint64_t term:2;
                uint64_t reserved_0_8:9;
        } cn56xx;
+       struct cvmx_mio_boot_pin_defs_cn52xx cn63xx;
+       struct cvmx_mio_boot_pin_defs_cn52xx cn63xxp1;
 };
 
 union cvmx_mio_boot_reg_cfgx {
@@ -539,6 +498,8 @@ union cvmx_mio_boot_reg_cfgx {
        struct cvmx_mio_boot_reg_cfgx_s cn56xxp1;
        struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xx;
        struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xxp1;
+       struct cvmx_mio_boot_reg_cfgx_s cn63xx;
+       struct cvmx_mio_boot_reg_cfgx_s cn63xxp1;
 };
 
 union cvmx_mio_boot_reg_timx {
@@ -583,6 +544,8 @@ union cvmx_mio_boot_reg_timx {
        struct cvmx_mio_boot_reg_timx_s cn56xxp1;
        struct cvmx_mio_boot_reg_timx_s cn58xx;
        struct cvmx_mio_boot_reg_timx_s cn58xxp1;
+       struct cvmx_mio_boot_reg_timx_s cn63xx;
+       struct cvmx_mio_boot_reg_timx_s cn63xxp1;
 };
 
 union cvmx_mio_boot_thr {
@@ -611,6 +574,8 @@ union cvmx_mio_boot_thr {
        struct cvmx_mio_boot_thr_s cn56xxp1;
        struct cvmx_mio_boot_thr_cn30xx cn58xx;
        struct cvmx_mio_boot_thr_cn30xx cn58xxp1;
+       struct cvmx_mio_boot_thr_s cn63xx;
+       struct cvmx_mio_boot_thr_s cn63xxp1;
 };
 
 union cvmx_mio_fus_bnk_datx {
@@ -625,6 +590,8 @@ union cvmx_mio_fus_bnk_datx {
        struct cvmx_mio_fus_bnk_datx_s cn56xxp1;
        struct cvmx_mio_fus_bnk_datx_s cn58xx;
        struct cvmx_mio_fus_bnk_datx_s cn58xxp1;
+       struct cvmx_mio_fus_bnk_datx_s cn63xx;
+       struct cvmx_mio_fus_bnk_datx_s cn63xxp1;
 };
 
 union cvmx_mio_fus_dat0 {
@@ -644,6 +611,8 @@ union cvmx_mio_fus_dat0 {
        struct cvmx_mio_fus_dat0_s cn56xxp1;
        struct cvmx_mio_fus_dat0_s cn58xx;
        struct cvmx_mio_fus_dat0_s cn58xxp1;
+       struct cvmx_mio_fus_dat0_s cn63xx;
+       struct cvmx_mio_fus_dat0_s cn63xxp1;
 };
 
 union cvmx_mio_fus_dat1 {
@@ -663,12 +632,15 @@ union cvmx_mio_fus_dat1 {
        struct cvmx_mio_fus_dat1_s cn56xxp1;
        struct cvmx_mio_fus_dat1_s cn58xx;
        struct cvmx_mio_fus_dat1_s cn58xxp1;
+       struct cvmx_mio_fus_dat1_s cn63xx;
+       struct cvmx_mio_fus_dat1_s cn63xxp1;
 };
 
 union cvmx_mio_fus_dat2 {
        uint64_t u64;
        struct cvmx_mio_fus_dat2_s {
-               uint64_t reserved_34_63:30;
+               uint64_t reserved_35_63:29;
+               uint64_t dorm_crypto:1;
                uint64_t fus318:1;
                uint64_t raid_en:1;
                uint64_t reserved_30_31:2;
@@ -775,14 +747,38 @@ union cvmx_mio_fus_dat2 {
                uint64_t pp_dis:16;
        } cn58xx;
        struct cvmx_mio_fus_dat2_cn58xx cn58xxp1;
+       struct cvmx_mio_fus_dat2_cn63xx {
+               uint64_t reserved_35_63:29;
+               uint64_t dorm_crypto:1;
+               uint64_t fus318:1;
+               uint64_t raid_en:1;
+               uint64_t reserved_29_31:3;
+               uint64_t nodfa_cp2:1;
+               uint64_t nomul:1;
+               uint64_t nocrypto:1;
+               uint64_t reserved_24_25:2;
+               uint64_t chip_id:8;
+               uint64_t reserved_6_15:10;
+               uint64_t pp_dis:6;
+       } cn63xx;
+       struct cvmx_mio_fus_dat2_cn63xx cn63xxp1;
 };
 
 union cvmx_mio_fus_dat3 {
        uint64_t u64;
        struct cvmx_mio_fus_dat3_s {
-               uint64_t reserved_32_63:32;
+               uint64_t reserved_58_63:6;
+               uint64_t pll_ctl:10;
+               uint64_t dfa_info_dte:3;
+               uint64_t dfa_info_clm:4;
+               uint64_t reserved_40_40:1;
+               uint64_t ema:2;
+               uint64_t efus_lck_rsv:1;
+               uint64_t efus_lck_man:1;
+               uint64_t pll_half_dis:1;
+               uint64_t l2c_crip:3;
                uint64_t pll_div4:1;
-               uint64_t zip_crip:2;
+               uint64_t reserved_29_30:2;
                uint64_t bar2_en:1;
                uint64_t efus_lck:1;
                uint64_t efus_ign:1;
@@ -801,7 +797,17 @@ union cvmx_mio_fus_dat3 {
                uint64_t nodfa_dte:1;
                uint64_t icache:24;
        } cn30xx;
-       struct cvmx_mio_fus_dat3_s cn31xx;
+       struct cvmx_mio_fus_dat3_cn31xx {
+               uint64_t reserved_32_63:32;
+               uint64_t pll_div4:1;
+               uint64_t zip_crip:2;
+               uint64_t bar2_en:1;
+               uint64_t efus_lck:1;
+               uint64_t efus_ign:1;
+               uint64_t nozip:1;
+               uint64_t nodfa_dte:1;
+               uint64_t icache:24;
+       } cn31xx;
        struct cvmx_mio_fus_dat3_cn38xx {
                uint64_t reserved_31_63:33;
                uint64_t zip_crip:2;
@@ -828,6 +834,27 @@ union cvmx_mio_fus_dat3 {
        struct cvmx_mio_fus_dat3_cn38xx cn56xxp1;
        struct cvmx_mio_fus_dat3_cn38xx cn58xx;
        struct cvmx_mio_fus_dat3_cn38xx cn58xxp1;
+       struct cvmx_mio_fus_dat3_cn63xx {
+               uint64_t reserved_58_63:6;
+               uint64_t pll_ctl:10;
+               uint64_t dfa_info_dte:3;
+               uint64_t dfa_info_clm:4;
+               uint64_t reserved_40_40:1;
+               uint64_t ema:2;
+               uint64_t efus_lck_rsv:1;
+               uint64_t efus_lck_man:1;
+               uint64_t pll_half_dis:1;
+               uint64_t l2c_crip:3;
+               uint64_t reserved_31_31:1;
+               uint64_t zip_info:2;
+               uint64_t bar2_en:1;
+               uint64_t efus_lck:1;
+               uint64_t efus_ign:1;
+               uint64_t nozip:1;
+               uint64_t nodfa_dte:1;
+               uint64_t reserved_0_23:24;
+       } cn63xx;
+       struct cvmx_mio_fus_dat3_cn63xx cn63xxp1;
 };
 
 union cvmx_mio_fus_ema {
@@ -848,6 +875,8 @@ union cvmx_mio_fus_ema {
                uint64_t ema:2;
        } cn58xx;
        struct cvmx_mio_fus_ema_cn58xx cn58xxp1;
+       struct cvmx_mio_fus_ema_s cn63xx;
+       struct cvmx_mio_fus_ema_s cn63xxp1;
 };
 
 union cvmx_mio_fus_pdf {
@@ -861,60 +890,96 @@ union cvmx_mio_fus_pdf {
        struct cvmx_mio_fus_pdf_s cn56xx;
        struct cvmx_mio_fus_pdf_s cn56xxp1;
        struct cvmx_mio_fus_pdf_s cn58xx;
+       struct cvmx_mio_fus_pdf_s cn63xx;
+       struct cvmx_mio_fus_pdf_s cn63xxp1;
 };
 
 union cvmx_mio_fus_pll {
        uint64_t u64;
        struct cvmx_mio_fus_pll_s {
-               uint64_t reserved_2_63:62;
+               uint64_t reserved_8_63:56;
+               uint64_t c_cout_rst:1;
+               uint64_t c_cout_sel:2;
+               uint64_t pnr_cout_rst:1;
+               uint64_t pnr_cout_sel:2;
                uint64_t rfslip:1;
                uint64_t fbslip:1;
        } s;
-       struct cvmx_mio_fus_pll_s cn50xx;
-       struct cvmx_mio_fus_pll_s cn52xx;
-       struct cvmx_mio_fus_pll_s cn52xxp1;
-       struct cvmx_mio_fus_pll_s cn56xx;
-       struct cvmx_mio_fus_pll_s cn56xxp1;
-       struct cvmx_mio_fus_pll_s cn58xx;
-       struct cvmx_mio_fus_pll_s cn58xxp1;
+       struct cvmx_mio_fus_pll_cn50xx {
+               uint64_t reserved_2_63:62;
+               uint64_t rfslip:1;
+               uint64_t fbslip:1;
+       } cn50xx;
+       struct cvmx_mio_fus_pll_cn50xx cn52xx;
+       struct cvmx_mio_fus_pll_cn50xx cn52xxp1;
+       struct cvmx_mio_fus_pll_cn50xx cn56xx;
+       struct cvmx_mio_fus_pll_cn50xx cn56xxp1;
+       struct cvmx_mio_fus_pll_cn50xx cn58xx;
+       struct cvmx_mio_fus_pll_cn50xx cn58xxp1;
+       struct cvmx_mio_fus_pll_s cn63xx;
+       struct cvmx_mio_fus_pll_s cn63xxp1;
 };
 
 union cvmx_mio_fus_prog {
        uint64_t u64;
        struct cvmx_mio_fus_prog_s {
-               uint64_t reserved_1_63:63;
+               uint64_t reserved_2_63:62;
+               uint64_t soft:1;
                uint64_t prog:1;
        } s;
-       struct cvmx_mio_fus_prog_s cn30xx;
-       struct cvmx_mio_fus_prog_s cn31xx;
-       struct cvmx_mio_fus_prog_s cn38xx;
-       struct cvmx_mio_fus_prog_s cn38xxp2;
-       struct cvmx_mio_fus_prog_s cn50xx;
-       struct cvmx_mio_fus_prog_s cn52xx;
-       struct cvmx_mio_fus_prog_s cn52xxp1;
-       struct cvmx_mio_fus_prog_s cn56xx;
-       struct cvmx_mio_fus_prog_s cn56xxp1;
-       struct cvmx_mio_fus_prog_s cn58xx;
-       struct cvmx_mio_fus_prog_s cn58xxp1;
+       struct cvmx_mio_fus_prog_cn30xx {
+               uint64_t reserved_1_63:63;
+               uint64_t prog:1;
+       } cn30xx;
+       struct cvmx_mio_fus_prog_cn30xx cn31xx;
+       struct cvmx_mio_fus_prog_cn30xx cn38xx;
+       struct cvmx_mio_fus_prog_cn30xx cn38xxp2;
+       struct cvmx_mio_fus_prog_cn30xx cn50xx;
+       struct cvmx_mio_fus_prog_cn30xx cn52xx;
+       struct cvmx_mio_fus_prog_cn30xx cn52xxp1;
+       struct cvmx_mio_fus_prog_cn30xx cn56xx;
+       struct cvmx_mio_fus_prog_cn30xx cn56xxp1;
+       struct cvmx_mio_fus_prog_cn30xx cn58xx;
+       struct cvmx_mio_fus_prog_cn30xx cn58xxp1;
+       struct cvmx_mio_fus_prog_s cn63xx;
+       struct cvmx_mio_fus_prog_s cn63xxp1;
 };
 
 union cvmx_mio_fus_prog_times {
        uint64_t u64;
        struct cvmx_mio_fus_prog_times_s {
+               uint64_t reserved_35_63:29;
+               uint64_t vgate_pin:1;
+               uint64_t fsrc_pin:1;
+               uint64_t prog_pin:1;
+               uint64_t reserved_6_31:26;
+               uint64_t setup:6;
+       } s;
+       struct cvmx_mio_fus_prog_times_cn50xx {
                uint64_t reserved_33_63:31;
                uint64_t prog_pin:1;
                uint64_t out:8;
                uint64_t sclk_lo:4;
                uint64_t sclk_hi:12;
                uint64_t setup:8;
-       } s;
-       struct cvmx_mio_fus_prog_times_s cn50xx;
-       struct cvmx_mio_fus_prog_times_s cn52xx;
-       struct cvmx_mio_fus_prog_times_s cn52xxp1;
-       struct cvmx_mio_fus_prog_times_s cn56xx;
-       struct cvmx_mio_fus_prog_times_s cn56xxp1;
-       struct cvmx_mio_fus_prog_times_s cn58xx;
-       struct cvmx_mio_fus_prog_times_s cn58xxp1;
+       } cn50xx;
+       struct cvmx_mio_fus_prog_times_cn50xx cn52xx;
+       struct cvmx_mio_fus_prog_times_cn50xx cn52xxp1;
+       struct cvmx_mio_fus_prog_times_cn50xx cn56xx;
+       struct cvmx_mio_fus_prog_times_cn50xx cn56xxp1;
+       struct cvmx_mio_fus_prog_times_cn50xx cn58xx;
+       struct cvmx_mio_fus_prog_times_cn50xx cn58xxp1;
+       struct cvmx_mio_fus_prog_times_cn63xx {
+               uint64_t reserved_35_63:29;
+               uint64_t vgate_pin:1;
+               uint64_t fsrc_pin:1;
+               uint64_t prog_pin:1;
+               uint64_t out:7;
+               uint64_t sclk_lo:4;
+               uint64_t sclk_hi:15;
+               uint64_t setup:6;
+       } cn63xx;
+       struct cvmx_mio_fus_prog_times_cn63xx cn63xxp1;
 };
 
 union cvmx_mio_fus_rcmd {
@@ -948,6 +1013,57 @@ union cvmx_mio_fus_rcmd {
        struct cvmx_mio_fus_rcmd_s cn56xxp1;
        struct cvmx_mio_fus_rcmd_cn30xx cn58xx;
        struct cvmx_mio_fus_rcmd_cn30xx cn58xxp1;
+       struct cvmx_mio_fus_rcmd_s cn63xx;
+       struct cvmx_mio_fus_rcmd_s cn63xxp1;
+};
+
+union cvmx_mio_fus_read_times {
+       uint64_t u64;
+       struct cvmx_mio_fus_read_times_s {
+               uint64_t reserved_26_63:38;
+               uint64_t sch:4;
+               uint64_t fsh:4;
+               uint64_t prh:4;
+               uint64_t sdh:4;
+               uint64_t setup:10;
+       } s;
+       struct cvmx_mio_fus_read_times_s cn63xx;
+       struct cvmx_mio_fus_read_times_s cn63xxp1;
+};
+
+union cvmx_mio_fus_repair_res0 {
+       uint64_t u64;
+       struct cvmx_mio_fus_repair_res0_s {
+               uint64_t reserved_55_63:9;
+               uint64_t too_many:1;
+               uint64_t repair2:18;
+               uint64_t repair1:18;
+               uint64_t repair0:18;
+       } s;
+       struct cvmx_mio_fus_repair_res0_s cn63xx;
+       struct cvmx_mio_fus_repair_res0_s cn63xxp1;
+};
+
+union cvmx_mio_fus_repair_res1 {
+       uint64_t u64;
+       struct cvmx_mio_fus_repair_res1_s {
+               uint64_t reserved_54_63:10;
+               uint64_t repair5:18;
+               uint64_t repair4:18;
+               uint64_t repair3:18;
+       } s;
+       struct cvmx_mio_fus_repair_res1_s cn63xx;
+       struct cvmx_mio_fus_repair_res1_s cn63xxp1;
+};
+
+union cvmx_mio_fus_repair_res2 {
+       uint64_t u64;
+       struct cvmx_mio_fus_repair_res2_s {
+               uint64_t reserved_18_63:46;
+               uint64_t repair6:18;
+       } s;
+       struct cvmx_mio_fus_repair_res2_s cn63xx;
+       struct cvmx_mio_fus_repair_res2_s cn63xxp1;
 };
 
 union cvmx_mio_fus_spr_repair_res {
@@ -968,6 +1084,8 @@ union cvmx_mio_fus_spr_repair_res {
        struct cvmx_mio_fus_spr_repair_res_s cn56xxp1;
        struct cvmx_mio_fus_spr_repair_res_s cn58xx;
        struct cvmx_mio_fus_spr_repair_res_s cn58xxp1;
+       struct cvmx_mio_fus_spr_repair_res_s cn63xx;
+       struct cvmx_mio_fus_spr_repair_res_s cn63xxp1;
 };
 
 union cvmx_mio_fus_spr_repair_sum {
@@ -986,6 +1104,8 @@ union cvmx_mio_fus_spr_repair_sum {
        struct cvmx_mio_fus_spr_repair_sum_s cn56xxp1;
        struct cvmx_mio_fus_spr_repair_sum_s cn58xx;
        struct cvmx_mio_fus_spr_repair_sum_s cn58xxp1;
+       struct cvmx_mio_fus_spr_repair_sum_s cn63xx;
+       struct cvmx_mio_fus_spr_repair_sum_s cn63xxp1;
 };
 
 union cvmx_mio_fus_unlock {
@@ -1021,6 +1141,22 @@ union cvmx_mio_fus_wadr {
        struct cvmx_mio_fus_wadr_cn52xx cn56xxp1;
        struct cvmx_mio_fus_wadr_cn50xx cn58xx;
        struct cvmx_mio_fus_wadr_cn50xx cn58xxp1;
+       struct cvmx_mio_fus_wadr_cn63xx {
+               uint64_t reserved_4_63:60;
+               uint64_t addr:4;
+       } cn63xx;
+       struct cvmx_mio_fus_wadr_cn63xx cn63xxp1;
+};
+
+union cvmx_mio_gpio_comp {
+       uint64_t u64;
+       struct cvmx_mio_gpio_comp_s {
+               uint64_t reserved_12_63:52;
+               uint64_t pctl:6;
+               uint64_t nctl:6;
+       } s;
+       struct cvmx_mio_gpio_comp_s cn63xx;
+       struct cvmx_mio_gpio_comp_s cn63xxp1;
 };
 
 union cvmx_mio_ndf_dma_cfg {
@@ -1038,6 +1174,8 @@ union cvmx_mio_ndf_dma_cfg {
                uint64_t adr:36;
        } s;
        struct cvmx_mio_ndf_dma_cfg_s cn52xx;
+       struct cvmx_mio_ndf_dma_cfg_s cn63xx;
+       struct cvmx_mio_ndf_dma_cfg_s cn63xxp1;
 };
 
 union cvmx_mio_ndf_dma_int {
@@ -1047,6 +1185,8 @@ union cvmx_mio_ndf_dma_int {
                uint64_t done:1;
        } s;
        struct cvmx_mio_ndf_dma_int_s cn52xx;
+       struct cvmx_mio_ndf_dma_int_s cn63xx;
+       struct cvmx_mio_ndf_dma_int_s cn63xxp1;
 };
 
 union cvmx_mio_ndf_dma_int_en {
@@ -1056,6 +1196,8 @@ union cvmx_mio_ndf_dma_int_en {
                uint64_t done:1;
        } s;
        struct cvmx_mio_ndf_dma_int_en_s cn52xx;
+       struct cvmx_mio_ndf_dma_int_en_s cn63xx;
+       struct cvmx_mio_ndf_dma_int_en_s cn63xxp1;
 };
 
 union cvmx_mio_pll_ctl {
@@ -1078,6 +1220,173 @@ union cvmx_mio_pll_setting {
        struct cvmx_mio_pll_setting_s cn31xx;
 };
 
+union cvmx_mio_ptp_clock_cfg {
+       uint64_t u64;
+       struct cvmx_mio_ptp_clock_cfg_s {
+               uint64_t reserved_24_63:40;
+               uint64_t evcnt_in:6;
+               uint64_t evcnt_edge:1;
+               uint64_t evcnt_en:1;
+               uint64_t tstmp_in:6;
+               uint64_t tstmp_edge:1;
+               uint64_t tstmp_en:1;
+               uint64_t ext_clk_in:6;
+               uint64_t ext_clk_en:1;
+               uint64_t ptp_en:1;
+       } s;
+       struct cvmx_mio_ptp_clock_cfg_s cn63xx;
+       struct cvmx_mio_ptp_clock_cfg_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_clock_comp {
+       uint64_t u64;
+       struct cvmx_mio_ptp_clock_comp_s {
+               uint64_t nanosec:32;
+               uint64_t frnanosec:32;
+       } s;
+       struct cvmx_mio_ptp_clock_comp_s cn63xx;
+       struct cvmx_mio_ptp_clock_comp_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_clock_hi {
+       uint64_t u64;
+       struct cvmx_mio_ptp_clock_hi_s {
+               uint64_t nanosec:64;
+       } s;
+       struct cvmx_mio_ptp_clock_hi_s cn63xx;
+       struct cvmx_mio_ptp_clock_hi_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_clock_lo {
+       uint64_t u64;
+       struct cvmx_mio_ptp_clock_lo_s {
+               uint64_t reserved_32_63:32;
+               uint64_t frnanosec:32;
+       } s;
+       struct cvmx_mio_ptp_clock_lo_s cn63xx;
+       struct cvmx_mio_ptp_clock_lo_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_evt_cnt {
+       uint64_t u64;
+       struct cvmx_mio_ptp_evt_cnt_s {
+               uint64_t cntr:64;
+       } s;
+       struct cvmx_mio_ptp_evt_cnt_s cn63xx;
+       struct cvmx_mio_ptp_evt_cnt_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_timestamp {
+       uint64_t u64;
+       struct cvmx_mio_ptp_timestamp_s {
+               uint64_t nanosec:64;
+       } s;
+       struct cvmx_mio_ptp_timestamp_s cn63xx;
+       struct cvmx_mio_ptp_timestamp_s cn63xxp1;
+};
+
+union cvmx_mio_rst_boot {
+       uint64_t u64;
+       struct cvmx_mio_rst_boot_s {
+               uint64_t reserved_36_63:28;
+               uint64_t c_mul:6;
+               uint64_t pnr_mul:6;
+               uint64_t qlm2_spd:4;
+               uint64_t qlm1_spd:4;
+               uint64_t qlm0_spd:4;
+               uint64_t lboot:10;
+               uint64_t rboot:1;
+               uint64_t rboot_pin:1;
+       } s;
+       struct cvmx_mio_rst_boot_s cn63xx;
+       struct cvmx_mio_rst_boot_s cn63xxp1;
+};
+
+union cvmx_mio_rst_cfg {
+       uint64_t u64;
+       struct cvmx_mio_rst_cfg_s {
+               uint64_t bist_delay:58;
+               uint64_t reserved_3_5:3;
+               uint64_t cntl_clr_bist:1;
+               uint64_t warm_clr_bist:1;
+               uint64_t soft_clr_bist:1;
+       } s;
+       struct cvmx_mio_rst_cfg_s cn63xx;
+       struct cvmx_mio_rst_cfg_cn63xxp1 {
+               uint64_t bist_delay:58;
+               uint64_t reserved_2_5:4;
+               uint64_t warm_clr_bist:1;
+               uint64_t soft_clr_bist:1;
+       } cn63xxp1;
+};
+
+union cvmx_mio_rst_ctlx {
+       uint64_t u64;
+       struct cvmx_mio_rst_ctlx_s {
+               uint64_t reserved_10_63:54;
+               uint64_t prst_link:1;
+               uint64_t rst_done:1;
+               uint64_t rst_link:1;
+               uint64_t host_mode:1;
+               uint64_t prtmode:2;
+               uint64_t rst_drv:1;
+               uint64_t rst_rcv:1;
+               uint64_t rst_chip:1;
+               uint64_t rst_val:1;
+       } s;
+       struct cvmx_mio_rst_ctlx_s cn63xx;
+       struct cvmx_mio_rst_ctlx_cn63xxp1 {
+               uint64_t reserved_9_63:55;
+               uint64_t rst_done:1;
+               uint64_t rst_link:1;
+               uint64_t host_mode:1;
+               uint64_t prtmode:2;
+               uint64_t rst_drv:1;
+               uint64_t rst_rcv:1;
+               uint64_t rst_chip:1;
+               uint64_t rst_val:1;
+       } cn63xxp1;
+};
+
+union cvmx_mio_rst_delay {
+       uint64_t u64;
+       struct cvmx_mio_rst_delay_s {
+               uint64_t reserved_32_63:32;
+               uint64_t soft_rst_dly:16;
+               uint64_t warm_rst_dly:16;
+       } s;
+       struct cvmx_mio_rst_delay_s cn63xx;
+       struct cvmx_mio_rst_delay_s cn63xxp1;
+};
+
+union cvmx_mio_rst_int {
+       uint64_t u64;
+       struct cvmx_mio_rst_int_s {
+               uint64_t reserved_10_63:54;
+               uint64_t perst1:1;
+               uint64_t perst0:1;
+               uint64_t reserved_2_7:6;
+               uint64_t rst_link1:1;
+               uint64_t rst_link0:1;
+       } s;
+       struct cvmx_mio_rst_int_s cn63xx;
+       struct cvmx_mio_rst_int_s cn63xxp1;
+};
+
+union cvmx_mio_rst_int_en {
+       uint64_t u64;
+       struct cvmx_mio_rst_int_en_s {
+               uint64_t reserved_10_63:54;
+               uint64_t perst1:1;
+               uint64_t perst0:1;
+               uint64_t reserved_2_7:6;
+               uint64_t rst_link1:1;
+               uint64_t rst_link0:1;
+       } s;
+       struct cvmx_mio_rst_int_en_s cn63xx;
+       struct cvmx_mio_rst_int_en_s cn63xxp1;
+};
+
 union cvmx_mio_twsx_int {
        uint64_t u64;
        struct cvmx_mio_twsx_int_s {
@@ -1115,6 +1424,8 @@ union cvmx_mio_twsx_int {
        struct cvmx_mio_twsx_int_s cn56xxp1;
        struct cvmx_mio_twsx_int_s cn58xx;
        struct cvmx_mio_twsx_int_s cn58xxp1;
+       struct cvmx_mio_twsx_int_s cn63xx;
+       struct cvmx_mio_twsx_int_s cn63xxp1;
 };
 
 union cvmx_mio_twsx_sw_twsi {
@@ -1144,6 +1455,8 @@ union cvmx_mio_twsx_sw_twsi {
        struct cvmx_mio_twsx_sw_twsi_s cn56xxp1;
        struct cvmx_mio_twsx_sw_twsi_s cn58xx;
        struct cvmx_mio_twsx_sw_twsi_s cn58xxp1;
+       struct cvmx_mio_twsx_sw_twsi_s cn63xx;
+       struct cvmx_mio_twsx_sw_twsi_s cn63xxp1;
 };
 
 union cvmx_mio_twsx_sw_twsi_ext {
@@ -1164,6 +1477,8 @@ union cvmx_mio_twsx_sw_twsi_ext {
        struct cvmx_mio_twsx_sw_twsi_ext_s cn56xxp1;
        struct cvmx_mio_twsx_sw_twsi_ext_s cn58xx;
        struct cvmx_mio_twsx_sw_twsi_ext_s cn58xxp1;
+       struct cvmx_mio_twsx_sw_twsi_ext_s cn63xx;
+       struct cvmx_mio_twsx_sw_twsi_ext_s cn63xxp1;
 };
 
 union cvmx_mio_twsx_twsi_sw {
@@ -1184,6 +1499,8 @@ union cvmx_mio_twsx_twsi_sw {
        struct cvmx_mio_twsx_twsi_sw_s cn56xxp1;
        struct cvmx_mio_twsx_twsi_sw_s cn58xx;
        struct cvmx_mio_twsx_twsi_sw_s cn58xxp1;
+       struct cvmx_mio_twsx_twsi_sw_s cn63xx;
+       struct cvmx_mio_twsx_twsi_sw_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_dlh {
@@ -1203,6 +1520,8 @@ union cvmx_mio_uartx_dlh {
        struct cvmx_mio_uartx_dlh_s cn56xxp1;
        struct cvmx_mio_uartx_dlh_s cn58xx;
        struct cvmx_mio_uartx_dlh_s cn58xxp1;
+       struct cvmx_mio_uartx_dlh_s cn63xx;
+       struct cvmx_mio_uartx_dlh_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_dll {
@@ -1222,6 +1541,8 @@ union cvmx_mio_uartx_dll {
        struct cvmx_mio_uartx_dll_s cn56xxp1;
        struct cvmx_mio_uartx_dll_s cn58xx;
        struct cvmx_mio_uartx_dll_s cn58xxp1;
+       struct cvmx_mio_uartx_dll_s cn63xx;
+       struct cvmx_mio_uartx_dll_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_far {
@@ -1241,6 +1562,8 @@ union cvmx_mio_uartx_far {
        struct cvmx_mio_uartx_far_s cn56xxp1;
        struct cvmx_mio_uartx_far_s cn58xx;
        struct cvmx_mio_uartx_far_s cn58xxp1;
+       struct cvmx_mio_uartx_far_s cn63xx;
+       struct cvmx_mio_uartx_far_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_fcr {
@@ -1265,6 +1588,8 @@ union cvmx_mio_uartx_fcr {
        struct cvmx_mio_uartx_fcr_s cn56xxp1;
        struct cvmx_mio_uartx_fcr_s cn58xx;
        struct cvmx_mio_uartx_fcr_s cn58xxp1;
+       struct cvmx_mio_uartx_fcr_s cn63xx;
+       struct cvmx_mio_uartx_fcr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_htx {
@@ -1284,6 +1609,8 @@ union cvmx_mio_uartx_htx {
        struct cvmx_mio_uartx_htx_s cn56xxp1;
        struct cvmx_mio_uartx_htx_s cn58xx;
        struct cvmx_mio_uartx_htx_s cn58xxp1;
+       struct cvmx_mio_uartx_htx_s cn63xx;
+       struct cvmx_mio_uartx_htx_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_ier {
@@ -1308,6 +1635,8 @@ union cvmx_mio_uartx_ier {
        struct cvmx_mio_uartx_ier_s cn56xxp1;
        struct cvmx_mio_uartx_ier_s cn58xx;
        struct cvmx_mio_uartx_ier_s cn58xxp1;
+       struct cvmx_mio_uartx_ier_s cn63xx;
+       struct cvmx_mio_uartx_ier_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_iir {
@@ -1329,6 +1658,8 @@ union cvmx_mio_uartx_iir {
        struct cvmx_mio_uartx_iir_s cn56xxp1;
        struct cvmx_mio_uartx_iir_s cn58xx;
        struct cvmx_mio_uartx_iir_s cn58xxp1;
+       struct cvmx_mio_uartx_iir_s cn63xx;
+       struct cvmx_mio_uartx_iir_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_lcr {
@@ -1354,6 +1685,8 @@ union cvmx_mio_uartx_lcr {
        struct cvmx_mio_uartx_lcr_s cn56xxp1;
        struct cvmx_mio_uartx_lcr_s cn58xx;
        struct cvmx_mio_uartx_lcr_s cn58xxp1;
+       struct cvmx_mio_uartx_lcr_s cn63xx;
+       struct cvmx_mio_uartx_lcr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_lsr {
@@ -1380,6 +1713,8 @@ union cvmx_mio_uartx_lsr {
        struct cvmx_mio_uartx_lsr_s cn56xxp1;
        struct cvmx_mio_uartx_lsr_s cn58xx;
        struct cvmx_mio_uartx_lsr_s cn58xxp1;
+       struct cvmx_mio_uartx_lsr_s cn63xx;
+       struct cvmx_mio_uartx_lsr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_mcr {
@@ -1404,6 +1739,8 @@ union cvmx_mio_uartx_mcr {
        struct cvmx_mio_uartx_mcr_s cn56xxp1;
        struct cvmx_mio_uartx_mcr_s cn58xx;
        struct cvmx_mio_uartx_mcr_s cn58xxp1;
+       struct cvmx_mio_uartx_mcr_s cn63xx;
+       struct cvmx_mio_uartx_mcr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_msr {
@@ -1430,6 +1767,8 @@ union cvmx_mio_uartx_msr {
        struct cvmx_mio_uartx_msr_s cn56xxp1;
        struct cvmx_mio_uartx_msr_s cn58xx;
        struct cvmx_mio_uartx_msr_s cn58xxp1;
+       struct cvmx_mio_uartx_msr_s cn63xx;
+       struct cvmx_mio_uartx_msr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_rbr {
@@ -1449,6 +1788,8 @@ union cvmx_mio_uartx_rbr {
        struct cvmx_mio_uartx_rbr_s cn56xxp1;
        struct cvmx_mio_uartx_rbr_s cn58xx;
        struct cvmx_mio_uartx_rbr_s cn58xxp1;
+       struct cvmx_mio_uartx_rbr_s cn63xx;
+       struct cvmx_mio_uartx_rbr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_rfl {
@@ -1468,6 +1809,8 @@ union cvmx_mio_uartx_rfl {
        struct cvmx_mio_uartx_rfl_s cn56xxp1;
        struct cvmx_mio_uartx_rfl_s cn58xx;
        struct cvmx_mio_uartx_rfl_s cn58xxp1;
+       struct cvmx_mio_uartx_rfl_s cn63xx;
+       struct cvmx_mio_uartx_rfl_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_rfw {
@@ -1489,6 +1832,8 @@ union cvmx_mio_uartx_rfw {
        struct cvmx_mio_uartx_rfw_s cn56xxp1;
        struct cvmx_mio_uartx_rfw_s cn58xx;
        struct cvmx_mio_uartx_rfw_s cn58xxp1;
+       struct cvmx_mio_uartx_rfw_s cn63xx;
+       struct cvmx_mio_uartx_rfw_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_sbcr {
@@ -1508,6 +1853,8 @@ union cvmx_mio_uartx_sbcr {
        struct cvmx_mio_uartx_sbcr_s cn56xxp1;
        struct cvmx_mio_uartx_sbcr_s cn58xx;
        struct cvmx_mio_uartx_sbcr_s cn58xxp1;
+       struct cvmx_mio_uartx_sbcr_s cn63xx;
+       struct cvmx_mio_uartx_sbcr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_scr {
@@ -1527,6 +1874,8 @@ union cvmx_mio_uartx_scr {
        struct cvmx_mio_uartx_scr_s cn56xxp1;
        struct cvmx_mio_uartx_scr_s cn58xx;
        struct cvmx_mio_uartx_scr_s cn58xxp1;
+       struct cvmx_mio_uartx_scr_s cn63xx;
+       struct cvmx_mio_uartx_scr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_sfe {
@@ -1546,6 +1895,8 @@ union cvmx_mio_uartx_sfe {
        struct cvmx_mio_uartx_sfe_s cn56xxp1;
        struct cvmx_mio_uartx_sfe_s cn58xx;
        struct cvmx_mio_uartx_sfe_s cn58xxp1;
+       struct cvmx_mio_uartx_sfe_s cn63xx;
+       struct cvmx_mio_uartx_sfe_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_srr {
@@ -1567,6 +1918,8 @@ union cvmx_mio_uartx_srr {
        struct cvmx_mio_uartx_srr_s cn56xxp1;
        struct cvmx_mio_uartx_srr_s cn58xx;
        struct cvmx_mio_uartx_srr_s cn58xxp1;
+       struct cvmx_mio_uartx_srr_s cn63xx;
+       struct cvmx_mio_uartx_srr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_srt {
@@ -1586,6 +1939,8 @@ union cvmx_mio_uartx_srt {
        struct cvmx_mio_uartx_srt_s cn56xxp1;
        struct cvmx_mio_uartx_srt_s cn58xx;
        struct cvmx_mio_uartx_srt_s cn58xxp1;
+       struct cvmx_mio_uartx_srt_s cn63xx;
+       struct cvmx_mio_uartx_srt_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_srts {
@@ -1605,6 +1960,8 @@ union cvmx_mio_uartx_srts {
        struct cvmx_mio_uartx_srts_s cn56xxp1;
        struct cvmx_mio_uartx_srts_s cn58xx;
        struct cvmx_mio_uartx_srts_s cn58xxp1;
+       struct cvmx_mio_uartx_srts_s cn63xx;
+       struct cvmx_mio_uartx_srts_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_stt {
@@ -1624,6 +1981,8 @@ union cvmx_mio_uartx_stt {
        struct cvmx_mio_uartx_stt_s cn56xxp1;
        struct cvmx_mio_uartx_stt_s cn58xx;
        struct cvmx_mio_uartx_stt_s cn58xxp1;
+       struct cvmx_mio_uartx_stt_s cn63xx;
+       struct cvmx_mio_uartx_stt_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_tfl {
@@ -1643,6 +2002,8 @@ union cvmx_mio_uartx_tfl {
        struct cvmx_mio_uartx_tfl_s cn56xxp1;
        struct cvmx_mio_uartx_tfl_s cn58xx;
        struct cvmx_mio_uartx_tfl_s cn58xxp1;
+       struct cvmx_mio_uartx_tfl_s cn63xx;
+       struct cvmx_mio_uartx_tfl_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_tfr {
@@ -1662,6 +2023,8 @@ union cvmx_mio_uartx_tfr {
        struct cvmx_mio_uartx_tfr_s cn56xxp1;
        struct cvmx_mio_uartx_tfr_s cn58xx;
        struct cvmx_mio_uartx_tfr_s cn58xxp1;
+       struct cvmx_mio_uartx_tfr_s cn63xx;
+       struct cvmx_mio_uartx_tfr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_thr {
@@ -1681,6 +2044,8 @@ union cvmx_mio_uartx_thr {
        struct cvmx_mio_uartx_thr_s cn56xxp1;
        struct cvmx_mio_uartx_thr_s cn58xx;
        struct cvmx_mio_uartx_thr_s cn58xxp1;
+       struct cvmx_mio_uartx_thr_s cn63xx;
+       struct cvmx_mio_uartx_thr_s cn63xxp1;
 };
 
 union cvmx_mio_uartx_usr {
@@ -1704,6 +2069,8 @@ union cvmx_mio_uartx_usr {
        struct cvmx_mio_uartx_usr_s cn56xxp1;
        struct cvmx_mio_uartx_usr_s cn58xx;
        struct cvmx_mio_uartx_usr_s cn58xxp1;
+       struct cvmx_mio_uartx_usr_s cn63xx;
+       struct cvmx_mio_uartx_usr_s cn63xxp1;
 };
 
 union cvmx_mio_uart2_dlh {
index dab6dca492f908210f6d576890f0877886ea132a..7057c447e69ed15ce54f4f225b7d0f8505cf5420 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_MIXX_DEFS_H__
 #define __CVMX_MIXX_DEFS_H__
 
-#define CVMX_MIXX_BIST(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100078ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_CTL(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100020ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_INTENA(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100050ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_IRCNT(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100030ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_IRHWM(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100028ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_IRING1(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100010ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_IRING2(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100018ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ISR(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100048ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ORCNT(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100040ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ORHWM(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100038ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ORING1(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100000ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_ORING2(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100008ull + (((offset) & 1) * 2048))
-#define CVMX_MIXX_REMCNT(offset) \
-        CVMX_ADD_IO_SEG(0x0001070000100058ull + (((offset) & 1) * 2048))
+#define CVMX_MIXX_BIST(offset) (CVMX_ADD_IO_SEG(0x0001070000100078ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_CTL(offset) (CVMX_ADD_IO_SEG(0x0001070000100020ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_INTENA(offset) (CVMX_ADD_IO_SEG(0x0001070000100050ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100030ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRHWM(offset) (CVMX_ADD_IO_SEG(0x0001070000100028ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRING1(offset) (CVMX_ADD_IO_SEG(0x0001070000100010ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRING2(offset) (CVMX_ADD_IO_SEG(0x0001070000100018ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ISR(offset) (CVMX_ADD_IO_SEG(0x0001070000100048ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100040ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORHWM(offset) (CVMX_ADD_IO_SEG(0x0001070000100038ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORING1(offset) (CVMX_ADD_IO_SEG(0x0001070000100000ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORING2(offset) (CVMX_ADD_IO_SEG(0x0001070000100008ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_REMCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100058ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_TSCTL(offset) (CVMX_ADD_IO_SEG(0x0001070000100068ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_TSTAMP(offset) (CVMX_ADD_IO_SEG(0x0001070000100060ull) + ((offset) & 1) * 2048)
 
 union cvmx_mixx_bist {
        uint64_t u64;
        struct cvmx_mixx_bist_s {
-               uint64_t reserved_4_63:60;
+               uint64_t reserved_6_63:58;
+               uint64_t opfdat:1;
+               uint64_t mrgdat:1;
                uint64_t mrqdat:1;
                uint64_t ipfdat:1;
                uint64_t irfdat:1;
                uint64_t orfdat:1;
        } s;
-       struct cvmx_mixx_bist_s cn52xx;
-       struct cvmx_mixx_bist_s cn52xxp1;
-       struct cvmx_mixx_bist_s cn56xx;
-       struct cvmx_mixx_bist_s cn56xxp1;
+       struct cvmx_mixx_bist_cn52xx {
+               uint64_t reserved_4_63:60;
+               uint64_t mrqdat:1;
+               uint64_t ipfdat:1;
+               uint64_t irfdat:1;
+               uint64_t orfdat:1;
+       } cn52xx;
+       struct cvmx_mixx_bist_cn52xx cn52xxp1;
+       struct cvmx_mixx_bist_cn52xx cn56xx;
+       struct cvmx_mixx_bist_cn52xx cn56xxp1;
+       struct cvmx_mixx_bist_s cn63xx;
+       struct cvmx_mixx_bist_s cn63xxp1;
 };
 
 union cvmx_mixx_ctl {
        uint64_t u64;
        struct cvmx_mixx_ctl_s {
-               uint64_t reserved_8_63:56;
+               uint64_t reserved_12_63:52;
+               uint64_t ts_thresh:4;
                uint64_t crc_strip:1;
                uint64_t busy:1;
                uint64_t en:1;
@@ -82,16 +82,28 @@ union cvmx_mixx_ctl {
                uint64_t nbtarb:1;
                uint64_t mrq_hwm:2;
        } s;
-       struct cvmx_mixx_ctl_s cn52xx;
-       struct cvmx_mixx_ctl_s cn52xxp1;
-       struct cvmx_mixx_ctl_s cn56xx;
-       struct cvmx_mixx_ctl_s cn56xxp1;
+       struct cvmx_mixx_ctl_cn52xx {
+               uint64_t reserved_8_63:56;
+               uint64_t crc_strip:1;
+               uint64_t busy:1;
+               uint64_t en:1;
+               uint64_t reset:1;
+               uint64_t lendian:1;
+               uint64_t nbtarb:1;
+               uint64_t mrq_hwm:2;
+       } cn52xx;
+       struct cvmx_mixx_ctl_cn52xx cn52xxp1;
+       struct cvmx_mixx_ctl_cn52xx cn56xx;
+       struct cvmx_mixx_ctl_cn52xx cn56xxp1;
+       struct cvmx_mixx_ctl_s cn63xx;
+       struct cvmx_mixx_ctl_s cn63xxp1;
 };
 
 union cvmx_mixx_intena {
        uint64_t u64;
        struct cvmx_mixx_intena_s {
-               uint64_t reserved_7_63:57;
+               uint64_t reserved_8_63:56;
+               uint64_t tsena:1;
                uint64_t orunena:1;
                uint64_t irunena:1;
                uint64_t data_drpena:1;
@@ -100,10 +112,21 @@ union cvmx_mixx_intena {
                uint64_t ivfena:1;
                uint64_t ovfena:1;
        } s;
-       struct cvmx_mixx_intena_s cn52xx;
-       struct cvmx_mixx_intena_s cn52xxp1;
-       struct cvmx_mixx_intena_s cn56xx;
-       struct cvmx_mixx_intena_s cn56xxp1;
+       struct cvmx_mixx_intena_cn52xx {
+               uint64_t reserved_7_63:57;
+               uint64_t orunena:1;
+               uint64_t irunena:1;
+               uint64_t data_drpena:1;
+               uint64_t ithena:1;
+               uint64_t othena:1;
+               uint64_t ivfena:1;
+               uint64_t ovfena:1;
+       } cn52xx;
+       struct cvmx_mixx_intena_cn52xx cn52xxp1;
+       struct cvmx_mixx_intena_cn52xx cn56xx;
+       struct cvmx_mixx_intena_cn52xx cn56xxp1;
+       struct cvmx_mixx_intena_s cn63xx;
+       struct cvmx_mixx_intena_s cn63xxp1;
 };
 
 union cvmx_mixx_ircnt {
@@ -116,6 +139,8 @@ union cvmx_mixx_ircnt {
        struct cvmx_mixx_ircnt_s cn52xxp1;
        struct cvmx_mixx_ircnt_s cn56xx;
        struct cvmx_mixx_ircnt_s cn56xxp1;
+       struct cvmx_mixx_ircnt_s cn63xx;
+       struct cvmx_mixx_ircnt_s cn63xxp1;
 };
 
 union cvmx_mixx_irhwm {
@@ -129,21 +154,30 @@ union cvmx_mixx_irhwm {
        struct cvmx_mixx_irhwm_s cn52xxp1;
        struct cvmx_mixx_irhwm_s cn56xx;
        struct cvmx_mixx_irhwm_s cn56xxp1;
+       struct cvmx_mixx_irhwm_s cn63xx;
+       struct cvmx_mixx_irhwm_s cn63xxp1;
 };
 
 union cvmx_mixx_iring1 {
        uint64_t u64;
        struct cvmx_mixx_iring1_s {
+               uint64_t reserved_60_63:4;
+               uint64_t isize:20;
+               uint64_t ibase:37;
+               uint64_t reserved_0_2:3;
+       } s;
+       struct cvmx_mixx_iring1_cn52xx {
                uint64_t reserved_60_63:4;
                uint64_t isize:20;
                uint64_t reserved_36_39:4;
                uint64_t ibase:33;
                uint64_t reserved_0_2:3;
-       } s;
-       struct cvmx_mixx_iring1_s cn52xx;
-       struct cvmx_mixx_iring1_s cn52xxp1;
-       struct cvmx_mixx_iring1_s cn56xx;
-       struct cvmx_mixx_iring1_s cn56xxp1;
+       } cn52xx;
+       struct cvmx_mixx_iring1_cn52xx cn52xxp1;
+       struct cvmx_mixx_iring1_cn52xx cn56xx;
+       struct cvmx_mixx_iring1_cn52xx cn56xxp1;
+       struct cvmx_mixx_iring1_s cn63xx;
+       struct cvmx_mixx_iring1_s cn63xxp1;
 };
 
 union cvmx_mixx_iring2 {
@@ -158,12 +192,15 @@ union cvmx_mixx_iring2 {
        struct cvmx_mixx_iring2_s cn52xxp1;
        struct cvmx_mixx_iring2_s cn56xx;
        struct cvmx_mixx_iring2_s cn56xxp1;
+       struct cvmx_mixx_iring2_s cn63xx;
+       struct cvmx_mixx_iring2_s cn63xxp1;
 };
 
 union cvmx_mixx_isr {
        uint64_t u64;
        struct cvmx_mixx_isr_s {
-               uint64_t reserved_7_63:57;
+               uint64_t reserved_8_63:56;
+               uint64_t ts:1;
                uint64_t orun:1;
                uint64_t irun:1;
                uint64_t data_drp:1;
@@ -172,10 +209,21 @@ union cvmx_mixx_isr {
                uint64_t idblovf:1;
                uint64_t odblovf:1;
        } s;
-       struct cvmx_mixx_isr_s cn52xx;
-       struct cvmx_mixx_isr_s cn52xxp1;
-       struct cvmx_mixx_isr_s cn56xx;
-       struct cvmx_mixx_isr_s cn56xxp1;
+       struct cvmx_mixx_isr_cn52xx {
+               uint64_t reserved_7_63:57;
+               uint64_t orun:1;
+               uint64_t irun:1;
+               uint64_t data_drp:1;
+               uint64_t irthresh:1;
+               uint64_t orthresh:1;
+               uint64_t idblovf:1;
+               uint64_t odblovf:1;
+       } cn52xx;
+       struct cvmx_mixx_isr_cn52xx cn52xxp1;
+       struct cvmx_mixx_isr_cn52xx cn56xx;
+       struct cvmx_mixx_isr_cn52xx cn56xxp1;
+       struct cvmx_mixx_isr_s cn63xx;
+       struct cvmx_mixx_isr_s cn63xxp1;
 };
 
 union cvmx_mixx_orcnt {
@@ -188,6 +236,8 @@ union cvmx_mixx_orcnt {
        struct cvmx_mixx_orcnt_s cn52xxp1;
        struct cvmx_mixx_orcnt_s cn56xx;
        struct cvmx_mixx_orcnt_s cn56xxp1;
+       struct cvmx_mixx_orcnt_s cn63xx;
+       struct cvmx_mixx_orcnt_s cn63xxp1;
 };
 
 union cvmx_mixx_orhwm {
@@ -200,21 +250,30 @@ union cvmx_mixx_orhwm {
        struct cvmx_mixx_orhwm_s cn52xxp1;
        struct cvmx_mixx_orhwm_s cn56xx;
        struct cvmx_mixx_orhwm_s cn56xxp1;
+       struct cvmx_mixx_orhwm_s cn63xx;
+       struct cvmx_mixx_orhwm_s cn63xxp1;
 };
 
 union cvmx_mixx_oring1 {
        uint64_t u64;
        struct cvmx_mixx_oring1_s {
+               uint64_t reserved_60_63:4;
+               uint64_t osize:20;
+               uint64_t obase:37;
+               uint64_t reserved_0_2:3;
+       } s;
+       struct cvmx_mixx_oring1_cn52xx {
                uint64_t reserved_60_63:4;
                uint64_t osize:20;
                uint64_t reserved_36_39:4;
                uint64_t obase:33;
                uint64_t reserved_0_2:3;
-       } s;
-       struct cvmx_mixx_oring1_s cn52xx;
-       struct cvmx_mixx_oring1_s cn52xxp1;
-       struct cvmx_mixx_oring1_s cn56xx;
-       struct cvmx_mixx_oring1_s cn56xxp1;
+       } cn52xx;
+       struct cvmx_mixx_oring1_cn52xx cn52xxp1;
+       struct cvmx_mixx_oring1_cn52xx cn56xx;
+       struct cvmx_mixx_oring1_cn52xx cn56xxp1;
+       struct cvmx_mixx_oring1_s cn63xx;
+       struct cvmx_mixx_oring1_s cn63xxp1;
 };
 
 union cvmx_mixx_oring2 {
@@ -229,6 +288,8 @@ union cvmx_mixx_oring2 {
        struct cvmx_mixx_oring2_s cn52xxp1;
        struct cvmx_mixx_oring2_s cn56xx;
        struct cvmx_mixx_oring2_s cn56xxp1;
+       struct cvmx_mixx_oring2_s cn63xx;
+       struct cvmx_mixx_oring2_s cn63xxp1;
 };
 
 union cvmx_mixx_remcnt {
@@ -243,6 +304,31 @@ union cvmx_mixx_remcnt {
        struct cvmx_mixx_remcnt_s cn52xxp1;
        struct cvmx_mixx_remcnt_s cn56xx;
        struct cvmx_mixx_remcnt_s cn56xxp1;
+       struct cvmx_mixx_remcnt_s cn63xx;
+       struct cvmx_mixx_remcnt_s cn63xxp1;
+};
+
+union cvmx_mixx_tsctl {
+       uint64_t u64;
+       struct cvmx_mixx_tsctl_s {
+               uint64_t reserved_21_63:43;
+               uint64_t tsavl:5;
+               uint64_t reserved_13_15:3;
+               uint64_t tstot:5;
+               uint64_t reserved_5_7:3;
+               uint64_t tscnt:5;
+       } s;
+       struct cvmx_mixx_tsctl_s cn63xx;
+       struct cvmx_mixx_tsctl_s cn63xxp1;
+};
+
+union cvmx_mixx_tstamp {
+       uint64_t u64;
+       struct cvmx_mixx_tstamp_s {
+               uint64_t tstamp:64;
+       } s;
+       struct cvmx_mixx_tstamp_s cn63xx;
+       struct cvmx_mixx_tstamp_s cn63xxp1;
 };
 
 #endif
index 4b347bb8ce802989c8a5c1107264e70cd58ce526..9899a9d2ba721fb4ac437a00f967a7acf1d7fbbe 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_NPEI_DEFS_H__
 #define __CVMX_NPEI_DEFS_H__
 
-#define CVMX_NPEI_BAR1_INDEXX(offset) \
-        (0x0000000000000000ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_BIST_STATUS \
-        (0x0000000000000580ull)
-#define CVMX_NPEI_BIST_STATUS2 \
-        (0x0000000000000680ull)
-#define CVMX_NPEI_CTL_PORT0 \
-        (0x0000000000000250ull)
-#define CVMX_NPEI_CTL_PORT1 \
-        (0x0000000000000260ull)
-#define CVMX_NPEI_CTL_STATUS \
-        (0x0000000000000570ull)
-#define CVMX_NPEI_CTL_STATUS2 \
-        (0x0000000000003C00ull)
-#define CVMX_NPEI_DATA_OUT_CNT \
-        (0x00000000000005F0ull)
-#define CVMX_NPEI_DBG_DATA \
-        (0x0000000000000510ull)
-#define CVMX_NPEI_DBG_SELECT \
-        (0x0000000000000500ull)
-#define CVMX_NPEI_DMA0_INT_LEVEL \
-        (0x00000000000005C0ull)
-#define CVMX_NPEI_DMA1_INT_LEVEL \
-        (0x00000000000005D0ull)
-#define CVMX_NPEI_DMAX_COUNTS(offset) \
-        (0x0000000000000450ull + (((offset) & 7) * 16))
-#define CVMX_NPEI_DMAX_DBELL(offset) \
-        (0x00000000000003B0ull + (((offset) & 7) * 16))
-#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) \
-        (0x0000000000000400ull + (((offset) & 7) * 16))
-#define CVMX_NPEI_DMAX_NADDR(offset) \
-        (0x00000000000004A0ull + (((offset) & 7) * 16))
-#define CVMX_NPEI_DMA_CNTS \
-        (0x00000000000005E0ull)
-#define CVMX_NPEI_DMA_CONTROL \
-        (0x00000000000003A0ull)
-#define CVMX_NPEI_INT_A_ENB \
-        (0x0000000000000560ull)
-#define CVMX_NPEI_INT_A_ENB2 \
-        (0x0000000000003CE0ull)
-#define CVMX_NPEI_INT_A_SUM \
-        (0x0000000000000550ull)
-#define CVMX_NPEI_INT_ENB \
-        (0x0000000000000540ull)
-#define CVMX_NPEI_INT_ENB2 \
-        (0x0000000000003CD0ull)
-#define CVMX_NPEI_INT_INFO \
-        (0x0000000000000590ull)
-#define CVMX_NPEI_INT_SUM \
-        (0x0000000000000530ull)
-#define CVMX_NPEI_INT_SUM2 \
-        (0x0000000000003CC0ull)
-#define CVMX_NPEI_LAST_WIN_RDATA0 \
-        (0x0000000000000600ull)
-#define CVMX_NPEI_LAST_WIN_RDATA1 \
-        (0x0000000000000610ull)
-#define CVMX_NPEI_MEM_ACCESS_CTL \
-        (0x00000000000004F0ull)
-#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) \
-        (0x0000000000000340ull + (((offset) & 31) * 16) - 16 * 12)
-#define CVMX_NPEI_MSI_ENB0 \
-        (0x0000000000003C50ull)
-#define CVMX_NPEI_MSI_ENB1 \
-        (0x0000000000003C60ull)
-#define CVMX_NPEI_MSI_ENB2 \
-        (0x0000000000003C70ull)
-#define CVMX_NPEI_MSI_ENB3 \
-        (0x0000000000003C80ull)
-#define CVMX_NPEI_MSI_RCV0 \
-        (0x0000000000003C10ull)
-#define CVMX_NPEI_MSI_RCV1 \
-        (0x0000000000003C20ull)
-#define CVMX_NPEI_MSI_RCV2 \
-        (0x0000000000003C30ull)
-#define CVMX_NPEI_MSI_RCV3 \
-        (0x0000000000003C40ull)
-#define CVMX_NPEI_MSI_RD_MAP \
-        (0x0000000000003CA0ull)
-#define CVMX_NPEI_MSI_W1C_ENB0 \
-        (0x0000000000003CF0ull)
-#define CVMX_NPEI_MSI_W1C_ENB1 \
-        (0x0000000000003D00ull)
-#define CVMX_NPEI_MSI_W1C_ENB2 \
-        (0x0000000000003D10ull)
-#define CVMX_NPEI_MSI_W1C_ENB3 \
-        (0x0000000000003D20ull)
-#define CVMX_NPEI_MSI_W1S_ENB0 \
-        (0x0000000000003D30ull)
-#define CVMX_NPEI_MSI_W1S_ENB1 \
-        (0x0000000000003D40ull)
-#define CVMX_NPEI_MSI_W1S_ENB2 \
-        (0x0000000000003D50ull)
-#define CVMX_NPEI_MSI_W1S_ENB3 \
-        (0x0000000000003D60ull)
-#define CVMX_NPEI_MSI_WR_MAP \
-        (0x0000000000003C90ull)
-#define CVMX_NPEI_PCIE_CREDIT_CNT \
-        (0x0000000000003D70ull)
-#define CVMX_NPEI_PCIE_MSI_RCV \
-        (0x0000000000003CB0ull)
-#define CVMX_NPEI_PCIE_MSI_RCV_B1 \
-        (0x0000000000000650ull)
-#define CVMX_NPEI_PCIE_MSI_RCV_B2 \
-        (0x0000000000000660ull)
-#define CVMX_NPEI_PCIE_MSI_RCV_B3 \
-        (0x0000000000000670ull)
-#define CVMX_NPEI_PKTX_CNTS(offset) \
-        (0x0000000000002400ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) \
-        (0x0000000000002800ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \
-        (0x0000000000002C00ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \
-        (0x0000000000003000ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) \
-        (0x0000000000003400ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_IN_BP(offset) \
-        (0x0000000000003800ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) \
-        (0x0000000000001400ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \
-        (0x0000000000001800ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \
-        (0x0000000000001C00ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKT_CNT_INT \
-        (0x0000000000001110ull)
-#define CVMX_NPEI_PKT_CNT_INT_ENB \
-        (0x0000000000001130ull)
-#define CVMX_NPEI_PKT_DATA_OUT_ES \
-        (0x00000000000010B0ull)
-#define CVMX_NPEI_PKT_DATA_OUT_NS \
-        (0x00000000000010A0ull)
-#define CVMX_NPEI_PKT_DATA_OUT_ROR \
-        (0x0000000000001090ull)
-#define CVMX_NPEI_PKT_DPADDR \
-        (0x0000000000001080ull)
-#define CVMX_NPEI_PKT_INPUT_CONTROL \
-        (0x0000000000001150ull)
-#define CVMX_NPEI_PKT_INSTR_ENB \
-        (0x0000000000001000ull)
-#define CVMX_NPEI_PKT_INSTR_RD_SIZE \
-        (0x0000000000001190ull)
-#define CVMX_NPEI_PKT_INSTR_SIZE \
-        (0x0000000000001020ull)
-#define CVMX_NPEI_PKT_INT_LEVELS \
-        (0x0000000000001100ull)
-#define CVMX_NPEI_PKT_IN_BP \
-        (0x00000000000006B0ull)
-#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) \
-        (0x0000000000002000ull + (((offset) & 31) * 16))
-#define CVMX_NPEI_PKT_IN_INSTR_COUNTS \
-        (0x00000000000006A0ull)
-#define CVMX_NPEI_PKT_IN_PCIE_PORT \
-        (0x00000000000011A0ull)
-#define CVMX_NPEI_PKT_IPTR \
-        (0x0000000000001070ull)
-#define CVMX_NPEI_PKT_OUTPUT_WMARK \
-        (0x0000000000001160ull)
-#define CVMX_NPEI_PKT_OUT_BMODE \
-        (0x00000000000010D0ull)
-#define CVMX_NPEI_PKT_OUT_ENB \
-        (0x0000000000001010ull)
-#define CVMX_NPEI_PKT_PCIE_PORT \
-        (0x00000000000010E0ull)
-#define CVMX_NPEI_PKT_PORT_IN_RST \
-        (0x0000000000000690ull)
-#define CVMX_NPEI_PKT_SLIST_ES \
-        (0x0000000000001050ull)
-#define CVMX_NPEI_PKT_SLIST_ID_SIZE \
-        (0x0000000000001180ull)
-#define CVMX_NPEI_PKT_SLIST_NS \
-        (0x0000000000001040ull)
-#define CVMX_NPEI_PKT_SLIST_ROR \
-        (0x0000000000001030ull)
-#define CVMX_NPEI_PKT_TIME_INT \
-        (0x0000000000001120ull)
-#define CVMX_NPEI_PKT_TIME_INT_ENB \
-        (0x0000000000001140ull)
-#define CVMX_NPEI_RSL_INT_BLOCKS \
-        (0x0000000000000520ull)
-#define CVMX_NPEI_SCRATCH_1 \
-        (0x0000000000000270ull)
-#define CVMX_NPEI_STATE1 \
-        (0x0000000000000620ull)
-#define CVMX_NPEI_STATE2 \
-        (0x0000000000000630ull)
-#define CVMX_NPEI_STATE3 \
-        (0x0000000000000640ull)
-#define CVMX_NPEI_WINDOW_CTL \
-        (0x0000000000000380ull)
-#define CVMX_NPEI_WIN_RD_ADDR \
-        (0x0000000000000210ull)
-#define CVMX_NPEI_WIN_RD_DATA \
-        (0x0000000000000240ull)
-#define CVMX_NPEI_WIN_WR_ADDR \
-        (0x0000000000000200ull)
-#define CVMX_NPEI_WIN_WR_DATA \
-        (0x0000000000000220ull)
-#define CVMX_NPEI_WIN_WR_MASK \
-        (0x0000000000000230ull)
+#define CVMX_NPEI_BAR1_INDEXX(offset) (0x0000000000000000ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_BIST_STATUS (0x0000000000000580ull)
+#define CVMX_NPEI_BIST_STATUS2 (0x0000000000000680ull)
+#define CVMX_NPEI_CTL_PORT0 (0x0000000000000250ull)
+#define CVMX_NPEI_CTL_PORT1 (0x0000000000000260ull)
+#define CVMX_NPEI_CTL_STATUS (0x0000000000000570ull)
+#define CVMX_NPEI_CTL_STATUS2 (0x0000000000003C00ull)
+#define CVMX_NPEI_DATA_OUT_CNT (0x00000000000005F0ull)
+#define CVMX_NPEI_DBG_DATA (0x0000000000000510ull)
+#define CVMX_NPEI_DBG_SELECT (0x0000000000000500ull)
+#define CVMX_NPEI_DMA0_INT_LEVEL (0x00000000000005C0ull)
+#define CVMX_NPEI_DMA1_INT_LEVEL (0x00000000000005D0ull)
+#define CVMX_NPEI_DMAX_COUNTS(offset) (0x0000000000000450ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMAX_DBELL(offset) (0x00000000000003B0ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) (0x0000000000000400ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMAX_NADDR(offset) (0x00000000000004A0ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMA_CNTS (0x00000000000005E0ull)
+#define CVMX_NPEI_DMA_CONTROL (0x00000000000003A0ull)
+#define CVMX_NPEI_DMA_PCIE_REQ_NUM (0x00000000000005B0ull)
+#define CVMX_NPEI_DMA_STATE1 (0x00000000000006C0ull)
+#define CVMX_NPEI_DMA_STATE1_P1 (0x0000000000000680ull)
+#define CVMX_NPEI_DMA_STATE2 (0x00000000000006D0ull)
+#define CVMX_NPEI_DMA_STATE2_P1 (0x0000000000000690ull)
+#define CVMX_NPEI_DMA_STATE3_P1 (0x00000000000006A0ull)
+#define CVMX_NPEI_DMA_STATE4_P1 (0x00000000000006B0ull)
+#define CVMX_NPEI_DMA_STATE5_P1 (0x00000000000006C0ull)
+#define CVMX_NPEI_INT_A_ENB (0x0000000000000560ull)
+#define CVMX_NPEI_INT_A_ENB2 (0x0000000000003CE0ull)
+#define CVMX_NPEI_INT_A_SUM (0x0000000000000550ull)
+#define CVMX_NPEI_INT_ENB (0x0000000000000540ull)
+#define CVMX_NPEI_INT_ENB2 (0x0000000000003CD0ull)
+#define CVMX_NPEI_INT_INFO (0x0000000000000590ull)
+#define CVMX_NPEI_INT_SUM (0x0000000000000530ull)
+#define CVMX_NPEI_INT_SUM2 (0x0000000000003CC0ull)
+#define CVMX_NPEI_LAST_WIN_RDATA0 (0x0000000000000600ull)
+#define CVMX_NPEI_LAST_WIN_RDATA1 (0x0000000000000610ull)
+#define CVMX_NPEI_MEM_ACCESS_CTL (0x00000000000004F0ull)
+#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) (0x0000000000000340ull + ((offset) & 31) * 16 - 16*12)
+#define CVMX_NPEI_MSI_ENB0 (0x0000000000003C50ull)
+#define CVMX_NPEI_MSI_ENB1 (0x0000000000003C60ull)
+#define CVMX_NPEI_MSI_ENB2 (0x0000000000003C70ull)
+#define CVMX_NPEI_MSI_ENB3 (0x0000000000003C80ull)
+#define CVMX_NPEI_MSI_RCV0 (0x0000000000003C10ull)
+#define CVMX_NPEI_MSI_RCV1 (0x0000000000003C20ull)
+#define CVMX_NPEI_MSI_RCV2 (0x0000000000003C30ull)
+#define CVMX_NPEI_MSI_RCV3 (0x0000000000003C40ull)
+#define CVMX_NPEI_MSI_RD_MAP (0x0000000000003CA0ull)
+#define CVMX_NPEI_MSI_W1C_ENB0 (0x0000000000003CF0ull)
+#define CVMX_NPEI_MSI_W1C_ENB1 (0x0000000000003D00ull)
+#define CVMX_NPEI_MSI_W1C_ENB2 (0x0000000000003D10ull)
+#define CVMX_NPEI_MSI_W1C_ENB3 (0x0000000000003D20ull)
+#define CVMX_NPEI_MSI_W1S_ENB0 (0x0000000000003D30ull)
+#define CVMX_NPEI_MSI_W1S_ENB1 (0x0000000000003D40ull)
+#define CVMX_NPEI_MSI_W1S_ENB2 (0x0000000000003D50ull)
+#define CVMX_NPEI_MSI_W1S_ENB3 (0x0000000000003D60ull)
+#define CVMX_NPEI_MSI_WR_MAP (0x0000000000003C90ull)
+#define CVMX_NPEI_PCIE_CREDIT_CNT (0x0000000000003D70ull)
+#define CVMX_NPEI_PCIE_MSI_RCV (0x0000000000003CB0ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B1 (0x0000000000000650ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B2 (0x0000000000000660ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B3 (0x0000000000000670ull)
+#define CVMX_NPEI_PKTX_CNTS(offset) (0x0000000000002400ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) (0x0000000000002800ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) (0x0000000000002C00ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) (0x0000000000003000ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) (0x0000000000003400ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_IN_BP(offset) (0x0000000000003800ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) (0x0000000000001400ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) (0x0000000000001800ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) (0x0000000000001C00ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKT_CNT_INT (0x0000000000001110ull)
+#define CVMX_NPEI_PKT_CNT_INT_ENB (0x0000000000001130ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ES (0x00000000000010B0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_NS (0x00000000000010A0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ROR (0x0000000000001090ull)
+#define CVMX_NPEI_PKT_DPADDR (0x0000000000001080ull)
+#define CVMX_NPEI_PKT_INPUT_CONTROL (0x0000000000001150ull)
+#define CVMX_NPEI_PKT_INSTR_ENB (0x0000000000001000ull)
+#define CVMX_NPEI_PKT_INSTR_RD_SIZE (0x0000000000001190ull)
+#define CVMX_NPEI_PKT_INSTR_SIZE (0x0000000000001020ull)
+#define CVMX_NPEI_PKT_INT_LEVELS (0x0000000000001100ull)
+#define CVMX_NPEI_PKT_IN_BP (0x00000000000006B0ull)
+#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) (0x0000000000002000ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKT_IN_INSTR_COUNTS (0x00000000000006A0ull)
+#define CVMX_NPEI_PKT_IN_PCIE_PORT (0x00000000000011A0ull)
+#define CVMX_NPEI_PKT_IPTR (0x0000000000001070ull)
+#define CVMX_NPEI_PKT_OUTPUT_WMARK (0x0000000000001160ull)
+#define CVMX_NPEI_PKT_OUT_BMODE (0x00000000000010D0ull)
+#define CVMX_NPEI_PKT_OUT_ENB (0x0000000000001010ull)
+#define CVMX_NPEI_PKT_PCIE_PORT (0x00000000000010E0ull)
+#define CVMX_NPEI_PKT_PORT_IN_RST (0x0000000000000690ull)
+#define CVMX_NPEI_PKT_SLIST_ES (0x0000000000001050ull)
+#define CVMX_NPEI_PKT_SLIST_ID_SIZE (0x0000000000001180ull)
+#define CVMX_NPEI_PKT_SLIST_NS (0x0000000000001040ull)
+#define CVMX_NPEI_PKT_SLIST_ROR (0x0000000000001030ull)
+#define CVMX_NPEI_PKT_TIME_INT (0x0000000000001120ull)
+#define CVMX_NPEI_PKT_TIME_INT_ENB (0x0000000000001140ull)
+#define CVMX_NPEI_RSL_INT_BLOCKS (0x0000000000000520ull)
+#define CVMX_NPEI_SCRATCH_1 (0x0000000000000270ull)
+#define CVMX_NPEI_STATE1 (0x0000000000000620ull)
+#define CVMX_NPEI_STATE2 (0x0000000000000630ull)
+#define CVMX_NPEI_STATE3 (0x0000000000000640ull)
+#define CVMX_NPEI_WINDOW_CTL (0x0000000000000380ull)
+#define CVMX_NPEI_WIN_RD_ADDR (0x0000000000000210ull)
+#define CVMX_NPEI_WIN_RD_DATA (0x0000000000000240ull)
+#define CVMX_NPEI_WIN_WR_ADDR (0x0000000000000200ull)
+#define CVMX_NPEI_WIN_WR_DATA (0x0000000000000220ull)
+#define CVMX_NPEI_WIN_WR_MASK (0x0000000000000230ull)
 
 union cvmx_npei_bar1_indexx {
        uint32_t u32;
@@ -248,9 +156,7 @@ union cvmx_npei_bist_status {
        uint64_t u64;
        struct cvmx_npei_bist_status_s {
                uint64_t pkt_rdf:1;
-               uint64_t pkt_pmem:1;
-               uint64_t pkt_p1:1;
-               uint64_t reserved_60_60:1;
+               uint64_t reserved_60_62:3;
                uint64_t pcr_gim:1;
                uint64_t pkt_pif:1;
                uint64_t pcsr_int:1;
@@ -301,9 +207,7 @@ union cvmx_npei_bist_status {
        } s;
        struct cvmx_npei_bist_status_cn52xx {
                uint64_t pkt_rdf:1;
-               uint64_t pkt_pmem:1;
-               uint64_t pkt_p1:1;
-               uint64_t reserved_60_60:1;
+               uint64_t reserved_60_62:3;
                uint64_t pcr_gim:1;
                uint64_t pkt_pif:1;
                uint64_t pcsr_int:1;
@@ -410,66 +314,7 @@ union cvmx_npei_bist_status {
                uint64_t msi:1;
                uint64_t ncb_cmd:1;
        } cn52xxp1;
-       struct cvmx_npei_bist_status_cn56xx {
-               uint64_t pkt_rdf:1;
-               uint64_t reserved_60_62:3;
-               uint64_t pcr_gim:1;
-               uint64_t pkt_pif:1;
-               uint64_t pcsr_int:1;
-               uint64_t pcsr_im:1;
-               uint64_t pcsr_cnt:1;
-               uint64_t pcsr_id:1;
-               uint64_t pcsr_sl:1;
-               uint64_t pkt_imem:1;
-               uint64_t pkt_pfm:1;
-               uint64_t pkt_pof:1;
-               uint64_t reserved_48_49:2;
-               uint64_t pkt_pop0:1;
-               uint64_t pkt_pop1:1;
-               uint64_t d0_mem:1;
-               uint64_t d1_mem:1;
-               uint64_t d2_mem:1;
-               uint64_t d3_mem:1;
-               uint64_t d4_mem:1;
-               uint64_t ds_mem:1;
-               uint64_t reserved_36_39:4;
-               uint64_t d0_pst:1;
-               uint64_t d1_pst:1;
-               uint64_t d2_pst:1;
-               uint64_t d3_pst:1;
-               uint64_t d4_pst:1;
-               uint64_t n2p0_c:1;
-               uint64_t n2p0_o:1;
-               uint64_t n2p1_c:1;
-               uint64_t n2p1_o:1;
-               uint64_t cpl_p0:1;
-               uint64_t cpl_p1:1;
-               uint64_t p2n1_po:1;
-               uint64_t p2n1_no:1;
-               uint64_t p2n1_co:1;
-               uint64_t p2n0_po:1;
-               uint64_t p2n0_no:1;
-               uint64_t p2n0_co:1;
-               uint64_t p2n0_c0:1;
-               uint64_t p2n0_c1:1;
-               uint64_t p2n0_n:1;
-               uint64_t p2n0_p0:1;
-               uint64_t p2n0_p1:1;
-               uint64_t p2n1_c0:1;
-               uint64_t p2n1_c1:1;
-               uint64_t p2n1_n:1;
-               uint64_t p2n1_p0:1;
-               uint64_t p2n1_p1:1;
-               uint64_t csm0:1;
-               uint64_t csm1:1;
-               uint64_t dif0:1;
-               uint64_t dif1:1;
-               uint64_t dif2:1;
-               uint64_t dif3:1;
-               uint64_t dif4:1;
-               uint64_t msi:1;
-               uint64_t ncb_cmd:1;
-       } cn56xx;
+       struct cvmx_npei_bist_status_cn52xx cn56xx;
        struct cvmx_npei_bist_status_cn56xxp1 {
                uint64_t reserved_58_63:6;
                uint64_t pcsr_int:1;
@@ -536,7 +381,16 @@ union cvmx_npei_bist_status {
 union cvmx_npei_bist_status2 {
        uint64_t u64;
        struct cvmx_npei_bist_status2_s {
-               uint64_t reserved_5_63:59;
+               uint64_t reserved_14_63:50;
+               uint64_t prd_tag:1;
+               uint64_t prd_st0:1;
+               uint64_t prd_st1:1;
+               uint64_t prd_err:1;
+               uint64_t nrd_st:1;
+               uint64_t nwe_st:1;
+               uint64_t nwe_wr0:1;
+               uint64_t nwe_wr1:1;
+               uint64_t pkt_rd:1;
                uint64_t psc_p0:1;
                uint64_t psc_p1:1;
                uint64_t pkt_gd:1;
@@ -630,8 +484,7 @@ union cvmx_npei_ctl_status {
        } cn52xxp1;
        struct cvmx_npei_ctl_status_s cn56xx;
        struct cvmx_npei_ctl_status_cn56xxp1 {
-               uint64_t reserved_16_63:48;
-               uint64_t ring_en:1;
+               uint64_t reserved_15_63:49;
                uint64_t lnk_rst:1;
                uint64_t arb:1;
                uint64_t pkt_bp:4;
@@ -756,14 +609,14 @@ union cvmx_npei_dmax_ibuff_saddr {
                uint64_t saddr:29;
                uint64_t reserved_0_6:7;
        } s;
-       struct cvmx_npei_dmax_ibuff_saddr_cn52xx {
+       struct cvmx_npei_dmax_ibuff_saddr_s cn52xx;
+       struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 {
                uint64_t reserved_36_63:28;
                uint64_t saddr:29;
                uint64_t reserved_0_6:7;
-       } cn52xx;
-       struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn52xxp1;
+       } cn52xxp1;
        struct cvmx_npei_dmax_ibuff_saddr_s cn56xx;
-       struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn56xxp1;
+       struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 cn56xxp1;
 };
 
 union cvmx_npei_dmax_naddr {
@@ -817,7 +670,8 @@ union cvmx_npei_dma_cnts {
 union cvmx_npei_dma_control {
        uint64_t u64;
        struct cvmx_npei_dma_control_s {
-               uint64_t reserved_39_63:25;
+               uint64_t reserved_40_63:24;
+               uint64_t p_32b_m:1;
                uint64_t dma4_enb:1;
                uint64_t dma3_enb:1;
                uint64_t dma2_enb:1;
@@ -853,7 +707,161 @@ union cvmx_npei_dma_control {
                uint64_t csize:14;
        } cn52xxp1;
        struct cvmx_npei_dma_control_s cn56xx;
-       struct cvmx_npei_dma_control_s cn56xxp1;
+       struct cvmx_npei_dma_control_cn56xxp1 {
+               uint64_t reserved_39_63:25;
+               uint64_t dma4_enb:1;
+               uint64_t dma3_enb:1;
+               uint64_t dma2_enb:1;
+               uint64_t dma1_enb:1;
+               uint64_t dma0_enb:1;
+               uint64_t b0_lend:1;
+               uint64_t dwb_denb:1;
+               uint64_t dwb_ichk:9;
+               uint64_t fpa_que:3;
+               uint64_t o_add1:1;
+               uint64_t o_ro:1;
+               uint64_t o_ns:1;
+               uint64_t o_es:2;
+               uint64_t o_mode:1;
+               uint64_t csize:14;
+       } cn56xxp1;
+};
+
+union cvmx_npei_dma_pcie_req_num {
+       uint64_t u64;
+       struct cvmx_npei_dma_pcie_req_num_s {
+               uint64_t dma_arb:1;
+               uint64_t reserved_53_62:10;
+               uint64_t pkt_cnt:5;
+               uint64_t reserved_45_47:3;
+               uint64_t dma4_cnt:5;
+               uint64_t reserved_37_39:3;
+               uint64_t dma3_cnt:5;
+               uint64_t reserved_29_31:3;
+               uint64_t dma2_cnt:5;
+               uint64_t reserved_21_23:3;
+               uint64_t dma1_cnt:5;
+               uint64_t reserved_13_15:3;
+               uint64_t dma0_cnt:5;
+               uint64_t reserved_5_7:3;
+               uint64_t dma_cnt:5;
+       } s;
+       struct cvmx_npei_dma_pcie_req_num_s cn52xx;
+       struct cvmx_npei_dma_pcie_req_num_s cn56xx;
+};
+
+union cvmx_npei_dma_state1 {
+       uint64_t u64;
+       struct cvmx_npei_dma_state1_s {
+               uint64_t reserved_40_63:24;
+               uint64_t d4_dwe:8;
+               uint64_t d3_dwe:8;
+               uint64_t d2_dwe:8;
+               uint64_t d1_dwe:8;
+               uint64_t d0_dwe:8;
+       } s;
+       struct cvmx_npei_dma_state1_s cn52xx;
+};
+
+union cvmx_npei_dma_state1_p1 {
+       uint64_t u64;
+       struct cvmx_npei_dma_state1_p1_s {
+               uint64_t reserved_60_63:4;
+               uint64_t d0_difst:7;
+               uint64_t d1_difst:7;
+               uint64_t d2_difst:7;
+               uint64_t d3_difst:7;
+               uint64_t d4_difst:7;
+               uint64_t d0_reqst:5;
+               uint64_t d1_reqst:5;
+               uint64_t d2_reqst:5;
+               uint64_t d3_reqst:5;
+               uint64_t d4_reqst:5;
+       } s;
+       struct cvmx_npei_dma_state1_p1_cn52xxp1 {
+               uint64_t reserved_60_63:4;
+               uint64_t d0_difst:7;
+               uint64_t d1_difst:7;
+               uint64_t d2_difst:7;
+               uint64_t d3_difst:7;
+               uint64_t reserved_25_31:7;
+               uint64_t d0_reqst:5;
+               uint64_t d1_reqst:5;
+               uint64_t d2_reqst:5;
+               uint64_t d3_reqst:5;
+               uint64_t reserved_0_4:5;
+       } cn52xxp1;
+       struct cvmx_npei_dma_state1_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state2 {
+       uint64_t u64;
+       struct cvmx_npei_dma_state2_s {
+               uint64_t reserved_28_63:36;
+               uint64_t ndwe:4;
+               uint64_t reserved_21_23:3;
+               uint64_t ndre:5;
+               uint64_t reserved_10_15:6;
+               uint64_t prd:10;
+       } s;
+       struct cvmx_npei_dma_state2_s cn52xx;
+};
+
+union cvmx_npei_dma_state2_p1 {
+       uint64_t u64;
+       struct cvmx_npei_dma_state2_p1_s {
+               uint64_t reserved_45_63:19;
+               uint64_t d0_dffst:9;
+               uint64_t d1_dffst:9;
+               uint64_t d2_dffst:9;
+               uint64_t d3_dffst:9;
+               uint64_t d4_dffst:9;
+       } s;
+       struct cvmx_npei_dma_state2_p1_cn52xxp1 {
+               uint64_t reserved_45_63:19;
+               uint64_t d0_dffst:9;
+               uint64_t d1_dffst:9;
+               uint64_t d2_dffst:9;
+               uint64_t d3_dffst:9;
+               uint64_t reserved_0_8:9;
+       } cn52xxp1;
+       struct cvmx_npei_dma_state2_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state3_p1 {
+       uint64_t u64;
+       struct cvmx_npei_dma_state3_p1_s {
+               uint64_t reserved_60_63:4;
+               uint64_t d0_drest:15;
+               uint64_t d1_drest:15;
+               uint64_t d2_drest:15;
+               uint64_t d3_drest:15;
+       } s;
+       struct cvmx_npei_dma_state3_p1_s cn52xxp1;
+       struct cvmx_npei_dma_state3_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state4_p1 {
+       uint64_t u64;
+       struct cvmx_npei_dma_state4_p1_s {
+               uint64_t reserved_52_63:12;
+               uint64_t d0_dwest:13;
+               uint64_t d1_dwest:13;
+               uint64_t d2_dwest:13;
+               uint64_t d3_dwest:13;
+       } s;
+       struct cvmx_npei_dma_state4_p1_s cn52xxp1;
+       struct cvmx_npei_dma_state4_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state5_p1 {
+       uint64_t u64;
+       struct cvmx_npei_dma_state5_p1_s {
+               uint64_t reserved_28_63:36;
+               uint64_t d4_drest:15;
+               uint64_t d4_dwest:13;
+       } s;
+       struct cvmx_npei_dma_state5_p1_s cn56xxp1;
 };
 
 union cvmx_npei_int_a_enb {
@@ -871,17 +879,7 @@ union cvmx_npei_int_a_enb {
                uint64_t dma1_cpl:1;
                uint64_t dma0_cpl:1;
        } s;
-       struct cvmx_npei_int_a_enb_cn52xx {
-               uint64_t reserved_8_63:56;
-               uint64_t p1_rdlk:1;
-               uint64_t p0_rdlk:1;
-               uint64_t pgl_err:1;
-               uint64_t pdi_err:1;
-               uint64_t pop_err:1;
-               uint64_t pins_err:1;
-               uint64_t dma1_cpl:1;
-               uint64_t dma0_cpl:1;
-       } cn52xx;
+       struct cvmx_npei_int_a_enb_s cn52xx;
        struct cvmx_npei_int_a_enb_cn52xxp1 {
                uint64_t reserved_2_63:62;
                uint64_t dma1_cpl:1;
@@ -905,16 +903,7 @@ union cvmx_npei_int_a_enb2 {
                uint64_t dma1_cpl:1;
                uint64_t dma0_cpl:1;
        } s;
-       struct cvmx_npei_int_a_enb2_cn52xx {
-               uint64_t reserved_8_63:56;
-               uint64_t p1_rdlk:1;
-               uint64_t p0_rdlk:1;
-               uint64_t pgl_err:1;
-               uint64_t pdi_err:1;
-               uint64_t pop_err:1;
-               uint64_t pins_err:1;
-               uint64_t reserved_0_1:2;
-       } cn52xx;
+       struct cvmx_npei_int_a_enb2_s cn52xx;
        struct cvmx_npei_int_a_enb2_cn52xxp1 {
                uint64_t reserved_2_63:62;
                uint64_t dma1_cpl:1;
@@ -938,17 +927,7 @@ union cvmx_npei_int_a_sum {
                uint64_t dma1_cpl:1;
                uint64_t dma0_cpl:1;
        } s;
-       struct cvmx_npei_int_a_sum_cn52xx {
-               uint64_t reserved_8_63:56;
-               uint64_t p1_rdlk:1;
-               uint64_t p0_rdlk:1;
-               uint64_t pgl_err:1;
-               uint64_t pdi_err:1;
-               uint64_t pop_err:1;
-               uint64_t pins_err:1;
-               uint64_t dma1_cpl:1;
-               uint64_t dma0_cpl:1;
-       } cn52xx;
+       struct cvmx_npei_int_a_sum_s cn52xx;
        struct cvmx_npei_int_a_sum_cn52xxp1 {
                uint64_t reserved_2_63:62;
                uint64_t dma1_cpl:1;
@@ -1550,10 +1529,7 @@ union cvmx_npei_int_sum {
                uint64_t c0_se:1;
                uint64_t reserved_20_20:1;
                uint64_t c0_aeri:1;
-               uint64_t ptime:1;
-               uint64_t pcnt:1;
-               uint64_t pidbof:1;
-               uint64_t psldbof:1;
+               uint64_t reserved_15_18:4;
                uint64_t dtime1:1;
                uint64_t dtime0:1;
                uint64_t dcnt1:1;
@@ -1959,7 +1935,6 @@ union cvmx_npei_pktx_cnts {
        } s;
        struct cvmx_npei_pktx_cnts_s cn52xx;
        struct cvmx_npei_pktx_cnts_s cn56xx;
-       struct cvmx_npei_pktx_cnts_s cn56xxp1;
 };
 
 union cvmx_npei_pktx_in_bp {
@@ -1970,7 +1945,6 @@ union cvmx_npei_pktx_in_bp {
        } s;
        struct cvmx_npei_pktx_in_bp_s cn52xx;
        struct cvmx_npei_pktx_in_bp_s cn56xx;
-       struct cvmx_npei_pktx_in_bp_s cn56xxp1;
 };
 
 union cvmx_npei_pktx_instr_baddr {
@@ -1981,7 +1955,6 @@ union cvmx_npei_pktx_instr_baddr {
        } s;
        struct cvmx_npei_pktx_instr_baddr_s cn52xx;
        struct cvmx_npei_pktx_instr_baddr_s cn56xx;
-       struct cvmx_npei_pktx_instr_baddr_s cn56xxp1;
 };
 
 union cvmx_npei_pktx_instr_baoff_dbell {
@@ -1992,7 +1965,6 @@ union cvmx_npei_pktx_instr_baoff_dbell {
        } s;
        struct cvmx_npei_pktx_instr_baoff_dbell_s cn52xx;
        struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xx;
-       struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xxp1;
 };
 
 union cvmx_npei_pktx_instr_fifo_rsize {
@@ -2006,7 +1978,6 @@ union cvmx_npei_pktx_instr_fifo_rsize {
        } s;
        struct cvmx_npei_pktx_instr_fifo_rsize_s cn52xx;
        struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xx;
-       struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xxp1;
 };
 
 union cvmx_npei_pktx_instr_header {
@@ -2014,21 +1985,20 @@ union cvmx_npei_pktx_instr_header {
        struct cvmx_npei_pktx_instr_header_s {
                uint64_t reserved_44_63:20;
                uint64_t pbp:1;
-               uint64_t rsv_f:5;
+               uint64_t reserved_38_42:5;
                uint64_t rparmode:2;
-               uint64_t rsv_e:1;
+               uint64_t reserved_35_35:1;
                uint64_t rskp_len:7;
-               uint64_t rsv_d:6;
+               uint64_t reserved_22_27:6;
                uint64_t use_ihdr:1;
-               uint64_t rsv_c:5;
+               uint64_t reserved_16_20:5;
                uint64_t par_mode:2;
-               uint64_t rsv_b:1;
+               uint64_t reserved_13_13:1;
                uint64_t skp_len:7;
-               uint64_t rsv_a:6;
+               uint64_t reserved_0_5:6;
        } s;
        struct cvmx_npei_pktx_instr_header_s cn52xx;
        struct cvmx_npei_pktx_instr_header_s cn56xx;
-       struct cvmx_npei_pktx_instr_header_s cn56xxp1;
 };
 
 union cvmx_npei_pktx_slist_baddr {
@@ -2039,7 +2009,6 @@ union cvmx_npei_pktx_slist_baddr {
        } s;
        struct cvmx_npei_pktx_slist_baddr_s cn52xx;
        struct cvmx_npei_pktx_slist_baddr_s cn56xx;
-       struct cvmx_npei_pktx_slist_baddr_s cn56xxp1;
 };
 
 union cvmx_npei_pktx_slist_baoff_dbell {
@@ -2050,7 +2019,6 @@ union cvmx_npei_pktx_slist_baoff_dbell {
        } s;
        struct cvmx_npei_pktx_slist_baoff_dbell_s cn52xx;
        struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xx;
-       struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xxp1;
 };
 
 union cvmx_npei_pktx_slist_fifo_rsize {
@@ -2061,7 +2029,6 @@ union cvmx_npei_pktx_slist_fifo_rsize {
        } s;
        struct cvmx_npei_pktx_slist_fifo_rsize_s cn52xx;
        struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xx;
-       struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_cnt_int {
@@ -2072,7 +2039,6 @@ union cvmx_npei_pkt_cnt_int {
        } s;
        struct cvmx_npei_pkt_cnt_int_s cn52xx;
        struct cvmx_npei_pkt_cnt_int_s cn56xx;
-       struct cvmx_npei_pkt_cnt_int_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_cnt_int_enb {
@@ -2083,7 +2049,6 @@ union cvmx_npei_pkt_cnt_int_enb {
        } s;
        struct cvmx_npei_pkt_cnt_int_enb_s cn52xx;
        struct cvmx_npei_pkt_cnt_int_enb_s cn56xx;
-       struct cvmx_npei_pkt_cnt_int_enb_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_data_out_es {
@@ -2093,7 +2058,6 @@ union cvmx_npei_pkt_data_out_es {
        } s;
        struct cvmx_npei_pkt_data_out_es_s cn52xx;
        struct cvmx_npei_pkt_data_out_es_s cn56xx;
-       struct cvmx_npei_pkt_data_out_es_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_data_out_ns {
@@ -2104,7 +2068,6 @@ union cvmx_npei_pkt_data_out_ns {
        } s;
        struct cvmx_npei_pkt_data_out_ns_s cn52xx;
        struct cvmx_npei_pkt_data_out_ns_s cn56xx;
-       struct cvmx_npei_pkt_data_out_ns_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_data_out_ror {
@@ -2115,7 +2078,6 @@ union cvmx_npei_pkt_data_out_ror {
        } s;
        struct cvmx_npei_pkt_data_out_ror_s cn52xx;
        struct cvmx_npei_pkt_data_out_ror_s cn56xx;
-       struct cvmx_npei_pkt_data_out_ror_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_dpaddr {
@@ -2126,7 +2088,6 @@ union cvmx_npei_pkt_dpaddr {
        } s;
        struct cvmx_npei_pkt_dpaddr_s cn52xx;
        struct cvmx_npei_pkt_dpaddr_s cn56xx;
-       struct cvmx_npei_pkt_dpaddr_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_in_bp {
@@ -2135,6 +2096,7 @@ union cvmx_npei_pkt_in_bp {
                uint64_t reserved_32_63:32;
                uint64_t bp:32;
        } s;
+       struct cvmx_npei_pkt_in_bp_s cn52xx;
        struct cvmx_npei_pkt_in_bp_s cn56xx;
 };
 
@@ -2146,7 +2108,6 @@ union cvmx_npei_pkt_in_donex_cnts {
        } s;
        struct cvmx_npei_pkt_in_donex_cnts_s cn52xx;
        struct cvmx_npei_pkt_in_donex_cnts_s cn56xx;
-       struct cvmx_npei_pkt_in_donex_cnts_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_in_instr_counts {
@@ -2184,7 +2145,6 @@ union cvmx_npei_pkt_input_control {
        } s;
        struct cvmx_npei_pkt_input_control_s cn52xx;
        struct cvmx_npei_pkt_input_control_s cn56xx;
-       struct cvmx_npei_pkt_input_control_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_instr_enb {
@@ -2195,7 +2155,6 @@ union cvmx_npei_pkt_instr_enb {
        } s;
        struct cvmx_npei_pkt_instr_enb_s cn52xx;
        struct cvmx_npei_pkt_instr_enb_s cn56xx;
-       struct cvmx_npei_pkt_instr_enb_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_instr_rd_size {
@@ -2215,7 +2174,6 @@ union cvmx_npei_pkt_instr_size {
        } s;
        struct cvmx_npei_pkt_instr_size_s cn52xx;
        struct cvmx_npei_pkt_instr_size_s cn56xx;
-       struct cvmx_npei_pkt_instr_size_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_int_levels {
@@ -2227,7 +2185,6 @@ union cvmx_npei_pkt_int_levels {
        } s;
        struct cvmx_npei_pkt_int_levels_s cn52xx;
        struct cvmx_npei_pkt_int_levels_s cn56xx;
-       struct cvmx_npei_pkt_int_levels_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_iptr {
@@ -2238,7 +2195,6 @@ union cvmx_npei_pkt_iptr {
        } s;
        struct cvmx_npei_pkt_iptr_s cn52xx;
        struct cvmx_npei_pkt_iptr_s cn56xx;
-       struct cvmx_npei_pkt_iptr_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_out_bmode {
@@ -2249,7 +2205,6 @@ union cvmx_npei_pkt_out_bmode {
        } s;
        struct cvmx_npei_pkt_out_bmode_s cn52xx;
        struct cvmx_npei_pkt_out_bmode_s cn56xx;
-       struct cvmx_npei_pkt_out_bmode_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_out_enb {
@@ -2260,7 +2215,6 @@ union cvmx_npei_pkt_out_enb {
        } s;
        struct cvmx_npei_pkt_out_enb_s cn52xx;
        struct cvmx_npei_pkt_out_enb_s cn56xx;
-       struct cvmx_npei_pkt_out_enb_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_output_wmark {
@@ -2280,7 +2234,6 @@ union cvmx_npei_pkt_pcie_port {
        } s;
        struct cvmx_npei_pkt_pcie_port_s cn52xx;
        struct cvmx_npei_pkt_pcie_port_s cn56xx;
-       struct cvmx_npei_pkt_pcie_port_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_port_in_rst {
@@ -2300,7 +2253,6 @@ union cvmx_npei_pkt_slist_es {
        } s;
        struct cvmx_npei_pkt_slist_es_s cn52xx;
        struct cvmx_npei_pkt_slist_es_s cn56xx;
-       struct cvmx_npei_pkt_slist_es_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_slist_id_size {
@@ -2312,7 +2264,6 @@ union cvmx_npei_pkt_slist_id_size {
        } s;
        struct cvmx_npei_pkt_slist_id_size_s cn52xx;
        struct cvmx_npei_pkt_slist_id_size_s cn56xx;
-       struct cvmx_npei_pkt_slist_id_size_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_slist_ns {
@@ -2323,7 +2274,6 @@ union cvmx_npei_pkt_slist_ns {
        } s;
        struct cvmx_npei_pkt_slist_ns_s cn52xx;
        struct cvmx_npei_pkt_slist_ns_s cn56xx;
-       struct cvmx_npei_pkt_slist_ns_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_slist_ror {
@@ -2334,7 +2284,6 @@ union cvmx_npei_pkt_slist_ror {
        } s;
        struct cvmx_npei_pkt_slist_ror_s cn52xx;
        struct cvmx_npei_pkt_slist_ror_s cn56xx;
-       struct cvmx_npei_pkt_slist_ror_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_time_int {
@@ -2345,7 +2294,6 @@ union cvmx_npei_pkt_time_int {
        } s;
        struct cvmx_npei_pkt_time_int_s cn52xx;
        struct cvmx_npei_pkt_time_int_s cn56xx;
-       struct cvmx_npei_pkt_time_int_s cn56xxp1;
 };
 
 union cvmx_npei_pkt_time_int_enb {
@@ -2356,7 +2304,6 @@ union cvmx_npei_pkt_time_int_enb {
        } s;
        struct cvmx_npei_pkt_time_int_enb_s cn52xx;
        struct cvmx_npei_pkt_time_int_enb_s cn56xx;
-       struct cvmx_npei_pkt_time_int_enb_s cn56xxp1;
 };
 
 union cvmx_npei_rsl_int_blocks {
@@ -2371,7 +2318,8 @@ union cvmx_npei_rsl_int_blocks {
                uint64_t asxpcs0:1;
                uint64_t reserved_21_21:1;
                uint64_t pip:1;
-               uint64_t reserved_18_19:2;
+               uint64_t spx1:1;
+               uint64_t spx0:1;
                uint64_t lmc0:1;
                uint64_t l2c:1;
                uint64_t usb1:1;
@@ -2383,7 +2331,7 @@ union cvmx_npei_rsl_int_blocks {
                uint64_t ipd:1;
                uint64_t reserved_8_8:1;
                uint64_t zip:1;
-               uint64_t reserved_6_6:1;
+               uint64_t dfa:1;
                uint64_t fpa:1;
                uint64_t key:1;
                uint64_t npei:1;
@@ -2393,37 +2341,8 @@ union cvmx_npei_rsl_int_blocks {
        } s;
        struct cvmx_npei_rsl_int_blocks_s cn52xx;
        struct cvmx_npei_rsl_int_blocks_s cn52xxp1;
-       struct cvmx_npei_rsl_int_blocks_cn56xx {
-               uint64_t reserved_31_63:33;
-               uint64_t iob:1;
-               uint64_t lmc1:1;
-               uint64_t agl:1;
-               uint64_t reserved_24_27:4;
-               uint64_t asxpcs1:1;
-               uint64_t asxpcs0:1;
-               uint64_t reserved_21_21:1;
-               uint64_t pip:1;
-               uint64_t reserved_18_19:2;
-               uint64_t lmc0:1;
-               uint64_t l2c:1;
-               uint64_t reserved_15_15:1;
-               uint64_t rad:1;
-               uint64_t usb:1;
-               uint64_t pow:1;
-               uint64_t tim:1;
-               uint64_t pko:1;
-               uint64_t ipd:1;
-               uint64_t reserved_8_8:1;
-               uint64_t zip:1;
-               uint64_t reserved_6_6:1;
-               uint64_t fpa:1;
-               uint64_t key:1;
-               uint64_t npei:1;
-               uint64_t gmx1:1;
-               uint64_t gmx0:1;
-               uint64_t mio:1;
-       } cn56xx;
-       struct cvmx_npei_rsl_int_blocks_cn56xx cn56xxp1;
+       struct cvmx_npei_rsl_int_blocks_s cn56xx;
+       struct cvmx_npei_rsl_int_blocks_s cn56xxp1;
 };
 
 union cvmx_npei_scratch_1 {
index 4e03cd8561e312e6a9ace37db08db04b448935a5..f089c780060fc35b0e164fab6ef1717cc43982a1 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_NPI_DEFS_H__
 #define __CVMX_NPI_DEFS_H__
 
-#define CVMX_NPI_BASE_ADDR_INPUT0 \
-        CVMX_ADD_IO_SEG(0x00011F0000000070ull)
-#define CVMX_NPI_BASE_ADDR_INPUT1 \
-        CVMX_ADD_IO_SEG(0x00011F0000000080ull)
-#define CVMX_NPI_BASE_ADDR_INPUT2 \
-        CVMX_ADD_IO_SEG(0x00011F0000000090ull)
-#define CVMX_NPI_BASE_ADDR_INPUT3 \
-        CVMX_ADD_IO_SEG(0x00011F00000000A0ull)
-#define CVMX_NPI_BASE_ADDR_INPUTX(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000000070ull + (((offset) & 3) * 16))
-#define CVMX_NPI_BASE_ADDR_OUTPUT0 \
-        CVMX_ADD_IO_SEG(0x00011F00000000B8ull)
-#define CVMX_NPI_BASE_ADDR_OUTPUT1 \
-        CVMX_ADD_IO_SEG(0x00011F00000000C0ull)
-#define CVMX_NPI_BASE_ADDR_OUTPUT2 \
-        CVMX_ADD_IO_SEG(0x00011F00000000C8ull)
-#define CVMX_NPI_BASE_ADDR_OUTPUT3 \
-        CVMX_ADD_IO_SEG(0x00011F00000000D0ull)
-#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) \
-        CVMX_ADD_IO_SEG(0x00011F00000000B8ull + (((offset) & 3) * 8))
-#define CVMX_NPI_BIST_STATUS \
-        CVMX_ADD_IO_SEG(0x00011F00000003F8ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUT0 \
-        CVMX_ADD_IO_SEG(0x00011F00000000E0ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUT1 \
-        CVMX_ADD_IO_SEG(0x00011F00000000E8ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUT2 \
-        CVMX_ADD_IO_SEG(0x00011F00000000F0ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUT3 \
-        CVMX_ADD_IO_SEG(0x00011F00000000F8ull)
-#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) \
-        CVMX_ADD_IO_SEG(0x00011F00000000E0ull + (((offset) & 3) * 8))
-#define CVMX_NPI_COMP_CTL \
-        CVMX_ADD_IO_SEG(0x00011F0000000218ull)
-#define CVMX_NPI_CTL_STATUS \
-        CVMX_ADD_IO_SEG(0x00011F0000000010ull)
-#define CVMX_NPI_DBG_SELECT \
-        CVMX_ADD_IO_SEG(0x00011F0000000008ull)
-#define CVMX_NPI_DMA_CONTROL \
-        CVMX_ADD_IO_SEG(0x00011F0000000128ull)
-#define CVMX_NPI_DMA_HIGHP_COUNTS \
-        CVMX_ADD_IO_SEG(0x00011F0000000148ull)
-#define CVMX_NPI_DMA_HIGHP_NADDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000158ull)
-#define CVMX_NPI_DMA_LOWP_COUNTS \
-        CVMX_ADD_IO_SEG(0x00011F0000000140ull)
-#define CVMX_NPI_DMA_LOWP_NADDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000150ull)
-#define CVMX_NPI_HIGHP_DBELL \
-        CVMX_ADD_IO_SEG(0x00011F0000000120ull)
-#define CVMX_NPI_HIGHP_IBUFF_SADDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000110ull)
-#define CVMX_NPI_INPUT_CONTROL \
-        CVMX_ADD_IO_SEG(0x00011F0000000138ull)
-#define CVMX_NPI_INT_ENB \
-        CVMX_ADD_IO_SEG(0x00011F0000000020ull)
-#define CVMX_NPI_INT_SUM \
-        CVMX_ADD_IO_SEG(0x00011F0000000018ull)
-#define CVMX_NPI_LOWP_DBELL \
-        CVMX_ADD_IO_SEG(0x00011F0000000118ull)
-#define CVMX_NPI_LOWP_IBUFF_SADDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000108ull)
-#define CVMX_NPI_MEM_ACCESS_SUBID3 \
-        CVMX_ADD_IO_SEG(0x00011F0000000028ull)
-#define CVMX_NPI_MEM_ACCESS_SUBID4 \
-        CVMX_ADD_IO_SEG(0x00011F0000000030ull)
-#define CVMX_NPI_MEM_ACCESS_SUBID5 \
-        CVMX_ADD_IO_SEG(0x00011F0000000038ull)
-#define CVMX_NPI_MEM_ACCESS_SUBID6 \
-        CVMX_ADD_IO_SEG(0x00011F0000000040ull)
-#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000000028ull + (((offset) & 7) * 8) - 8 * 3)
-#define CVMX_NPI_MSI_RCV \
-        (0x0000000000000190ull)
-#define CVMX_NPI_NPI_MSI_RCV \
-        CVMX_ADD_IO_SEG(0x00011F0000001190ull)
-#define CVMX_NPI_NUM_DESC_OUTPUT0 \
-        CVMX_ADD_IO_SEG(0x00011F0000000050ull)
-#define CVMX_NPI_NUM_DESC_OUTPUT1 \
-        CVMX_ADD_IO_SEG(0x00011F0000000058ull)
-#define CVMX_NPI_NUM_DESC_OUTPUT2 \
-        CVMX_ADD_IO_SEG(0x00011F0000000060ull)
-#define CVMX_NPI_NUM_DESC_OUTPUT3 \
-        CVMX_ADD_IO_SEG(0x00011F0000000068ull)
-#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000000050ull + (((offset) & 3) * 8))
-#define CVMX_NPI_OUTPUT_CONTROL \
-        CVMX_ADD_IO_SEG(0x00011F0000000100ull)
-#define CVMX_NPI_P0_DBPAIR_ADDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000180ull)
-#define CVMX_NPI_P0_INSTR_ADDR \
-        CVMX_ADD_IO_SEG(0x00011F00000001C0ull)
-#define CVMX_NPI_P0_INSTR_CNTS \
-        CVMX_ADD_IO_SEG(0x00011F00000001A0ull)
-#define CVMX_NPI_P0_PAIR_CNTS \
-        CVMX_ADD_IO_SEG(0x00011F0000000160ull)
-#define CVMX_NPI_P1_DBPAIR_ADDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000188ull)
-#define CVMX_NPI_P1_INSTR_ADDR \
-        CVMX_ADD_IO_SEG(0x00011F00000001C8ull)
-#define CVMX_NPI_P1_INSTR_CNTS \
-        CVMX_ADD_IO_SEG(0x00011F00000001A8ull)
-#define CVMX_NPI_P1_PAIR_CNTS \
-        CVMX_ADD_IO_SEG(0x00011F0000000168ull)
-#define CVMX_NPI_P2_DBPAIR_ADDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000190ull)
-#define CVMX_NPI_P2_INSTR_ADDR \
-        CVMX_ADD_IO_SEG(0x00011F00000001D0ull)
-#define CVMX_NPI_P2_INSTR_CNTS \
-        CVMX_ADD_IO_SEG(0x00011F00000001B0ull)
-#define CVMX_NPI_P2_PAIR_CNTS \
-        CVMX_ADD_IO_SEG(0x00011F0000000170ull)
-#define CVMX_NPI_P3_DBPAIR_ADDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000198ull)
-#define CVMX_NPI_P3_INSTR_ADDR \
-        CVMX_ADD_IO_SEG(0x00011F00000001D8ull)
-#define CVMX_NPI_P3_INSTR_CNTS \
-        CVMX_ADD_IO_SEG(0x00011F00000001B8ull)
-#define CVMX_NPI_P3_PAIR_CNTS \
-        CVMX_ADD_IO_SEG(0x00011F0000000178ull)
-#define CVMX_NPI_PCI_BAR1_INDEXX(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000001100ull + (((offset) & 31) * 4))
-#define CVMX_NPI_PCI_BIST_REG \
-        CVMX_ADD_IO_SEG(0x00011F00000011C0ull)
-#define CVMX_NPI_PCI_BURST_SIZE \
-        CVMX_ADD_IO_SEG(0x00011F00000000D8ull)
-#define CVMX_NPI_PCI_CFG00 \
-        CVMX_ADD_IO_SEG(0x00011F0000001800ull)
-#define CVMX_NPI_PCI_CFG01 \
-        CVMX_ADD_IO_SEG(0x00011F0000001804ull)
-#define CVMX_NPI_PCI_CFG02 \
-        CVMX_ADD_IO_SEG(0x00011F0000001808ull)
-#define CVMX_NPI_PCI_CFG03 \
-        CVMX_ADD_IO_SEG(0x00011F000000180Cull)
-#define CVMX_NPI_PCI_CFG04 \
-        CVMX_ADD_IO_SEG(0x00011F0000001810ull)
-#define CVMX_NPI_PCI_CFG05 \
-        CVMX_ADD_IO_SEG(0x00011F0000001814ull)
-#define CVMX_NPI_PCI_CFG06 \
-        CVMX_ADD_IO_SEG(0x00011F0000001818ull)
-#define CVMX_NPI_PCI_CFG07 \
-        CVMX_ADD_IO_SEG(0x00011F000000181Cull)
-#define CVMX_NPI_PCI_CFG08 \
-        CVMX_ADD_IO_SEG(0x00011F0000001820ull)
-#define CVMX_NPI_PCI_CFG09 \
-        CVMX_ADD_IO_SEG(0x00011F0000001824ull)
-#define CVMX_NPI_PCI_CFG10 \
-        CVMX_ADD_IO_SEG(0x00011F0000001828ull)
-#define CVMX_NPI_PCI_CFG11 \
-        CVMX_ADD_IO_SEG(0x00011F000000182Cull)
-#define CVMX_NPI_PCI_CFG12 \
-        CVMX_ADD_IO_SEG(0x00011F0000001830ull)
-#define CVMX_NPI_PCI_CFG13 \
-        CVMX_ADD_IO_SEG(0x00011F0000001834ull)
-#define CVMX_NPI_PCI_CFG15 \
-        CVMX_ADD_IO_SEG(0x00011F000000183Cull)
-#define CVMX_NPI_PCI_CFG16 \
-        CVMX_ADD_IO_SEG(0x00011F0000001840ull)
-#define CVMX_NPI_PCI_CFG17 \
-        CVMX_ADD_IO_SEG(0x00011F0000001844ull)
-#define CVMX_NPI_PCI_CFG18 \
-        CVMX_ADD_IO_SEG(0x00011F0000001848ull)
-#define CVMX_NPI_PCI_CFG19 \
-        CVMX_ADD_IO_SEG(0x00011F000000184Cull)
-#define CVMX_NPI_PCI_CFG20 \
-        CVMX_ADD_IO_SEG(0x00011F0000001850ull)
-#define CVMX_NPI_PCI_CFG21 \
-        CVMX_ADD_IO_SEG(0x00011F0000001854ull)
-#define CVMX_NPI_PCI_CFG22 \
-        CVMX_ADD_IO_SEG(0x00011F0000001858ull)
-#define CVMX_NPI_PCI_CFG56 \
-        CVMX_ADD_IO_SEG(0x00011F00000018E0ull)
-#define CVMX_NPI_PCI_CFG57 \
-        CVMX_ADD_IO_SEG(0x00011F00000018E4ull)
-#define CVMX_NPI_PCI_CFG58 \
-        CVMX_ADD_IO_SEG(0x00011F00000018E8ull)
-#define CVMX_NPI_PCI_CFG59 \
-        CVMX_ADD_IO_SEG(0x00011F00000018ECull)
-#define CVMX_NPI_PCI_CFG60 \
-        CVMX_ADD_IO_SEG(0x00011F00000018F0ull)
-#define CVMX_NPI_PCI_CFG61 \
-        CVMX_ADD_IO_SEG(0x00011F00000018F4ull)
-#define CVMX_NPI_PCI_CFG62 \
-        CVMX_ADD_IO_SEG(0x00011F00000018F8ull)
-#define CVMX_NPI_PCI_CFG63 \
-        CVMX_ADD_IO_SEG(0x00011F00000018FCull)
-#define CVMX_NPI_PCI_CNT_REG \
-        CVMX_ADD_IO_SEG(0x00011F00000011B8ull)
-#define CVMX_NPI_PCI_CTL_STATUS_2 \
-        CVMX_ADD_IO_SEG(0x00011F000000118Cull)
-#define CVMX_NPI_PCI_INT_ARB_CFG \
-        CVMX_ADD_IO_SEG(0x00011F0000000130ull)
-#define CVMX_NPI_PCI_INT_ENB2 \
-        CVMX_ADD_IO_SEG(0x00011F00000011A0ull)
-#define CVMX_NPI_PCI_INT_SUM2 \
-        CVMX_ADD_IO_SEG(0x00011F0000001198ull)
-#define CVMX_NPI_PCI_READ_CMD \
-        CVMX_ADD_IO_SEG(0x00011F0000000048ull)
-#define CVMX_NPI_PCI_READ_CMD_6 \
-        CVMX_ADD_IO_SEG(0x00011F0000001180ull)
-#define CVMX_NPI_PCI_READ_CMD_C \
-        CVMX_ADD_IO_SEG(0x00011F0000001184ull)
-#define CVMX_NPI_PCI_READ_CMD_E \
-        CVMX_ADD_IO_SEG(0x00011F0000001188ull)
-#define CVMX_NPI_PCI_SCM_REG \
-        CVMX_ADD_IO_SEG(0x00011F00000011A8ull)
-#define CVMX_NPI_PCI_TSR_REG \
-        CVMX_ADD_IO_SEG(0x00011F00000011B0ull)
-#define CVMX_NPI_PORT32_INSTR_HDR \
-        CVMX_ADD_IO_SEG(0x00011F00000001F8ull)
-#define CVMX_NPI_PORT33_INSTR_HDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000200ull)
-#define CVMX_NPI_PORT34_INSTR_HDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000208ull)
-#define CVMX_NPI_PORT35_INSTR_HDR \
-        CVMX_ADD_IO_SEG(0x00011F0000000210ull)
-#define CVMX_NPI_PORT_BP_CONTROL \
-        CVMX_ADD_IO_SEG(0x00011F00000001F0ull)
-#define CVMX_NPI_PX_DBPAIR_ADDR(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000000180ull + (((offset) & 3) * 8))
-#define CVMX_NPI_PX_INSTR_ADDR(offset) \
-        CVMX_ADD_IO_SEG(0x00011F00000001C0ull + (((offset) & 3) * 8))
-#define CVMX_NPI_PX_INSTR_CNTS(offset) \
-        CVMX_ADD_IO_SEG(0x00011F00000001A0ull + (((offset) & 3) * 8))
-#define CVMX_NPI_PX_PAIR_CNTS(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000000160ull + (((offset) & 3) * 8))
-#define CVMX_NPI_RSL_INT_BLOCKS \
-        CVMX_ADD_IO_SEG(0x00011F0000000000ull)
-#define CVMX_NPI_SIZE_INPUT0 \
-        CVMX_ADD_IO_SEG(0x00011F0000000078ull)
-#define CVMX_NPI_SIZE_INPUT1 \
-        CVMX_ADD_IO_SEG(0x00011F0000000088ull)
-#define CVMX_NPI_SIZE_INPUT2 \
-        CVMX_ADD_IO_SEG(0x00011F0000000098ull)
-#define CVMX_NPI_SIZE_INPUT3 \
-        CVMX_ADD_IO_SEG(0x00011F00000000A8ull)
-#define CVMX_NPI_SIZE_INPUTX(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000000078ull + (((offset) & 3) * 16))
-#define CVMX_NPI_WIN_READ_TO \
-        CVMX_ADD_IO_SEG(0x00011F00000001E0ull)
+#define CVMX_NPI_BASE_ADDR_INPUT0 CVMX_NPI_BASE_ADDR_INPUTX(0)
+#define CVMX_NPI_BASE_ADDR_INPUT1 CVMX_NPI_BASE_ADDR_INPUTX(1)
+#define CVMX_NPI_BASE_ADDR_INPUT2 CVMX_NPI_BASE_ADDR_INPUTX(2)
+#define CVMX_NPI_BASE_ADDR_INPUT3 CVMX_NPI_BASE_ADDR_INPUTX(3)
+#define CVMX_NPI_BASE_ADDR_INPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000070ull) + ((offset) & 3) * 16)
+#define CVMX_NPI_BASE_ADDR_OUTPUT0 CVMX_NPI_BASE_ADDR_OUTPUTX(0)
+#define CVMX_NPI_BASE_ADDR_OUTPUT1 CVMX_NPI_BASE_ADDR_OUTPUTX(1)
+#define CVMX_NPI_BASE_ADDR_OUTPUT2 CVMX_NPI_BASE_ADDR_OUTPUTX(2)
+#define CVMX_NPI_BASE_ADDR_OUTPUT3 CVMX_NPI_BASE_ADDR_OUTPUTX(3)
+#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F00000000B8ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F00000003F8ull))
+#define CVMX_NPI_BUFF_SIZE_OUTPUT0 CVMX_NPI_BUFF_SIZE_OUTPUTX(0)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT1 CVMX_NPI_BUFF_SIZE_OUTPUTX(1)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT2 CVMX_NPI_BUFF_SIZE_OUTPUTX(2)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT3 CVMX_NPI_BUFF_SIZE_OUTPUTX(3)
+#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F00000000E0ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_COMP_CTL (CVMX_ADD_IO_SEG(0x00011F0000000218ull))
+#define CVMX_NPI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000000010ull))
+#define CVMX_NPI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000000008ull))
+#define CVMX_NPI_DMA_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000128ull))
+#define CVMX_NPI_DMA_HIGHP_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000000148ull))
+#define CVMX_NPI_DMA_HIGHP_NADDR (CVMX_ADD_IO_SEG(0x00011F0000000158ull))
+#define CVMX_NPI_DMA_LOWP_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000000140ull))
+#define CVMX_NPI_DMA_LOWP_NADDR (CVMX_ADD_IO_SEG(0x00011F0000000150ull))
+#define CVMX_NPI_HIGHP_DBELL (CVMX_ADD_IO_SEG(0x00011F0000000120ull))
+#define CVMX_NPI_HIGHP_IBUFF_SADDR (CVMX_ADD_IO_SEG(0x00011F0000000110ull))
+#define CVMX_NPI_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000138ull))
+#define CVMX_NPI_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000000020ull))
+#define CVMX_NPI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000000018ull))
+#define CVMX_NPI_LOWP_DBELL (CVMX_ADD_IO_SEG(0x00011F0000000118ull))
+#define CVMX_NPI_LOWP_IBUFF_SADDR (CVMX_ADD_IO_SEG(0x00011F0000000108ull))
+#define CVMX_NPI_MEM_ACCESS_SUBID3 CVMX_NPI_MEM_ACCESS_SUBIDX(3)
+#define CVMX_NPI_MEM_ACCESS_SUBID4 CVMX_NPI_MEM_ACCESS_SUBIDX(4)
+#define CVMX_NPI_MEM_ACCESS_SUBID5 CVMX_NPI_MEM_ACCESS_SUBIDX(5)
+#define CVMX_NPI_MEM_ACCESS_SUBID6 CVMX_NPI_MEM_ACCESS_SUBIDX(6)
+#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000028ull) + ((offset) & 7) * 8 - 8*3)
+#define CVMX_NPI_MSI_RCV (0x0000000000000190ull)
+#define CVMX_NPI_NPI_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F0000001190ull))
+#define CVMX_NPI_NUM_DESC_OUTPUT0 CVMX_NPI_NUM_DESC_OUTPUTX(0)
+#define CVMX_NPI_NUM_DESC_OUTPUT1 CVMX_NPI_NUM_DESC_OUTPUTX(1)
+#define CVMX_NPI_NUM_DESC_OUTPUT2 CVMX_NPI_NUM_DESC_OUTPUTX(2)
+#define CVMX_NPI_NUM_DESC_OUTPUT3 CVMX_NPI_NUM_DESC_OUTPUTX(3)
+#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000050ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_OUTPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000100ull))
+#define CVMX_NPI_P0_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(0)
+#define CVMX_NPI_P0_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(0)
+#define CVMX_NPI_P0_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(0)
+#define CVMX_NPI_P0_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(0)
+#define CVMX_NPI_P1_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(1)
+#define CVMX_NPI_P1_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(1)
+#define CVMX_NPI_P1_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(1)
+#define CVMX_NPI_P1_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(1)
+#define CVMX_NPI_P2_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(2)
+#define CVMX_NPI_P2_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(2)
+#define CVMX_NPI_P2_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(2)
+#define CVMX_NPI_P2_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(2)
+#define CVMX_NPI_P3_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(3)
+#define CVMX_NPI_P3_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(3)
+#define CVMX_NPI_P3_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(3)
+#define CVMX_NPI_P3_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(3)
+#define CVMX_NPI_PCI_BAR1_INDEXX(offset) (CVMX_ADD_IO_SEG(0x00011F0000001100ull) + ((offset) & 31) * 4)
+#define CVMX_NPI_PCI_BIST_REG (CVMX_ADD_IO_SEG(0x00011F00000011C0ull))
+#define CVMX_NPI_PCI_BURST_SIZE (CVMX_ADD_IO_SEG(0x00011F00000000D8ull))
+#define CVMX_NPI_PCI_CFG00 (CVMX_ADD_IO_SEG(0x00011F0000001800ull))
+#define CVMX_NPI_PCI_CFG01 (CVMX_ADD_IO_SEG(0x00011F0000001804ull))
+#define CVMX_NPI_PCI_CFG02 (CVMX_ADD_IO_SEG(0x00011F0000001808ull))
+#define CVMX_NPI_PCI_CFG03 (CVMX_ADD_IO_SEG(0x00011F000000180Cull))
+#define CVMX_NPI_PCI_CFG04 (CVMX_ADD_IO_SEG(0x00011F0000001810ull))
+#define CVMX_NPI_PCI_CFG05 (CVMX_ADD_IO_SEG(0x00011F0000001814ull))
+#define CVMX_NPI_PCI_CFG06 (CVMX_ADD_IO_SEG(0x00011F0000001818ull))
+#define CVMX_NPI_PCI_CFG07 (CVMX_ADD_IO_SEG(0x00011F000000181Cull))
+#define CVMX_NPI_PCI_CFG08 (CVMX_ADD_IO_SEG(0x00011F0000001820ull))
+#define CVMX_NPI_PCI_CFG09 (CVMX_ADD_IO_SEG(0x00011F0000001824ull))
+#define CVMX_NPI_PCI_CFG10 (CVMX_ADD_IO_SEG(0x00011F0000001828ull))
+#define CVMX_NPI_PCI_CFG11 (CVMX_ADD_IO_SEG(0x00011F000000182Cull))
+#define CVMX_NPI_PCI_CFG12 (CVMX_ADD_IO_SEG(0x00011F0000001830ull))
+#define CVMX_NPI_PCI_CFG13 (CVMX_ADD_IO_SEG(0x00011F0000001834ull))
+#define CVMX_NPI_PCI_CFG15 (CVMX_ADD_IO_SEG(0x00011F000000183Cull))
+#define CVMX_NPI_PCI_CFG16 (CVMX_ADD_IO_SEG(0x00011F0000001840ull))
+#define CVMX_NPI_PCI_CFG17 (CVMX_ADD_IO_SEG(0x00011F0000001844ull))
+#define CVMX_NPI_PCI_CFG18 (CVMX_ADD_IO_SEG(0x00011F0000001848ull))
+#define CVMX_NPI_PCI_CFG19 (CVMX_ADD_IO_SEG(0x00011F000000184Cull))
+#define CVMX_NPI_PCI_CFG20 (CVMX_ADD_IO_SEG(0x00011F0000001850ull))
+#define CVMX_NPI_PCI_CFG21 (CVMX_ADD_IO_SEG(0x00011F0000001854ull))
+#define CVMX_NPI_PCI_CFG22 (CVMX_ADD_IO_SEG(0x00011F0000001858ull))
+#define CVMX_NPI_PCI_CFG56 (CVMX_ADD_IO_SEG(0x00011F00000018E0ull))
+#define CVMX_NPI_PCI_CFG57 (CVMX_ADD_IO_SEG(0x00011F00000018E4ull))
+#define CVMX_NPI_PCI_CFG58 (CVMX_ADD_IO_SEG(0x00011F00000018E8ull))
+#define CVMX_NPI_PCI_CFG59 (CVMX_ADD_IO_SEG(0x00011F00000018ECull))
+#define CVMX_NPI_PCI_CFG60 (CVMX_ADD_IO_SEG(0x00011F00000018F0ull))
+#define CVMX_NPI_PCI_CFG61 (CVMX_ADD_IO_SEG(0x00011F00000018F4ull))
+#define CVMX_NPI_PCI_CFG62 (CVMX_ADD_IO_SEG(0x00011F00000018F8ull))
+#define CVMX_NPI_PCI_CFG63 (CVMX_ADD_IO_SEG(0x00011F00000018FCull))
+#define CVMX_NPI_PCI_CNT_REG (CVMX_ADD_IO_SEG(0x00011F00000011B8ull))
+#define CVMX_NPI_PCI_CTL_STATUS_2 (CVMX_ADD_IO_SEG(0x00011F000000118Cull))
+#define CVMX_NPI_PCI_INT_ARB_CFG (CVMX_ADD_IO_SEG(0x00011F0000000130ull))
+#define CVMX_NPI_PCI_INT_ENB2 (CVMX_ADD_IO_SEG(0x00011F00000011A0ull))
+#define CVMX_NPI_PCI_INT_SUM2 (CVMX_ADD_IO_SEG(0x00011F0000001198ull))
+#define CVMX_NPI_PCI_READ_CMD (CVMX_ADD_IO_SEG(0x00011F0000000048ull))
+#define CVMX_NPI_PCI_READ_CMD_6 (CVMX_ADD_IO_SEG(0x00011F0000001180ull))
+#define CVMX_NPI_PCI_READ_CMD_C (CVMX_ADD_IO_SEG(0x00011F0000001184ull))
+#define CVMX_NPI_PCI_READ_CMD_E (CVMX_ADD_IO_SEG(0x00011F0000001188ull))
+#define CVMX_NPI_PCI_SCM_REG (CVMX_ADD_IO_SEG(0x00011F00000011A8ull))
+#define CVMX_NPI_PCI_TSR_REG (CVMX_ADD_IO_SEG(0x00011F00000011B0ull))
+#define CVMX_NPI_PORT32_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F00000001F8ull))
+#define CVMX_NPI_PORT33_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000200ull))
+#define CVMX_NPI_PORT34_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000208ull))
+#define CVMX_NPI_PORT35_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000210ull))
+#define CVMX_NPI_PORT_BP_CONTROL (CVMX_ADD_IO_SEG(0x00011F00000001F0ull))
+#define CVMX_NPI_PX_DBPAIR_ADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000000180ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_PX_INSTR_ADDR(offset) (CVMX_ADD_IO_SEG(0x00011F00000001C0ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_PX_INSTR_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F00000001A0ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_PX_PAIR_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000000160ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_RSL_INT_BLOCKS (CVMX_ADD_IO_SEG(0x00011F0000000000ull))
+#define CVMX_NPI_SIZE_INPUT0 CVMX_NPI_SIZE_INPUTX(0)
+#define CVMX_NPI_SIZE_INPUT1 CVMX_NPI_SIZE_INPUTX(1)
+#define CVMX_NPI_SIZE_INPUT2 CVMX_NPI_SIZE_INPUTX(2)
+#define CVMX_NPI_SIZE_INPUT3 CVMX_NPI_SIZE_INPUTX(3)
+#define CVMX_NPI_SIZE_INPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000078ull) + ((offset) & 3) * 16)
+#define CVMX_NPI_WIN_READ_TO (CVMX_ADD_IO_SEG(0x00011F00000001E0ull))
 
 union cvmx_npi_base_addr_inputx {
        uint64_t u64;
index 90f8d6535753a52bf04ddc6438ed1b548d4848c2..6ff6d9d357ba4dc2316b4f04d5fb28595b6d041d 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_PCI_DEFS_H__
 #define __CVMX_PCI_DEFS_H__
 
-#define CVMX_PCI_BAR1_INDEXX(offset) \
-        (0x0000000000000100ull + (((offset) & 31) * 4))
-#define CVMX_PCI_BIST_REG \
-        (0x00000000000001C0ull)
-#define CVMX_PCI_CFG00 \
-        (0x0000000000000000ull)
-#define CVMX_PCI_CFG01 \
-        (0x0000000000000004ull)
-#define CVMX_PCI_CFG02 \
-        (0x0000000000000008ull)
-#define CVMX_PCI_CFG03 \
-        (0x000000000000000Cull)
-#define CVMX_PCI_CFG04 \
-        (0x0000000000000010ull)
-#define CVMX_PCI_CFG05 \
-        (0x0000000000000014ull)
-#define CVMX_PCI_CFG06 \
-        (0x0000000000000018ull)
-#define CVMX_PCI_CFG07 \
-        (0x000000000000001Cull)
-#define CVMX_PCI_CFG08 \
-        (0x0000000000000020ull)
-#define CVMX_PCI_CFG09 \
-        (0x0000000000000024ull)
-#define CVMX_PCI_CFG10 \
-        (0x0000000000000028ull)
-#define CVMX_PCI_CFG11 \
-        (0x000000000000002Cull)
-#define CVMX_PCI_CFG12 \
-        (0x0000000000000030ull)
-#define CVMX_PCI_CFG13 \
-        (0x0000000000000034ull)
-#define CVMX_PCI_CFG15 \
-        (0x000000000000003Cull)
-#define CVMX_PCI_CFG16 \
-        (0x0000000000000040ull)
-#define CVMX_PCI_CFG17 \
-        (0x0000000000000044ull)
-#define CVMX_PCI_CFG18 \
-        (0x0000000000000048ull)
-#define CVMX_PCI_CFG19 \
-        (0x000000000000004Cull)
-#define CVMX_PCI_CFG20 \
-        (0x0000000000000050ull)
-#define CVMX_PCI_CFG21 \
-        (0x0000000000000054ull)
-#define CVMX_PCI_CFG22 \
-        (0x0000000000000058ull)
-#define CVMX_PCI_CFG56 \
-        (0x00000000000000E0ull)
-#define CVMX_PCI_CFG57 \
-        (0x00000000000000E4ull)
-#define CVMX_PCI_CFG58 \
-        (0x00000000000000E8ull)
-#define CVMX_PCI_CFG59 \
-        (0x00000000000000ECull)
-#define CVMX_PCI_CFG60 \
-        (0x00000000000000F0ull)
-#define CVMX_PCI_CFG61 \
-        (0x00000000000000F4ull)
-#define CVMX_PCI_CFG62 \
-        (0x00000000000000F8ull)
-#define CVMX_PCI_CFG63 \
-        (0x00000000000000FCull)
-#define CVMX_PCI_CNT_REG \
-        (0x00000000000001B8ull)
-#define CVMX_PCI_CTL_STATUS_2 \
-        (0x000000000000018Cull)
-#define CVMX_PCI_DBELL_0 \
-        (0x0000000000000080ull)
-#define CVMX_PCI_DBELL_1 \
-        (0x0000000000000088ull)
-#define CVMX_PCI_DBELL_2 \
-        (0x0000000000000090ull)
-#define CVMX_PCI_DBELL_3 \
-        (0x0000000000000098ull)
-#define CVMX_PCI_DBELL_X(offset) \
-        (0x0000000000000080ull + (((offset) & 3) * 8))
-#define CVMX_PCI_DMA_CNT0 \
-        (0x00000000000000A0ull)
-#define CVMX_PCI_DMA_CNT1 \
-        (0x00000000000000A8ull)
-#define CVMX_PCI_DMA_CNTX(offset) \
-        (0x00000000000000A0ull + (((offset) & 1) * 8))
-#define CVMX_PCI_DMA_INT_LEV0 \
-        (0x00000000000000A4ull)
-#define CVMX_PCI_DMA_INT_LEV1 \
-        (0x00000000000000ACull)
-#define CVMX_PCI_DMA_INT_LEVX(offset) \
-        (0x00000000000000A4ull + (((offset) & 1) * 8))
-#define CVMX_PCI_DMA_TIME0 \
-        (0x00000000000000B0ull)
-#define CVMX_PCI_DMA_TIME1 \
-        (0x00000000000000B4ull)
-#define CVMX_PCI_DMA_TIMEX(offset) \
-        (0x00000000000000B0ull + (((offset) & 1) * 4))
-#define CVMX_PCI_INSTR_COUNT0 \
-        (0x0000000000000084ull)
-#define CVMX_PCI_INSTR_COUNT1 \
-        (0x000000000000008Cull)
-#define CVMX_PCI_INSTR_COUNT2 \
-        (0x0000000000000094ull)
-#define CVMX_PCI_INSTR_COUNT3 \
-        (0x000000000000009Cull)
-#define CVMX_PCI_INSTR_COUNTX(offset) \
-        (0x0000000000000084ull + (((offset) & 3) * 8))
-#define CVMX_PCI_INT_ENB \
-        (0x0000000000000038ull)
-#define CVMX_PCI_INT_ENB2 \
-        (0x00000000000001A0ull)
-#define CVMX_PCI_INT_SUM \
-        (0x0000000000000030ull)
-#define CVMX_PCI_INT_SUM2 \
-        (0x0000000000000198ull)
-#define CVMX_PCI_MSI_RCV \
-        (0x00000000000000F0ull)
-#define CVMX_PCI_PKTS_SENT0 \
-        (0x0000000000000040ull)
-#define CVMX_PCI_PKTS_SENT1 \
-        (0x0000000000000050ull)
-#define CVMX_PCI_PKTS_SENT2 \
-        (0x0000000000000060ull)
-#define CVMX_PCI_PKTS_SENT3 \
-        (0x0000000000000070ull)
-#define CVMX_PCI_PKTS_SENTX(offset) \
-        (0x0000000000000040ull + (((offset) & 3) * 16))
-#define CVMX_PCI_PKTS_SENT_INT_LEV0 \
-        (0x0000000000000048ull)
-#define CVMX_PCI_PKTS_SENT_INT_LEV1 \
-        (0x0000000000000058ull)
-#define CVMX_PCI_PKTS_SENT_INT_LEV2 \
-        (0x0000000000000068ull)
-#define CVMX_PCI_PKTS_SENT_INT_LEV3 \
-        (0x0000000000000078ull)
-#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) \
-        (0x0000000000000048ull + (((offset) & 3) * 16))
-#define CVMX_PCI_PKTS_SENT_TIME0 \
-        (0x000000000000004Cull)
-#define CVMX_PCI_PKTS_SENT_TIME1 \
-        (0x000000000000005Cull)
-#define CVMX_PCI_PKTS_SENT_TIME2 \
-        (0x000000000000006Cull)
-#define CVMX_PCI_PKTS_SENT_TIME3 \
-        (0x000000000000007Cull)
-#define CVMX_PCI_PKTS_SENT_TIMEX(offset) \
-        (0x000000000000004Cull + (((offset) & 3) * 16))
-#define CVMX_PCI_PKT_CREDITS0 \
-        (0x0000000000000044ull)
-#define CVMX_PCI_PKT_CREDITS1 \
-        (0x0000000000000054ull)
-#define CVMX_PCI_PKT_CREDITS2 \
-        (0x0000000000000064ull)
-#define CVMX_PCI_PKT_CREDITS3 \
-        (0x0000000000000074ull)
-#define CVMX_PCI_PKT_CREDITSX(offset) \
-        (0x0000000000000044ull + (((offset) & 3) * 16))
-#define CVMX_PCI_READ_CMD_6 \
-        (0x0000000000000180ull)
-#define CVMX_PCI_READ_CMD_C \
-        (0x0000000000000184ull)
-#define CVMX_PCI_READ_CMD_E \
-        (0x0000000000000188ull)
-#define CVMX_PCI_READ_TIMEOUT \
-        CVMX_ADD_IO_SEG(0x00011F00000000B0ull)
-#define CVMX_PCI_SCM_REG \
-        (0x00000000000001A8ull)
-#define CVMX_PCI_TSR_REG \
-        (0x00000000000001B0ull)
-#define CVMX_PCI_WIN_RD_ADDR \
-        (0x0000000000000008ull)
-#define CVMX_PCI_WIN_RD_DATA \
-        (0x0000000000000020ull)
-#define CVMX_PCI_WIN_WR_ADDR \
-        (0x0000000000000000ull)
-#define CVMX_PCI_WIN_WR_DATA \
-        (0x0000000000000010ull)
-#define CVMX_PCI_WIN_WR_MASK \
-        (0x0000000000000018ull)
+#define CVMX_PCI_BAR1_INDEXX(offset) (0x0000000000000100ull + ((offset) & 31) * 4)
+#define CVMX_PCI_BIST_REG (0x00000000000001C0ull)
+#define CVMX_PCI_CFG00 (0x0000000000000000ull)
+#define CVMX_PCI_CFG01 (0x0000000000000004ull)
+#define CVMX_PCI_CFG02 (0x0000000000000008ull)
+#define CVMX_PCI_CFG03 (0x000000000000000Cull)
+#define CVMX_PCI_CFG04 (0x0000000000000010ull)
+#define CVMX_PCI_CFG05 (0x0000000000000014ull)
+#define CVMX_PCI_CFG06 (0x0000000000000018ull)
+#define CVMX_PCI_CFG07 (0x000000000000001Cull)
+#define CVMX_PCI_CFG08 (0x0000000000000020ull)
+#define CVMX_PCI_CFG09 (0x0000000000000024ull)
+#define CVMX_PCI_CFG10 (0x0000000000000028ull)
+#define CVMX_PCI_CFG11 (0x000000000000002Cull)
+#define CVMX_PCI_CFG12 (0x0000000000000030ull)
+#define CVMX_PCI_CFG13 (0x0000000000000034ull)
+#define CVMX_PCI_CFG15 (0x000000000000003Cull)
+#define CVMX_PCI_CFG16 (0x0000000000000040ull)
+#define CVMX_PCI_CFG17 (0x0000000000000044ull)
+#define CVMX_PCI_CFG18 (0x0000000000000048ull)
+#define CVMX_PCI_CFG19 (0x000000000000004Cull)
+#define CVMX_PCI_CFG20 (0x0000000000000050ull)
+#define CVMX_PCI_CFG21 (0x0000000000000054ull)
+#define CVMX_PCI_CFG22 (0x0000000000000058ull)
+#define CVMX_PCI_CFG56 (0x00000000000000E0ull)
+#define CVMX_PCI_CFG57 (0x00000000000000E4ull)
+#define CVMX_PCI_CFG58 (0x00000000000000E8ull)
+#define CVMX_PCI_CFG59 (0x00000000000000ECull)
+#define CVMX_PCI_CFG60 (0x00000000000000F0ull)
+#define CVMX_PCI_CFG61 (0x00000000000000F4ull)
+#define CVMX_PCI_CFG62 (0x00000000000000F8ull)
+#define CVMX_PCI_CFG63 (0x00000000000000FCull)
+#define CVMX_PCI_CNT_REG (0x00000000000001B8ull)
+#define CVMX_PCI_CTL_STATUS_2 (0x000000000000018Cull)
+#define CVMX_PCI_DBELL_X(offset) (0x0000000000000080ull + ((offset) & 3) * 8)
+#define CVMX_PCI_DMA_CNT0 CVMX_PCI_DMA_CNTX(0)
+#define CVMX_PCI_DMA_CNT1 CVMX_PCI_DMA_CNTX(1)
+#define CVMX_PCI_DMA_CNTX(offset) (0x00000000000000A0ull + ((offset) & 1) * 8)
+#define CVMX_PCI_DMA_INT_LEV0 CVMX_PCI_DMA_INT_LEVX(0)
+#define CVMX_PCI_DMA_INT_LEV1 CVMX_PCI_DMA_INT_LEVX(1)
+#define CVMX_PCI_DMA_INT_LEVX(offset) (0x00000000000000A4ull + ((offset) & 1) * 8)
+#define CVMX_PCI_DMA_TIME0 CVMX_PCI_DMA_TIMEX(0)
+#define CVMX_PCI_DMA_TIME1 CVMX_PCI_DMA_TIMEX(1)
+#define CVMX_PCI_DMA_TIMEX(offset) (0x00000000000000B0ull + ((offset) & 1) * 4)
+#define CVMX_PCI_INSTR_COUNT0 CVMX_PCI_INSTR_COUNTX(0)
+#define CVMX_PCI_INSTR_COUNT1 CVMX_PCI_INSTR_COUNTX(1)
+#define CVMX_PCI_INSTR_COUNT2 CVMX_PCI_INSTR_COUNTX(2)
+#define CVMX_PCI_INSTR_COUNT3 CVMX_PCI_INSTR_COUNTX(3)
+#define CVMX_PCI_INSTR_COUNTX(offset) (0x0000000000000084ull + ((offset) & 3) * 8)
+#define CVMX_PCI_INT_ENB (0x0000000000000038ull)
+#define CVMX_PCI_INT_ENB2 (0x00000000000001A0ull)
+#define CVMX_PCI_INT_SUM (0x0000000000000030ull)
+#define CVMX_PCI_INT_SUM2 (0x0000000000000198ull)
+#define CVMX_PCI_MSI_RCV (0x00000000000000F0ull)
+#define CVMX_PCI_PKTS_SENT0 CVMX_PCI_PKTS_SENTX(0)
+#define CVMX_PCI_PKTS_SENT1 CVMX_PCI_PKTS_SENTX(1)
+#define CVMX_PCI_PKTS_SENT2 CVMX_PCI_PKTS_SENTX(2)
+#define CVMX_PCI_PKTS_SENT3 CVMX_PCI_PKTS_SENTX(3)
+#define CVMX_PCI_PKTS_SENTX(offset) (0x0000000000000040ull + ((offset) & 3) * 16)
+#define CVMX_PCI_PKTS_SENT_INT_LEV0 CVMX_PCI_PKTS_SENT_INT_LEVX(0)
+#define CVMX_PCI_PKTS_SENT_INT_LEV1 CVMX_PCI_PKTS_SENT_INT_LEVX(1)
+#define CVMX_PCI_PKTS_SENT_INT_LEV2 CVMX_PCI_PKTS_SENT_INT_LEVX(2)
+#define CVMX_PCI_PKTS_SENT_INT_LEV3 CVMX_PCI_PKTS_SENT_INT_LEVX(3)
+#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) (0x0000000000000048ull + ((offset) & 3) * 16)
+#define CVMX_PCI_PKTS_SENT_TIME0 CVMX_PCI_PKTS_SENT_TIMEX(0)
+#define CVMX_PCI_PKTS_SENT_TIME1 CVMX_PCI_PKTS_SENT_TIMEX(1)
+#define CVMX_PCI_PKTS_SENT_TIME2 CVMX_PCI_PKTS_SENT_TIMEX(2)
+#define CVMX_PCI_PKTS_SENT_TIME3 CVMX_PCI_PKTS_SENT_TIMEX(3)
+#define CVMX_PCI_PKTS_SENT_TIMEX(offset) (0x000000000000004Cull + ((offset) & 3) * 16)
+#define CVMX_PCI_PKT_CREDITS0 CVMX_PCI_PKT_CREDITSX(0)
+#define CVMX_PCI_PKT_CREDITS1 CVMX_PCI_PKT_CREDITSX(1)
+#define CVMX_PCI_PKT_CREDITS2 CVMX_PCI_PKT_CREDITSX(2)
+#define CVMX_PCI_PKT_CREDITS3 CVMX_PCI_PKT_CREDITSX(3)
+#define CVMX_PCI_PKT_CREDITSX(offset) (0x0000000000000044ull + ((offset) & 3) * 16)
+#define CVMX_PCI_READ_CMD_6 (0x0000000000000180ull)
+#define CVMX_PCI_READ_CMD_C (0x0000000000000184ull)
+#define CVMX_PCI_READ_CMD_E (0x0000000000000188ull)
+#define CVMX_PCI_READ_TIMEOUT (CVMX_ADD_IO_SEG(0x00011F00000000B0ull))
+#define CVMX_PCI_SCM_REG (0x00000000000001A8ull)
+#define CVMX_PCI_TSR_REG (0x00000000000001B0ull)
+#define CVMX_PCI_WIN_RD_ADDR (0x0000000000000008ull)
+#define CVMX_PCI_WIN_RD_DATA (0x0000000000000020ull)
+#define CVMX_PCI_WIN_WR_ADDR (0x0000000000000000ull)
+#define CVMX_PCI_WIN_WR_DATA (0x0000000000000010ull)
+#define CVMX_PCI_WIN_WR_MASK (0x0000000000000018ull)
 
 union cvmx_pci_bar1_indexx {
        uint32_t u32;
index 75574c9189425d7dbc31596796b39b7899741e25..f8cb88902efbd472c613e6ac45ee26aff25cb2f3 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_PCIERCX_DEFS_H__
 #define __CVMX_PCIERCX_DEFS_H__
 
-#define CVMX_PCIERCX_CFG000(offset) \
-        (0x0000000000000000ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG001(offset) \
-        (0x0000000000000004ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG002(offset) \
-        (0x0000000000000008ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG003(offset) \
-        (0x000000000000000Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG004(offset) \
-        (0x0000000000000010ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG005(offset) \
-        (0x0000000000000014ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG006(offset) \
-        (0x0000000000000018ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG007(offset) \
-        (0x000000000000001Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG008(offset) \
-        (0x0000000000000020ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG009(offset) \
-        (0x0000000000000024ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG010(offset) \
-        (0x0000000000000028ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG011(offset) \
-        (0x000000000000002Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG012(offset) \
-        (0x0000000000000030ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG013(offset) \
-        (0x0000000000000034ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG014(offset) \
-        (0x0000000000000038ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG015(offset) \
-        (0x000000000000003Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG016(offset) \
-        (0x0000000000000040ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG017(offset) \
-        (0x0000000000000044ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG020(offset) \
-        (0x0000000000000050ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG021(offset) \
-        (0x0000000000000054ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG022(offset) \
-        (0x0000000000000058ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG023(offset) \
-        (0x000000000000005Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG028(offset) \
-        (0x0000000000000070ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG029(offset) \
-        (0x0000000000000074ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG030(offset) \
-        (0x0000000000000078ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG031(offset) \
-        (0x000000000000007Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG032(offset) \
-        (0x0000000000000080ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG033(offset) \
-        (0x0000000000000084ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG034(offset) \
-        (0x0000000000000088ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG035(offset) \
-        (0x000000000000008Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG036(offset) \
-        (0x0000000000000090ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG037(offset) \
-        (0x0000000000000094ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG038(offset) \
-        (0x0000000000000098ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG039(offset) \
-        (0x000000000000009Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG040(offset) \
-        (0x00000000000000A0ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG041(offset) \
-        (0x00000000000000A4ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG042(offset) \
-        (0x00000000000000A8ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG064(offset) \
-        (0x0000000000000100ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG065(offset) \
-        (0x0000000000000104ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG066(offset) \
-        (0x0000000000000108ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG067(offset) \
-        (0x000000000000010Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG068(offset) \
-        (0x0000000000000110ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG069(offset) \
-        (0x0000000000000114ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG070(offset) \
-        (0x0000000000000118ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG071(offset) \
-        (0x000000000000011Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG072(offset) \
-        (0x0000000000000120ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG073(offset) \
-        (0x0000000000000124ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG074(offset) \
-        (0x0000000000000128ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG075(offset) \
-        (0x000000000000012Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG076(offset) \
-        (0x0000000000000130ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG077(offset) \
-        (0x0000000000000134ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG448(offset) \
-        (0x0000000000000700ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG449(offset) \
-        (0x0000000000000704ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG450(offset) \
-        (0x0000000000000708ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG451(offset) \
-        (0x000000000000070Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG452(offset) \
-        (0x0000000000000710ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG453(offset) \
-        (0x0000000000000714ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG454(offset) \
-        (0x0000000000000718ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG455(offset) \
-        (0x000000000000071Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG456(offset) \
-        (0x0000000000000720ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG458(offset) \
-        (0x0000000000000728ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG459(offset) \
-        (0x000000000000072Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG460(offset) \
-        (0x0000000000000730ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG461(offset) \
-        (0x0000000000000734ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG462(offset) \
-        (0x0000000000000738ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG463(offset) \
-        (0x000000000000073Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG464(offset) \
-        (0x0000000000000740ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG465(offset) \
-        (0x0000000000000744ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG466(offset) \
-        (0x0000000000000748ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG467(offset) \
-        (0x000000000000074Cull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG468(offset) \
-        (0x0000000000000750ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG490(offset) \
-        (0x00000000000007A8ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG491(offset) \
-        (0x00000000000007ACull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG492(offset) \
-        (0x00000000000007B0ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG516(offset) \
-        (0x0000000000000810ull + (((offset) & 1) * 0))
-#define CVMX_PCIERCX_CFG517(offset) \
-        (0x0000000000000814ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG000(block_id) (0x0000000000000000ull)
+#define CVMX_PCIERCX_CFG001(block_id) (0x0000000000000004ull)
+#define CVMX_PCIERCX_CFG002(block_id) (0x0000000000000008ull)
+#define CVMX_PCIERCX_CFG003(block_id) (0x000000000000000Cull)
+#define CVMX_PCIERCX_CFG004(block_id) (0x0000000000000010ull)
+#define CVMX_PCIERCX_CFG005(block_id) (0x0000000000000014ull)
+#define CVMX_PCIERCX_CFG006(block_id) (0x0000000000000018ull)
+#define CVMX_PCIERCX_CFG007(block_id) (0x000000000000001Cull)
+#define CVMX_PCIERCX_CFG008(block_id) (0x0000000000000020ull)
+#define CVMX_PCIERCX_CFG009(block_id) (0x0000000000000024ull)
+#define CVMX_PCIERCX_CFG010(block_id) (0x0000000000000028ull)
+#define CVMX_PCIERCX_CFG011(block_id) (0x000000000000002Cull)
+#define CVMX_PCIERCX_CFG012(block_id) (0x0000000000000030ull)
+#define CVMX_PCIERCX_CFG013(block_id) (0x0000000000000034ull)
+#define CVMX_PCIERCX_CFG014(block_id) (0x0000000000000038ull)
+#define CVMX_PCIERCX_CFG015(block_id) (0x000000000000003Cull)
+#define CVMX_PCIERCX_CFG016(block_id) (0x0000000000000040ull)
+#define CVMX_PCIERCX_CFG017(block_id) (0x0000000000000044ull)
+#define CVMX_PCIERCX_CFG020(block_id) (0x0000000000000050ull)
+#define CVMX_PCIERCX_CFG021(block_id) (0x0000000000000054ull)
+#define CVMX_PCIERCX_CFG022(block_id) (0x0000000000000058ull)
+#define CVMX_PCIERCX_CFG023(block_id) (0x000000000000005Cull)
+#define CVMX_PCIERCX_CFG028(block_id) (0x0000000000000070ull)
+#define CVMX_PCIERCX_CFG029(block_id) (0x0000000000000074ull)
+#define CVMX_PCIERCX_CFG030(block_id) (0x0000000000000078ull)
+#define CVMX_PCIERCX_CFG031(block_id) (0x000000000000007Cull)
+#define CVMX_PCIERCX_CFG032(block_id) (0x0000000000000080ull)
+#define CVMX_PCIERCX_CFG033(block_id) (0x0000000000000084ull)
+#define CVMX_PCIERCX_CFG034(block_id) (0x0000000000000088ull)
+#define CVMX_PCIERCX_CFG035(block_id) (0x000000000000008Cull)
+#define CVMX_PCIERCX_CFG036(block_id) (0x0000000000000090ull)
+#define CVMX_PCIERCX_CFG037(block_id) (0x0000000000000094ull)
+#define CVMX_PCIERCX_CFG038(block_id) (0x0000000000000098ull)
+#define CVMX_PCIERCX_CFG039(block_id) (0x000000000000009Cull)
+#define CVMX_PCIERCX_CFG040(block_id) (0x00000000000000A0ull)
+#define CVMX_PCIERCX_CFG041(block_id) (0x00000000000000A4ull)
+#define CVMX_PCIERCX_CFG042(block_id) (0x00000000000000A8ull)
+#define CVMX_PCIERCX_CFG064(block_id) (0x0000000000000100ull)
+#define CVMX_PCIERCX_CFG065(block_id) (0x0000000000000104ull)
+#define CVMX_PCIERCX_CFG066(block_id) (0x0000000000000108ull)
+#define CVMX_PCIERCX_CFG067(block_id) (0x000000000000010Cull)
+#define CVMX_PCIERCX_CFG068(block_id) (0x0000000000000110ull)
+#define CVMX_PCIERCX_CFG069(block_id) (0x0000000000000114ull)
+#define CVMX_PCIERCX_CFG070(block_id) (0x0000000000000118ull)
+#define CVMX_PCIERCX_CFG071(block_id) (0x000000000000011Cull)
+#define CVMX_PCIERCX_CFG072(block_id) (0x0000000000000120ull)
+#define CVMX_PCIERCX_CFG073(block_id) (0x0000000000000124ull)
+#define CVMX_PCIERCX_CFG074(block_id) (0x0000000000000128ull)
+#define CVMX_PCIERCX_CFG075(block_id) (0x000000000000012Cull)
+#define CVMX_PCIERCX_CFG076(block_id) (0x0000000000000130ull)
+#define CVMX_PCIERCX_CFG077(block_id) (0x0000000000000134ull)
+#define CVMX_PCIERCX_CFG448(block_id) (0x0000000000000700ull)
+#define CVMX_PCIERCX_CFG449(block_id) (0x0000000000000704ull)
+#define CVMX_PCIERCX_CFG450(block_id) (0x0000000000000708ull)
+#define CVMX_PCIERCX_CFG451(block_id) (0x000000000000070Cull)
+#define CVMX_PCIERCX_CFG452(block_id) (0x0000000000000710ull)
+#define CVMX_PCIERCX_CFG453(block_id) (0x0000000000000714ull)
+#define CVMX_PCIERCX_CFG454(block_id) (0x0000000000000718ull)
+#define CVMX_PCIERCX_CFG455(block_id) (0x000000000000071Cull)
+#define CVMX_PCIERCX_CFG456(block_id) (0x0000000000000720ull)
+#define CVMX_PCIERCX_CFG458(block_id) (0x0000000000000728ull)
+#define CVMX_PCIERCX_CFG459(block_id) (0x000000000000072Cull)
+#define CVMX_PCIERCX_CFG460(block_id) (0x0000000000000730ull)
+#define CVMX_PCIERCX_CFG461(block_id) (0x0000000000000734ull)
+#define CVMX_PCIERCX_CFG462(block_id) (0x0000000000000738ull)
+#define CVMX_PCIERCX_CFG463(block_id) (0x000000000000073Cull)
+#define CVMX_PCIERCX_CFG464(block_id) (0x0000000000000740ull)
+#define CVMX_PCIERCX_CFG465(block_id) (0x0000000000000744ull)
+#define CVMX_PCIERCX_CFG466(block_id) (0x0000000000000748ull)
+#define CVMX_PCIERCX_CFG467(block_id) (0x000000000000074Cull)
+#define CVMX_PCIERCX_CFG468(block_id) (0x0000000000000750ull)
+#define CVMX_PCIERCX_CFG490(block_id) (0x00000000000007A8ull)
+#define CVMX_PCIERCX_CFG491(block_id) (0x00000000000007ACull)
+#define CVMX_PCIERCX_CFG492(block_id) (0x00000000000007B0ull)
+#define CVMX_PCIERCX_CFG515(block_id) (0x000000000000080Cull)
+#define CVMX_PCIERCX_CFG516(block_id) (0x0000000000000810ull)
+#define CVMX_PCIERCX_CFG517(block_id) (0x0000000000000814ull)
 
 union cvmx_pciercx_cfg000 {
        uint32_t u32;
@@ -191,6 +116,8 @@ union cvmx_pciercx_cfg000 {
        struct cvmx_pciercx_cfg000_s cn52xxp1;
        struct cvmx_pciercx_cfg000_s cn56xx;
        struct cvmx_pciercx_cfg000_s cn56xxp1;
+       struct cvmx_pciercx_cfg000_s cn63xx;
+       struct cvmx_pciercx_cfg000_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg001 {
@@ -225,6 +152,8 @@ union cvmx_pciercx_cfg001 {
        struct cvmx_pciercx_cfg001_s cn52xxp1;
        struct cvmx_pciercx_cfg001_s cn56xx;
        struct cvmx_pciercx_cfg001_s cn56xxp1;
+       struct cvmx_pciercx_cfg001_s cn63xx;
+       struct cvmx_pciercx_cfg001_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg002 {
@@ -239,6 +168,8 @@ union cvmx_pciercx_cfg002 {
        struct cvmx_pciercx_cfg002_s cn52xxp1;
        struct cvmx_pciercx_cfg002_s cn56xx;
        struct cvmx_pciercx_cfg002_s cn56xxp1;
+       struct cvmx_pciercx_cfg002_s cn63xx;
+       struct cvmx_pciercx_cfg002_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg003 {
@@ -254,6 +185,8 @@ union cvmx_pciercx_cfg003 {
        struct cvmx_pciercx_cfg003_s cn52xxp1;
        struct cvmx_pciercx_cfg003_s cn56xx;
        struct cvmx_pciercx_cfg003_s cn56xxp1;
+       struct cvmx_pciercx_cfg003_s cn63xx;
+       struct cvmx_pciercx_cfg003_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg004 {
@@ -265,6 +198,8 @@ union cvmx_pciercx_cfg004 {
        struct cvmx_pciercx_cfg004_s cn52xxp1;
        struct cvmx_pciercx_cfg004_s cn56xx;
        struct cvmx_pciercx_cfg004_s cn56xxp1;
+       struct cvmx_pciercx_cfg004_s cn63xx;
+       struct cvmx_pciercx_cfg004_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg005 {
@@ -276,6 +211,8 @@ union cvmx_pciercx_cfg005 {
        struct cvmx_pciercx_cfg005_s cn52xxp1;
        struct cvmx_pciercx_cfg005_s cn56xx;
        struct cvmx_pciercx_cfg005_s cn56xxp1;
+       struct cvmx_pciercx_cfg005_s cn63xx;
+       struct cvmx_pciercx_cfg005_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg006 {
@@ -290,6 +227,8 @@ union cvmx_pciercx_cfg006 {
        struct cvmx_pciercx_cfg006_s cn52xxp1;
        struct cvmx_pciercx_cfg006_s cn56xx;
        struct cvmx_pciercx_cfg006_s cn56xxp1;
+       struct cvmx_pciercx_cfg006_s cn63xx;
+       struct cvmx_pciercx_cfg006_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg007 {
@@ -317,6 +256,8 @@ union cvmx_pciercx_cfg007 {
        struct cvmx_pciercx_cfg007_s cn52xxp1;
        struct cvmx_pciercx_cfg007_s cn56xx;
        struct cvmx_pciercx_cfg007_s cn56xxp1;
+       struct cvmx_pciercx_cfg007_s cn63xx;
+       struct cvmx_pciercx_cfg007_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg008 {
@@ -331,6 +272,8 @@ union cvmx_pciercx_cfg008 {
        struct cvmx_pciercx_cfg008_s cn52xxp1;
        struct cvmx_pciercx_cfg008_s cn56xx;
        struct cvmx_pciercx_cfg008_s cn56xxp1;
+       struct cvmx_pciercx_cfg008_s cn63xx;
+       struct cvmx_pciercx_cfg008_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg009 {
@@ -347,6 +290,8 @@ union cvmx_pciercx_cfg009 {
        struct cvmx_pciercx_cfg009_s cn52xxp1;
        struct cvmx_pciercx_cfg009_s cn56xx;
        struct cvmx_pciercx_cfg009_s cn56xxp1;
+       struct cvmx_pciercx_cfg009_s cn63xx;
+       struct cvmx_pciercx_cfg009_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg010 {
@@ -358,6 +303,8 @@ union cvmx_pciercx_cfg010 {
        struct cvmx_pciercx_cfg010_s cn52xxp1;
        struct cvmx_pciercx_cfg010_s cn56xx;
        struct cvmx_pciercx_cfg010_s cn56xxp1;
+       struct cvmx_pciercx_cfg010_s cn63xx;
+       struct cvmx_pciercx_cfg010_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg011 {
@@ -369,6 +316,8 @@ union cvmx_pciercx_cfg011 {
        struct cvmx_pciercx_cfg011_s cn52xxp1;
        struct cvmx_pciercx_cfg011_s cn56xx;
        struct cvmx_pciercx_cfg011_s cn56xxp1;
+       struct cvmx_pciercx_cfg011_s cn63xx;
+       struct cvmx_pciercx_cfg011_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg012 {
@@ -381,6 +330,8 @@ union cvmx_pciercx_cfg012 {
        struct cvmx_pciercx_cfg012_s cn52xxp1;
        struct cvmx_pciercx_cfg012_s cn56xx;
        struct cvmx_pciercx_cfg012_s cn56xxp1;
+       struct cvmx_pciercx_cfg012_s cn63xx;
+       struct cvmx_pciercx_cfg012_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg013 {
@@ -393,6 +344,8 @@ union cvmx_pciercx_cfg013 {
        struct cvmx_pciercx_cfg013_s cn52xxp1;
        struct cvmx_pciercx_cfg013_s cn56xx;
        struct cvmx_pciercx_cfg013_s cn56xxp1;
+       struct cvmx_pciercx_cfg013_s cn63xx;
+       struct cvmx_pciercx_cfg013_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg014 {
@@ -404,6 +357,8 @@ union cvmx_pciercx_cfg014 {
        struct cvmx_pciercx_cfg014_s cn52xxp1;
        struct cvmx_pciercx_cfg014_s cn56xx;
        struct cvmx_pciercx_cfg014_s cn56xxp1;
+       struct cvmx_pciercx_cfg014_s cn63xx;
+       struct cvmx_pciercx_cfg014_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg015 {
@@ -429,6 +384,8 @@ union cvmx_pciercx_cfg015 {
        struct cvmx_pciercx_cfg015_s cn52xxp1;
        struct cvmx_pciercx_cfg015_s cn56xx;
        struct cvmx_pciercx_cfg015_s cn56xxp1;
+       struct cvmx_pciercx_cfg015_s cn63xx;
+       struct cvmx_pciercx_cfg015_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg016 {
@@ -449,6 +406,8 @@ union cvmx_pciercx_cfg016 {
        struct cvmx_pciercx_cfg016_s cn52xxp1;
        struct cvmx_pciercx_cfg016_s cn56xx;
        struct cvmx_pciercx_cfg016_s cn56xxp1;
+       struct cvmx_pciercx_cfg016_s cn63xx;
+       struct cvmx_pciercx_cfg016_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg017 {
@@ -471,6 +430,8 @@ union cvmx_pciercx_cfg017 {
        struct cvmx_pciercx_cfg017_s cn52xxp1;
        struct cvmx_pciercx_cfg017_s cn56xx;
        struct cvmx_pciercx_cfg017_s cn56xxp1;
+       struct cvmx_pciercx_cfg017_s cn63xx;
+       struct cvmx_pciercx_cfg017_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg020 {
@@ -488,6 +449,8 @@ union cvmx_pciercx_cfg020 {
        struct cvmx_pciercx_cfg020_s cn52xxp1;
        struct cvmx_pciercx_cfg020_s cn56xx;
        struct cvmx_pciercx_cfg020_s cn56xxp1;
+       struct cvmx_pciercx_cfg020_s cn63xx;
+       struct cvmx_pciercx_cfg020_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg021 {
@@ -500,6 +463,8 @@ union cvmx_pciercx_cfg021 {
        struct cvmx_pciercx_cfg021_s cn52xxp1;
        struct cvmx_pciercx_cfg021_s cn56xx;
        struct cvmx_pciercx_cfg021_s cn56xxp1;
+       struct cvmx_pciercx_cfg021_s cn63xx;
+       struct cvmx_pciercx_cfg021_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg022 {
@@ -511,6 +476,8 @@ union cvmx_pciercx_cfg022 {
        struct cvmx_pciercx_cfg022_s cn52xxp1;
        struct cvmx_pciercx_cfg022_s cn56xx;
        struct cvmx_pciercx_cfg022_s cn56xxp1;
+       struct cvmx_pciercx_cfg022_s cn63xx;
+       struct cvmx_pciercx_cfg022_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg023 {
@@ -523,6 +490,8 @@ union cvmx_pciercx_cfg023 {
        struct cvmx_pciercx_cfg023_s cn52xxp1;
        struct cvmx_pciercx_cfg023_s cn56xx;
        struct cvmx_pciercx_cfg023_s cn56xxp1;
+       struct cvmx_pciercx_cfg023_s cn63xx;
+       struct cvmx_pciercx_cfg023_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg028 {
@@ -540,6 +509,8 @@ union cvmx_pciercx_cfg028 {
        struct cvmx_pciercx_cfg028_s cn52xxp1;
        struct cvmx_pciercx_cfg028_s cn56xx;
        struct cvmx_pciercx_cfg028_s cn56xxp1;
+       struct cvmx_pciercx_cfg028_s cn63xx;
+       struct cvmx_pciercx_cfg028_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg029 {
@@ -561,6 +532,8 @@ union cvmx_pciercx_cfg029 {
        struct cvmx_pciercx_cfg029_s cn52xxp1;
        struct cvmx_pciercx_cfg029_s cn56xx;
        struct cvmx_pciercx_cfg029_s cn56xxp1;
+       struct cvmx_pciercx_cfg029_s cn63xx;
+       struct cvmx_pciercx_cfg029_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg030 {
@@ -590,6 +563,8 @@ union cvmx_pciercx_cfg030 {
        struct cvmx_pciercx_cfg030_s cn52xxp1;
        struct cvmx_pciercx_cfg030_s cn56xx;
        struct cvmx_pciercx_cfg030_s cn56xxp1;
+       struct cvmx_pciercx_cfg030_s cn63xx;
+       struct cvmx_pciercx_cfg030_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg031 {
@@ -611,6 +586,8 @@ union cvmx_pciercx_cfg031 {
        struct cvmx_pciercx_cfg031_s cn52xxp1;
        struct cvmx_pciercx_cfg031_s cn56xx;
        struct cvmx_pciercx_cfg031_s cn56xxp1;
+       struct cvmx_pciercx_cfg031_s cn63xx;
+       struct cvmx_pciercx_cfg031_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg032 {
@@ -641,6 +618,8 @@ union cvmx_pciercx_cfg032 {
        struct cvmx_pciercx_cfg032_s cn52xxp1;
        struct cvmx_pciercx_cfg032_s cn56xx;
        struct cvmx_pciercx_cfg032_s cn56xxp1;
+       struct cvmx_pciercx_cfg032_s cn63xx;
+       struct cvmx_pciercx_cfg032_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg033 {
@@ -663,6 +642,8 @@ union cvmx_pciercx_cfg033 {
        struct cvmx_pciercx_cfg033_s cn52xxp1;
        struct cvmx_pciercx_cfg033_s cn56xx;
        struct cvmx_pciercx_cfg033_s cn56xxp1;
+       struct cvmx_pciercx_cfg033_s cn63xx;
+       struct cvmx_pciercx_cfg033_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg034 {
@@ -695,6 +676,8 @@ union cvmx_pciercx_cfg034 {
        struct cvmx_pciercx_cfg034_s cn52xxp1;
        struct cvmx_pciercx_cfg034_s cn56xx;
        struct cvmx_pciercx_cfg034_s cn56xxp1;
+       struct cvmx_pciercx_cfg034_s cn63xx;
+       struct cvmx_pciercx_cfg034_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg035 {
@@ -713,6 +696,8 @@ union cvmx_pciercx_cfg035 {
        struct cvmx_pciercx_cfg035_s cn52xxp1;
        struct cvmx_pciercx_cfg035_s cn56xx;
        struct cvmx_pciercx_cfg035_s cn56xxp1;
+       struct cvmx_pciercx_cfg035_s cn63xx;
+       struct cvmx_pciercx_cfg035_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg036 {
@@ -727,6 +712,8 @@ union cvmx_pciercx_cfg036 {
        struct cvmx_pciercx_cfg036_s cn52xxp1;
        struct cvmx_pciercx_cfg036_s cn56xx;
        struct cvmx_pciercx_cfg036_s cn56xxp1;
+       struct cvmx_pciercx_cfg036_s cn63xx;
+       struct cvmx_pciercx_cfg036_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg037 {
@@ -740,6 +727,8 @@ union cvmx_pciercx_cfg037 {
        struct cvmx_pciercx_cfg037_s cn52xxp1;
        struct cvmx_pciercx_cfg037_s cn56xx;
        struct cvmx_pciercx_cfg037_s cn56xxp1;
+       struct cvmx_pciercx_cfg037_s cn63xx;
+       struct cvmx_pciercx_cfg037_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg038 {
@@ -753,28 +742,51 @@ union cvmx_pciercx_cfg038 {
        struct cvmx_pciercx_cfg038_s cn52xxp1;
        struct cvmx_pciercx_cfg038_s cn56xx;
        struct cvmx_pciercx_cfg038_s cn56xxp1;
+       struct cvmx_pciercx_cfg038_s cn63xx;
+       struct cvmx_pciercx_cfg038_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg039 {
        uint32_t u32;
        struct cvmx_pciercx_cfg039_s {
-               uint32_t reserved_0_31:32;
+               uint32_t reserved_9_31:23;
+               uint32_t cls:1;
+               uint32_t slsv:7;
+               uint32_t reserved_0_0:1;
        } s;
-       struct cvmx_pciercx_cfg039_s cn52xx;
-       struct cvmx_pciercx_cfg039_s cn52xxp1;
-       struct cvmx_pciercx_cfg039_s cn56xx;
-       struct cvmx_pciercx_cfg039_s cn56xxp1;
+       struct cvmx_pciercx_cfg039_cn52xx {
+               uint32_t reserved_0_31:32;
+       } cn52xx;
+       struct cvmx_pciercx_cfg039_cn52xx cn52xxp1;
+       struct cvmx_pciercx_cfg039_cn52xx cn56xx;
+       struct cvmx_pciercx_cfg039_cn52xx cn56xxp1;
+       struct cvmx_pciercx_cfg039_s cn63xx;
+       struct cvmx_pciercx_cfg039_cn52xx cn63xxp1;
 };
 
 union cvmx_pciercx_cfg040 {
        uint32_t u32;
        struct cvmx_pciercx_cfg040_s {
+               uint32_t reserved_17_31:15;
+               uint32_t cdl:1;
+               uint32_t reserved_13_15:3;
+               uint32_t cde:1;
+               uint32_t csos:1;
+               uint32_t emc:1;
+               uint32_t tm:3;
+               uint32_t sde:1;
+               uint32_t hasd:1;
+               uint32_t ec:1;
+               uint32_t tls:4;
+       } s;
+       struct cvmx_pciercx_cfg040_cn52xx {
                uint32_t reserved_0_31:32;
-       } s;
-       struct cvmx_pciercx_cfg040_s cn52xx;
-       struct cvmx_pciercx_cfg040_s cn52xxp1;
-       struct cvmx_pciercx_cfg040_s cn56xx;
-       struct cvmx_pciercx_cfg040_s cn56xxp1;
+       } cn52xx;
+       struct cvmx_pciercx_cfg040_cn52xx cn52xxp1;
+       struct cvmx_pciercx_cfg040_cn52xx cn56xx;
+       struct cvmx_pciercx_cfg040_cn52xx cn56xxp1;
+       struct cvmx_pciercx_cfg040_s cn63xx;
+       struct cvmx_pciercx_cfg040_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg041 {
@@ -786,6 +798,8 @@ union cvmx_pciercx_cfg041 {
        struct cvmx_pciercx_cfg041_s cn52xxp1;
        struct cvmx_pciercx_cfg041_s cn56xx;
        struct cvmx_pciercx_cfg041_s cn56xxp1;
+       struct cvmx_pciercx_cfg041_s cn63xx;
+       struct cvmx_pciercx_cfg041_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg042 {
@@ -797,6 +811,8 @@ union cvmx_pciercx_cfg042 {
        struct cvmx_pciercx_cfg042_s cn52xxp1;
        struct cvmx_pciercx_cfg042_s cn56xx;
        struct cvmx_pciercx_cfg042_s cn56xxp1;
+       struct cvmx_pciercx_cfg042_s cn63xx;
+       struct cvmx_pciercx_cfg042_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg064 {
@@ -810,6 +826,8 @@ union cvmx_pciercx_cfg064 {
        struct cvmx_pciercx_cfg064_s cn52xxp1;
        struct cvmx_pciercx_cfg064_s cn56xx;
        struct cvmx_pciercx_cfg064_s cn56xxp1;
+       struct cvmx_pciercx_cfg064_s cn63xx;
+       struct cvmx_pciercx_cfg064_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg065 {
@@ -834,6 +852,8 @@ union cvmx_pciercx_cfg065 {
        struct cvmx_pciercx_cfg065_s cn52xxp1;
        struct cvmx_pciercx_cfg065_s cn56xx;
        struct cvmx_pciercx_cfg065_s cn56xxp1;
+       struct cvmx_pciercx_cfg065_s cn63xx;
+       struct cvmx_pciercx_cfg065_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg066 {
@@ -858,6 +878,8 @@ union cvmx_pciercx_cfg066 {
        struct cvmx_pciercx_cfg066_s cn52xxp1;
        struct cvmx_pciercx_cfg066_s cn56xx;
        struct cvmx_pciercx_cfg066_s cn56xxp1;
+       struct cvmx_pciercx_cfg066_s cn63xx;
+       struct cvmx_pciercx_cfg066_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg067 {
@@ -882,6 +904,8 @@ union cvmx_pciercx_cfg067 {
        struct cvmx_pciercx_cfg067_s cn52xxp1;
        struct cvmx_pciercx_cfg067_s cn56xx;
        struct cvmx_pciercx_cfg067_s cn56xxp1;
+       struct cvmx_pciercx_cfg067_s cn63xx;
+       struct cvmx_pciercx_cfg067_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg068 {
@@ -901,6 +925,8 @@ union cvmx_pciercx_cfg068 {
        struct cvmx_pciercx_cfg068_s cn52xxp1;
        struct cvmx_pciercx_cfg068_s cn56xx;
        struct cvmx_pciercx_cfg068_s cn56xxp1;
+       struct cvmx_pciercx_cfg068_s cn63xx;
+       struct cvmx_pciercx_cfg068_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg069 {
@@ -920,6 +946,8 @@ union cvmx_pciercx_cfg069 {
        struct cvmx_pciercx_cfg069_s cn52xxp1;
        struct cvmx_pciercx_cfg069_s cn56xx;
        struct cvmx_pciercx_cfg069_s cn56xxp1;
+       struct cvmx_pciercx_cfg069_s cn63xx;
+       struct cvmx_pciercx_cfg069_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg070 {
@@ -936,6 +964,8 @@ union cvmx_pciercx_cfg070 {
        struct cvmx_pciercx_cfg070_s cn52xxp1;
        struct cvmx_pciercx_cfg070_s cn56xx;
        struct cvmx_pciercx_cfg070_s cn56xxp1;
+       struct cvmx_pciercx_cfg070_s cn63xx;
+       struct cvmx_pciercx_cfg070_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg071 {
@@ -947,6 +977,8 @@ union cvmx_pciercx_cfg071 {
        struct cvmx_pciercx_cfg071_s cn52xxp1;
        struct cvmx_pciercx_cfg071_s cn56xx;
        struct cvmx_pciercx_cfg071_s cn56xxp1;
+       struct cvmx_pciercx_cfg071_s cn63xx;
+       struct cvmx_pciercx_cfg071_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg072 {
@@ -958,6 +990,8 @@ union cvmx_pciercx_cfg072 {
        struct cvmx_pciercx_cfg072_s cn52xxp1;
        struct cvmx_pciercx_cfg072_s cn56xx;
        struct cvmx_pciercx_cfg072_s cn56xxp1;
+       struct cvmx_pciercx_cfg072_s cn63xx;
+       struct cvmx_pciercx_cfg072_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg073 {
@@ -969,6 +1003,8 @@ union cvmx_pciercx_cfg073 {
        struct cvmx_pciercx_cfg073_s cn52xxp1;
        struct cvmx_pciercx_cfg073_s cn56xx;
        struct cvmx_pciercx_cfg073_s cn56xxp1;
+       struct cvmx_pciercx_cfg073_s cn63xx;
+       struct cvmx_pciercx_cfg073_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg074 {
@@ -980,6 +1016,8 @@ union cvmx_pciercx_cfg074 {
        struct cvmx_pciercx_cfg074_s cn52xxp1;
        struct cvmx_pciercx_cfg074_s cn56xx;
        struct cvmx_pciercx_cfg074_s cn56xxp1;
+       struct cvmx_pciercx_cfg074_s cn63xx;
+       struct cvmx_pciercx_cfg074_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg075 {
@@ -994,6 +1032,8 @@ union cvmx_pciercx_cfg075 {
        struct cvmx_pciercx_cfg075_s cn52xxp1;
        struct cvmx_pciercx_cfg075_s cn56xx;
        struct cvmx_pciercx_cfg075_s cn56xxp1;
+       struct cvmx_pciercx_cfg075_s cn63xx;
+       struct cvmx_pciercx_cfg075_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg076 {
@@ -1013,6 +1053,8 @@ union cvmx_pciercx_cfg076 {
        struct cvmx_pciercx_cfg076_s cn52xxp1;
        struct cvmx_pciercx_cfg076_s cn56xx;
        struct cvmx_pciercx_cfg076_s cn56xxp1;
+       struct cvmx_pciercx_cfg076_s cn63xx;
+       struct cvmx_pciercx_cfg076_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg077 {
@@ -1025,6 +1067,8 @@ union cvmx_pciercx_cfg077 {
        struct cvmx_pciercx_cfg077_s cn52xxp1;
        struct cvmx_pciercx_cfg077_s cn56xx;
        struct cvmx_pciercx_cfg077_s cn56xxp1;
+       struct cvmx_pciercx_cfg077_s cn63xx;
+       struct cvmx_pciercx_cfg077_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg448 {
@@ -1037,6 +1081,8 @@ union cvmx_pciercx_cfg448 {
        struct cvmx_pciercx_cfg448_s cn52xxp1;
        struct cvmx_pciercx_cfg448_s cn56xx;
        struct cvmx_pciercx_cfg448_s cn56xxp1;
+       struct cvmx_pciercx_cfg448_s cn63xx;
+       struct cvmx_pciercx_cfg448_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg449 {
@@ -1048,6 +1094,8 @@ union cvmx_pciercx_cfg449 {
        struct cvmx_pciercx_cfg449_s cn52xxp1;
        struct cvmx_pciercx_cfg449_s cn56xx;
        struct cvmx_pciercx_cfg449_s cn56xxp1;
+       struct cvmx_pciercx_cfg449_s cn63xx;
+       struct cvmx_pciercx_cfg449_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg450 {
@@ -1064,6 +1112,8 @@ union cvmx_pciercx_cfg450 {
        struct cvmx_pciercx_cfg450_s cn52xxp1;
        struct cvmx_pciercx_cfg450_s cn56xx;
        struct cvmx_pciercx_cfg450_s cn56xxp1;
+       struct cvmx_pciercx_cfg450_s cn63xx;
+       struct cvmx_pciercx_cfg450_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg451 {
@@ -1080,6 +1130,8 @@ union cvmx_pciercx_cfg451 {
        struct cvmx_pciercx_cfg451_s cn52xxp1;
        struct cvmx_pciercx_cfg451_s cn56xx;
        struct cvmx_pciercx_cfg451_s cn56xxp1;
+       struct cvmx_pciercx_cfg451_s cn63xx;
+       struct cvmx_pciercx_cfg451_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg452 {
@@ -1103,6 +1155,8 @@ union cvmx_pciercx_cfg452 {
        struct cvmx_pciercx_cfg452_s cn52xxp1;
        struct cvmx_pciercx_cfg452_s cn56xx;
        struct cvmx_pciercx_cfg452_s cn56xxp1;
+       struct cvmx_pciercx_cfg452_s cn63xx;
+       struct cvmx_pciercx_cfg452_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg453 {
@@ -1118,6 +1172,8 @@ union cvmx_pciercx_cfg453 {
        struct cvmx_pciercx_cfg453_s cn52xxp1;
        struct cvmx_pciercx_cfg453_s cn56xx;
        struct cvmx_pciercx_cfg453_s cn56xxp1;
+       struct cvmx_pciercx_cfg453_s cn63xx;
+       struct cvmx_pciercx_cfg453_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg454 {
@@ -1136,6 +1192,8 @@ union cvmx_pciercx_cfg454 {
        struct cvmx_pciercx_cfg454_s cn52xxp1;
        struct cvmx_pciercx_cfg454_s cn56xx;
        struct cvmx_pciercx_cfg454_s cn56xxp1;
+       struct cvmx_pciercx_cfg454_s cn63xx;
+       struct cvmx_pciercx_cfg454_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg455 {
@@ -1165,6 +1223,8 @@ union cvmx_pciercx_cfg455 {
        struct cvmx_pciercx_cfg455_s cn52xxp1;
        struct cvmx_pciercx_cfg455_s cn56xx;
        struct cvmx_pciercx_cfg455_s cn56xxp1;
+       struct cvmx_pciercx_cfg455_s cn63xx;
+       struct cvmx_pciercx_cfg455_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg456 {
@@ -1178,6 +1238,8 @@ union cvmx_pciercx_cfg456 {
        struct cvmx_pciercx_cfg456_s cn52xxp1;
        struct cvmx_pciercx_cfg456_s cn56xx;
        struct cvmx_pciercx_cfg456_s cn56xxp1;
+       struct cvmx_pciercx_cfg456_s cn63xx;
+       struct cvmx_pciercx_cfg456_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg458 {
@@ -1189,6 +1251,8 @@ union cvmx_pciercx_cfg458 {
        struct cvmx_pciercx_cfg458_s cn52xxp1;
        struct cvmx_pciercx_cfg458_s cn56xx;
        struct cvmx_pciercx_cfg458_s cn56xxp1;
+       struct cvmx_pciercx_cfg458_s cn63xx;
+       struct cvmx_pciercx_cfg458_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg459 {
@@ -1200,6 +1264,8 @@ union cvmx_pciercx_cfg459 {
        struct cvmx_pciercx_cfg459_s cn52xxp1;
        struct cvmx_pciercx_cfg459_s cn56xx;
        struct cvmx_pciercx_cfg459_s cn56xxp1;
+       struct cvmx_pciercx_cfg459_s cn63xx;
+       struct cvmx_pciercx_cfg459_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg460 {
@@ -1213,6 +1279,8 @@ union cvmx_pciercx_cfg460 {
        struct cvmx_pciercx_cfg460_s cn52xxp1;
        struct cvmx_pciercx_cfg460_s cn56xx;
        struct cvmx_pciercx_cfg460_s cn56xxp1;
+       struct cvmx_pciercx_cfg460_s cn63xx;
+       struct cvmx_pciercx_cfg460_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg461 {
@@ -1226,6 +1294,8 @@ union cvmx_pciercx_cfg461 {
        struct cvmx_pciercx_cfg461_s cn52xxp1;
        struct cvmx_pciercx_cfg461_s cn56xx;
        struct cvmx_pciercx_cfg461_s cn56xxp1;
+       struct cvmx_pciercx_cfg461_s cn63xx;
+       struct cvmx_pciercx_cfg461_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg462 {
@@ -1239,6 +1309,8 @@ union cvmx_pciercx_cfg462 {
        struct cvmx_pciercx_cfg462_s cn52xxp1;
        struct cvmx_pciercx_cfg462_s cn56xx;
        struct cvmx_pciercx_cfg462_s cn56xxp1;
+       struct cvmx_pciercx_cfg462_s cn63xx;
+       struct cvmx_pciercx_cfg462_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg463 {
@@ -1253,6 +1325,8 @@ union cvmx_pciercx_cfg463 {
        struct cvmx_pciercx_cfg463_s cn52xxp1;
        struct cvmx_pciercx_cfg463_s cn56xx;
        struct cvmx_pciercx_cfg463_s cn56xxp1;
+       struct cvmx_pciercx_cfg463_s cn63xx;
+       struct cvmx_pciercx_cfg463_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg464 {
@@ -1267,6 +1341,8 @@ union cvmx_pciercx_cfg464 {
        struct cvmx_pciercx_cfg464_s cn52xxp1;
        struct cvmx_pciercx_cfg464_s cn56xx;
        struct cvmx_pciercx_cfg464_s cn56xxp1;
+       struct cvmx_pciercx_cfg464_s cn63xx;
+       struct cvmx_pciercx_cfg464_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg465 {
@@ -1281,6 +1357,8 @@ union cvmx_pciercx_cfg465 {
        struct cvmx_pciercx_cfg465_s cn52xxp1;
        struct cvmx_pciercx_cfg465_s cn56xx;
        struct cvmx_pciercx_cfg465_s cn56xxp1;
+       struct cvmx_pciercx_cfg465_s cn63xx;
+       struct cvmx_pciercx_cfg465_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg466 {
@@ -1298,6 +1376,8 @@ union cvmx_pciercx_cfg466 {
        struct cvmx_pciercx_cfg466_s cn52xxp1;
        struct cvmx_pciercx_cfg466_s cn56xx;
        struct cvmx_pciercx_cfg466_s cn56xxp1;
+       struct cvmx_pciercx_cfg466_s cn63xx;
+       struct cvmx_pciercx_cfg466_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg467 {
@@ -1313,6 +1393,8 @@ union cvmx_pciercx_cfg467 {
        struct cvmx_pciercx_cfg467_s cn52xxp1;
        struct cvmx_pciercx_cfg467_s cn56xx;
        struct cvmx_pciercx_cfg467_s cn56xxp1;
+       struct cvmx_pciercx_cfg467_s cn63xx;
+       struct cvmx_pciercx_cfg467_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg468 {
@@ -1328,6 +1410,8 @@ union cvmx_pciercx_cfg468 {
        struct cvmx_pciercx_cfg468_s cn52xxp1;
        struct cvmx_pciercx_cfg468_s cn56xx;
        struct cvmx_pciercx_cfg468_s cn56xxp1;
+       struct cvmx_pciercx_cfg468_s cn63xx;
+       struct cvmx_pciercx_cfg468_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg490 {
@@ -1342,6 +1426,8 @@ union cvmx_pciercx_cfg490 {
        struct cvmx_pciercx_cfg490_s cn52xxp1;
        struct cvmx_pciercx_cfg490_s cn56xx;
        struct cvmx_pciercx_cfg490_s cn56xxp1;
+       struct cvmx_pciercx_cfg490_s cn63xx;
+       struct cvmx_pciercx_cfg490_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg491 {
@@ -1356,6 +1442,8 @@ union cvmx_pciercx_cfg491 {
        struct cvmx_pciercx_cfg491_s cn52xxp1;
        struct cvmx_pciercx_cfg491_s cn56xx;
        struct cvmx_pciercx_cfg491_s cn56xxp1;
+       struct cvmx_pciercx_cfg491_s cn63xx;
+       struct cvmx_pciercx_cfg491_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg492 {
@@ -1370,6 +1458,23 @@ union cvmx_pciercx_cfg492 {
        struct cvmx_pciercx_cfg492_s cn52xxp1;
        struct cvmx_pciercx_cfg492_s cn56xx;
        struct cvmx_pciercx_cfg492_s cn56xxp1;
+       struct cvmx_pciercx_cfg492_s cn63xx;
+       struct cvmx_pciercx_cfg492_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg515 {
+       uint32_t u32;
+       struct cvmx_pciercx_cfg515_s {
+               uint32_t reserved_21_31:11;
+               uint32_t s_d_e:1;
+               uint32_t ctcrb:1;
+               uint32_t cpyts:1;
+               uint32_t dsc:1;
+               uint32_t le:9;
+               uint32_t n_fts:8;
+       } s;
+       struct cvmx_pciercx_cfg515_s cn63xx;
+       struct cvmx_pciercx_cfg515_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg516 {
@@ -1381,6 +1486,8 @@ union cvmx_pciercx_cfg516 {
        struct cvmx_pciercx_cfg516_s cn52xxp1;
        struct cvmx_pciercx_cfg516_s cn56xx;
        struct cvmx_pciercx_cfg516_s cn56xxp1;
+       struct cvmx_pciercx_cfg516_s cn63xx;
+       struct cvmx_pciercx_cfg516_s cn63xxp1;
 };
 
 union cvmx_pciercx_cfg517 {
@@ -1392,6 +1499,8 @@ union cvmx_pciercx_cfg517 {
        struct cvmx_pciercx_cfg517_s cn52xxp1;
        struct cvmx_pciercx_cfg517_s cn56xx;
        struct cvmx_pciercx_cfg517_s cn56xxp1;
+       struct cvmx_pciercx_cfg517_s cn63xx;
+       struct cvmx_pciercx_cfg517_s cn63xxp1;
 };
 
 #endif
index f40cfaf84454579cd98fd6f869f95f0a40af97d1..aef84851a94c49327dc465e5e2479701c22ce56a 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_PESCX_DEFS_H__
 #define __CVMX_PESCX_DEFS_H__
 
-#define CVMX_PESCX_BIST_STATUS(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000018ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_BIST_STATUS2(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000418ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CFG_RD(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000030ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CFG_WR(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000028ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CPL_LUT_VALID(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000098ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CTL_STATUS(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000000ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_CTL_STATUS2(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000400ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_DBG_INFO(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000008ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_DBG_INFO_EN(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C80000A0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_DIAG_STATUS(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000020ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2N_BAR0_START(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000080ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2N_BAR1_START(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000088ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2N_BAR2_START(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000090ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2P_BARX_END(offset, block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000048ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_P2P_BARX_START(offset, block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000040ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PESCX_TLP_CREDITS(block_id) \
-        CVMX_ADD_IO_SEG(0x00011800C8000038ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000018ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_BIST_STATUS2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000418ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CFG_RD(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000030ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CFG_WR(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000028ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CPL_LUT_VALID(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000098ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000000ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CTL_STATUS2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000400ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_DBG_INFO(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000008ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_DBG_INFO_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800C80000A0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_DIAG_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000020ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2N_BAR0_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000080ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2N_BAR1_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000088ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2N_BAR2_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000090ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2P_BARX_END(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000048ull) + (((offset) & 3) + ((block_id) & 1) * 0x800000ull) * 16)
+#define CVMX_PESCX_P2P_BARX_START(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000040ull) + (((offset) & 3) + ((block_id) & 1) * 0x800000ull) * 16)
+#define CVMX_PESCX_TLP_CREDITS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000038ull) + ((block_id) & 1) * 0x8000000ull)
 
 union cvmx_pescx_bist_status {
        uint64_t u64;
index 5ea5dc571b548dac6dc73ac1ddbdfc0d3eb624c9..5ab8679d89af0698d55d54441eb96910bb6752ec 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_PEXP_DEFS_H__
 #define __CVMX_PEXP_DEFS_H__
 
-#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000008000ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_BIST_STATUS \
-        CVMX_ADD_IO_SEG(0x00011F0000008580ull)
-#define CVMX_PEXP_NPEI_BIST_STATUS2 \
-        CVMX_ADD_IO_SEG(0x00011F0000008680ull)
-#define CVMX_PEXP_NPEI_CTL_PORT0 \
-        CVMX_ADD_IO_SEG(0x00011F0000008250ull)
-#define CVMX_PEXP_NPEI_CTL_PORT1 \
-        CVMX_ADD_IO_SEG(0x00011F0000008260ull)
-#define CVMX_PEXP_NPEI_CTL_STATUS \
-        CVMX_ADD_IO_SEG(0x00011F0000008570ull)
-#define CVMX_PEXP_NPEI_CTL_STATUS2 \
-        CVMX_ADD_IO_SEG(0x00011F000000BC00ull)
-#define CVMX_PEXP_NPEI_DATA_OUT_CNT \
-        CVMX_ADD_IO_SEG(0x00011F00000085F0ull)
-#define CVMX_PEXP_NPEI_DBG_DATA \
-        CVMX_ADD_IO_SEG(0x00011F0000008510ull)
-#define CVMX_PEXP_NPEI_DBG_SELECT \
-        CVMX_ADD_IO_SEG(0x00011F0000008500ull)
-#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL \
-        CVMX_ADD_IO_SEG(0x00011F00000085C0ull)
-#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL \
-        CVMX_ADD_IO_SEG(0x00011F00000085D0ull)
-#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000008450ull + (((offset) & 7) * 16))
-#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) \
-        CVMX_ADD_IO_SEG(0x00011F00000083B0ull + (((offset) & 7) * 16))
-#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000008400ull + (((offset) & 7) * 16))
-#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) \
-        CVMX_ADD_IO_SEG(0x00011F00000084A0ull + (((offset) & 7) * 16))
-#define CVMX_PEXP_NPEI_DMA_CNTS \
-        CVMX_ADD_IO_SEG(0x00011F00000085E0ull)
-#define CVMX_PEXP_NPEI_DMA_CONTROL \
-        CVMX_ADD_IO_SEG(0x00011F00000083A0ull)
-#define CVMX_PEXP_NPEI_INT_A_ENB \
-        CVMX_ADD_IO_SEG(0x00011F0000008560ull)
-#define CVMX_PEXP_NPEI_INT_A_ENB2 \
-        CVMX_ADD_IO_SEG(0x00011F000000BCE0ull)
-#define CVMX_PEXP_NPEI_INT_A_SUM \
-        CVMX_ADD_IO_SEG(0x00011F0000008550ull)
-#define CVMX_PEXP_NPEI_INT_ENB \
-        CVMX_ADD_IO_SEG(0x00011F0000008540ull)
-#define CVMX_PEXP_NPEI_INT_ENB2 \
-        CVMX_ADD_IO_SEG(0x00011F000000BCD0ull)
-#define CVMX_PEXP_NPEI_INT_INFO \
-        CVMX_ADD_IO_SEG(0x00011F0000008590ull)
-#define CVMX_PEXP_NPEI_INT_SUM \
-        CVMX_ADD_IO_SEG(0x00011F0000008530ull)
-#define CVMX_PEXP_NPEI_INT_SUM2 \
-        CVMX_ADD_IO_SEG(0x00011F000000BCC0ull)
-#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 \
-        CVMX_ADD_IO_SEG(0x00011F0000008600ull)
-#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 \
-        CVMX_ADD_IO_SEG(0x00011F0000008610ull)
-#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL \
-        CVMX_ADD_IO_SEG(0x00011F00000084F0ull)
-#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000008280ull + (((offset) & 31) * 16) - 16 * 12)
-#define CVMX_PEXP_NPEI_MSI_ENB0 \
-        CVMX_ADD_IO_SEG(0x00011F000000BC50ull)
-#define CVMX_PEXP_NPEI_MSI_ENB1 \
-        CVMX_ADD_IO_SEG(0x00011F000000BC60ull)
-#define CVMX_PEXP_NPEI_MSI_ENB2 \
-        CVMX_ADD_IO_SEG(0x00011F000000BC70ull)
-#define CVMX_PEXP_NPEI_MSI_ENB3 \
-        CVMX_ADD_IO_SEG(0x00011F000000BC80ull)
-#define CVMX_PEXP_NPEI_MSI_RCV0 \
-        CVMX_ADD_IO_SEG(0x00011F000000BC10ull)
-#define CVMX_PEXP_NPEI_MSI_RCV1 \
-        CVMX_ADD_IO_SEG(0x00011F000000BC20ull)
-#define CVMX_PEXP_NPEI_MSI_RCV2 \
-        CVMX_ADD_IO_SEG(0x00011F000000BC30ull)
-#define CVMX_PEXP_NPEI_MSI_RCV3 \
-        CVMX_ADD_IO_SEG(0x00011F000000BC40ull)
-#define CVMX_PEXP_NPEI_MSI_RD_MAP \
-        CVMX_ADD_IO_SEG(0x00011F000000BCA0ull)
-#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 \
-        CVMX_ADD_IO_SEG(0x00011F000000BCF0ull)
-#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 \
-        CVMX_ADD_IO_SEG(0x00011F000000BD00ull)
-#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 \
-        CVMX_ADD_IO_SEG(0x00011F000000BD10ull)
-#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 \
-        CVMX_ADD_IO_SEG(0x00011F000000BD20ull)
-#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 \
-        CVMX_ADD_IO_SEG(0x00011F000000BD30ull)
-#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 \
-        CVMX_ADD_IO_SEG(0x00011F000000BD40ull)
-#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 \
-        CVMX_ADD_IO_SEG(0x00011F000000BD50ull)
-#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 \
-        CVMX_ADD_IO_SEG(0x00011F000000BD60ull)
-#define CVMX_PEXP_NPEI_MSI_WR_MAP \
-        CVMX_ADD_IO_SEG(0x00011F000000BC90ull)
-#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT \
-        CVMX_ADD_IO_SEG(0x00011F000000BD70ull)
-#define CVMX_PEXP_NPEI_PCIE_MSI_RCV \
-        CVMX_ADD_IO_SEG(0x00011F000000BCB0ull)
-#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 \
-        CVMX_ADD_IO_SEG(0x00011F0000008650ull)
-#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 \
-        CVMX_ADD_IO_SEG(0x00011F0000008660ull)
-#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 \
-        CVMX_ADD_IO_SEG(0x00011F0000008670ull)
-#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) \
-        CVMX_ADD_IO_SEG(0x00011F000000A400ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) \
-        CVMX_ADD_IO_SEG(0x00011F000000A800ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \
-        CVMX_ADD_IO_SEG(0x00011F000000AC00ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \
-        CVMX_ADD_IO_SEG(0x00011F000000B000ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) \
-        CVMX_ADD_IO_SEG(0x00011F000000B400ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) \
-        CVMX_ADD_IO_SEG(0x00011F000000B800ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000009400ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000009800ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \
-        CVMX_ADD_IO_SEG(0x00011F0000009C00ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKT_CNT_INT \
-        CVMX_ADD_IO_SEG(0x00011F0000009110ull)
-#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB \
-        CVMX_ADD_IO_SEG(0x00011F0000009130ull)
-#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES \
-        CVMX_ADD_IO_SEG(0x00011F00000090B0ull)
-#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS \
-        CVMX_ADD_IO_SEG(0x00011F00000090A0ull)
-#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR \
-        CVMX_ADD_IO_SEG(0x00011F0000009090ull)
-#define CVMX_PEXP_NPEI_PKT_DPADDR \
-        CVMX_ADD_IO_SEG(0x00011F0000009080ull)
-#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL \
-        CVMX_ADD_IO_SEG(0x00011F0000009150ull)
-#define CVMX_PEXP_NPEI_PKT_INSTR_ENB \
-        CVMX_ADD_IO_SEG(0x00011F0000009000ull)
-#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE \
-        CVMX_ADD_IO_SEG(0x00011F0000009190ull)
-#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE \
-        CVMX_ADD_IO_SEG(0x00011F0000009020ull)
-#define CVMX_PEXP_NPEI_PKT_INT_LEVELS \
-        CVMX_ADD_IO_SEG(0x00011F0000009100ull)
-#define CVMX_PEXP_NPEI_PKT_IN_BP \
-        CVMX_ADD_IO_SEG(0x00011F00000086B0ull)
-#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) \
-        CVMX_ADD_IO_SEG(0x00011F000000A000ull + (((offset) & 31) * 16))
-#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS \
-        CVMX_ADD_IO_SEG(0x00011F00000086A0ull)
-#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT \
-        CVMX_ADD_IO_SEG(0x00011F00000091A0ull)
-#define CVMX_PEXP_NPEI_PKT_IPTR \
-        CVMX_ADD_IO_SEG(0x00011F0000009070ull)
-#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK \
-        CVMX_ADD_IO_SEG(0x00011F0000009160ull)
-#define CVMX_PEXP_NPEI_PKT_OUT_BMODE \
-        CVMX_ADD_IO_SEG(0x00011F00000090D0ull)
-#define CVMX_PEXP_NPEI_PKT_OUT_ENB \
-        CVMX_ADD_IO_SEG(0x00011F0000009010ull)
-#define CVMX_PEXP_NPEI_PKT_PCIE_PORT \
-        CVMX_ADD_IO_SEG(0x00011F00000090E0ull)
-#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST \
-        CVMX_ADD_IO_SEG(0x00011F0000008690ull)
-#define CVMX_PEXP_NPEI_PKT_SLIST_ES \
-        CVMX_ADD_IO_SEG(0x00011F0000009050ull)
-#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE \
-        CVMX_ADD_IO_SEG(0x00011F0000009180ull)
-#define CVMX_PEXP_NPEI_PKT_SLIST_NS \
-        CVMX_ADD_IO_SEG(0x00011F0000009040ull)
-#define CVMX_PEXP_NPEI_PKT_SLIST_ROR \
-        CVMX_ADD_IO_SEG(0x00011F0000009030ull)
-#define CVMX_PEXP_NPEI_PKT_TIME_INT \
-        CVMX_ADD_IO_SEG(0x00011F0000009120ull)
-#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB \
-        CVMX_ADD_IO_SEG(0x00011F0000009140ull)
-#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS \
-        CVMX_ADD_IO_SEG(0x00011F0000008520ull)
-#define CVMX_PEXP_NPEI_SCRATCH_1 \
-        CVMX_ADD_IO_SEG(0x00011F0000008270ull)
-#define CVMX_PEXP_NPEI_STATE1 \
-        CVMX_ADD_IO_SEG(0x00011F0000008620ull)
-#define CVMX_PEXP_NPEI_STATE2 \
-        CVMX_ADD_IO_SEG(0x00011F0000008630ull)
-#define CVMX_PEXP_NPEI_STATE3 \
-        CVMX_ADD_IO_SEG(0x00011F0000008640ull)
-#define CVMX_PEXP_NPEI_WINDOW_CTL \
-        CVMX_ADD_IO_SEG(0x00011F0000008380ull)
+#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) (CVMX_ADD_IO_SEG(0x00011F0000008000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F0000008580ull))
+#define CVMX_PEXP_NPEI_BIST_STATUS2 (CVMX_ADD_IO_SEG(0x00011F0000008680ull))
+#define CVMX_PEXP_NPEI_CTL_PORT0 (CVMX_ADD_IO_SEG(0x00011F0000008250ull))
+#define CVMX_PEXP_NPEI_CTL_PORT1 (CVMX_ADD_IO_SEG(0x00011F0000008260ull))
+#define CVMX_PEXP_NPEI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000008570ull))
+#define CVMX_PEXP_NPEI_CTL_STATUS2 (CVMX_ADD_IO_SEG(0x00011F000000BC00ull))
+#define CVMX_PEXP_NPEI_DATA_OUT_CNT (CVMX_ADD_IO_SEG(0x00011F00000085F0ull))
+#define CVMX_PEXP_NPEI_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F0000008510ull))
+#define CVMX_PEXP_NPEI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000008500ull))
+#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL (CVMX_ADD_IO_SEG(0x00011F00000085C0ull))
+#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL (CVMX_ADD_IO_SEG(0x00011F00000085D0ull))
+#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000008450ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F00000083B0ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000008400ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) (CVMX_ADD_IO_SEG(0x00011F00000084A0ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMA_CNTS (CVMX_ADD_IO_SEG(0x00011F00000085E0ull))
+#define CVMX_PEXP_NPEI_DMA_CONTROL (CVMX_ADD_IO_SEG(0x00011F00000083A0ull))
+#define CVMX_PEXP_NPEI_DMA_PCIE_REQ_NUM (CVMX_ADD_IO_SEG(0x00011F00000085B0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE1 (CVMX_ADD_IO_SEG(0x00011F00000086C0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE1_P1 (CVMX_ADD_IO_SEG(0x00011F0000008680ull))
+#define CVMX_PEXP_NPEI_DMA_STATE2 (CVMX_ADD_IO_SEG(0x00011F00000086D0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE2_P1 (CVMX_ADD_IO_SEG(0x00011F0000008690ull))
+#define CVMX_PEXP_NPEI_DMA_STATE3_P1 (CVMX_ADD_IO_SEG(0x00011F00000086A0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE4_P1 (CVMX_ADD_IO_SEG(0x00011F00000086B0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE5_P1 (CVMX_ADD_IO_SEG(0x00011F00000086C0ull))
+#define CVMX_PEXP_NPEI_INT_A_ENB (CVMX_ADD_IO_SEG(0x00011F0000008560ull))
+#define CVMX_PEXP_NPEI_INT_A_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BCE0ull))
+#define CVMX_PEXP_NPEI_INT_A_SUM (CVMX_ADD_IO_SEG(0x00011F0000008550ull))
+#define CVMX_PEXP_NPEI_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000008540ull))
+#define CVMX_PEXP_NPEI_INT_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BCD0ull))
+#define CVMX_PEXP_NPEI_INT_INFO (CVMX_ADD_IO_SEG(0x00011F0000008590ull))
+#define CVMX_PEXP_NPEI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000008530ull))
+#define CVMX_PEXP_NPEI_INT_SUM2 (CVMX_ADD_IO_SEG(0x00011F000000BCC0ull))
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 (CVMX_ADD_IO_SEG(0x00011F0000008600ull))
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 (CVMX_ADD_IO_SEG(0x00011F0000008610ull))
+#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL (CVMX_ADD_IO_SEG(0x00011F00000084F0ull))
+#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F0000008280ull) + ((offset) & 31) * 16 - 16*12)
+#define CVMX_PEXP_NPEI_MSI_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BC50ull))
+#define CVMX_PEXP_NPEI_MSI_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BC60ull))
+#define CVMX_PEXP_NPEI_MSI_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BC70ull))
+#define CVMX_PEXP_NPEI_MSI_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BC80ull))
+#define CVMX_PEXP_NPEI_MSI_RCV0 (CVMX_ADD_IO_SEG(0x00011F000000BC10ull))
+#define CVMX_PEXP_NPEI_MSI_RCV1 (CVMX_ADD_IO_SEG(0x00011F000000BC20ull))
+#define CVMX_PEXP_NPEI_MSI_RCV2 (CVMX_ADD_IO_SEG(0x00011F000000BC30ull))
+#define CVMX_PEXP_NPEI_MSI_RCV3 (CVMX_ADD_IO_SEG(0x00011F000000BC40ull))
+#define CVMX_PEXP_NPEI_MSI_RD_MAP (CVMX_ADD_IO_SEG(0x00011F000000BCA0ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BCF0ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BD00ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BD10ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BD20ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BD30ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BD40ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BD50ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BD60ull))
+#define CVMX_PEXP_NPEI_MSI_WR_MAP (CVMX_ADD_IO_SEG(0x00011F000000BC90ull))
+#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT (CVMX_ADD_IO_SEG(0x00011F000000BD70ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F000000BCB0ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 (CVMX_ADD_IO_SEG(0x00011F0000008650ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 (CVMX_ADD_IO_SEG(0x00011F0000008660ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 (CVMX_ADD_IO_SEG(0x00011F0000008670ull))
+#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F000000A400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F000000A800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F000000AC00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F000000B000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) (CVMX_ADD_IO_SEG(0x00011F000000B400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) (CVMX_ADD_IO_SEG(0x00011F000000B800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000009400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000009800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000009C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKT_CNT_INT (CVMX_ADD_IO_SEG(0x00011F0000009110ull))
+#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009130ull))
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES (CVMX_ADD_IO_SEG(0x00011F00000090B0ull))
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS (CVMX_ADD_IO_SEG(0x00011F00000090A0ull))
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR (CVMX_ADD_IO_SEG(0x00011F0000009090ull))
+#define CVMX_PEXP_NPEI_PKT_DPADDR (CVMX_ADD_IO_SEG(0x00011F0000009080ull))
+#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000009150ull))
+#define CVMX_PEXP_NPEI_PKT_INSTR_ENB (CVMX_ADD_IO_SEG(0x00011F0000009000ull))
+#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009190ull))
+#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009020ull))
+#define CVMX_PEXP_NPEI_PKT_INT_LEVELS (CVMX_ADD_IO_SEG(0x00011F0000009100ull))
+#define CVMX_PEXP_NPEI_PKT_IN_BP (CVMX_ADD_IO_SEG(0x00011F00000086B0ull))
+#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F000000A000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS (CVMX_ADD_IO_SEG(0x00011F00000086A0ull))
+#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000091A0ull))
+#define CVMX_PEXP_NPEI_PKT_IPTR (CVMX_ADD_IO_SEG(0x00011F0000009070ull))
+#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK (CVMX_ADD_IO_SEG(0x00011F0000009160ull))
+#define CVMX_PEXP_NPEI_PKT_OUT_BMODE (CVMX_ADD_IO_SEG(0x00011F00000090D0ull))
+#define CVMX_PEXP_NPEI_PKT_OUT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009010ull))
+#define CVMX_PEXP_NPEI_PKT_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000090E0ull))
+#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST (CVMX_ADD_IO_SEG(0x00011F0000008690ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_ES (CVMX_ADD_IO_SEG(0x00011F0000009050ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009180ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_NS (CVMX_ADD_IO_SEG(0x00011F0000009040ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_ROR (CVMX_ADD_IO_SEG(0x00011F0000009030ull))
+#define CVMX_PEXP_NPEI_PKT_TIME_INT (CVMX_ADD_IO_SEG(0x00011F0000009120ull))
+#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009140ull))
+#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS (CVMX_ADD_IO_SEG(0x00011F0000008520ull))
+#define CVMX_PEXP_NPEI_SCRATCH_1 (CVMX_ADD_IO_SEG(0x00011F0000008270ull))
+#define CVMX_PEXP_NPEI_STATE1 (CVMX_ADD_IO_SEG(0x00011F0000008620ull))
+#define CVMX_PEXP_NPEI_STATE2 (CVMX_ADD_IO_SEG(0x00011F0000008630ull))
+#define CVMX_PEXP_NPEI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000008640ull))
+#define CVMX_PEXP_NPEI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F0000008380ull))
+#define CVMX_PEXP_SLI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010580ull))
+#define CVMX_PEXP_SLI_CTL_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010050ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010570ull))
+#define CVMX_PEXP_SLI_DATA_OUT_CNT (CVMX_ADD_IO_SEG(0x00011F00000105F0ull))
+#define CVMX_PEXP_SLI_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F0000010310ull))
+#define CVMX_PEXP_SLI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000010300ull))
+#define CVMX_PEXP_SLI_DMAX_CNT(offset) (CVMX_ADD_IO_SEG(0x00011F0000010400ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_DMAX_INT_LEVEL(offset) (CVMX_ADD_IO_SEG(0x00011F00000103E0ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_DMAX_TIM(offset) (CVMX_ADD_IO_SEG(0x00011F0000010420ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_INT_ENB_CIU (CVMX_ADD_IO_SEG(0x00011F0000013CD0ull))
+#define CVMX_PEXP_SLI_INT_ENB_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010340ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000010330ull))
+#define CVMX_PEXP_SLI_LAST_WIN_RDATA0 (CVMX_ADD_IO_SEG(0x00011F0000010600ull))
+#define CVMX_PEXP_SLI_LAST_WIN_RDATA1 (CVMX_ADD_IO_SEG(0x00011F0000010610ull))
+#define CVMX_PEXP_SLI_MAC_CREDIT_CNT (CVMX_ADD_IO_SEG(0x00011F0000013D70ull))
+#define CVMX_PEXP_SLI_MEM_ACCESS_CTL (CVMX_ADD_IO_SEG(0x00011F00000102F0ull))
+#define CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F00000100E0ull) + ((offset) & 31) * 16 - 16*12)
+#define CVMX_PEXP_SLI_MSI_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013C50ull))
+#define CVMX_PEXP_SLI_MSI_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013C60ull))
+#define CVMX_PEXP_SLI_MSI_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013C70ull))
+#define CVMX_PEXP_SLI_MSI_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013C80ull))
+#define CVMX_PEXP_SLI_MSI_RCV0 (CVMX_ADD_IO_SEG(0x00011F0000013C10ull))
+#define CVMX_PEXP_SLI_MSI_RCV1 (CVMX_ADD_IO_SEG(0x00011F0000013C20ull))
+#define CVMX_PEXP_SLI_MSI_RCV2 (CVMX_ADD_IO_SEG(0x00011F0000013C30ull))
+#define CVMX_PEXP_SLI_MSI_RCV3 (CVMX_ADD_IO_SEG(0x00011F0000013C40ull))
+#define CVMX_PEXP_SLI_MSI_RD_MAP (CVMX_ADD_IO_SEG(0x00011F0000013CA0ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013CF0ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013D00ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013D10ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013D20ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013D30ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013D40ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013D50ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013D60ull))
+#define CVMX_PEXP_SLI_MSI_WR_MAP (CVMX_ADD_IO_SEG(0x00011F0000013C90ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F0000013CB0ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B1 (CVMX_ADD_IO_SEG(0x00011F0000010650ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B2 (CVMX_ADD_IO_SEG(0x00011F0000010660ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B3 (CVMX_ADD_IO_SEG(0x00011F0000010670ull))
+#define CVMX_PEXP_SLI_PKTX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000012400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000012800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000012C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000013000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_HEADER(offset) (CVMX_ADD_IO_SEG(0x00011F0000013400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_IN_BP(offset) (CVMX_ADD_IO_SEG(0x00011F0000013800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_OUT_SIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000010C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_SLIST_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000011400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_SLIST_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000011800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_SLIST_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000011C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKT_CNT_INT (CVMX_ADD_IO_SEG(0x00011F0000011130ull))
+#define CVMX_PEXP_SLI_PKT_CNT_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011150ull))
+#define CVMX_PEXP_SLI_PKT_CTL (CVMX_ADD_IO_SEG(0x00011F0000011220ull))
+#define CVMX_PEXP_SLI_PKT_DATA_OUT_ES (CVMX_ADD_IO_SEG(0x00011F00000110B0ull))
+#define CVMX_PEXP_SLI_PKT_DATA_OUT_NS (CVMX_ADD_IO_SEG(0x00011F00000110A0ull))
+#define CVMX_PEXP_SLI_PKT_DATA_OUT_ROR (CVMX_ADD_IO_SEG(0x00011F0000011090ull))
+#define CVMX_PEXP_SLI_PKT_DPADDR (CVMX_ADD_IO_SEG(0x00011F0000011080ull))
+#define CVMX_PEXP_SLI_PKT_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000011170ull))
+#define CVMX_PEXP_SLI_PKT_INSTR_ENB (CVMX_ADD_IO_SEG(0x00011F0000011000ull))
+#define CVMX_PEXP_SLI_PKT_INSTR_RD_SIZE (CVMX_ADD_IO_SEG(0x00011F00000111A0ull))
+#define CVMX_PEXP_SLI_PKT_INSTR_SIZE (CVMX_ADD_IO_SEG(0x00011F0000011020ull))
+#define CVMX_PEXP_SLI_PKT_INT_LEVELS (CVMX_ADD_IO_SEG(0x00011F0000011120ull))
+#define CVMX_PEXP_SLI_PKT_IN_BP (CVMX_ADD_IO_SEG(0x00011F0000011210ull))
+#define CVMX_PEXP_SLI_PKT_IN_DONEX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000012000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKT_IN_INSTR_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000011200ull))
+#define CVMX_PEXP_SLI_PKT_IN_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000111B0ull))
+#define CVMX_PEXP_SLI_PKT_IPTR (CVMX_ADD_IO_SEG(0x00011F0000011070ull))
+#define CVMX_PEXP_SLI_PKT_OUTPUT_WMARK (CVMX_ADD_IO_SEG(0x00011F0000011180ull))
+#define CVMX_PEXP_SLI_PKT_OUT_BMODE (CVMX_ADD_IO_SEG(0x00011F00000110D0ull))
+#define CVMX_PEXP_SLI_PKT_OUT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011010ull))
+#define CVMX_PEXP_SLI_PKT_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000110E0ull))
+#define CVMX_PEXP_SLI_PKT_PORT_IN_RST (CVMX_ADD_IO_SEG(0x00011F00000111F0ull))
+#define CVMX_PEXP_SLI_PKT_SLIST_ES (CVMX_ADD_IO_SEG(0x00011F0000011050ull))
+#define CVMX_PEXP_SLI_PKT_SLIST_NS (CVMX_ADD_IO_SEG(0x00011F0000011040ull))
+#define CVMX_PEXP_SLI_PKT_SLIST_ROR (CVMX_ADD_IO_SEG(0x00011F0000011030ull))
+#define CVMX_PEXP_SLI_PKT_TIME_INT (CVMX_ADD_IO_SEG(0x00011F0000011140ull))
+#define CVMX_PEXP_SLI_PKT_TIME_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011160ull))
+#define CVMX_PEXP_SLI_S2M_PORTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011F0000013D80ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_SCRATCH_1 (CVMX_ADD_IO_SEG(0x00011F00000103C0ull))
+#define CVMX_PEXP_SLI_SCRATCH_2 (CVMX_ADD_IO_SEG(0x00011F00000103D0ull))
+#define CVMX_PEXP_SLI_STATE1 (CVMX_ADD_IO_SEG(0x00011F0000010620ull))
+#define CVMX_PEXP_SLI_STATE2 (CVMX_ADD_IO_SEG(0x00011F0000010630ull))
+#define CVMX_PEXP_SLI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000010640ull))
+#define CVMX_PEXP_SLI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F00000102E0ull))
 
 #endif
index 2d82e24be51c46416b4a521588bcba176d3de045..39fd75b03f7733df3806b192887921daff62b4d2 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_POW_DEFS_H__
 #define __CVMX_POW_DEFS_H__
 
-#define CVMX_POW_BIST_STAT \
-        CVMX_ADD_IO_SEG(0x00016700000003F8ull)
-#define CVMX_POW_DS_PC \
-        CVMX_ADD_IO_SEG(0x0001670000000398ull)
-#define CVMX_POW_ECC_ERR \
-        CVMX_ADD_IO_SEG(0x0001670000000218ull)
-#define CVMX_POW_INT_CTL \
-        CVMX_ADD_IO_SEG(0x0001670000000220ull)
-#define CVMX_POW_IQ_CNTX(offset) \
-        CVMX_ADD_IO_SEG(0x0001670000000340ull + (((offset) & 7) * 8))
-#define CVMX_POW_IQ_COM_CNT \
-        CVMX_ADD_IO_SEG(0x0001670000000388ull)
-#define CVMX_POW_IQ_INT \
-        CVMX_ADD_IO_SEG(0x0001670000000238ull)
-#define CVMX_POW_IQ_INT_EN \
-        CVMX_ADD_IO_SEG(0x0001670000000240ull)
-#define CVMX_POW_IQ_THRX(offset) \
-        CVMX_ADD_IO_SEG(0x00016700000003A0ull + (((offset) & 7) * 8))
-#define CVMX_POW_NOS_CNT \
-        CVMX_ADD_IO_SEG(0x0001670000000228ull)
-#define CVMX_POW_NW_TIM \
-        CVMX_ADD_IO_SEG(0x0001670000000210ull)
-#define CVMX_POW_PF_RST_MSK \
-        CVMX_ADD_IO_SEG(0x0001670000000230ull)
-#define CVMX_POW_PP_GRP_MSKX(offset) \
-        CVMX_ADD_IO_SEG(0x0001670000000000ull + (((offset) & 15) * 8))
-#define CVMX_POW_QOS_RNDX(offset) \
-        CVMX_ADD_IO_SEG(0x00016700000001C0ull + (((offset) & 7) * 8))
-#define CVMX_POW_QOS_THRX(offset) \
-        CVMX_ADD_IO_SEG(0x0001670000000180ull + (((offset) & 7) * 8))
-#define CVMX_POW_TS_PC \
-        CVMX_ADD_IO_SEG(0x0001670000000390ull)
-#define CVMX_POW_WA_COM_PC \
-        CVMX_ADD_IO_SEG(0x0001670000000380ull)
-#define CVMX_POW_WA_PCX(offset) \
-        CVMX_ADD_IO_SEG(0x0001670000000300ull + (((offset) & 7) * 8))
-#define CVMX_POW_WQ_INT \
-        CVMX_ADD_IO_SEG(0x0001670000000200ull)
-#define CVMX_POW_WQ_INT_CNTX(offset) \
-        CVMX_ADD_IO_SEG(0x0001670000000100ull + (((offset) & 15) * 8))
-#define CVMX_POW_WQ_INT_PC \
-        CVMX_ADD_IO_SEG(0x0001670000000208ull)
-#define CVMX_POW_WQ_INT_THRX(offset) \
-        CVMX_ADD_IO_SEG(0x0001670000000080ull + (((offset) & 15) * 8))
-#define CVMX_POW_WS_PCX(offset) \
-        CVMX_ADD_IO_SEG(0x0001670000000280ull + (((offset) & 15) * 8))
+#define CVMX_POW_BIST_STAT (CVMX_ADD_IO_SEG(0x00016700000003F8ull))
+#define CVMX_POW_DS_PC (CVMX_ADD_IO_SEG(0x0001670000000398ull))
+#define CVMX_POW_ECC_ERR (CVMX_ADD_IO_SEG(0x0001670000000218ull))
+#define CVMX_POW_INT_CTL (CVMX_ADD_IO_SEG(0x0001670000000220ull))
+#define CVMX_POW_IQ_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001670000000340ull) + ((offset) & 7) * 8)
+#define CVMX_POW_IQ_COM_CNT (CVMX_ADD_IO_SEG(0x0001670000000388ull))
+#define CVMX_POW_IQ_INT (CVMX_ADD_IO_SEG(0x0001670000000238ull))
+#define CVMX_POW_IQ_INT_EN (CVMX_ADD_IO_SEG(0x0001670000000240ull))
+#define CVMX_POW_IQ_THRX(offset) (CVMX_ADD_IO_SEG(0x00016700000003A0ull) + ((offset) & 7) * 8)
+#define CVMX_POW_NOS_CNT (CVMX_ADD_IO_SEG(0x0001670000000228ull))
+#define CVMX_POW_NW_TIM (CVMX_ADD_IO_SEG(0x0001670000000210ull))
+#define CVMX_POW_PF_RST_MSK (CVMX_ADD_IO_SEG(0x0001670000000230ull))
+#define CVMX_POW_PP_GRP_MSKX(offset) (CVMX_ADD_IO_SEG(0x0001670000000000ull) + ((offset) & 15) * 8)
+#define CVMX_POW_QOS_RNDX(offset) (CVMX_ADD_IO_SEG(0x00016700000001C0ull) + ((offset) & 7) * 8)
+#define CVMX_POW_QOS_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000180ull) + ((offset) & 7) * 8)
+#define CVMX_POW_TS_PC (CVMX_ADD_IO_SEG(0x0001670000000390ull))
+#define CVMX_POW_WA_COM_PC (CVMX_ADD_IO_SEG(0x0001670000000380ull))
+#define CVMX_POW_WA_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000300ull) + ((offset) & 7) * 8)
+#define CVMX_POW_WQ_INT (CVMX_ADD_IO_SEG(0x0001670000000200ull))
+#define CVMX_POW_WQ_INT_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001670000000100ull) + ((offset) & 15) * 8)
+#define CVMX_POW_WQ_INT_PC (CVMX_ADD_IO_SEG(0x0001670000000208ull))
+#define CVMX_POW_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000080ull) + ((offset) & 15) * 8)
+#define CVMX_POW_WS_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000280ull) + ((offset) & 15) * 8)
 
 union cvmx_pow_bist_stat {
        uint64_t u64;
@@ -160,6 +137,19 @@ union cvmx_pow_bist_stat {
        struct cvmx_pow_bist_stat_cn56xx cn56xxp1;
        struct cvmx_pow_bist_stat_cn38xx cn58xx;
        struct cvmx_pow_bist_stat_cn38xx cn58xxp1;
+       struct cvmx_pow_bist_stat_cn63xx {
+               uint64_t reserved_22_63:42;
+               uint64_t pp:6;
+               uint64_t reserved_12_15:4;
+               uint64_t cam:1;
+               uint64_t nbr:3;
+               uint64_t nbt:4;
+               uint64_t index:1;
+               uint64_t fidx:1;
+               uint64_t pend:1;
+               uint64_t adr:1;
+       } cn63xx;
+       struct cvmx_pow_bist_stat_cn63xx cn63xxp1;
 };
 
 union cvmx_pow_ds_pc {
@@ -179,6 +169,8 @@ union cvmx_pow_ds_pc {
        struct cvmx_pow_ds_pc_s cn56xxp1;
        struct cvmx_pow_ds_pc_s cn58xx;
        struct cvmx_pow_ds_pc_s cn58xxp1;
+       struct cvmx_pow_ds_pc_s cn63xx;
+       struct cvmx_pow_ds_pc_s cn63xxp1;
 };
 
 union cvmx_pow_ecc_err {
@@ -219,6 +211,8 @@ union cvmx_pow_ecc_err {
        struct cvmx_pow_ecc_err_s cn56xxp1;
        struct cvmx_pow_ecc_err_s cn58xx;
        struct cvmx_pow_ecc_err_s cn58xxp1;
+       struct cvmx_pow_ecc_err_s cn63xx;
+       struct cvmx_pow_ecc_err_s cn63xxp1;
 };
 
 union cvmx_pow_int_ctl {
@@ -239,6 +233,8 @@ union cvmx_pow_int_ctl {
        struct cvmx_pow_int_ctl_s cn56xxp1;
        struct cvmx_pow_int_ctl_s cn58xx;
        struct cvmx_pow_int_ctl_s cn58xxp1;
+       struct cvmx_pow_int_ctl_s cn63xx;
+       struct cvmx_pow_int_ctl_s cn63xxp1;
 };
 
 union cvmx_pow_iq_cntx {
@@ -258,6 +254,8 @@ union cvmx_pow_iq_cntx {
        struct cvmx_pow_iq_cntx_s cn56xxp1;
        struct cvmx_pow_iq_cntx_s cn58xx;
        struct cvmx_pow_iq_cntx_s cn58xxp1;
+       struct cvmx_pow_iq_cntx_s cn63xx;
+       struct cvmx_pow_iq_cntx_s cn63xxp1;
 };
 
 union cvmx_pow_iq_com_cnt {
@@ -277,6 +275,8 @@ union cvmx_pow_iq_com_cnt {
        struct cvmx_pow_iq_com_cnt_s cn56xxp1;
        struct cvmx_pow_iq_com_cnt_s cn58xx;
        struct cvmx_pow_iq_com_cnt_s cn58xxp1;
+       struct cvmx_pow_iq_com_cnt_s cn63xx;
+       struct cvmx_pow_iq_com_cnt_s cn63xxp1;
 };
 
 union cvmx_pow_iq_int {
@@ -289,6 +289,8 @@ union cvmx_pow_iq_int {
        struct cvmx_pow_iq_int_s cn52xxp1;
        struct cvmx_pow_iq_int_s cn56xx;
        struct cvmx_pow_iq_int_s cn56xxp1;
+       struct cvmx_pow_iq_int_s cn63xx;
+       struct cvmx_pow_iq_int_s cn63xxp1;
 };
 
 union cvmx_pow_iq_int_en {
@@ -301,6 +303,8 @@ union cvmx_pow_iq_int_en {
        struct cvmx_pow_iq_int_en_s cn52xxp1;
        struct cvmx_pow_iq_int_en_s cn56xx;
        struct cvmx_pow_iq_int_en_s cn56xxp1;
+       struct cvmx_pow_iq_int_en_s cn63xx;
+       struct cvmx_pow_iq_int_en_s cn63xxp1;
 };
 
 union cvmx_pow_iq_thrx {
@@ -313,6 +317,8 @@ union cvmx_pow_iq_thrx {
        struct cvmx_pow_iq_thrx_s cn52xxp1;
        struct cvmx_pow_iq_thrx_s cn56xx;
        struct cvmx_pow_iq_thrx_s cn56xxp1;
+       struct cvmx_pow_iq_thrx_s cn63xx;
+       struct cvmx_pow_iq_thrx_s cn63xxp1;
 };
 
 union cvmx_pow_nos_cnt {
@@ -341,6 +347,11 @@ union cvmx_pow_nos_cnt {
        struct cvmx_pow_nos_cnt_s cn56xxp1;
        struct cvmx_pow_nos_cnt_s cn58xx;
        struct cvmx_pow_nos_cnt_s cn58xxp1;
+       struct cvmx_pow_nos_cnt_cn63xx {
+               uint64_t reserved_11_63:53;
+               uint64_t nos_cnt:11;
+       } cn63xx;
+       struct cvmx_pow_nos_cnt_cn63xx cn63xxp1;
 };
 
 union cvmx_pow_nw_tim {
@@ -360,6 +371,8 @@ union cvmx_pow_nw_tim {
        struct cvmx_pow_nw_tim_s cn56xxp1;
        struct cvmx_pow_nw_tim_s cn58xx;
        struct cvmx_pow_nw_tim_s cn58xxp1;
+       struct cvmx_pow_nw_tim_s cn63xx;
+       struct cvmx_pow_nw_tim_s cn63xxp1;
 };
 
 union cvmx_pow_pf_rst_msk {
@@ -375,6 +388,8 @@ union cvmx_pow_pf_rst_msk {
        struct cvmx_pow_pf_rst_msk_s cn56xxp1;
        struct cvmx_pow_pf_rst_msk_s cn58xx;
        struct cvmx_pow_pf_rst_msk_s cn58xxp1;
+       struct cvmx_pow_pf_rst_msk_s cn63xx;
+       struct cvmx_pow_pf_rst_msk_s cn63xxp1;
 };
 
 union cvmx_pow_pp_grp_mskx {
@@ -405,6 +420,8 @@ union cvmx_pow_pp_grp_mskx {
        struct cvmx_pow_pp_grp_mskx_s cn56xxp1;
        struct cvmx_pow_pp_grp_mskx_s cn58xx;
        struct cvmx_pow_pp_grp_mskx_s cn58xxp1;
+       struct cvmx_pow_pp_grp_mskx_s cn63xx;
+       struct cvmx_pow_pp_grp_mskx_s cn63xxp1;
 };
 
 union cvmx_pow_qos_rndx {
@@ -427,6 +444,8 @@ union cvmx_pow_qos_rndx {
        struct cvmx_pow_qos_rndx_s cn56xxp1;
        struct cvmx_pow_qos_rndx_s cn58xx;
        struct cvmx_pow_qos_rndx_s cn58xxp1;
+       struct cvmx_pow_qos_rndx_s cn63xx;
+       struct cvmx_pow_qos_rndx_s cn63xxp1;
 };
 
 union cvmx_pow_qos_thrx {
@@ -485,6 +504,19 @@ union cvmx_pow_qos_thrx {
        struct cvmx_pow_qos_thrx_s cn56xxp1;
        struct cvmx_pow_qos_thrx_s cn58xx;
        struct cvmx_pow_qos_thrx_s cn58xxp1;
+       struct cvmx_pow_qos_thrx_cn63xx {
+               uint64_t reserved_59_63:5;
+               uint64_t des_cnt:11;
+               uint64_t reserved_47_47:1;
+               uint64_t buf_cnt:11;
+               uint64_t reserved_35_35:1;
+               uint64_t free_cnt:11;
+               uint64_t reserved_22_23:2;
+               uint64_t max_thr:10;
+               uint64_t reserved_10_11:2;
+               uint64_t min_thr:10;
+       } cn63xx;
+       struct cvmx_pow_qos_thrx_cn63xx cn63xxp1;
 };
 
 union cvmx_pow_ts_pc {
@@ -504,6 +536,8 @@ union cvmx_pow_ts_pc {
        struct cvmx_pow_ts_pc_s cn56xxp1;
        struct cvmx_pow_ts_pc_s cn58xx;
        struct cvmx_pow_ts_pc_s cn58xxp1;
+       struct cvmx_pow_ts_pc_s cn63xx;
+       struct cvmx_pow_ts_pc_s cn63xxp1;
 };
 
 union cvmx_pow_wa_com_pc {
@@ -523,6 +557,8 @@ union cvmx_pow_wa_com_pc {
        struct cvmx_pow_wa_com_pc_s cn56xxp1;
        struct cvmx_pow_wa_com_pc_s cn58xx;
        struct cvmx_pow_wa_com_pc_s cn58xxp1;
+       struct cvmx_pow_wa_com_pc_s cn63xx;
+       struct cvmx_pow_wa_com_pc_s cn63xxp1;
 };
 
 union cvmx_pow_wa_pcx {
@@ -542,6 +578,8 @@ union cvmx_pow_wa_pcx {
        struct cvmx_pow_wa_pcx_s cn56xxp1;
        struct cvmx_pow_wa_pcx_s cn58xx;
        struct cvmx_pow_wa_pcx_s cn58xxp1;
+       struct cvmx_pow_wa_pcx_s cn63xx;
+       struct cvmx_pow_wa_pcx_s cn63xxp1;
 };
 
 union cvmx_pow_wq_int {
@@ -562,6 +600,8 @@ union cvmx_pow_wq_int {
        struct cvmx_pow_wq_int_s cn56xxp1;
        struct cvmx_pow_wq_int_s cn58xx;
        struct cvmx_pow_wq_int_s cn58xxp1;
+       struct cvmx_pow_wq_int_s cn63xx;
+       struct cvmx_pow_wq_int_s cn63xxp1;
 };
 
 union cvmx_pow_wq_int_cntx {
@@ -604,6 +644,15 @@ union cvmx_pow_wq_int_cntx {
        struct cvmx_pow_wq_int_cntx_s cn56xxp1;
        struct cvmx_pow_wq_int_cntx_s cn58xx;
        struct cvmx_pow_wq_int_cntx_s cn58xxp1;
+       struct cvmx_pow_wq_int_cntx_cn63xx {
+               uint64_t reserved_28_63:36;
+               uint64_t tc_cnt:4;
+               uint64_t reserved_23_23:1;
+               uint64_t ds_cnt:11;
+               uint64_t reserved_11_11:1;
+               uint64_t iq_cnt:11;
+       } cn63xx;
+       struct cvmx_pow_wq_int_cntx_cn63xx cn63xxp1;
 };
 
 union cvmx_pow_wq_int_pc {
@@ -626,6 +675,8 @@ union cvmx_pow_wq_int_pc {
        struct cvmx_pow_wq_int_pc_s cn56xxp1;
        struct cvmx_pow_wq_int_pc_s cn58xx;
        struct cvmx_pow_wq_int_pc_s cn58xxp1;
+       struct cvmx_pow_wq_int_pc_s cn63xx;
+       struct cvmx_pow_wq_int_pc_s cn63xxp1;
 };
 
 union cvmx_pow_wq_int_thrx {
@@ -674,6 +725,16 @@ union cvmx_pow_wq_int_thrx {
        struct cvmx_pow_wq_int_thrx_s cn56xxp1;
        struct cvmx_pow_wq_int_thrx_s cn58xx;
        struct cvmx_pow_wq_int_thrx_s cn58xxp1;
+       struct cvmx_pow_wq_int_thrx_cn63xx {
+               uint64_t reserved_29_63:35;
+               uint64_t tc_en:1;
+               uint64_t tc_thr:4;
+               uint64_t reserved_22_23:2;
+               uint64_t ds_thr:10;
+               uint64_t reserved_10_11:2;
+               uint64_t iq_thr:10;
+       } cn63xx;
+       struct cvmx_pow_wq_int_thrx_cn63xx cn63xxp1;
 };
 
 union cvmx_pow_ws_pcx {
@@ -693,6 +754,8 @@ union cvmx_pow_ws_pcx {
        struct cvmx_pow_ws_pcx_s cn56xxp1;
        struct cvmx_pow_ws_pcx_s cn58xx;
        struct cvmx_pow_ws_pcx_s cn58xxp1;
+       struct cvmx_pow_ws_pcx_s cn63xx;
+       struct cvmx_pow_ws_pcx_s cn63xxp1;
 };
 
 #endif
index 4586958c97bebba1ebf274f904af0d8bf41abb46..c45da1f35ea7a70a4fc4635ea3c846db7d202f08 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 
 #include <linux/types.h>
 
-#define CVMX_RNM_BIST_STATUS \
-        CVMX_ADD_IO_SEG(0x0001180040000008ull)
-#define CVMX_RNM_CTL_STATUS \
-        CVMX_ADD_IO_SEG(0x0001180040000000ull)
+#define CVMX_RNM_BIST_STATUS (CVMX_ADD_IO_SEG(0x0001180040000008ull))
+#define CVMX_RNM_CTL_STATUS (CVMX_ADD_IO_SEG(0x0001180040000000ull))
+#define CVMX_RNM_EER_DBG (CVMX_ADD_IO_SEG(0x0001180040000018ull))
+#define CVMX_RNM_EER_KEY (CVMX_ADD_IO_SEG(0x0001180040000010ull))
+#define CVMX_RNM_SERIAL_NUM (CVMX_ADD_IO_SEG(0x0001180040000020ull))
 
 union cvmx_rnm_bist_status {
        uint64_t u64;
@@ -53,12 +54,16 @@ union cvmx_rnm_bist_status {
        struct cvmx_rnm_bist_status_s cn56xxp1;
        struct cvmx_rnm_bist_status_s cn58xx;
        struct cvmx_rnm_bist_status_s cn58xxp1;
+       struct cvmx_rnm_bist_status_s cn63xx;
+       struct cvmx_rnm_bist_status_s cn63xxp1;
 };
 
 union cvmx_rnm_ctl_status {
        uint64_t u64;
        struct cvmx_rnm_ctl_status_s {
-               uint64_t reserved_9_63:55;
+               uint64_t reserved_11_63:53;
+               uint64_t eer_lck:1;
+               uint64_t eer_val:1;
                uint64_t ent_sel:4;
                uint64_t exp_ent:1;
                uint64_t rng_rst:1;
@@ -76,13 +81,49 @@ union cvmx_rnm_ctl_status {
        struct cvmx_rnm_ctl_status_cn30xx cn31xx;
        struct cvmx_rnm_ctl_status_cn30xx cn38xx;
        struct cvmx_rnm_ctl_status_cn30xx cn38xxp2;
-       struct cvmx_rnm_ctl_status_s cn50xx;
-       struct cvmx_rnm_ctl_status_s cn52xx;
-       struct cvmx_rnm_ctl_status_s cn52xxp1;
-       struct cvmx_rnm_ctl_status_s cn56xx;
-       struct cvmx_rnm_ctl_status_s cn56xxp1;
-       struct cvmx_rnm_ctl_status_s cn58xx;
-       struct cvmx_rnm_ctl_status_s cn58xxp1;
+       struct cvmx_rnm_ctl_status_cn50xx {
+               uint64_t reserved_9_63:55;
+               uint64_t ent_sel:4;
+               uint64_t exp_ent:1;
+               uint64_t rng_rst:1;
+               uint64_t rnm_rst:1;
+               uint64_t rng_en:1;
+               uint64_t ent_en:1;
+       } cn50xx;
+       struct cvmx_rnm_ctl_status_cn50xx cn52xx;
+       struct cvmx_rnm_ctl_status_cn50xx cn52xxp1;
+       struct cvmx_rnm_ctl_status_cn50xx cn56xx;
+       struct cvmx_rnm_ctl_status_cn50xx cn56xxp1;
+       struct cvmx_rnm_ctl_status_cn50xx cn58xx;
+       struct cvmx_rnm_ctl_status_cn50xx cn58xxp1;
+       struct cvmx_rnm_ctl_status_s cn63xx;
+       struct cvmx_rnm_ctl_status_s cn63xxp1;
+};
+
+union cvmx_rnm_eer_dbg {
+       uint64_t u64;
+       struct cvmx_rnm_eer_dbg_s {
+               uint64_t dat:64;
+       } s;
+       struct cvmx_rnm_eer_dbg_s cn63xx;
+       struct cvmx_rnm_eer_dbg_s cn63xxp1;
+};
+
+union cvmx_rnm_eer_key {
+       uint64_t u64;
+       struct cvmx_rnm_eer_key_s {
+               uint64_t key:64;
+       } s;
+       struct cvmx_rnm_eer_key_s cn63xx;
+       struct cvmx_rnm_eer_key_s cn63xxp1;
+};
+
+union cvmx_rnm_serial_num {
+       uint64_t u64;
+       struct cvmx_rnm_serial_num_s {
+               uint64_t dat:64;
+       } s;
+       struct cvmx_rnm_serial_num_s cn63xx;
 };
 
 #endif
index 9ae45fcbe3e39dfd10a1fe409308198ebc03471c..4f3c0666e94a5f7ce059c88dc5fe922909cdb117 100644 (file)
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
 #ifndef __CVMX_SMIX_DEFS_H__
 #define __CVMX_SMIX_DEFS_H__
 
-#define CVMX_SMIX_CLK(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_CMD(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_EN(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_RD_DAT(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_WR_DAT(offset) \
-        CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_CLK(offset) (CVMX_ADD_IO_SEG(0x0001180000001818ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_CMD(offset) (CVMX_ADD_IO_SEG(0x0001180000001800ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_EN(offset) (CVMX_ADD_IO_SEG(0x0001180000001820ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_RD_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001810ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_WR_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001808ull) + ((offset) & 1) * 256)
 
 union cvmx_smix_clk {
        uint64_t u64;
@@ -56,7 +51,8 @@ union cvmx_smix_clk {
        struct cvmx_smix_clk_cn30xx {
                uint64_t reserved_21_63:43;
                uint64_t sample_hi:5;
-               uint64_t reserved_14_15:2;
+               uint64_t sample_mode:1;
+               uint64_t reserved_14_14:1;
                uint64_t clk_idle:1;
                uint64_t preamble:1;
                uint64_t sample:4;
@@ -65,23 +61,15 @@ union cvmx_smix_clk {
        struct cvmx_smix_clk_cn30xx cn31xx;
        struct cvmx_smix_clk_cn30xx cn38xx;
        struct cvmx_smix_clk_cn30xx cn38xxp2;
-       struct cvmx_smix_clk_cn50xx {
-               uint64_t reserved_25_63:39;
-               uint64_t mode:1;
-               uint64_t reserved_21_23:3;
-               uint64_t sample_hi:5;
-               uint64_t reserved_14_15:2;
-               uint64_t clk_idle:1;
-               uint64_t preamble:1;
-               uint64_t sample:4;
-               uint64_t phase:8;
-       } cn50xx;
+       struct cvmx_smix_clk_s cn50xx;
        struct cvmx_smix_clk_s cn52xx;
-       struct cvmx_smix_clk_cn50xx cn52xxp1;
+       struct cvmx_smix_clk_s cn52xxp1;
        struct cvmx_smix_clk_s cn56xx;
-       struct cvmx_smix_clk_cn50xx cn56xxp1;
+       struct cvmx_smix_clk_s cn56xxp1;
        struct cvmx_smix_clk_cn30xx cn58xx;
        struct cvmx_smix_clk_cn30xx cn58xxp1;
+       struct cvmx_smix_clk_s cn63xx;
+       struct cvmx_smix_clk_s cn63xxp1;
 };
 
 union cvmx_smix_cmd {
@@ -112,6 +100,8 @@ union cvmx_smix_cmd {
        struct cvmx_smix_cmd_s cn56xxp1;
        struct cvmx_smix_cmd_cn30xx cn58xx;
        struct cvmx_smix_cmd_cn30xx cn58xxp1;
+       struct cvmx_smix_cmd_s cn63xx;
+       struct cvmx_smix_cmd_s cn63xxp1;
 };
 
 union cvmx_smix_en {
@@ -131,6 +121,8 @@ union cvmx_smix_en {
        struct cvmx_smix_en_s cn56xxp1;
        struct cvmx_smix_en_s cn58xx;
        struct cvmx_smix_en_s cn58xxp1;
+       struct cvmx_smix_en_s cn63xx;
+       struct cvmx_smix_en_s cn63xxp1;
 };
 
 union cvmx_smix_rd_dat {
@@ -152,6 +144,8 @@ union cvmx_smix_rd_dat {
        struct cvmx_smix_rd_dat_s cn56xxp1;
        struct cvmx_smix_rd_dat_s cn58xx;
        struct cvmx_smix_rd_dat_s cn58xxp1;
+       struct cvmx_smix_rd_dat_s cn63xx;
+       struct cvmx_smix_rd_dat_s cn63xxp1;
 };
 
 union cvmx_smix_wr_dat {
@@ -173,6 +167,8 @@ union cvmx_smix_wr_dat {
        struct cvmx_smix_wr_dat_s cn56xxp1;
        struct cvmx_smix_wr_dat_s cn58xx;
        struct cvmx_smix_wr_dat_s cn58xxp1;
+       struct cvmx_smix_wr_dat_s cn63xx;
+       struct cvmx_smix_wr_dat_s cn63xxp1;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h b/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
new file mode 100644 (file)
index 0000000..594f1b6
--- /dev/null
@@ -0,0 +1,261 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 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
+ ***********************license end**************************************/
+
+#ifndef __CVMX_UCTLX_TYPEDEFS_H__
+#define __CVMX_UCTLX_TYPEDEFS_H__
+
+#define CVMX_UCTLX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A0ull))
+#define CVMX_UCTLX_CLK_RST_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000000ull))
+#define CVMX_UCTLX_EHCI_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000080ull))
+#define CVMX_UCTLX_EHCI_FLA(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A8ull))
+#define CVMX_UCTLX_ERTO_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000090ull))
+#define CVMX_UCTLX_IF_ENA(block_id) (CVMX_ADD_IO_SEG(0x000118006F000030ull))
+#define CVMX_UCTLX_INT_ENA(block_id) (CVMX_ADD_IO_SEG(0x000118006F000028ull))
+#define CVMX_UCTLX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x000118006F000020ull))
+#define CVMX_UCTLX_OHCI_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000088ull))
+#define CVMX_UCTLX_ORTO_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000098ull))
+#define CVMX_UCTLX_PPAF_WM(block_id) (CVMX_ADD_IO_SEG(0x000118006F000038ull))
+#define CVMX_UCTLX_UPHY_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F000008ull))
+#define CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(offset, block_id) (CVMX_ADD_IO_SEG(0x000118006F000010ull) + (((offset) & 1) + ((block_id) & 0) * 0x0ull) * 8)
+
+union cvmx_uctlx_bist_status {
+       uint64_t u64;
+       struct cvmx_uctlx_bist_status_s {
+               uint64_t reserved_6_63:58;
+               uint64_t data_bis:1;
+               uint64_t desc_bis:1;
+               uint64_t erbm_bis:1;
+               uint64_t orbm_bis:1;
+               uint64_t wrbm_bis:1;
+               uint64_t ppaf_bis:1;
+       } s;
+       struct cvmx_uctlx_bist_status_s       cn63xx;
+       struct cvmx_uctlx_bist_status_s       cn63xxp1;
+};
+
+union cvmx_uctlx_clk_rst_ctl {
+       uint64_t u64;
+       struct cvmx_uctlx_clk_rst_ctl_s {
+               uint64_t reserved_25_63:39;
+               uint64_t clear_bist:1;
+               uint64_t start_bist:1;
+               uint64_t ehci_sm:1;
+               uint64_t ohci_clkcktrst:1;
+               uint64_t ohci_sm:1;
+               uint64_t ohci_susp_lgcy:1;
+               uint64_t app_start_clk:1;
+               uint64_t o_clkdiv_rst:1;
+               uint64_t h_clkdiv_byp:1;
+               uint64_t h_clkdiv_rst:1;
+               uint64_t h_clkdiv_en:1;
+               uint64_t o_clkdiv_en:1;
+               uint64_t h_div:4;
+               uint64_t p_refclk_sel:2;
+               uint64_t p_refclk_div:2;
+               uint64_t reserved_4_4:1;
+               uint64_t p_com_on:1;
+               uint64_t p_por:1;
+               uint64_t p_prst:1;
+               uint64_t hrst:1;
+       } s;
+       struct cvmx_uctlx_clk_rst_ctl_s       cn63xx;
+       struct cvmx_uctlx_clk_rst_ctl_s       cn63xxp1;
+};
+
+union cvmx_uctlx_ehci_ctl {
+       uint64_t u64;
+       struct cvmx_uctlx_ehci_ctl_s {
+               uint64_t reserved_20_63:44;
+               uint64_t desc_rbm:1;
+               uint64_t reg_nb:1;
+               uint64_t l2c_dc:1;
+               uint64_t l2c_bc:1;
+               uint64_t l2c_0pag:1;
+               uint64_t l2c_stt:1;
+               uint64_t l2c_buff_emod:2;
+               uint64_t l2c_desc_emod:2;
+               uint64_t inv_reg_a2:1;
+               uint64_t ehci_64b_addr_en:1;
+               uint64_t l2c_addr_msb:8;
+       } s;
+       struct cvmx_uctlx_ehci_ctl_s          cn63xx;
+       struct cvmx_uctlx_ehci_ctl_s          cn63xxp1;
+};
+
+union cvmx_uctlx_ehci_fla {
+       uint64_t u64;
+       struct cvmx_uctlx_ehci_fla_s {
+               uint64_t reserved_6_63:58;
+               uint64_t fla:6;
+       } s;
+       struct cvmx_uctlx_ehci_fla_s          cn63xx;
+       struct cvmx_uctlx_ehci_fla_s          cn63xxp1;
+};
+
+union cvmx_uctlx_erto_ctl {
+       uint64_t u64;
+       struct cvmx_uctlx_erto_ctl_s {
+               uint64_t reserved_32_63:32;
+               uint64_t to_val:27;
+               uint64_t reserved_0_4:5;
+       } s;
+       struct cvmx_uctlx_erto_ctl_s          cn63xx;
+       struct cvmx_uctlx_erto_ctl_s          cn63xxp1;
+};
+
+union cvmx_uctlx_if_ena {
+       uint64_t u64;
+       struct cvmx_uctlx_if_ena_s {
+               uint64_t reserved_1_63:63;
+               uint64_t en:1;
+       } s;
+       struct cvmx_uctlx_if_ena_s            cn63xx;
+       struct cvmx_uctlx_if_ena_s            cn63xxp1;
+};
+
+union cvmx_uctlx_int_ena {
+       uint64_t u64;
+       struct cvmx_uctlx_int_ena_s {
+               uint64_t reserved_8_63:56;
+               uint64_t ec_ovf_e:1;
+               uint64_t oc_ovf_e:1;
+               uint64_t wb_pop_e:1;
+               uint64_t wb_psh_f:1;
+               uint64_t cf_psh_f:1;
+               uint64_t or_psh_f:1;
+               uint64_t er_psh_f:1;
+               uint64_t pp_psh_f:1;
+       } s;
+       struct cvmx_uctlx_int_ena_s           cn63xx;
+       struct cvmx_uctlx_int_ena_s           cn63xxp1;
+};
+
+union cvmx_uctlx_int_reg {
+       uint64_t u64;
+       struct cvmx_uctlx_int_reg_s {
+               uint64_t reserved_8_63:56;
+               uint64_t ec_ovf_e:1;
+               uint64_t oc_ovf_e:1;
+               uint64_t wb_pop_e:1;
+               uint64_t wb_psh_f:1;
+               uint64_t cf_psh_f:1;
+               uint64_t or_psh_f:1;
+               uint64_t er_psh_f:1;
+               uint64_t pp_psh_f:1;
+       } s;
+       struct cvmx_uctlx_int_reg_s           cn63xx;
+       struct cvmx_uctlx_int_reg_s           cn63xxp1;
+};
+
+union cvmx_uctlx_ohci_ctl {
+       uint64_t u64;
+       struct cvmx_uctlx_ohci_ctl_s {
+               uint64_t reserved_19_63:45;
+               uint64_t reg_nb:1;
+               uint64_t l2c_dc:1;
+               uint64_t l2c_bc:1;
+               uint64_t l2c_0pag:1;
+               uint64_t l2c_stt:1;
+               uint64_t l2c_buff_emod:2;
+               uint64_t l2c_desc_emod:2;
+               uint64_t inv_reg_a2:1;
+               uint64_t reserved_8_8:1;
+               uint64_t l2c_addr_msb:8;
+       } s;
+       struct cvmx_uctlx_ohci_ctl_s          cn63xx;
+       struct cvmx_uctlx_ohci_ctl_s          cn63xxp1;
+};
+
+union cvmx_uctlx_orto_ctl {
+       uint64_t u64;
+       struct cvmx_uctlx_orto_ctl_s {
+               uint64_t reserved_32_63:32;
+               uint64_t to_val:24;
+               uint64_t reserved_0_7:8;
+       } s;
+       struct cvmx_uctlx_orto_ctl_s          cn63xx;
+       struct cvmx_uctlx_orto_ctl_s          cn63xxp1;
+};
+
+union cvmx_uctlx_ppaf_wm {
+       uint64_t u64;
+       struct cvmx_uctlx_ppaf_wm_s {
+               uint64_t reserved_5_63:59;
+               uint64_t wm:5;
+       } s;
+       struct cvmx_uctlx_ppaf_wm_s           cn63xx;
+       struct cvmx_uctlx_ppaf_wm_s           cn63xxp1;
+};
+
+union cvmx_uctlx_uphy_ctl_status {
+       uint64_t u64;
+       struct cvmx_uctlx_uphy_ctl_status_s {
+               uint64_t reserved_10_63:54;
+               uint64_t bist_done:1;
+               uint64_t bist_err:1;
+               uint64_t hsbist:1;
+               uint64_t fsbist:1;
+               uint64_t lsbist:1;
+               uint64_t siddq:1;
+               uint64_t vtest_en:1;
+               uint64_t uphy_bist:1;
+               uint64_t bist_en:1;
+               uint64_t ate_reset:1;
+       } s;
+       struct cvmx_uctlx_uphy_ctl_status_s   cn63xx;
+       struct cvmx_uctlx_uphy_ctl_status_s   cn63xxp1;
+};
+
+union cvmx_uctlx_uphy_portx_ctl_status {
+       uint64_t u64;
+       struct cvmx_uctlx_uphy_portx_ctl_status_s {
+               uint64_t reserved_43_63:21;
+               uint64_t tdata_out:4;
+               uint64_t txbiststuffenh:1;
+               uint64_t txbiststuffen:1;
+               uint64_t dmpulldown:1;
+               uint64_t dppulldown:1;
+               uint64_t vbusvldext:1;
+               uint64_t portreset:1;
+               uint64_t txhsvxtune:2;
+               uint64_t txvreftune:4;
+               uint64_t txrisetune:1;
+               uint64_t txpreemphasistune:1;
+               uint64_t txfslstune:4;
+               uint64_t sqrxtune:3;
+               uint64_t compdistune:3;
+               uint64_t loop_en:1;
+               uint64_t tclk:1;
+               uint64_t tdata_sel:1;
+               uint64_t taddr_in:4;
+               uint64_t tdata_in:8;
+       } s;
+       struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xx;
+       struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xxp1;
+};
+
+#endif
index cf50336eca2e5bbef2b93975efe4203a08f7c3f1..700f88e31cad8a14b5a10741dc5b5c369bc75e27 100644 (file)
 #ifndef __OCTEON_MODEL_H__
 #define __OCTEON_MODEL_H__
 
-/* NOTE: These must match what is checked in common-config.mk */
-/* Defines to represent the different versions of Octeon.  */
-
-/*
- * IMPORTANT: When the default pass is updated for an Octeon Model,
- * the corresponding change must also be made in the oct-sim script.
- */
-
 /*
  * The defines below should be used with the OCTEON_IS_MODEL() macro
  * to determine what model of chip the software is running on.  Models
 #define OM_IGNORE_MINOR_REVISION  0x08000000
 #define OM_FLAG_MASK              0xff000000
 
+#define OM_MATCH_5XXX_FAMILY_MODELS     0x20000000 /* Match all cn5XXX Octeon models. */
+#define OM_MATCH_6XXX_FAMILY_MODELS     0x40000000 /* Match all cn6XXX Octeon models. */
+
+/*
+ * CN6XXX models with new revision encoding
+ */
+#define OCTEON_CN63XX_PASS1_0   0x000d9000
+#define OCTEON_CN63XX_PASS1_1   0x000d9001
+#define OCTEON_CN63XX_PASS1_2   0x000d9002
+#define OCTEON_CN63XX_PASS2_0   0x000d9008
+
+#define OCTEON_CN63XX           (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN63XX_PASS1_X   (OCTEON_CN63XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN63XX_PASS2_X   (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
+
 /*
  * CN5XXX models with new revision encoding
  */
                                 | OM_MATCH_PREVIOUS_MODELS \
                                 | OM_IGNORE_REVISION)
 
+#define OCTEON_CN5XXX           (OCTEON_CN58XX_PASS1_0 | OM_MATCH_5XXX_FAMILY_MODELS)
+#define OCTEON_CN6XXX           (OCTEON_CN63XX_PASS1_0 | OM_MATCH_6XXX_FAMILY_MODELS)
+
 /* The revision byte (low byte) has two different encodings.
  * CN3XXX:
  *
                                      | OCTEON_58XX_MODEL_MASK)
 #define OCTEON_58XX_MODEL_MINOR_REV_MASK (OCTEON_58XX_MODEL_REV_MASK \
                                          & 0x00fffff8)
+#define OCTEON_5XXX_MODEL_MASK       0x00ff0fc0
 
 #define __OCTEON_MATCH_MASK__(x, y, z) (((x) & (z)) == ((y) & (z)))
 
@@ -273,6 +284,15 @@ static inline int __OCTEON_IS_MODEL_COMPILE__(uint32_t arg_model,
                    __OCTEON_MATCH_MASK__((chip_model), (arg_model),
                                          OCTEON_58XX_MODEL_REV_MASK))
                        return 1;
+
+               if (((arg_model & OM_MATCH_5XXX_FAMILY_MODELS) == OM_MATCH_5XXX_FAMILY_MODELS) &&
+                   ((chip_model) >= OCTEON_CN58XX_PASS1_0) && ((chip_model) < OCTEON_CN63XX_PASS1_0))
+                       return 1;
+
+               if (((arg_model & OM_MATCH_6XXX_FAMILY_MODELS) == OM_MATCH_6XXX_FAMILY_MODELS) &&
+                   ((chip_model) >= OCTEON_CN63XX_PASS1_0))
+                       return 1;
+
                if ((arg_model & OM_MATCH_PREVIOUS_MODELS) &&
                    ((chip_model & OCTEON_58XX_MODEL_MASK) <
                            (arg_model & OCTEON_58XX_MODEL_MASK)))
index 917a6c413b1abfd511b1333e4b903be04c0809cf..6b34afd0d4e7d7ff7ec68f93a15e2d57c07059de 100644 (file)
@@ -35,6 +35,7 @@ extern int octeon_is_simulation(void);
 extern int octeon_is_pci_host(void);
 extern int octeon_usb_is_ref_clk(void);
 extern uint64_t octeon_get_clock_rate(void);
+extern u64 octeon_get_io_clock_rate(void);
 extern const char *octeon_board_type_string(void);
 extern const char *octeon_get_pci_interrupts(void);
 extern int octeon_get_southbridge_interrupt(void);
index ece78043acf6e0572e501f26a51cc16243da3c43..fba2ba200f587a885d559b71fbda755d2c92b5a9 100644 (file)
 extern int (*octeon_pcibios_map_irq)(const struct pci_dev *dev,
                                     u8 slot, u8 pin);
 
+/*
+ * For PCI (not PCIe) the BAR2 base address.
+ */
+#define OCTEON_BAR2_PCI_ADDRESS 0x8000000000ull
+
+/*
+ * For PCI (not PCIe) the base of the memory mapped by BAR1
+ */
+extern u64 octeon_bar1_pci_phys;
+
 /*
  * The following defines are used when octeon_dma_bar_type =
  * OCTEON_DMA_BAR_TYPE_BIG
diff --git a/arch/mips/include/asm/perf_event.h b/arch/mips/include/asm/perf_event.h
new file mode 100644 (file)
index 0000000..e00007c
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/mips/include/asm/perf_event.h
+ *
+ * Copyright (C) 2010 MIPS Technologies, Inc.
+ * Author: Deng-Cheng Zhu
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MIPS_PERF_EVENT_H__
+#define __MIPS_PERF_EVENT_H__
+
+/*
+ * MIPS performance counters do not raise NMI upon overflow, a regular
+ * interrupt will be signaled. Hence we can do the pending perf event
+ * work at the tail of the irq handler.
+ */
+static inline void
+set_perf_event_pending(void)
+{
+}
+
+#endif /* __MIPS_PERF_EVENT_H__ */
index f00896087ddab34b861ac6770e8166d9f2fa764a..55908fd56b1fc66ed5fe99d61bc54b8a243a1159 100644 (file)
 #endif
 #define PTRS_PER_PTE   ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
 
-#if PGDIR_SIZE >= TASK_SIZE
+#if PGDIR_SIZE >= TASK_SIZE64
 #define USER_PTRS_PER_PGD       (1)
 #else
-#define USER_PTRS_PER_PGD      (TASK_SIZE / PGDIR_SIZE)
+#define USER_PTRS_PER_PGD      (TASK_SIZE64 / PGDIR_SIZE)
 #endif
 #define FIRST_USER_ADDRESS     0UL
 
index 0d629bb93cbe1abc175ef5adcd7976e5d424d52e..ead6928fa6b822f7671ddec1859bbd217e799b88 100644 (file)
@@ -50,13 +50,10 @@ extern unsigned int vced_count, vcei_count;
  * so don't change it unless you know what you are doing.
  */
 #define TASK_SIZE      0x7fff8000UL
-#define STACK_TOP      ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE     ((TASK_SIZE / 3) & ~(PAGE_SIZE))
+#ifdef __KERNEL__
+#define STACK_TOP_MAX  TASK_SIZE
+#endif
 
 #define TASK_IS_32BIT_ADDR 1
 
@@ -71,28 +68,29 @@ extern unsigned int vced_count, vcei_count;
  * 8192EB ...
  */
 #define TASK_SIZE32    0x7fff8000UL
-#define TASK_SIZE      0x10000000000UL
-#define STACK_TOP      \
-       (((test_thread_flag(TIF_32BIT_ADDR) ?                           \
-          TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
+#define TASK_SIZE64    0x10000000000UL
+#define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
+
+#ifdef __KERNEL__
+#define STACK_TOP_MAX  TASK_SIZE64
+#endif
+
 
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE                                             \
-       (test_thread_flag(TIF_32BIT_ADDR) ?                             \
-               PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3))
 #define TASK_SIZE_OF(tsk)                                              \
-       (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+       (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
 
 #define TASK_IS_32BIT_ADDR test_thread_flag(TIF_32BIT_ADDR)
 
 #endif
 
-#ifdef __KERNEL__
-#define STACK_TOP_MAX  TASK_SIZE
-#endif
+#define STACK_TOP      ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
+
 
 #define NUM_FPU_REGS   32
 
index bb937ccfba1ea92507214309cf21d8d54d03fd6e..6018c80ce37a0add5dde7a60d0979c397ea188be 100644 (file)
@@ -115,21 +115,19 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
        } else if (kernel_uses_llsc) {
                unsigned long dummy;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     ll      %0, %3                  # xchg_u32      \n"
-               "       .set    mips0                                   \n"
-               "       move    %2, %z4                                 \n"
-               "       .set    mips3                                   \n"
-               "       sc      %2, %1                                  \n"
-               "       beqz    %2, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (retval), "=m" (*m), "=&r" (dummy)
-               : "R" (*m), "Jr" (val)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       ll      %0, %3          # xchg_u32      \n"
+                       "       .set    mips0                           \n"
+                       "       move    %2, %z4                         \n"
+                       "       .set    mips3                           \n"
+                       "       sc      %2, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (retval), "=m" (*m), "=&r" (dummy)
+                       : "R" (*m), "Jr" (val)
+                       : "memory");
+               } while (unlikely(!dummy));
        } else {
                unsigned long flags;
 
@@ -167,19 +165,17 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
        } else if (kernel_uses_llsc) {
                unsigned long dummy;
 
-               __asm__ __volatile__(
-               "       .set    mips3                                   \n"
-               "1:     lld     %0, %3                  # xchg_u64      \n"
-               "       move    %2, %z4                                 \n"
-               "       scd     %2, %1                                  \n"
-               "       beqz    %2, 2f                                  \n"
-               "       .subsection 2                                   \n"
-               "2:     b       1b                                      \n"
-               "       .previous                                       \n"
-               "       .set    mips0                                   \n"
-               : "=&r" (retval), "=m" (*m), "=&r" (dummy)
-               : "R" (*m), "Jr" (val)
-               : "memory");
+               do {
+                       __asm__ __volatile__(
+                       "       .set    mips3                           \n"
+                       "       lld     %0, %3          # xchg_u64      \n"
+                       "       move    %2, %z4                         \n"
+                       "       scd     %2, %1                          \n"
+                       "       .set    mips0                           \n"
+                       : "=&r" (retval), "=m" (*m), "=&r" (dummy)
+                       : "R" (*m), "Jr" (val)
+                       : "memory");
+               } while (unlikely(!dummy));
        } else {
                unsigned long flags;
 
index 70df9c0d3c5be20e2d7b646460276a44374fc077..d309556cacf8ac9348f8068b99197673f570b772 100644 (file)
@@ -83,6 +83,8 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
 #define THREAD_MASK (THREAD_SIZE - 1UL)
 
+#define STACK_WARN     (THREAD_SIZE / 8)
+
 #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
 
 #ifdef CONFIG_DEBUG_STACK_USAGE
index c2d53c18fd3604c6829e25956d48fade7f0d1bfc..653a412c036ca7a6b372862d5ecc88a0038b1c89 100644 (file)
@@ -35,7 +35,9 @@
 
 #ifdef CONFIG_64BIT
 
-#define __UA_LIMIT     (- TASK_SIZE)
+extern u64 __ua_limit;
+
+#define __UA_LIMIT     __ua_limit
 
 #define __UA_ADDR      ".dword"
 #define __UA_LA                "dla"
index 80884983270de35d19253287e4a12deec60ebb06..22b2e0e386170cd1fba74d7fa6bc06bd90d74226 100644 (file)
@@ -104,4 +104,6 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT)       += 8250-platform.o
 
 obj-$(CONFIG_MIPS_CPUFREQ)     += cpufreq/
 
+obj-$(CONFIG_HW_PERF_EVENTS)   += perf_event.o
+
 CPPFLAGS_vmlinux.lds           := $(KBUILD_CFLAGS)
index b1b304ea21288414415ec02f9005ee6e5eec9b2e..71620e19827ad681a7834f0e400104cec4968ef2 100644 (file)
@@ -25,6 +25,8 @@
 #include <asm/system.h>
 #include <asm/watch.h>
 #include <asm/spram.h>
+#include <asm/uaccess.h>
+
 /*
  * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
  * the implementation of the "wait" feature differs between CPU families. This
@@ -181,12 +183,13 @@ void __init check_wait(void)
        case CPU_5KC:
        case CPU_25KF:
        case CPU_PR4450:
-       case CPU_BCM3302:
-       case CPU_BCM6338:
-       case CPU_BCM6348:
-       case CPU_BCM6358:
+       case CPU_BMIPS3300:
+       case CPU_BMIPS4350:
+       case CPU_BMIPS4380:
+       case CPU_BMIPS5000:
        case CPU_CAVIUM_OCTEON:
        case CPU_CAVIUM_OCTEON_PLUS:
+       case CPU_CAVIUM_OCTEON2:
        case CPU_JZRISC:
                cpu_wait = r4k_wait;
                break;
@@ -902,33 +905,37 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
 {
        decode_configs(c);
        switch (c->processor_id & 0xff00) {
-       case PRID_IMP_BCM3302:
-        /* same as PRID_IMP_BCM6338 */
-               c->cputype = CPU_BCM3302;
-               __cpu_name[cpu] = "Broadcom BCM3302";
-               break;
-       case PRID_IMP_BCM4710:
-               c->cputype = CPU_BCM4710;
-               __cpu_name[cpu] = "Broadcom BCM4710";
-               break;
-       case PRID_IMP_BCM6345:
-               c->cputype = CPU_BCM6345;
-               __cpu_name[cpu] = "Broadcom BCM6345";
+       case PRID_IMP_BMIPS32:
+               c->cputype = CPU_BMIPS32;
+               __cpu_name[cpu] = "Broadcom BMIPS32";
+               break;
+       case PRID_IMP_BMIPS3300:
+       case PRID_IMP_BMIPS3300_ALT:
+       case PRID_IMP_BMIPS3300_BUG:
+               c->cputype = CPU_BMIPS3300;
+               __cpu_name[cpu] = "Broadcom BMIPS3300";
+               break;
+       case PRID_IMP_BMIPS43XX: {
+               int rev = c->processor_id & 0xff;
+
+               if (rev >= PRID_REV_BMIPS4380_LO &&
+                               rev <= PRID_REV_BMIPS4380_HI) {
+                       c->cputype = CPU_BMIPS4380;
+                       __cpu_name[cpu] = "Broadcom BMIPS4380";
+               } else {
+                       c->cputype = CPU_BMIPS4350;
+                       __cpu_name[cpu] = "Broadcom BMIPS4350";
+               }
                break;
-       case PRID_IMP_BCM6348:
-               c->cputype = CPU_BCM6348;
-               __cpu_name[cpu] = "Broadcom BCM6348";
+       }
+       case PRID_IMP_BMIPS5000:
+               c->cputype = CPU_BMIPS5000;
+               __cpu_name[cpu] = "Broadcom BMIPS5000";
+               c->options |= MIPS_CPU_ULRI;
                break;
-       case PRID_IMP_BCM4350:
-               switch (c->processor_id & 0xf0) {
-               case PRID_REV_BCM6358:
-                       c->cputype = CPU_BCM6358;
-                       __cpu_name[cpu] = "Broadcom BCM6358";
-                       break;
-               default:
-                       c->cputype = CPU_UNKNOWN;
-                       break;
-               }
+       case PRID_IMP_BMIPS4KC:
+               c->cputype = CPU_4KC;
+               __cpu_name[cpu] = "MIPS 4Kc";
                break;
        }
 }
@@ -953,6 +960,12 @@ platform:
                if (cpu == 0)
                        __elf_platform = "octeon";
                break;
+       case PRID_IMP_CAVIUM_CN63XX:
+               c->cputype = CPU_CAVIUM_OCTEON2;
+               __cpu_name[cpu] = "Cavium Octeon II";
+               if (cpu == 0)
+                       __elf_platform = "octeon2";
+               break;
        default:
                printk(KERN_INFO "Unknown Octeon chip!\n");
                c->cputype = CPU_UNKNOWN;
@@ -976,6 +989,12 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
        }
 }
 
+#ifdef CONFIG_64BIT
+/* For use by uaccess.h */
+u64 __ua_limit;
+EXPORT_SYMBOL(__ua_limit);
+#endif
+
 const char *__cpu_name[NR_CPUS];
 const char *__elf_platform;
 
@@ -1053,6 +1072,11 @@ __cpuinit void cpu_probe(void)
                c->srsets = 1;
 
        cpu_probe_vmbits(c);
+
+#ifdef CONFIG_64BIT
+       if (cpu == 0)
+               __ua_limit = ~((1ull << cpu_vmbits) - 1);
+#endif
 }
 
 __cpuinit void cpu_report(void)
index c6345f579a8a4ea13d00251c4d47272b4afffa1d..4f93db58a79ed9bdbecb1ba53c0c3eed9261d2e6 100644 (file)
@@ -151,6 +151,29 @@ void __init init_IRQ(void)
 #endif
 }
 
+#ifdef DEBUG_STACKOVERFLOW
+static inline void check_stack_overflow(void)
+{
+       unsigned long sp;
+
+       __asm__ __volatile__("move %0, $sp" : "=r" (sp));
+       sp &= THREAD_MASK;
+
+       /*
+        * Check for stack overflow: is there less than STACK_WARN free?
+        * STACK_WARN is defined as 1/8 of THREAD_SIZE by default.
+        */
+       if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
+               printk("do_IRQ: stack overflow: %ld\n",
+                      sp - sizeof(struct thread_info));
+               dump_stack();
+       }
+}
+#else
+static inline void check_stack_overflow(void) {}
+#endif
+
+
 /*
  * do_IRQ handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
@@ -159,6 +182,7 @@ void __init init_IRQ(void)
 void __irq_entry do_IRQ(unsigned int irq)
 {
        irq_enter();
+       check_stack_overflow();
        __DO_IRQ_SMTC_HOOK(irq);
        generic_handle_irq(irq);
        irq_exit();
diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c
new file mode 100644 (file)
index 0000000..2b7f3f7
--- /dev/null
@@ -0,0 +1,601 @@
+/*
+ * Linux performance counter support for MIPS.
+ *
+ * Copyright (C) 2010 MIPS Technologies, Inc.
+ * Author: Deng-Cheng Zhu
+ *
+ * This code is based on the implementation for ARM, which is in turn
+ * based on the sparc64 perf event code and the x86 code. Performance
+ * counter access is based on the MIPS Oprofile code. And the callchain
+ * support references the code of MIPS stacktrace.c.
+ *
+ * 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 <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/uaccess.h>
+
+#include <asm/irq.h>
+#include <asm/irq_regs.h>
+#include <asm/stacktrace.h>
+#include <asm/time.h> /* For perf_irq */
+
+/* These are for 32bit counters. For 64bit ones, define them accordingly. */
+#define MAX_PERIOD     ((1ULL << 32) - 1)
+#define VALID_COUNT    0x7fffffff
+#define TOTAL_BITS     32
+#define HIGHEST_BIT    31
+
+#define MIPS_MAX_HWEVENTS 4
+
+struct cpu_hw_events {
+       /* Array of events on this cpu. */
+       struct perf_event       *events[MIPS_MAX_HWEVENTS];
+
+       /*
+        * Set the bit (indexed by the counter number) when the counter
+        * is used for an event.
+        */
+       unsigned long           used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
+
+       /*
+        * The borrowed MSB for the performance counter. A MIPS performance
+        * counter uses its bit 31 (for 32bit counters) or bit 63 (for 64bit
+        * counters) as a factor of determining whether a counter overflow
+        * should be signaled. So here we use a separate MSB for each
+        * counter to make things easy.
+        */
+       unsigned long           msbs[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
+
+       /*
+        * Software copy of the control register for each performance counter.
+        * MIPS CPUs vary in performance counters. They use this differently,
+        * and even may not use it.
+        */
+       unsigned int            saved_ctrl[MIPS_MAX_HWEVENTS];
+};
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
+       .saved_ctrl = {0},
+};
+
+/* The description of MIPS performance events. */
+struct mips_perf_event {
+       unsigned int event_id;
+       /*
+        * MIPS performance counters are indexed starting from 0.
+        * CNTR_EVEN indicates the indexes of the counters to be used are
+        * even numbers.
+        */
+       unsigned int cntr_mask;
+       #define CNTR_EVEN       0x55555555
+       #define CNTR_ODD        0xaaaaaaaa
+#ifdef CONFIG_MIPS_MT_SMP
+       enum {
+               T  = 0,
+               V  = 1,
+               P  = 2,
+       } range;
+#else
+       #define T
+       #define V
+       #define P
+#endif
+};
+
+static struct mips_perf_event raw_event;
+static DEFINE_MUTEX(raw_event_mutex);
+
+#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+struct mips_pmu {
+       const char      *name;
+       int             irq;
+       irqreturn_t     (*handle_irq)(int irq, void *dev);
+       int             (*handle_shared_irq)(void);
+       void            (*start)(void);
+       void            (*stop)(void);
+       int             (*alloc_counter)(struct cpu_hw_events *cpuc,
+                                       struct hw_perf_event *hwc);
+       u64             (*read_counter)(unsigned int idx);
+       void            (*write_counter)(unsigned int idx, u64 val);
+       void            (*enable_event)(struct hw_perf_event *evt, int idx);
+       void            (*disable_event)(int idx);
+       const struct mips_perf_event *(*map_raw_event)(u64 config);
+       const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX];
+       const struct mips_perf_event (*cache_event_map)
+                               [PERF_COUNT_HW_CACHE_MAX]
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+                               [PERF_COUNT_HW_CACHE_RESULT_MAX];
+       unsigned int    num_counters;
+};
+
+static const struct mips_pmu *mipspmu;
+
+static int
+mipspmu_event_set_period(struct perf_event *event,
+                       struct hw_perf_event *hwc,
+                       int idx)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       s64 left = local64_read(&hwc->period_left);
+       s64 period = hwc->sample_period;
+       int ret = 0;
+       u64 uleft;
+       unsigned long flags;
+
+       if (unlikely(left <= -period)) {
+               left = period;
+               local64_set(&hwc->period_left, left);
+               hwc->last_period = period;
+               ret = 1;
+       }
+
+       if (unlikely(left <= 0)) {
+               left += period;
+               local64_set(&hwc->period_left, left);
+               hwc->last_period = period;
+               ret = 1;
+       }
+
+       if (left > (s64)MAX_PERIOD)
+               left = MAX_PERIOD;
+
+       local64_set(&hwc->prev_count, (u64)-left);
+
+       local_irq_save(flags);
+       uleft = (u64)(-left) & MAX_PERIOD;
+       uleft > VALID_COUNT ?
+               set_bit(idx, cpuc->msbs) : clear_bit(idx, cpuc->msbs);
+       mipspmu->write_counter(idx, (u64)(-left) & VALID_COUNT);
+       local_irq_restore(flags);
+
+       perf_event_update_userpage(event);
+
+       return ret;
+}
+
+static int mipspmu_enable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+       int idx;
+       int err = 0;
+
+       /* To look for a free counter for this event. */
+       idx = mipspmu->alloc_counter(cpuc, hwc);
+       if (idx < 0) {
+               err = idx;
+               goto out;
+       }
+
+       /*
+        * If there is an event in the counter we are going to use then
+        * make sure it is disabled.
+        */
+       event->hw.idx = idx;
+       mipspmu->disable_event(idx);
+       cpuc->events[idx] = event;
+
+       /* Set the period for the event. */
+       mipspmu_event_set_period(event, hwc, idx);
+
+       /* Enable the event. */
+       mipspmu->enable_event(hwc, idx);
+
+       /* Propagate our changes to the userspace mapping. */
+       perf_event_update_userpage(event);
+
+out:
+       return err;
+}
+
+static void mipspmu_event_update(struct perf_event *event,
+                       struct hw_perf_event *hwc,
+                       int idx)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       unsigned long flags;
+       int shift = 64 - TOTAL_BITS;
+       s64 prev_raw_count, new_raw_count;
+       s64 delta;
+
+again:
+       prev_raw_count = local64_read(&hwc->prev_count);
+       local_irq_save(flags);
+       /* Make the counter value be a "real" one. */
+       new_raw_count = mipspmu->read_counter(idx);
+       if (new_raw_count & (test_bit(idx, cpuc->msbs) << HIGHEST_BIT)) {
+               new_raw_count &= VALID_COUNT;
+               clear_bit(idx, cpuc->msbs);
+       } else
+               new_raw_count |= (test_bit(idx, cpuc->msbs) << HIGHEST_BIT);
+       local_irq_restore(flags);
+
+       if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+                               new_raw_count) != prev_raw_count)
+               goto again;
+
+       delta = (new_raw_count << shift) - (prev_raw_count << shift);
+       delta >>= shift;
+
+       local64_add(delta, &event->count);
+       local64_sub(delta, &hwc->period_left);
+
+       return;
+}
+
+static void mipspmu_disable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+       int idx = hwc->idx;
+
+
+       WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+
+       /* We are working on a local event. */
+       mipspmu->disable_event(idx);
+
+       barrier();
+
+       mipspmu_event_update(event, hwc, idx);
+       cpuc->events[idx] = NULL;
+       clear_bit(idx, cpuc->used_mask);
+
+       perf_event_update_userpage(event);
+}
+
+static void mipspmu_unthrottle(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+
+       mipspmu->enable_event(hwc, hwc->idx);
+}
+
+static void mipspmu_read(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+
+       /* Don't read disabled counters! */
+       if (hwc->idx < 0)
+               return;
+
+       mipspmu_event_update(event, hwc, hwc->idx);
+}
+
+static struct pmu pmu = {
+       .enable         = mipspmu_enable,
+       .disable        = mipspmu_disable,
+       .unthrottle     = mipspmu_unthrottle,
+       .read           = mipspmu_read,
+};
+
+static atomic_t active_events = ATOMIC_INIT(0);
+static DEFINE_MUTEX(pmu_reserve_mutex);
+static int (*save_perf_irq)(void);
+
+static int mipspmu_get_irq(void)
+{
+       int err;
+
+       if (mipspmu->irq >= 0) {
+               /* Request my own irq handler. */
+               err = request_irq(mipspmu->irq, mipspmu->handle_irq,
+                       IRQF_DISABLED | IRQF_NOBALANCING,
+                       "mips_perf_pmu", NULL);
+               if (err) {
+                       pr_warning("Unable to request IRQ%d for MIPS "
+                          "performance counters!\n", mipspmu->irq);
+               }
+       } else if (cp0_perfcount_irq < 0) {
+               /*
+                * We are sharing the irq number with the timer interrupt.
+                */
+               save_perf_irq = perf_irq;
+               perf_irq = mipspmu->handle_shared_irq;
+               err = 0;
+       } else {
+               pr_warning("The platform hasn't properly defined its "
+                       "interrupt controller.\n");
+               err = -ENOENT;
+       }
+
+       return err;
+}
+
+static void mipspmu_free_irq(void)
+{
+       if (mipspmu->irq >= 0)
+               free_irq(mipspmu->irq, NULL);
+       else if (cp0_perfcount_irq < 0)
+               perf_irq = save_perf_irq;
+}
+
+static inline unsigned int
+mipspmu_perf_event_encode(const struct mips_perf_event *pev)
+{
+/*
+ * Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for
+ * event_id.
+ */
+#ifdef CONFIG_MIPS_MT_SMP
+       return ((unsigned int)pev->range << 24) |
+               (pev->cntr_mask & 0xffff00) |
+               (pev->event_id & 0xff);
+#else
+       return (pev->cntr_mask & 0xffff00) |
+               (pev->event_id & 0xff);
+#endif
+}
+
+static const struct mips_perf_event *
+mipspmu_map_general_event(int idx)
+{
+       const struct mips_perf_event *pev;
+
+       pev = ((*mipspmu->general_event_map)[idx].event_id ==
+               UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) :
+               &(*mipspmu->general_event_map)[idx]);
+
+       return pev;
+}
+
+static const struct mips_perf_event *
+mipspmu_map_cache_event(u64 config)
+{
+       unsigned int cache_type, cache_op, cache_result;
+       const struct mips_perf_event *pev;
+
+       cache_type = (config >> 0) & 0xff;
+       if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+               return ERR_PTR(-EINVAL);
+
+       cache_op = (config >> 8) & 0xff;
+       if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+               return ERR_PTR(-EINVAL);
+
+       cache_result = (config >> 16) & 0xff;
+       if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+               return ERR_PTR(-EINVAL);
+
+       pev = &((*mipspmu->cache_event_map)
+                                       [cache_type]
+                                       [cache_op]
+                                       [cache_result]);
+
+       if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID)
+               return ERR_PTR(-EOPNOTSUPP);
+
+       return pev;
+
+}
+
+static int validate_event(struct cpu_hw_events *cpuc,
+              struct perf_event *event)
+{
+       struct hw_perf_event fake_hwc = event->hw;
+
+       if (event->pmu && event->pmu != &pmu)
+               return 0;
+
+       return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0;
+}
+
+static int validate_group(struct perf_event *event)
+{
+       struct perf_event *sibling, *leader = event->group_leader;
+       struct cpu_hw_events fake_cpuc;
+
+       memset(&fake_cpuc, 0, sizeof(fake_cpuc));
+
+       if (!validate_event(&fake_cpuc, leader))
+               return -ENOSPC;
+
+       list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+               if (!validate_event(&fake_cpuc, sibling))
+                       return -ENOSPC;
+       }
+
+       if (!validate_event(&fake_cpuc, event))
+               return -ENOSPC;
+
+       return 0;
+}
+
+/*
+ * mipsxx/rm9000/loongson2 have different performance counters, they have
+ * specific low-level init routines.
+ */
+static void reset_counters(void *arg);
+static int __hw_perf_event_init(struct perf_event *event);
+
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+       if (atomic_dec_and_mutex_lock(&active_events,
+                               &pmu_reserve_mutex)) {
+               /*
+                * We must not call the destroy function with interrupts
+                * disabled.
+                */
+               on_each_cpu(reset_counters,
+                       (void *)(long)mipspmu->num_counters, 1);
+               mipspmu_free_irq();
+               mutex_unlock(&pmu_reserve_mutex);
+       }
+}
+
+const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+       int err = 0;
+
+       if (!mipspmu || event->cpu >= nr_cpumask_bits ||
+               (event->cpu >= 0 && !cpu_online(event->cpu)))
+               return ERR_PTR(-ENODEV);
+
+       if (!atomic_inc_not_zero(&active_events)) {
+               if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) {
+                       atomic_dec(&active_events);
+                       return ERR_PTR(-ENOSPC);
+               }
+
+               mutex_lock(&pmu_reserve_mutex);
+               if (atomic_read(&active_events) == 0)
+                       err = mipspmu_get_irq();
+
+               if (!err)
+                       atomic_inc(&active_events);
+               mutex_unlock(&pmu_reserve_mutex);
+       }
+
+       if (err)
+               return ERR_PTR(err);
+
+       err = __hw_perf_event_init(event);
+       if (err)
+               hw_perf_event_destroy(event);
+
+       return err ? ERR_PTR(err) : &pmu;
+}
+
+void hw_perf_enable(void)
+{
+       if (mipspmu)
+               mipspmu->start();
+}
+
+void hw_perf_disable(void)
+{
+       if (mipspmu)
+               mipspmu->stop();
+}
+
+/* This is needed by specific irq handlers in perf_event_*.c */
+static void
+handle_associated_event(struct cpu_hw_events *cpuc,
+       int idx, struct perf_sample_data *data, struct pt_regs *regs)
+{
+       struct perf_event *event = cpuc->events[idx];
+       struct hw_perf_event *hwc = &event->hw;
+
+       mipspmu_event_update(event, hwc, idx);
+       data->period = event->hw.last_period;
+       if (!mipspmu_event_set_period(event, hwc, idx))
+               return;
+
+       if (perf_event_overflow(event, 0, data, regs))
+               mipspmu->disable_event(idx);
+}
+
+#include "perf_event_mipsxx.c"
+
+/* Callchain handling code. */
+static inline void
+callchain_store(struct perf_callchain_entry *entry,
+               u64 ip)
+{
+       if (entry->nr < PERF_MAX_STACK_DEPTH)
+               entry->ip[entry->nr++] = ip;
+}
+
+/*
+ * Leave userspace callchain empty for now. When we find a way to trace
+ * the user stack callchains, we add here.
+ */
+static void
+perf_callchain_user(struct pt_regs *regs,
+                   struct perf_callchain_entry *entry)
+{
+}
+
+static void save_raw_perf_callchain(struct perf_callchain_entry *entry,
+       unsigned long reg29)
+{
+       unsigned long *sp = (unsigned long *)reg29;
+       unsigned long addr;
+
+       while (!kstack_end(sp)) {
+               addr = *sp++;
+               if (__kernel_text_address(addr)) {
+                       callchain_store(entry, addr);
+                       if (entry->nr >= PERF_MAX_STACK_DEPTH)
+                               break;
+               }
+       }
+}
+
+static void
+perf_callchain_kernel(struct pt_regs *regs,
+                     struct perf_callchain_entry *entry)
+{
+       unsigned long sp = regs->regs[29];
+#ifdef CONFIG_KALLSYMS
+       unsigned long ra = regs->regs[31];
+       unsigned long pc = regs->cp0_epc;
+
+       callchain_store(entry, PERF_CONTEXT_KERNEL);
+       if (raw_show_trace || !__kernel_text_address(pc)) {
+               unsigned long stack_page =
+                       (unsigned long)task_stack_page(current);
+               if (stack_page && sp >= stack_page &&
+                   sp <= stack_page + THREAD_SIZE - 32)
+                       save_raw_perf_callchain(entry, sp);
+               return;
+       }
+       do {
+               callchain_store(entry, pc);
+               if (entry->nr >= PERF_MAX_STACK_DEPTH)
+                       break;
+               pc = unwind_stack(current, &sp, pc, &ra);
+       } while (pc);
+#else
+       callchain_store(entry, PERF_CONTEXT_KERNEL);
+       save_raw_perf_callchain(entry, sp);
+#endif
+}
+
+static void
+perf_do_callchain(struct pt_regs *regs,
+                 struct perf_callchain_entry *entry)
+{
+       int is_user;
+
+       if (!regs)
+               return;
+
+       is_user = user_mode(regs);
+
+       if (!current || !current->pid)
+               return;
+
+       if (is_user && current->state != TASK_RUNNING)
+               return;
+
+       if (!is_user) {
+               perf_callchain_kernel(regs, entry);
+               if (current->mm)
+                       regs = task_pt_regs(current);
+               else
+                       regs = NULL;
+       }
+       if (regs)
+               perf_callchain_user(regs, entry);
+}
+
+static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
+
+struct perf_callchain_entry *
+perf_callchain(struct pt_regs *regs)
+{
+       struct perf_callchain_entry *entry = &__get_cpu_var(pmc_irq_entry);
+
+       entry->nr = 0;
+       perf_do_callchain(regs, entry);
+       return entry;
+}
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
new file mode 100644 (file)
index 0000000..5c7c6fc
--- /dev/null
@@ -0,0 +1,1052 @@
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) || \
+    defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_SB1)
+
+#define M_CONFIG1_PC   (1 << 4)
+
+#define M_PERFCTL_EXL                  (1UL      <<  0)
+#define M_PERFCTL_KERNEL               (1UL      <<  1)
+#define M_PERFCTL_SUPERVISOR           (1UL      <<  2)
+#define M_PERFCTL_USER                 (1UL      <<  3)
+#define M_PERFCTL_INTERRUPT_ENABLE     (1UL      <<  4)
+#define M_PERFCTL_EVENT(event)         (((event) & 0x3ff)  << 5)
+#define M_PERFCTL_VPEID(vpe)           ((vpe)    << 16)
+#define M_PERFCTL_MT_EN(filter)                ((filter) << 20)
+#define    M_TC_EN_ALL                 M_PERFCTL_MT_EN(0)
+#define    M_TC_EN_VPE                 M_PERFCTL_MT_EN(1)
+#define    M_TC_EN_TC                  M_PERFCTL_MT_EN(2)
+#define M_PERFCTL_TCID(tcid)           ((tcid)   << 22)
+#define M_PERFCTL_WIDE                 (1UL      << 30)
+#define M_PERFCTL_MORE                 (1UL      << 31)
+
+#define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL |                \
+                                       M_PERFCTL_KERNEL |              \
+                                       M_PERFCTL_USER |                \
+                                       M_PERFCTL_SUPERVISOR |          \
+                                       M_PERFCTL_INTERRUPT_ENABLE)
+
+#ifdef CONFIG_MIPS_MT_SMP
+#define M_PERFCTL_CONFIG_MASK          0x3fff801f
+#else
+#define M_PERFCTL_CONFIG_MASK          0x1f
+#endif
+#define M_PERFCTL_EVENT_MASK           0xfe0
+
+#define M_COUNTER_OVERFLOW             (1UL      << 31)
+
+#ifdef CONFIG_MIPS_MT_SMP
+static int cpu_has_mipsmt_pertccounters;
+
+/*
+ * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because
+ * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs.
+ */
+#if defined(CONFIG_HW_PERF_EVENTS)
+#define vpe_id()       (cpu_has_mipsmt_pertccounters ? \
+                       0 : smp_processor_id())
+#else
+#define vpe_id()       (cpu_has_mipsmt_pertccounters ? \
+                       0 : cpu_data[smp_processor_id()].vpe_id)
+#endif
+
+/* Copied from op_model_mipsxx.c */
+static inline unsigned int vpe_shift(void)
+{
+       if (num_possible_cpus() > 1)
+               return 1;
+
+       return 0;
+}
+#else /* !CONFIG_MIPS_MT_SMP */
+#define vpe_id()       0
+
+static inline unsigned int vpe_shift(void)
+{
+       return 0;
+}
+#endif /* CONFIG_MIPS_MT_SMP */
+
+static inline unsigned int
+counters_total_to_per_cpu(unsigned int counters)
+{
+       return counters >> vpe_shift();
+}
+
+static inline unsigned int
+counters_per_cpu_to_total(unsigned int counters)
+{
+       return counters << vpe_shift();
+}
+
+#define __define_perf_accessors(r, n, np)                              \
+                                                                       \
+static inline unsigned int r_c0_ ## r ## n(void)                       \
+{                                                                      \
+       unsigned int cpu = vpe_id();                                    \
+                                                                       \
+       switch (cpu) {                                                  \
+       case 0:                                                         \
+               return read_c0_ ## r ## n();                            \
+       case 1:                                                         \
+               return read_c0_ ## r ## np();                           \
+       default:                                                        \
+               BUG();                                                  \
+       }                                                               \
+       return 0;                                                       \
+}                                                                      \
+                                                                       \
+static inline void w_c0_ ## r ## n(unsigned int value)                 \
+{                                                                      \
+       unsigned int cpu = vpe_id();                                    \
+                                                                       \
+       switch (cpu) {                                                  \
+       case 0:                                                         \
+               write_c0_ ## r ## n(value);                             \
+               return;                                                 \
+       case 1:                                                         \
+               write_c0_ ## r ## np(value);                            \
+               return;                                                 \
+       default:                                                        \
+               BUG();                                                  \
+       }                                                               \
+       return;                                                         \
+}                                                                      \
+
+__define_perf_accessors(perfcntr, 0, 2)
+__define_perf_accessors(perfcntr, 1, 3)
+__define_perf_accessors(perfcntr, 2, 0)
+__define_perf_accessors(perfcntr, 3, 1)
+
+__define_perf_accessors(perfctrl, 0, 2)
+__define_perf_accessors(perfctrl, 1, 3)
+__define_perf_accessors(perfctrl, 2, 0)
+__define_perf_accessors(perfctrl, 3, 1)
+
+static inline int __n_counters(void)
+{
+       if (!(read_c0_config1() & M_CONFIG1_PC))
+               return 0;
+       if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
+               return 1;
+       if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
+               return 2;
+       if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
+               return 3;
+
+       return 4;
+}
+
+static inline int n_counters(void)
+{
+       int counters;
+
+       switch (current_cpu_type()) {
+       case CPU_R10000:
+               counters = 2;
+               break;
+
+       case CPU_R12000:
+       case CPU_R14000:
+               counters = 4;
+               break;
+
+       default:
+               counters = __n_counters();
+       }
+
+       return counters;
+}
+
+static void reset_counters(void *arg)
+{
+       int counters = (int)(long)arg;
+       switch (counters) {
+       case 4:
+               w_c0_perfctrl3(0);
+               w_c0_perfcntr3(0);
+       case 3:
+               w_c0_perfctrl2(0);
+               w_c0_perfcntr2(0);
+       case 2:
+               w_c0_perfctrl1(0);
+               w_c0_perfcntr1(0);
+       case 1:
+               w_c0_perfctrl0(0);
+               w_c0_perfcntr0(0);
+       }
+}
+
+static inline u64
+mipsxx_pmu_read_counter(unsigned int idx)
+{
+       switch (idx) {
+       case 0:
+               return r_c0_perfcntr0();
+       case 1:
+               return r_c0_perfcntr1();
+       case 2:
+               return r_c0_perfcntr2();
+       case 3:
+               return r_c0_perfcntr3();
+       default:
+               WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
+               return 0;
+       }
+}
+
+static inline void
+mipsxx_pmu_write_counter(unsigned int idx, u64 val)
+{
+       switch (idx) {
+       case 0:
+               w_c0_perfcntr0(val);
+               return;
+       case 1:
+               w_c0_perfcntr1(val);
+               return;
+       case 2:
+               w_c0_perfcntr2(val);
+               return;
+       case 3:
+               w_c0_perfcntr3(val);
+               return;
+       }
+}
+
+static inline unsigned int
+mipsxx_pmu_read_control(unsigned int idx)
+{
+       switch (idx) {
+       case 0:
+               return r_c0_perfctrl0();
+       case 1:
+               return r_c0_perfctrl1();
+       case 2:
+               return r_c0_perfctrl2();
+       case 3:
+               return r_c0_perfctrl3();
+       default:
+               WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
+               return 0;
+       }
+}
+
+static inline void
+mipsxx_pmu_write_control(unsigned int idx, unsigned int val)
+{
+       switch (idx) {
+       case 0:
+               w_c0_perfctrl0(val);
+               return;
+       case 1:
+               w_c0_perfctrl1(val);
+               return;
+       case 2:
+               w_c0_perfctrl2(val);
+               return;
+       case 3:
+               w_c0_perfctrl3(val);
+               return;
+       }
+}
+
+#ifdef CONFIG_MIPS_MT_SMP
+static DEFINE_RWLOCK(pmuint_rwlock);
+#endif
+
+/* 24K/34K/1004K cores can share the same event map. */
+static const struct mips_perf_event mipsxxcore_event_map
+                               [PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P },
+       [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
+       [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID },
+       [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID },
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x02, CNTR_EVEN, T },
+       [PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T },
+       [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
+};
+
+/* 74K core has different branch event code. */
+static const struct mips_perf_event mipsxx74Kcore_event_map
+                               [PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P },
+       [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
+       [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID },
+       [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID },
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x27, CNTR_EVEN, T },
+       [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T },
+       [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
+};
+
+/* 24K/34K/1004K cores can share the same cache event map. */
+static const struct mips_perf_event mipsxxcore_cache_map
+                               [PERF_COUNT_HW_CACHE_MAX]
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+                               [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+       /*
+        * Like some other architectures (e.g. ARM), the performance
+        * counters don't differentiate between read and write
+        * accesses/misses, so this isn't strictly correct, but it's the
+        * best we can do. Writes and reads get combined.
+        */
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x0a, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x0b, CNTR_EVEN | CNTR_ODD, T },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x0a, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x0b, CNTR_EVEN | CNTR_ODD, T },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(L1I)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x09, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x09, CNTR_ODD, T },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x09, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x09, CNTR_ODD, T },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { 0x14, CNTR_EVEN, T },
+               /*
+                * Note that MIPS has only "hit" events countable for
+                * the prefetch operation.
+                */
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(LL)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x15, CNTR_ODD, P },
+               [C(RESULT_MISS)]        = { 0x16, CNTR_EVEN, P },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x15, CNTR_ODD, P },
+               [C(RESULT_MISS)]        = { 0x16, CNTR_EVEN, P },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(DTLB)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x06, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x06, CNTR_ODD, T },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x06, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x06, CNTR_ODD, T },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(ITLB)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x05, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x05, CNTR_ODD, T },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x05, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x05, CNTR_ODD, T },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(BPU)] = {
+       /* Using the same code for *HW_BRANCH* */
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x02, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x02, CNTR_ODD, T },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x02, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x02, CNTR_ODD, T },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+};
+
+/* 74K core has completely different cache event map. */
+static const struct mips_perf_event mipsxx74Kcore_cache_map
+                               [PERF_COUNT_HW_CACHE_MAX]
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+                               [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+       /*
+        * Like some other architectures (e.g. ARM), the performance
+        * counters don't differentiate between read and write
+        * accesses/misses, so this isn't strictly correct, but it's the
+        * best we can do. Writes and reads get combined.
+        */
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x17, CNTR_ODD, T },
+               [C(RESULT_MISS)]        = { 0x18, CNTR_ODD, T },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x17, CNTR_ODD, T },
+               [C(RESULT_MISS)]        = { 0x18, CNTR_ODD, T },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(L1I)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x06, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x06, CNTR_ODD, T },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x06, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x06, CNTR_ODD, T },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { 0x34, CNTR_EVEN, T },
+               /*
+                * Note that MIPS has only "hit" events countable for
+                * the prefetch operation.
+                */
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(LL)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x1c, CNTR_ODD, P },
+               [C(RESULT_MISS)]        = { 0x1d, CNTR_EVEN | CNTR_ODD, P },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x1c, CNTR_ODD, P },
+               [C(RESULT_MISS)]        = { 0x1d, CNTR_EVEN | CNTR_ODD, P },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(DTLB)] = {
+       /* 74K core does not have specific DTLB events. */
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(ITLB)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x04, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x04, CNTR_ODD, T },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x04, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x04, CNTR_ODD, T },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+[C(BPU)] = {
+       /* Using the same code for *HW_BRANCH* */
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x27, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x27, CNTR_ODD, T },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x27, CNTR_EVEN, T },
+               [C(RESULT_MISS)]        = { 0x27, CNTR_ODD, T },
+       },
+       [C(OP_PREFETCH)] = {
+               [C(RESULT_ACCESS)]      = { UNSUPPORTED_PERF_EVENT_ID },
+               [C(RESULT_MISS)]        = { UNSUPPORTED_PERF_EVENT_ID },
+       },
+},
+};
+
+#ifdef CONFIG_MIPS_MT_SMP
+static void
+check_and_calc_range(struct perf_event *event,
+                       const struct mips_perf_event *pev)
+{
+       struct hw_perf_event *hwc = &event->hw;
+
+       if (event->cpu >= 0) {
+               if (pev->range > V) {
+                       /*
+                        * The user selected an event that is processor
+                        * wide, while expecting it to be VPE wide.
+                        */
+                       hwc->config_base |= M_TC_EN_ALL;
+               } else {
+                       /*
+                        * FIXME: cpu_data[event->cpu].vpe_id reports 0
+                        * for both CPUs.
+                        */
+                       hwc->config_base |= M_PERFCTL_VPEID(event->cpu);
+                       hwc->config_base |= M_TC_EN_VPE;
+               }
+       } else
+               hwc->config_base |= M_TC_EN_ALL;
+}
+#else
+static void
+check_and_calc_range(struct perf_event *event,
+                       const struct mips_perf_event *pev)
+{
+}
+#endif
+
+static int __hw_perf_event_init(struct perf_event *event)
+{
+       struct perf_event_attr *attr = &event->attr;
+       struct hw_perf_event *hwc = &event->hw;
+       const struct mips_perf_event *pev;
+       int err;
+
+       /* Returning MIPS event descriptor for generic perf event. */
+       if (PERF_TYPE_HARDWARE == event->attr.type) {
+               if (event->attr.config >= PERF_COUNT_HW_MAX)
+                       return -EINVAL;
+               pev = mipspmu_map_general_event(event->attr.config);
+       } else if (PERF_TYPE_HW_CACHE == event->attr.type) {
+               pev = mipspmu_map_cache_event(event->attr.config);
+       } else if (PERF_TYPE_RAW == event->attr.type) {
+               /* We are working on the global raw event. */
+               mutex_lock(&raw_event_mutex);
+               pev = mipspmu->map_raw_event(event->attr.config);
+       } else {
+               /* The event type is not (yet) supported. */
+               return -EOPNOTSUPP;
+       }
+
+       if (IS_ERR(pev)) {
+               if (PERF_TYPE_RAW == event->attr.type)
+                       mutex_unlock(&raw_event_mutex);
+               return PTR_ERR(pev);
+       }
+
+       /*
+        * We allow max flexibility on how each individual counter shared
+        * by the single CPU operates (the mode exclusion and the range).
+        */
+       hwc->config_base = M_PERFCTL_INTERRUPT_ENABLE;
+
+       /* Calculate range bits and validate it. */
+       if (num_possible_cpus() > 1)
+               check_and_calc_range(event, pev);
+
+       hwc->event_base = mipspmu_perf_event_encode(pev);
+       if (PERF_TYPE_RAW == event->attr.type)
+               mutex_unlock(&raw_event_mutex);
+
+       if (!attr->exclude_user)
+               hwc->config_base |= M_PERFCTL_USER;
+       if (!attr->exclude_kernel) {
+               hwc->config_base |= M_PERFCTL_KERNEL;
+               /* MIPS kernel mode: KSU == 00b || EXL == 1 || ERL == 1 */
+               hwc->config_base |= M_PERFCTL_EXL;
+       }
+       if (!attr->exclude_hv)
+               hwc->config_base |= M_PERFCTL_SUPERVISOR;
+
+       hwc->config_base &= M_PERFCTL_CONFIG_MASK;
+       /*
+        * The event can belong to another cpu. We do not assign a local
+        * counter for it for now.
+        */
+       hwc->idx = -1;
+       hwc->config = 0;
+
+       if (!hwc->sample_period) {
+               hwc->sample_period  = MAX_PERIOD;
+               hwc->last_period    = hwc->sample_period;
+               local64_set(&hwc->period_left, hwc->sample_period);
+       }
+
+       err = 0;
+       if (event->group_leader != event) {
+               err = validate_group(event);
+               if (err)
+                       return -EINVAL;
+       }
+
+       event->destroy = hw_perf_event_destroy;
+
+       return err;
+}
+
+static void pause_local_counters(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int counters = mipspmu->num_counters;
+       unsigned long flags;
+
+       local_irq_save(flags);
+       switch (counters) {
+       case 4:
+               cpuc->saved_ctrl[3] = r_c0_perfctrl3();
+               w_c0_perfctrl3(cpuc->saved_ctrl[3] &
+                       ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+       case 3:
+               cpuc->saved_ctrl[2] = r_c0_perfctrl2();
+               w_c0_perfctrl2(cpuc->saved_ctrl[2] &
+                       ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+       case 2:
+               cpuc->saved_ctrl[1] = r_c0_perfctrl1();
+               w_c0_perfctrl1(cpuc->saved_ctrl[1] &
+                       ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+       case 1:
+               cpuc->saved_ctrl[0] = r_c0_perfctrl0();
+               w_c0_perfctrl0(cpuc->saved_ctrl[0] &
+                       ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+       }
+       local_irq_restore(flags);
+}
+
+static void resume_local_counters(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int counters = mipspmu->num_counters;
+       unsigned long flags;
+
+       local_irq_save(flags);
+       switch (counters) {
+       case 4:
+               w_c0_perfctrl3(cpuc->saved_ctrl[3]);
+       case 3:
+               w_c0_perfctrl2(cpuc->saved_ctrl[2]);
+       case 2:
+               w_c0_perfctrl1(cpuc->saved_ctrl[1]);
+       case 1:
+               w_c0_perfctrl0(cpuc->saved_ctrl[0]);
+       }
+       local_irq_restore(flags);
+}
+
+static int mipsxx_pmu_handle_shared_irq(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct perf_sample_data data;
+       unsigned int counters = mipspmu->num_counters;
+       unsigned int counter;
+       int handled = IRQ_NONE;
+       struct pt_regs *regs;
+
+       if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26)))
+               return handled;
+
+       /*
+        * First we pause the local counters, so that when we are locked
+        * here, the counters are all paused. When it gets locked due to
+        * perf_disable(), the timer interrupt handler will be delayed.
+        *
+        * See also mipsxx_pmu_start().
+        */
+       pause_local_counters();
+#ifdef CONFIG_MIPS_MT_SMP
+       read_lock(&pmuint_rwlock);
+#endif
+
+       regs = get_irq_regs();
+
+       perf_sample_data_init(&data, 0);
+
+       switch (counters) {
+#define HANDLE_COUNTER(n)                                              \
+       case n + 1:                                                     \
+               if (test_bit(n, cpuc->used_mask)) {                     \
+                       counter = r_c0_perfcntr ## n();                 \
+                       if (counter & M_COUNTER_OVERFLOW) {             \
+                               w_c0_perfcntr ## n(counter &            \
+                                               VALID_COUNT);           \
+                               if (test_and_change_bit(n, cpuc->msbs)) \
+                                       handle_associated_event(cpuc,   \
+                                               n, &data, regs);        \
+                               handled = IRQ_HANDLED;                  \
+                       }                                               \
+               }
+       HANDLE_COUNTER(3)
+       HANDLE_COUNTER(2)
+       HANDLE_COUNTER(1)
+       HANDLE_COUNTER(0)
+       }
+
+       /*
+        * Do all the work for the pending perf events. We can do this
+        * in here because the performance counter interrupt is a regular
+        * interrupt, not NMI.
+        */
+       if (handled == IRQ_HANDLED)
+               perf_event_do_pending();
+
+#ifdef CONFIG_MIPS_MT_SMP
+       read_unlock(&pmuint_rwlock);
+#endif
+       resume_local_counters();
+       return handled;
+}
+
+static irqreturn_t
+mipsxx_pmu_handle_irq(int irq, void *dev)
+{
+       return mipsxx_pmu_handle_shared_irq();
+}
+
+static void mipsxx_pmu_start(void)
+{
+#ifdef CONFIG_MIPS_MT_SMP
+       write_unlock(&pmuint_rwlock);
+#endif
+       resume_local_counters();
+}
+
+/*
+ * MIPS performance counters can be per-TC. The control registers can
+ * not be directly accessed accross CPUs. Hence if we want to do global
+ * control, we need cross CPU calls. on_each_cpu() can help us, but we
+ * can not make sure this function is called with interrupts enabled. So
+ * here we pause local counters and then grab a rwlock and leave the
+ * counters on other CPUs alone. If any counter interrupt raises while
+ * we own the write lock, simply pause local counters on that CPU and
+ * spin in the handler. Also we know we won't be switched to another
+ * CPU after pausing local counters and before grabbing the lock.
+ */
+static void mipsxx_pmu_stop(void)
+{
+       pause_local_counters();
+#ifdef CONFIG_MIPS_MT_SMP
+       write_lock(&pmuint_rwlock);
+#endif
+}
+
+static int
+mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc,
+                       struct hw_perf_event *hwc)
+{
+       int i;
+
+       /*
+        * We only need to care the counter mask. The range has been
+        * checked definitely.
+        */
+       unsigned long cntr_mask = (hwc->event_base >> 8) & 0xffff;
+
+       for (i = mipspmu->num_counters - 1; i >= 0; i--) {
+               /*
+                * Note that some MIPS perf events can be counted by both
+                * even and odd counters, wheresas many other are only by
+                * even _or_ odd counters. This introduces an issue that
+                * when the former kind of event takes the counter the
+                * latter kind of event wants to use, then the "counter
+                * allocation" for the latter event will fail. In fact if
+                * they can be dynamically swapped, they both feel happy.
+                * But here we leave this issue alone for now.
+                */
+               if (test_bit(i, &cntr_mask) &&
+                       !test_and_set_bit(i, cpuc->used_mask))
+                       return i;
+       }
+
+       return -EAGAIN;
+}
+
+static void
+mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       unsigned long flags;
+
+       WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+
+       local_irq_save(flags);
+       cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) |
+               (evt->config_base & M_PERFCTL_CONFIG_MASK) |
+               /* Make sure interrupt enabled. */
+               M_PERFCTL_INTERRUPT_ENABLE;
+       /*
+        * We do not actually let the counter run. Leave it until start().
+        */
+       local_irq_restore(flags);
+}
+
+static void
+mipsxx_pmu_disable_event(int idx)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       unsigned long flags;
+
+       WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+
+       local_irq_save(flags);
+       cpuc->saved_ctrl[idx] = mipsxx_pmu_read_control(idx) &
+               ~M_PERFCTL_COUNT_EVENT_WHENEVER;
+       mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]);
+       local_irq_restore(flags);
+}
+
+/* 24K */
+#define IS_UNSUPPORTED_24K_EVENT(r, b)                                 \
+       ((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 ||          \
+        (b) == 27 || (r) == 28 || (r) == 158 || (b) == 31 ||           \
+        (b) == 32 || (b) == 34 || (b) == 36 || (r) == 168 ||           \
+        (r) == 172 || (b) == 47 || ((b) >= 56 && (b) <= 63) ||         \
+        ((b) >= 68 && (b) <= 127))
+#define IS_BOTH_COUNTERS_24K_EVENT(b)                                  \
+       ((b) == 0 || (b) == 1 || (b) == 11)
+
+/* 34K */
+#define IS_UNSUPPORTED_34K_EVENT(r, b)                                 \
+       ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 36 ||           \
+        (b) == 38 || (r) == 175 || ((b) >= 56 && (b) <= 63) ||         \
+        ((b) >= 68 && (b) <= 127))
+#define IS_BOTH_COUNTERS_34K_EVENT(b)                                  \
+       ((b) == 0 || (b) == 1 || (b) == 11)
+#ifdef CONFIG_MIPS_MT_SMP
+#define IS_RANGE_P_34K_EVENT(r, b)                                     \
+       ((b) == 0 || (r) == 18 || (b) == 21 || (b) == 22 ||             \
+        (b) == 25 || (b) == 39 || (r) == 44 || (r) == 174 ||           \
+        (r) == 176 || ((b) >= 50 && (b) <= 55) ||                      \
+        ((b) >= 64 && (b) <= 67))
+#define IS_RANGE_V_34K_EVENT(r)        ((r) == 47)
+#endif
+
+/* 74K */
+#define IS_UNSUPPORTED_74K_EVENT(r, b)                                 \
+       ((r) == 5 || ((r) >= 135 && (r) <= 137) ||                      \
+        ((b) >= 10 && (b) <= 12) || (b) == 22 || (b) == 27 ||          \
+        (b) == 33 || (b) == 34 || ((b) >= 47 && (b) <= 49) ||          \
+        (r) == 178 || (b) == 55 || (b) == 57 || (b) == 60 ||           \
+        (b) == 61 || (r) == 62 || (r) == 191 ||                        \
+        ((b) >= 64 && (b) <= 127))
+#define IS_BOTH_COUNTERS_74K_EVENT(b)                                  \
+       ((b) == 0 || (b) == 1)
+
+/* 1004K */
+#define IS_UNSUPPORTED_1004K_EVENT(r, b)                               \
+       ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 38 ||           \
+        (r) == 175 || (b) == 63 || ((b) >= 68 && (b) <= 127))
+#define IS_BOTH_COUNTERS_1004K_EVENT(b)                                        \
+       ((b) == 0 || (b) == 1 || (b) == 11)
+#ifdef CONFIG_MIPS_MT_SMP
+#define IS_RANGE_P_1004K_EVENT(r, b)                                   \
+       ((b) == 0 || (r) == 18 || (b) == 21 || (b) == 22 ||             \
+        (b) == 25 || (b) == 36 || (b) == 39 || (r) == 44 ||            \
+        (r) == 174 || (r) == 176 || ((b) >= 50 && (b) <= 59) ||        \
+        (r) == 188 || (b) == 61 || (b) == 62 ||                        \
+        ((b) >= 64 && (b) <= 67))
+#define IS_RANGE_V_1004K_EVENT(r)      ((r) == 47)
+#endif
+
+/*
+ * User can use 0-255 raw events, where 0-127 for the events of even
+ * counters, and 128-255 for odd counters. Note that bit 7 is used to
+ * indicate the parity. So, for example, when user wants to take the
+ * Event Num of 15 for odd counters (by referring to the user manual),
+ * then 128 needs to be added to 15 as the input for the event config,
+ * i.e., 143 (0x8F) to be used.
+ */
+static const struct mips_perf_event *
+mipsxx_pmu_map_raw_event(u64 config)
+{
+       unsigned int raw_id = config & 0xff;
+       unsigned int base_id = raw_id & 0x7f;
+
+       switch (current_cpu_type()) {
+       case CPU_24K:
+               if (IS_UNSUPPORTED_24K_EVENT(raw_id, base_id))
+                       return ERR_PTR(-EOPNOTSUPP);
+               raw_event.event_id = base_id;
+               if (IS_BOTH_COUNTERS_24K_EVENT(base_id))
+                       raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+               else
+                       raw_event.cntr_mask =
+                               raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+               /*
+                * This is actually doing nothing. Non-multithreading
+                * CPUs will not check and calculate the range.
+                */
+               raw_event.range = P;
+#endif
+               break;
+       case CPU_34K:
+               if (IS_UNSUPPORTED_34K_EVENT(raw_id, base_id))
+                       return ERR_PTR(-EOPNOTSUPP);
+               raw_event.event_id = base_id;
+               if (IS_BOTH_COUNTERS_34K_EVENT(base_id))
+                       raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+               else
+                       raw_event.cntr_mask =
+                               raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+               if (IS_RANGE_P_34K_EVENT(raw_id, base_id))
+                       raw_event.range = P;
+               else if (unlikely(IS_RANGE_V_34K_EVENT(raw_id)))
+                       raw_event.range = V;
+               else
+                       raw_event.range = T;
+#endif
+               break;
+       case CPU_74K:
+               if (IS_UNSUPPORTED_74K_EVENT(raw_id, base_id))
+                       return ERR_PTR(-EOPNOTSUPP);
+               raw_event.event_id = base_id;
+               if (IS_BOTH_COUNTERS_74K_EVENT(base_id))
+                       raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+               else
+                       raw_event.cntr_mask =
+                               raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+               raw_event.range = P;
+#endif
+               break;
+       case CPU_1004K:
+               if (IS_UNSUPPORTED_1004K_EVENT(raw_id, base_id))
+                       return ERR_PTR(-EOPNOTSUPP);
+               raw_event.event_id = base_id;
+               if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
+                       raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+               else
+                       raw_event.cntr_mask =
+                               raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+               if (IS_RANGE_P_1004K_EVENT(raw_id, base_id))
+                       raw_event.range = P;
+               else if (unlikely(IS_RANGE_V_1004K_EVENT(raw_id)))
+                       raw_event.range = V;
+               else
+                       raw_event.range = T;
+#endif
+               break;
+       }
+
+       return &raw_event;
+}
+
+static struct mips_pmu mipsxxcore_pmu = {
+       .handle_irq = mipsxx_pmu_handle_irq,
+       .handle_shared_irq = mipsxx_pmu_handle_shared_irq,
+       .start = mipsxx_pmu_start,
+       .stop = mipsxx_pmu_stop,
+       .alloc_counter = mipsxx_pmu_alloc_counter,
+       .read_counter = mipsxx_pmu_read_counter,
+       .write_counter = mipsxx_pmu_write_counter,
+       .enable_event = mipsxx_pmu_enable_event,
+       .disable_event = mipsxx_pmu_disable_event,
+       .map_raw_event = mipsxx_pmu_map_raw_event,
+       .general_event_map = &mipsxxcore_event_map,
+       .cache_event_map = &mipsxxcore_cache_map,
+};
+
+static struct mips_pmu mipsxx74Kcore_pmu = {
+       .handle_irq = mipsxx_pmu_handle_irq,
+       .handle_shared_irq = mipsxx_pmu_handle_shared_irq,
+       .start = mipsxx_pmu_start,
+       .stop = mipsxx_pmu_stop,
+       .alloc_counter = mipsxx_pmu_alloc_counter,
+       .read_counter = mipsxx_pmu_read_counter,
+       .write_counter = mipsxx_pmu_write_counter,
+       .enable_event = mipsxx_pmu_enable_event,
+       .disable_event = mipsxx_pmu_disable_event,
+       .map_raw_event = mipsxx_pmu_map_raw_event,
+       .general_event_map = &mipsxx74Kcore_event_map,
+       .cache_event_map = &mipsxx74Kcore_cache_map,
+};
+
+static int __init
+init_hw_perf_events(void)
+{
+       int counters, irq;
+
+       pr_info("Performance counters: ");
+
+       counters = n_counters();
+       if (counters == 0) {
+               pr_cont("No available PMU.\n");
+               return -ENODEV;
+       }
+
+#ifdef CONFIG_MIPS_MT_SMP
+       cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19);
+       if (!cpu_has_mipsmt_pertccounters)
+               counters = counters_total_to_per_cpu(counters);
+#endif
+
+#ifdef MSC01E_INT_BASE
+       if (cpu_has_veic) {
+               /*
+                * Using platform specific interrupt controller defines.
+                */
+               irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
+       } else {
+#endif
+               if (cp0_perfcount_irq >= 0)
+                       irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
+               else
+                       irq = -1;
+#ifdef MSC01E_INT_BASE
+       }
+#endif
+
+       on_each_cpu(reset_counters, (void *)(long)counters, 1);
+
+       switch (current_cpu_type()) {
+       case CPU_24K:
+               mipsxxcore_pmu.name = "mips/24K";
+               mipsxxcore_pmu.num_counters = counters;
+               mipsxxcore_pmu.irq = irq;
+               mipspmu = &mipsxxcore_pmu;
+               break;
+       case CPU_34K:
+               mipsxxcore_pmu.name = "mips/34K";
+               mipsxxcore_pmu.num_counters = counters;
+               mipsxxcore_pmu.irq = irq;
+               mipspmu = &mipsxxcore_pmu;
+               break;
+       case CPU_74K:
+               mipsxx74Kcore_pmu.name = "mips/74K";
+               mipsxx74Kcore_pmu.num_counters = counters;
+               mipsxx74Kcore_pmu.irq = irq;
+               mipspmu = &mipsxx74Kcore_pmu;
+               break;
+       case CPU_1004K:
+               mipsxxcore_pmu.name = "mips/1004K";
+               mipsxxcore_pmu.num_counters = counters;
+               mipsxxcore_pmu.irq = irq;
+               mipspmu = &mipsxxcore_pmu;
+               break;
+       default:
+               pr_cont("Either hardware does not support performance "
+                       "counters, or not yet implemented.\n");
+               return -ENODEV;
+       }
+
+       if (mipspmu)
+               pr_cont("%s PMU enabled, %d counters available to each "
+                       "CPU, irq %d%s\n", mipspmu->name, counters, irq,
+                       irq < 0 ? " (share with timer interrupt)" : "");
+
+       return 0;
+}
+arch_initcall(init_hw_perf_events);
+
+#endif /* defined(CONFIG_CPU_MIPS32)... */
index a6b900f2962bb2dff92f93a4f53206a2c52bc812..acd3f2c49c069fa04af112d8c30dc008cf869351 100644 (file)
@@ -490,6 +490,7 @@ static void __init arch_mem_init(char **cmdline_p)
        bootmem_init();
        device_tree_init();
        sparse_init();
+       plat_swiotlb_setup();
        paging_init();
 }
 
index d053bf4759e417071760634656083151358ef23c..8e9fbe75894e5f5199618264fcddde6410d42dc7 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/notifier.h>
 #include <linux/kdb.h>
 #include <linux/irq.h>
+#include <linux/perf_event.h>
 
 #include <asm/bootinfo.h>
 #include <asm/branch.h>
@@ -576,10 +577,16 @@ static inline int simulate_sc(struct pt_regs *regs, unsigned int opcode)
  */
 static int simulate_llsc(struct pt_regs *regs, unsigned int opcode)
 {
-       if ((opcode & OPCODE) == LL)
+       if ((opcode & OPCODE) == LL) {
+               perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+                               1, 0, regs, 0);
                return simulate_ll(regs, opcode);
-       if ((opcode & OPCODE) == SC)
+       }
+       if ((opcode & OPCODE) == SC) {
+               perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+                               1, 0, regs, 0);
                return simulate_sc(regs, opcode);
+       }
 
        return -1;                      /* Must be something else ... */
 }
@@ -595,6 +602,8 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
        if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) {
                int rd = (opcode & RD) >> 11;
                int rt = (opcode & RT) >> 16;
+               perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+                               1, 0, regs, 0);
                switch (rd) {
                case 0:         /* CPU number */
                        regs->regs[rt] = smp_processor_id();
@@ -630,8 +639,11 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
 
 static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
 {
-       if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC)
+       if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC) {
+               perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+                               1, 0, regs, 0);
                return 0;
+       }
 
        return -1;                      /* Must be something else ... */
 }
@@ -1469,6 +1481,7 @@ void __cpuinit per_cpu_trap_init(void)
 {
        unsigned int cpu = smp_processor_id();
        unsigned int status_set = ST0_CU0;
+       unsigned int hwrena = cpu_hwrena_impl_bits;
 #ifdef CONFIG_MIPS_MT_SMTC
        int secondaryTC = 0;
        int bootTC = (cpu == 0);
@@ -1501,14 +1514,14 @@ void __cpuinit per_cpu_trap_init(void)
        change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
                         status_set);
 
-       if (cpu_has_mips_r2) {
-               unsigned int enable = 0x0000000f | cpu_hwrena_impl_bits;
+       if (cpu_has_mips_r2)
+               hwrena |= 0x0000000f;
 
-               if (!noulri && cpu_has_userlocal)
-                       enable |= (1 << 29);
+       if (!noulri && cpu_has_userlocal)
+               hwrena |= (1 << 29);
 
-               write_c0_hwrena(enable);
-       }
+       if (hwrena)
+               write_c0_hwrena(hwrena);
 
 #ifdef CONFIG_MIPS_MT_SMTC
        if (!secondaryTC) {
index 33d5a5ce4a29d56037a38abb346a99e0212c16c2..cfea1adfa1536dcb08302f9aa8ce3c279e37b7a9 100644 (file)
@@ -78,6 +78,8 @@
 #include <linux/smp.h>
 #include <linux/sched.h>
 #include <linux/debugfs.h>
+#include <linux/perf_event.h>
+
 #include <asm/asm.h>
 #include <asm/branch.h>
 #include <asm/byteorder.h>
@@ -109,6 +111,9 @@ static void emulate_load_store_insn(struct pt_regs *regs,
        unsigned long value;
        unsigned int res;
 
+       perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+                     1, 0, regs, 0);
+
        /*
         * This load never faults.
         */
@@ -511,6 +516,8 @@ asmlinkage void do_ade(struct pt_regs *regs)
        unsigned int __user *pc;
        mm_segment_t seg;
 
+       perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
+                       1, 0, regs, regs->cp0_badvaddr);
        /*
         * Did we catch a fault trying to load an instruction?
         * Or are we running in MIPS16 mode?
index c97ca69b94e05289752a42d814a1a37a8e248d7f..6e1b77fec7ea6da1c6236b67dcce54db06a54342 100644 (file)
@@ -20,7 +20,6 @@ config LEMOTE_FULOONG2E
        select SYS_SUPPORTS_LITTLE_ENDIAN
        select SYS_SUPPORTS_HIGHMEM
        select SYS_HAS_EARLY_PRINTK
-       select GENERIC_HARDIRQS_NO__DO_IRQ
        select GENERIC_ISA_DMA_SUPPORT_BROKEN
        select CPU_HAS_WB
        select LOONGSON_MC146818
@@ -40,7 +39,6 @@ config LEMOTE_MACH2F
        select CS5536
        select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
        select DMA_NONCOHERENT
-       select GENERIC_HARDIRQS_NO__DO_IRQ
        select GENERIC_ISA_DMA_SUPPORT_BROKEN
        select HW_HAS_PCI
        select I8259
index ec3faa413f3bb2d7dee3fc300d3291ba6cb729eb..b2ad1b0910ffb86d009dac8769310f30af3c3fcc 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/debugfs.h>
+#include <linux/perf_event.h>
 
 #include <asm/inst.h>
 #include <asm/bootinfo.h>
@@ -258,6 +259,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
        }
 
       emul:
+       perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+                       1, 0, xcp, 0);
        MIPS_FPU_EMU_INC_STATS(emulated);
        switch (MIPSInst_OPCODE(ir)) {
        case ldc1_op:{
index 0f9c488044d155aa0c9a7c262edfe6e1777d405e..16c4d256b76f3f7179e5a77b856bd3a7a3825a52 100644 (file)
@@ -181,10 +181,10 @@ static void __cpuinit probe_octeon(void)
        unsigned int config1;
        struct cpuinfo_mips *c = &current_cpu_data;
 
+       config1 = read_c0_config1();
        switch (c->cputype) {
        case CPU_CAVIUM_OCTEON:
        case CPU_CAVIUM_OCTEON_PLUS:
-               config1 = read_c0_config1();
                c->icache.linesz = 2 << ((config1 >> 19) & 7);
                c->icache.sets = 64 << ((config1 >> 22) & 7);
                c->icache.ways = 1 + ((config1 >> 16) & 7);
@@ -204,6 +204,20 @@ static void __cpuinit probe_octeon(void)
                c->options |= MIPS_CPU_PREFETCH;
                break;
 
+       case CPU_CAVIUM_OCTEON2:
+               c->icache.linesz = 2 << ((config1 >> 19) & 7);
+               c->icache.sets = 8;
+               c->icache.ways = 37;
+               c->icache.flags |= MIPS_CACHE_VTAG;
+               icache_size = c->icache.sets * c->icache.ways * c->icache.linesz;
+
+               c->dcache.linesz = 128;
+               c->dcache.ways = 32;
+               c->dcache.sets = 8;
+               dcache_size = c->dcache.sets * c->dcache.ways * c->dcache.linesz;
+               c->options |= MIPS_CPU_PREFETCH;
+               break;
+
        default:
                panic("Unsupported Cavium Networks CPU type\n");
                break;
index 6721ee2b1e8ba8308730f262898dc3c792730f49..b4923a75cb4b8c12354a3e0821797349db4cd0ef 100644 (file)
  *  o collapses to normal function call on UP kernels
  *  o collapses to normal function call on systems with a single shared
  *    primary cache.
+ *  o doesn't disable interrupts on the local CPU
  */
-static inline void r4k_on_each_cpu(void (*func) (void *info), void *info,
-                                   int wait)
+static inline void r4k_on_each_cpu(void (*func) (void *info), void *info)
 {
        preempt_disable();
 
 #if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
-       smp_call_function(func, info, wait);
+       smp_call_function(func, info, 1);
 #endif
        func(info);
        preempt_enable();
@@ -363,7 +363,7 @@ static inline void local_r4k___flush_cache_all(void * args)
 
 static void r4k___flush_cache_all(void)
 {
-       r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1);
+       r4k_on_each_cpu(local_r4k___flush_cache_all, NULL);
 }
 
 static inline int has_valid_asid(const struct mm_struct *mm)
@@ -410,7 +410,7 @@ static void r4k_flush_cache_range(struct vm_area_struct *vma,
        int exec = vma->vm_flags & VM_EXEC;
 
        if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
-               r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1);
+               r4k_on_each_cpu(local_r4k_flush_cache_range, vma);
 }
 
 static inline void local_r4k_flush_cache_mm(void * args)
@@ -442,7 +442,7 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
        if (!cpu_has_dc_aliases)
                return;
 
-       r4k_on_each_cpu(local_r4k_flush_cache_mm, mm, 1);
+       r4k_on_each_cpu(local_r4k_flush_cache_mm, mm);
 }
 
 struct flush_cache_page_args {
@@ -534,7 +534,7 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma,
        args.addr = addr;
        args.pfn = pfn;
 
-       r4k_on_each_cpu(local_r4k_flush_cache_page, &args, 1);
+       r4k_on_each_cpu(local_r4k_flush_cache_page, &args);
 }
 
 static inline void local_r4k_flush_data_cache_page(void * addr)
@@ -547,8 +547,7 @@ static void r4k_flush_data_cache_page(unsigned long addr)
        if (in_atomic())
                local_r4k_flush_data_cache_page((void *)addr);
        else
-               r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr,
-                               1);
+               r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr);
 }
 
 struct flush_icache_range_args {
@@ -589,7 +588,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
        args.start = start;
        args.end = end;
 
-       r4k_on_each_cpu(local_r4k_flush_icache_range_ipi, &args, 1);
+       r4k_on_each_cpu(local_r4k_flush_icache_range_ipi, &args);
        instruction_hazard();
 }
 
@@ -710,7 +709,7 @@ static void local_r4k_flush_cache_sigtramp(void * arg)
 
 static void r4k_flush_cache_sigtramp(unsigned long addr)
 {
-       r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr, 1);
+       r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr);
 }
 
 static void r4k_flush_icache_all(void)
index 469d4019f795bd072b0aa4ba109d075b5377f55c..4fc1a0fbe0074e154c64a89f8f40d90bd6e1bd91 100644 (file)
@@ -95,10 +95,9 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
 
        return ret;
 }
-
 EXPORT_SYMBOL(dma_alloc_noncoherent);
 
-void *dma_alloc_coherent(struct device *dev, size_t size,
+static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
        dma_addr_t * dma_handle, gfp_t gfp)
 {
        void *ret;
@@ -123,7 +122,6 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
        return ret;
 }
 
-EXPORT_SYMBOL(dma_alloc_coherent);
 
 void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
        dma_addr_t dma_handle)
@@ -131,10 +129,9 @@ void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
        plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
        free_pages((unsigned long) vaddr, get_order(size));
 }
-
 EXPORT_SYMBOL(dma_free_noncoherent);
 
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
        dma_addr_t dma_handle)
 {
        unsigned long addr = (unsigned long) vaddr;
@@ -151,8 +148,6 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
        free_pages(addr, get_order(size));
 }
 
-EXPORT_SYMBOL(dma_free_coherent);
-
 static inline void __dma_sync(unsigned long addr, size_t size,
        enum dma_data_direction direction)
 {
@@ -174,21 +169,8 @@ static inline void __dma_sync(unsigned long addr, size_t size,
        }
 }
 
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-       enum dma_data_direction direction)
-{
-       unsigned long addr = (unsigned long) ptr;
-
-       if (!plat_device_is_coherent(dev))
-               __dma_sync(addr, size, direction);
-
-       return plat_map_dma_mem(dev, ptr, size);
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-       enum dma_data_direction direction)
+static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
+       size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        if (cpu_is_noncoherent_r10000(dev))
                __dma_sync(dma_addr_to_virt(dev, dma_addr), size,
@@ -197,15 +179,11 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
        plat_unmap_dma_mem(dev, dma_addr, size, direction);
 }
 
-EXPORT_SYMBOL(dma_unmap_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-       enum dma_data_direction direction)
+static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg,
+       int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        int i;
 
-       BUG_ON(direction == DMA_NONE);
-
        for (i = 0; i < nents; i++, sg++) {
                unsigned long addr;
 
@@ -219,33 +197,27 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        return nents;
 }
 
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
+static dma_addr_t mips_dma_map_page(struct device *dev, struct page *page,
+       unsigned long offset, size_t size, enum dma_data_direction direction,
+       struct dma_attrs *attrs)
 {
-       BUG_ON(direction == DMA_NONE);
+       unsigned long addr;
 
-       if (!plat_device_is_coherent(dev)) {
-               unsigned long addr;
+       addr = (unsigned long) page_address(page) + offset;
 
-               addr = (unsigned long) page_address(page) + offset;
+       if (!plat_device_is_coherent(dev))
                __dma_sync(addr, size, direction);
-       }
 
-       return plat_map_dma_mem_page(dev, page) + offset;
+       return plat_map_dma_mem(dev, (void *)addr, size);
 }
 
-EXPORT_SYMBOL(dma_map_page);
-
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-       enum dma_data_direction direction)
+static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+       int nhwentries, enum dma_data_direction direction,
+       struct dma_attrs *attrs)
 {
        unsigned long addr;
        int i;
 
-       BUG_ON(direction == DMA_NONE);
-
        for (i = 0; i < nhwentries; i++, sg++) {
                if (!plat_device_is_coherent(dev) &&
                    direction != DMA_TO_DEVICE) {
@@ -257,13 +229,9 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
        }
 }
 
-EXPORT_SYMBOL(dma_unmap_sg);
-
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction)
+static void mips_dma_sync_single_for_cpu(struct device *dev,
+       dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
 {
-       BUG_ON(direction == DMA_NONE);
-
        if (cpu_is_noncoherent_r10000(dev)) {
                unsigned long addr;
 
@@ -272,13 +240,9 @@ void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
        }
 }
 
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction)
+static void mips_dma_sync_single_for_device(struct device *dev,
+       dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
 {
-       BUG_ON(direction == DMA_NONE);
-
        plat_extra_sync_for_device(dev);
        if (!plat_device_is_coherent(dev)) {
                unsigned long addr;
@@ -288,46 +252,11 @@ void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
        }
 }
 
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       if (cpu_is_noncoherent_r10000(dev)) {
-               unsigned long addr;
-
-               addr = dma_addr_to_virt(dev, dma_handle);
-               __dma_sync(addr + offset, size, direction);
-       }
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       plat_extra_sync_for_device(dev);
-       if (!plat_device_is_coherent(dev)) {
-               unsigned long addr;
-
-               addr = dma_addr_to_virt(dev, dma_handle);
-               __dma_sync(addr + offset, size, direction);
-       }
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
-
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-       enum dma_data_direction direction)
+static void mips_dma_sync_sg_for_cpu(struct device *dev,
+       struct scatterlist *sg, int nelems, enum dma_data_direction direction)
 {
        int i;
 
-       BUG_ON(direction == DMA_NONE);
-
        /* Make sure that gcc doesn't leave the empty loop body.  */
        for (i = 0; i < nelems; i++, sg++) {
                if (cpu_is_noncoherent_r10000(dev))
@@ -336,15 +265,11 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
        }
 }
 
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-       enum dma_data_direction direction)
+static void mips_dma_sync_sg_for_device(struct device *dev,
+       struct scatterlist *sg, int nelems, enum dma_data_direction direction)
 {
        int i;
 
-       BUG_ON(direction == DMA_NONE);
-
        /* Make sure that gcc doesn't leave the empty loop body.  */
        for (i = 0; i < nelems; i++, sg++) {
                if (!plat_device_is_coherent(dev))
@@ -353,24 +278,18 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
        }
 }
 
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-
-int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
        return plat_dma_mapping_error(dev, dma_addr);
 }
 
-EXPORT_SYMBOL(dma_mapping_error);
-
-int dma_supported(struct device *dev, u64 mask)
+int mips_dma_supported(struct device *dev, u64 mask)
 {
        return plat_dma_supported(dev, mask);
 }
 
-EXPORT_SYMBOL(dma_supported);
-
-void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-              enum dma_data_direction direction)
+void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+                        enum dma_data_direction direction)
 {
        BUG_ON(direction == DMA_NONE);
 
@@ -379,4 +298,30 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                __dma_sync((unsigned long)vaddr, size, direction);
 }
 
-EXPORT_SYMBOL(dma_cache_sync);
+static struct dma_map_ops mips_default_dma_map_ops = {
+       .alloc_coherent = mips_dma_alloc_coherent,
+       .free_coherent = mips_dma_free_coherent,
+       .map_page = mips_dma_map_page,
+       .unmap_page = mips_dma_unmap_page,
+       .map_sg = mips_dma_map_sg,
+       .unmap_sg = mips_dma_unmap_sg,
+       .sync_single_for_cpu = mips_dma_sync_single_for_cpu,
+       .sync_single_for_device = mips_dma_sync_single_for_device,
+       .sync_sg_for_cpu = mips_dma_sync_sg_for_cpu,
+       .sync_sg_for_device = mips_dma_sync_sg_for_device,
+       .mapping_error = mips_dma_mapping_error,
+       .dma_supported = mips_dma_supported
+};
+
+struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
+EXPORT_SYMBOL(mips_dma_map_ops);
+
+#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
+
+static int __init mips_dma_init(void)
+{
+       dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+       return 0;
+}
+fs_initcall(mips_dma_init);
index 783ad0065fdf49e8c35df2499e8fc7eca9b59ef4..137ee76a0045c2cc51629a07bbaf1deb382a1451 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/smp.h>
 #include <linux/module.h>
 #include <linux/kprobes.h>
+#include <linux/perf_event.h>
 
 #include <asm/branch.h>
 #include <asm/mmu_context.h>
@@ -144,6 +145,7 @@ good_area:
         * the fault.
         */
        fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
+       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
        if (unlikely(fault & VM_FAULT_ERROR)) {
                if (fault & VM_FAULT_OOM)
                        goto out_of_memory;
@@ -151,10 +153,15 @@ good_area:
                        goto do_sigbus;
                BUG();
        }
-       if (fault & VM_FAULT_MAJOR)
+       if (fault & VM_FAULT_MAJOR) {
+               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
+                               1, 0, regs, address);
                tsk->maj_flt++;
-       else
+       } else {
+               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
+                               1, 0, regs, address);
                tsk->min_flt++;
+       }
 
        up_read(&mm->mmap_sem);
        return;
index 5ab5fa8c1d8229659a4ba30f204943e5fcf70416..505fecad4684f272b7a00d6dd8e3f3098875df4c 100644 (file)
@@ -57,6 +57,34 @@ static struct bcache_ops mips_sc_ops = {
        .bc_inv = mips_sc_inv
 };
 
+/*
+ * Check if the L2 cache controller is activated on a particular platform.
+ * MTI's L2 controller and the L2 cache controller of Broadcom's BMIPS
+ * cores both use c0_config2's bit 12 as "L2 Bypass" bit, that is the
+ * cache being disabled.  However there is no guarantee for this to be
+ * true on all platforms.  In an act of stupidity the spec defined bits
+ * 12..15 as implementation defined so below function will eventually have
+ * to be replaced by a platform specific probe.
+ */
+static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
+{
+       /* Check the bypass bit (L2B) */
+       switch (c->cputype) {
+       case CPU_34K:
+       case CPU_74K:
+       case CPU_1004K:
+       case CPU_BMIPS5000:
+               if (config2 & (1 << 12))
+                       return 0;
+       }
+
+       tmp = (config2 >> 4) & 0x0f;
+       if (0 < tmp && tmp <= 7)
+               c->scache.linesz = 2 << tmp;
+       else
+               return 0;
+}
+
 static inline int __init mips_sc_probe(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
@@ -79,10 +107,8 @@ static inline int __init mips_sc_probe(void)
                return 0;
 
        config2 = read_c0_config2();
-       tmp = (config2 >> 4) & 0x0f;
-       if (0 < tmp && tmp <= 7)
-               c->scache.linesz = 2 << tmp;
-       else
+
+       if (!mips_sc_is_activated(c))
                return 0;
 
        tmp = (config2 >> 8) & 0x0f;
index 4510e61883eb2b8df22ea6e62f1bf13f4de1cc0d..93816f3bca67f79b1f5b6aeb028487c6d06e67ec 100644 (file)
@@ -338,13 +338,12 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
        case CPU_4KSC:
        case CPU_20KC:
        case CPU_25KF:
-       case CPU_BCM3302:
-       case CPU_BCM4710:
+       case CPU_BMIPS32:
+       case CPU_BMIPS3300:
+       case CPU_BMIPS4350:
+       case CPU_BMIPS4380:
+       case CPU_BMIPS5000:
        case CPU_LOONGSON2:
-       case CPU_BCM6338:
-       case CPU_BCM6345:
-       case CPU_BCM6348:
-       case CPU_BCM6358:
        case CPU_R5500:
                if (m4kc_tlbp_war())
                        uasm_i_nop(p);
index d2647a4e012bbaf2b7bdbeae1e581ea5f1d02e37..23afdebc8e5cf2db134af1d6e9d0df3f0f2dea38 100644 (file)
@@ -405,7 +405,6 @@ I_u1u2u3(_mfc0)
 I_u1u2u3(_mtc0)
 I_u2u1u3(_ori)
 I_u3u1u2(_or)
-I_u2s3u1(_pref)
 I_0(_rfe)
 I_u2s3u1(_sc)
 I_u2s3u1(_scd)
@@ -427,6 +426,25 @@ I_u1(_syscall);
 I_u1u2s3(_bbit0);
 I_u1u2s3(_bbit1);
 
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#include <asm/octeon/octeon.h>
+void __uasminit uasm_i_pref(u32 **buf, unsigned int a, signed int b,
+                           unsigned int c)
+{
+       if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5)
+               /*
+                * As per erratum Core-14449, replace prefetches 0-4,
+                * 6-24 with 'pref 28'.
+                */
+               build_insn(buf, insn_pref, c, 28, b);
+       else
+               build_insn(buf, insn_pref, c, a, b);
+}
+UASM_EXPORT_SYMBOL(uasm_i_pref);
+#else
+I_u2s3u1(_pref)
+#endif
+
 /* Handle labels. */
 void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
 {
index d248b707eff3c02c00f2b62eca1b8fa0d88782a4..2d74fc9ae3bae7c4bfb430639b6bf817a6789607 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/interrupt.h>
 #include <linux/time.h>
 #include <linux/delay.h>
+#include <linux/swiotlb.h>
 
 #include <asm/time.h>
 
@@ -19,6 +20,8 @@
 #include <asm/octeon/cvmx-pci-defs.h>
 #include <asm/octeon/pci-octeon.h>
 
+#include <dma-coherence.h>
+
 #define USE_OCTEON_INTERNAL_ARBITER
 
 /*
@@ -32,6 +35,8 @@
 /* Octeon't PCI controller uses did=3, subdid=3 for PCI memory. */
 #define OCTEON_PCI_MEMSPACE_OFFSET  (0x00011b0000000000ull)
 
+u64 octeon_bar1_pci_phys;
+
 /**
  * This is the bit decoding used for the Octeon PCI controller addresses
  */
@@ -170,6 +175,8 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
                pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
        }
 
+       dev->dev.archdata.dma_ops = octeon_pci_dma_map_ops;
+
        return 0;
 }
 
@@ -618,12 +625,10 @@ static int __init octeon_pci_setup(void)
         * before the readl()'s below. We don't want BAR2 overlapping
         * with BAR0/BAR1 during these reads.
         */
-       octeon_npi_write32(CVMX_NPI_PCI_CFG08, 0);
-       octeon_npi_write32(CVMX_NPI_PCI_CFG09, 0x80);
-
-       /* Disable the BAR1 movable mappings */
-       for (index = 0; index < 32; index++)
-               octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
+       octeon_npi_write32(CVMX_NPI_PCI_CFG08,
+                          (u32)(OCTEON_BAR2_PCI_ADDRESS & 0xffffffffull));
+       octeon_npi_write32(CVMX_NPI_PCI_CFG09,
+                          (u32)(OCTEON_BAR2_PCI_ADDRESS >> 32));
 
        if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) {
                /* Remap the Octeon BAR 0 to 0-2GB */
@@ -637,6 +642,25 @@ static int __init octeon_pci_setup(void)
                octeon_npi_write32(CVMX_NPI_PCI_CFG06, 2ul << 30);
                octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
 
+               /* BAR1 movable mappings set for identity mapping */
+               octeon_bar1_pci_phys = 0x80000000ull;
+               for (index = 0; index < 32; index++) {
+                       union cvmx_pci_bar1_indexx bar1_index;
+
+                       bar1_index.u32 = 0;
+                       /* Address bits[35:22] sent to L2C */
+                       bar1_index.s.addr_idx =
+                               (octeon_bar1_pci_phys >> 22) + index;
+                       /* Don't put PCI accesses in L2. */
+                       bar1_index.s.ca = 1;
+                       /* Endian Swap Mode */
+                       bar1_index.s.end_swp = 1;
+                       /* Set '1' when the selected address range is valid. */
+                       bar1_index.s.addr_v = 1;
+                       octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
+                                          bar1_index.u32);
+               }
+
                /* Devices go after BAR1 */
                octeon_pci_mem_resource.start =
                        OCTEON_PCI_MEMSPACE_OFFSET + (4ul << 30) -
@@ -652,6 +676,27 @@ static int __init octeon_pci_setup(void)
                octeon_npi_write32(CVMX_NPI_PCI_CFG06, 0);
                octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
 
+               /* BAR1 movable regions contiguous to cover the swiotlb */
+               octeon_bar1_pci_phys =
+                       virt_to_phys(octeon_swiotlb) & ~((1ull << 22) - 1);
+
+               for (index = 0; index < 32; index++) {
+                       union cvmx_pci_bar1_indexx bar1_index;
+
+                       bar1_index.u32 = 0;
+                       /* Address bits[35:22] sent to L2C */
+                       bar1_index.s.addr_idx =
+                               (octeon_bar1_pci_phys >> 22) + index;
+                       /* Don't put PCI accesses in L2. */
+                       bar1_index.s.ca = 1;
+                       /* Endian Swap Mode */
+                       bar1_index.s.end_swp = 1;
+                       /* Set '1' when the selected address range is valid. */
+                       bar1_index.s.addr_v = 1;
+                       octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
+                                          bar1_index.u32);
+               }
+
                /* Devices go after BAR0 */
                octeon_pci_mem_resource.start =
                        OCTEON_PCI_MEMSPACE_OFFSET + (128ul << 20) +
@@ -667,6 +712,9 @@ static int __init octeon_pci_setup(void)
         * was setup properly.
         */
        cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1);
+
+       octeon_pci_dma_init();
+
        return 0;
 }
 
index 861361e0c9afc668f5914f67ea8351134ab56ecc..385f035b24e44e8ce65f6834bce67d68e771e21a 100644 (file)
@@ -75,6 +75,8 @@ union cvmx_pcie_address {
        } mem;
 };
 
+#include <dma-coherence.h>
+
 /**
  * Return the Core virtual base address for PCIe IO access. IOs are
  * read/written as an offset from this address.
@@ -1391,6 +1393,9 @@ static int __init octeon_pcie_setup(void)
                        cvmx_pcie_get_io_size(1) - 1;
                register_pci_controller(&octeon_pcie1_controller);
        }
+
+       octeon_pci_dma_init();
+
        return 0;
 }
 
index c7e40b37aa65c3f9abe6a636273c442c0c708033..b6447190e1a2acee2b6fddf9ef90bd5a3d0a1da9 100644 (file)
@@ -682,9 +682,12 @@ config 4xx_SOC
        bool
 
 config FSL_LBC
-       bool
+       bool "Freescale Local Bus support"
+       depends on FSL_SOC
        help
-         Freescale Localbus support
+         Enables reporting of errors from the Freescale local bus
+         controller.  Also contains some common code used by
+         drivers for specific local bus peripherals.
 
 config FSL_GTM
        bool
index 1b5a21041f9bf96319a7de869005a3833f8666b6..5c1bf3466749563d2ee683b1a7c4dfef0903e0ea 100644 (file)
@@ -1,9 +1,10 @@
 /* Freescale Local Bus Controller
  *
- * Copyright (c) 2006-2007 Freescale Semiconductor
+ * Copyright © 2006-2007, 2010 Freescale Semiconductor
  *
  * Authors: Nick Spence <nick.spence@freescale.com>,
  *          Scott Wood <scottwood@freescale.com>
+ *          Jack Lan <jack.lan@freescale.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
@@ -26,6 +27,8 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <linux/io.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
 
 struct fsl_lbc_bank {
        __be32 br;             /**< Base Register  */
@@ -125,13 +128,23 @@ struct fsl_lbc_regs {
 #define LTESR_ATMW 0x00800000
 #define LTESR_ATMR 0x00400000
 #define LTESR_CS   0x00080000
+#define LTESR_UPM  0x00000002
 #define LTESR_CC   0x00000001
 #define LTESR_NAND_MASK (LTESR_FCT | LTESR_PAR | LTESR_CC)
+#define LTESR_MASK      (LTESR_BM | LTESR_FCT | LTESR_PAR | LTESR_WP \
+                        | LTESR_ATMW | LTESR_ATMR | LTESR_CS | LTESR_UPM \
+                        | LTESR_CC)
+#define LTESR_CLEAR    0xFFFFFFFF
+#define LTECCR_CLEAR   0xFFFFFFFF
+#define LTESR_STATUS   LTESR_MASK
+#define LTEIR_ENABLE   LTESR_MASK
+#define LTEDR_ENABLE   0x00000000
        __be32 ltedr;           /**< Transfer Error Disable Register */
        __be32 lteir;           /**< Transfer Error Interrupt Register */
        __be32 lteatr;          /**< Transfer Error Attributes Register */
        __be32 ltear;           /**< Transfer Error Address Register */
-       u8 res6[0xC];
+       __be32 lteccr;          /**< Transfer Error ECC Register */
+       u8 res6[0x8];
        __be32 lbcr;            /**< Configuration Register */
 #define LBCR_LDIS  0x80000000
 #define LBCR_LDIS_SHIFT    31
@@ -235,6 +248,7 @@ struct fsl_upm {
        int width;
 };
 
+extern u32 fsl_lbc_addr(phys_addr_t addr_base);
 extern int fsl_lbc_find(phys_addr_t addr_base);
 extern int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm);
 
@@ -265,7 +279,23 @@ static inline void fsl_upm_end_pattern(struct fsl_upm *upm)
                cpu_relax();
 }
 
+/* overview of the fsl lbc controller */
+
+struct fsl_lbc_ctrl {
+       /* device info */
+       struct device                   *dev;
+       struct fsl_lbc_regs __iomem     *regs;
+       int                             irq;
+       wait_queue_head_t               irq_wait;
+       spinlock_t                      lock;
+       void                            *nand;
+
+       /* status read from LTESR by irq handler */
+       unsigned int                    irq_status;
+};
+
 extern int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base,
                               u32 mar);
+extern struct fsl_lbc_ctrl *fsl_lbc_ctrl_dev;
 
 #endif /* __ASM_FSL_LBC_H */
index edd217006d270dc8ec112467d1d6fa048c8e0299..9db24e77b9f4bab53b471950b76ac626884e9960 100644 (file)
@@ -31,6 +31,7 @@ static inline void arch_kgdb_breakpoint(void)
        asm(".long 0x7d821008"); /* twge r2, r2 */
 }
 #define CACHE_FLUSH_IS_SAFE    1
+#define DBG_MAX_REG_NUM     70
 
 /* The number bytes of registers we have to save depends on a few
  * things.  For 64bit we default to not including vector registers and
index 7f61a3ac787c9ae6f848939d311d8a8756733cfa..7a9db64f3f0438f8bf366b9cb2244f1ef3178004 100644 (file)
@@ -194,40 +194,6 @@ static int kgdb_dabr_match(struct pt_regs *regs)
        ptr = (unsigned long *)ptr32; \
        } while (0)
 
-
-void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
-{
-       unsigned long *ptr = gdb_regs;
-       int reg;
-
-       memset(gdb_regs, 0, NUMREGBYTES);
-
-       for (reg = 0; reg < 32; reg++)
-               PACK64(ptr, regs->gpr[reg]);
-
-#ifdef CONFIG_FSL_BOOKE
-#ifdef CONFIG_SPE
-       for (reg = 0; reg < 32; reg++)
-               PACK64(ptr, current->thread.evr[reg]);
-#else
-       ptr += 32;
-#endif
-#else
-       /* fp registers not used by kernel, leave zero */
-       ptr += 32 * 8 / sizeof(long);
-#endif
-
-       PACK64(ptr, regs->nip);
-       PACK64(ptr, regs->msr);
-       PACK32(ptr, regs->ccr);
-       PACK64(ptr, regs->link);
-       PACK64(ptr, regs->ctr);
-       PACK32(ptr, regs->xer);
-
-       BUG_ON((unsigned long)ptr >
-              (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
-}
-
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 {
        struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp +
@@ -271,44 +237,140 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
               (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
 }
 
-#define UNPACK64(dest, ptr) do { dest = *(ptr++); } while (0)
+#define GDB_SIZEOF_REG sizeof(unsigned long)
+#define GDB_SIZEOF_REG_U32 sizeof(u32)
 
-#define UNPACK32(dest, ptr) do {       \
-       u32 *ptr32;                   \
-       ptr32 = (u32 *)ptr;           \
-       dest = *(ptr32++);            \
-       ptr = (unsigned long *)ptr32; \
-       } while (0)
+#ifdef CONFIG_FSL_BOOKE
+#define GDB_SIZEOF_FLOAT_REG sizeof(unsigned long)
+#else
+#define GDB_SIZEOF_FLOAT_REG sizeof(u64)
+#endif
 
-void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
 {
-       unsigned long *ptr = gdb_regs;
-       int reg;
-
-       for (reg = 0; reg < 32; reg++)
-               UNPACK64(regs->gpr[reg], ptr);
+       { "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[0]) },
+       { "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[1]) },
+       { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[2]) },
+       { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[3]) },
+       { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[4]) },
+       { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[5]) },
+       { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[6]) },
+       { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[7]) },
+       { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[8]) },
+       { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[9]) },
+       { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[10]) },
+       { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[11]) },
+       { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[12]) },
+       { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[13]) },
+       { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[14]) },
+       { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[15]) },
+       { "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[16]) },
+       { "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[17]) },
+       { "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[18]) },
+       { "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[19]) },
+       { "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[20]) },
+       { "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[21]) },
+       { "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[22]) },
+       { "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[23]) },
+       { "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[24]) },
+       { "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[25]) },
+       { "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[26]) },
+       { "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[27]) },
+       { "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[28]) },
+       { "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[29]) },
+       { "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[30]) },
+       { "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[31]) },
+
+       { "f0", GDB_SIZEOF_FLOAT_REG, 0 },
+       { "f1", GDB_SIZEOF_FLOAT_REG, 1 },
+       { "f2", GDB_SIZEOF_FLOAT_REG, 2 },
+       { "f3", GDB_SIZEOF_FLOAT_REG, 3 },
+       { "f4", GDB_SIZEOF_FLOAT_REG, 4 },
+       { "f5", GDB_SIZEOF_FLOAT_REG, 5 },
+       { "f6", GDB_SIZEOF_FLOAT_REG, 6 },
+       { "f7", GDB_SIZEOF_FLOAT_REG, 7 },
+       { "f8", GDB_SIZEOF_FLOAT_REG, 8 },
+       { "f9", GDB_SIZEOF_FLOAT_REG, 9 },
+       { "f10", GDB_SIZEOF_FLOAT_REG, 10 },
+       { "f11", GDB_SIZEOF_FLOAT_REG, 11 },
+       { "f12", GDB_SIZEOF_FLOAT_REG, 12 },
+       { "f13", GDB_SIZEOF_FLOAT_REG, 13 },
+       { "f14", GDB_SIZEOF_FLOAT_REG, 14 },
+       { "f15", GDB_SIZEOF_FLOAT_REG, 15 },
+       { "f16", GDB_SIZEOF_FLOAT_REG, 16 },
+       { "f17", GDB_SIZEOF_FLOAT_REG, 17 },
+       { "f18", GDB_SIZEOF_FLOAT_REG, 18 },
+       { "f19", GDB_SIZEOF_FLOAT_REG, 19 },
+       { "f20", GDB_SIZEOF_FLOAT_REG, 20 },
+       { "f21", GDB_SIZEOF_FLOAT_REG, 21 },
+       { "f22", GDB_SIZEOF_FLOAT_REG, 22 },
+       { "f23", GDB_SIZEOF_FLOAT_REG, 23 },
+       { "f24", GDB_SIZEOF_FLOAT_REG, 24 },
+       { "f25", GDB_SIZEOF_FLOAT_REG, 25 },
+       { "f26", GDB_SIZEOF_FLOAT_REG, 26 },
+       { "f27", GDB_SIZEOF_FLOAT_REG, 27 },
+       { "f28", GDB_SIZEOF_FLOAT_REG, 28 },
+       { "f29", GDB_SIZEOF_FLOAT_REG, 29 },
+       { "f30", GDB_SIZEOF_FLOAT_REG, 30 },
+       { "f31", GDB_SIZEOF_FLOAT_REG, 31 },
+
+       { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, nip) },
+       { "msr", GDB_SIZEOF_REG, offsetof(struct pt_regs, msr) },
+       { "cr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ccr) },
+       { "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, link) },
+       { "ctr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ctr) },
+       { "xer", GDB_SIZEOF_REG, offsetof(struct pt_regs, xer) },
+};
 
-#ifdef CONFIG_FSL_BOOKE
-#ifdef CONFIG_SPE
-       for (reg = 0; reg < 32; reg++)
-               UNPACK64(current->thread.evr[reg], ptr);
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+       if (regno >= DBG_MAX_REG_NUM || regno < 0)
+               return NULL;
+
+       if (regno < 32 || regno >= 64)
+               /* First 0 -> 31 gpr registers*/
+               /* pc, msr, ls... registers 64 -> 69 */
+               memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+                               dbg_reg_def[regno].size);
+
+       if (regno >= 32 && regno < 64) {
+               /* FP registers 32 -> 63 */
+#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
+               if (current)
+                       memcpy(mem, current->thread.evr[regno-32],
+                                       dbg_reg_def[regno].size);
 #else
-       ptr += 32;
+               /* fp registers not used by kernel, leave zero */
+               memset(mem, 0, dbg_reg_def[regno].size);
 #endif
+       }
+
+       return dbg_reg_def[regno].name;
+}
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+       if (regno >= DBG_MAX_REG_NUM || regno < 0)
+               return -EINVAL;
+
+       if (regno < 32 || regno >= 64)
+               /* First 0 -> 31 gpr registers*/
+               /* pc, msr, ls... registers 64 -> 69 */
+               memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+                               dbg_reg_def[regno].size);
+
+       if (regno >= 32 && regno < 64) {
+               /* FP registers 32 -> 63 */
+#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
+               memcpy(current->thread.evr[regno-32], mem,
+                               dbg_reg_def[regno].size);
 #else
-       /* fp registers not used by kernel, leave zero */
-       ptr += 32 * 8 / sizeof(int);
+               /* fp registers not used by kernel, leave zero */
+               return 0;
 #endif
+       }
 
-       UNPACK64(regs->nip, ptr);
-       UNPACK64(regs->msr, ptr);
-       UNPACK32(regs->ccr, ptr);
-       UNPACK64(regs->link, ptr);
-       UNPACK64(regs->ctr, ptr);
-       UNPACK32(regs->xer, ptr);
-
-       BUG_ON((unsigned long)ptr >
-              (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
+       return 0;
 }
 
 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
index 428d0e538aec50880f23b8b097698572a2d2a01a..b06bdae04064f59d2c4c4c98e76304dee6ca98c8 100644 (file)
@@ -127,7 +127,7 @@ static void kvm_patch_ins_nop(u32 *inst)
 
 static void kvm_patch_ins_b(u32 *inst, int addr)
 {
-#ifdef CONFIG_RELOCATABLE
+#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_PPC_BOOK3S)
        /* On relocatable kernels interrupts handlers and our code
           can be in different regions, so we don't patch them */
 
index 049846911ce4d18d8097507b9be0caa8d767733c..1cc471faac2dd4bac032a956860b4f10d29170cb 100644 (file)
@@ -416,7 +416,7 @@ lightweight_exit:
        lwz     r3, VCPU_PC(r4)
        mtsrr0  r3
        lwz     r3, VCPU_SHARED(r4)
-       lwz     r3, VCPU_SHARED_MSR(r3)
+       lwz     r3, (VCPU_SHARED_MSR + 4)(r3)
        oris    r3, r3, KVMPPC_MSR_MASK@h
        ori     r3, r3, KVMPPC_MSR_MASK@l
        mtsrr1  r3
index 71750f2dd5d34378c963acf7bf9d3a69a15863cc..e3768ee9b59537bf92eceb853fa9edf56d7d5b6c 100644 (file)
@@ -138,8 +138,8 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
        struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
 
        free_page((unsigned long)vcpu->arch.shared);
-       kvmppc_e500_tlb_uninit(vcpu_e500);
        kvm_vcpu_uninit(vcpu);
+       kvmppc_e500_tlb_uninit(vcpu_e500);
        kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
 }
 
index 2f87a1627f6cff35604f96e8e041cffd9af071ff..38f756f2505389ac5f59eb9ae3921ef72175eea1 100644 (file)
@@ -617,6 +617,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
        switch (ioctl) {
        case KVM_PPC_GET_PVINFO: {
                struct kvm_ppc_pvinfo pvinfo;
+               memset(&pvinfo, 0, sizeof(pvinfo));
                r = kvm_vm_ioctl_get_pvinfo(&pvinfo);
                if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) {
                        r = -EFAULT;
index 46fa04f12a9b979c7cbe50c703d43e2c2705604e..a021f5827a336ce97b6c62ed5b8d0ca625d571bf 100644 (file)
@@ -35,7 +35,6 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu)
        int i;
 
        /* pause guest execution to avoid concurrent updates */
-       local_irq_disable();
        mutex_lock(&vcpu->mutex);
 
        vcpu->arch.last_exit_type = 0xDEAD;
@@ -51,7 +50,6 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu)
        vcpu->arch.timing_last_enter.tv64 = 0;
 
        mutex_unlock(&vcpu->mutex);
-       local_irq_enable();
 }
 
 static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type)
index 5dec408d670353a9f4651a1b72a244e2a695d381..3532b92de98335d84f1f177721072428dd5c166f 100644 (file)
@@ -798,17 +798,17 @@ spufs_fill_super(struct super_block *sb, void *data, int silent)
        return spufs_create_root(sb, data);
 }
 
-static int
-spufs_get_sb(struct file_system_type *fstype, int flags,
-               const char *name, void *data, struct vfsmount *mnt)
+static struct dentry *
+spufs_mount(struct file_system_type *fstype, int flags,
+               const char *name, void *data)
 {
-       return get_sb_single(fstype, flags, data, spufs_fill_super, mnt);
+       return mount_single(fstype, flags, data, spufs_fill_super);
 }
 
 static struct file_system_type spufs_type = {
        .owner = THIS_MODULE,
        .name = "spufs",
-       .get_sb = spufs_get_sb,
+       .mount = spufs_mount,
        .kill_sb = kill_litter_super,
 };
 
index dceb8d1a843d7ccd63f46fc768c6352f2fb92b9c..4fcb5a4e60dddaeca9143a79c2ebb61a581d3be6 100644 (file)
@@ -1,9 +1,12 @@
 /*
  * Freescale LBC and UPM routines.
  *
- * Copyright (c) 2007-2008  MontaVista Software, Inc.
+ * Copyright © 2007-2008  MontaVista Software, Inc.
+ * Copyright © 2010 Freescale Semiconductor
  *
  * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
+ * Author: Jack Lan <Jack.Lan@freescale.com>
+ * Author: Roy Zang <tie-fei.zang@freescale.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
 #include <linux/types.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mod_devicetable.h>
 #include <asm/prom.h>
 #include <asm/fsl_lbc.h>
 
 static spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock);
-static struct fsl_lbc_regs __iomem *fsl_lbc_regs;
+struct fsl_lbc_ctrl *fsl_lbc_ctrl_dev;
+EXPORT_SYMBOL(fsl_lbc_ctrl_dev);
 
-static char __initdata *compat_lbc[] = {
-       "fsl,pq2-localbus",
-       "fsl,pq2pro-localbus",
-       "fsl,pq3-localbus",
-       "fsl,elbc",
-};
-
-static int __init fsl_lbc_init(void)
+/**
+ * fsl_lbc_addr - convert the base address
+ * @addr_base: base address of the memory bank
+ *
+ * This function converts a base address of lbc into the right format for the
+ * BR register. If the SOC has eLBC then it returns 32bit physical address
+ * else it convers a 34bit local bus physical address to correct format of
+ * 32bit address for BR register (Example: MPC8641).
+ */
+u32 fsl_lbc_addr(phys_addr_t addr_base)
 {
-       struct device_node *lbus;
-       int i;
+       struct device_node *np = fsl_lbc_ctrl_dev->dev->of_node;
+       u32 addr = addr_base & 0xffff8000;
 
-       for (i = 0; i < ARRAY_SIZE(compat_lbc); i++) {
-               lbus = of_find_compatible_node(NULL, NULL, compat_lbc[i]);
-               if (lbus)
-                       goto found;
-       }
-       return -ENODEV;
+       if (of_device_is_compatible(np, "fsl,elbc"))
+               return addr;
 
-found:
-       fsl_lbc_regs = of_iomap(lbus, 0);
-       of_node_put(lbus);
-       if (!fsl_lbc_regs)
-               return -ENOMEM;
-       return 0;
+       return addr | ((addr_base & 0x300000000ull) >> 19);
 }
-arch_initcall(fsl_lbc_init);
+EXPORT_SYMBOL(fsl_lbc_addr);
 
 /**
  * fsl_lbc_find - find Localbus bank
@@ -65,15 +66,17 @@ arch_initcall(fsl_lbc_init);
 int fsl_lbc_find(phys_addr_t addr_base)
 {
        int i;
+       struct fsl_lbc_regs __iomem *lbc;
 
-       if (!fsl_lbc_regs)
+       if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
                return -ENODEV;
 
-       for (i = 0; i < ARRAY_SIZE(fsl_lbc_regs->bank); i++) {
-               __be32 br = in_be32(&fsl_lbc_regs->bank[i].br);
-               __be32 or = in_be32(&fsl_lbc_regs->bank[i].or);
+       lbc = fsl_lbc_ctrl_dev->regs;
+       for (i = 0; i < ARRAY_SIZE(lbc->bank); i++) {
+               __be32 br = in_be32(&lbc->bank[i].br);
+               __be32 or = in_be32(&lbc->bank[i].or);
 
-               if (br & BR_V && (br & or & BR_BA) == addr_base)
+               if (br & BR_V && (br & or & BR_BA) == fsl_lbc_addr(addr_base))
                        return i;
        }
 
@@ -94,22 +97,27 @@ int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm)
 {
        int bank;
        __be32 br;
+       struct fsl_lbc_regs __iomem *lbc;
 
        bank = fsl_lbc_find(addr_base);
        if (bank < 0)
                return bank;
 
-       br = in_be32(&fsl_lbc_regs->bank[bank].br);
+       if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
+               return -ENODEV;
+
+       lbc = fsl_lbc_ctrl_dev->regs;
+       br = in_be32(&lbc->bank[bank].br);
 
        switch (br & BR_MSEL) {
        case BR_MS_UPMA:
-               upm->mxmr = &fsl_lbc_regs->mamr;
+               upm->mxmr = &lbc->mamr;
                break;
        case BR_MS_UPMB:
-               upm->mxmr = &fsl_lbc_regs->mbmr;
+               upm->mxmr = &lbc->mbmr;
                break;
        case BR_MS_UPMC:
-               upm->mxmr = &fsl_lbc_regs->mcmr;
+               upm->mxmr = &lbc->mcmr;
                break;
        default:
                return -EINVAL;
@@ -148,9 +156,12 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
        int ret = 0;
        unsigned long flags;
 
+       if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
+               return -ENODEV;
+
        spin_lock_irqsave(&fsl_lbc_lock, flags);
 
-       out_be32(&fsl_lbc_regs->mar, mar);
+       out_be32(&fsl_lbc_ctrl_dev->regs->mar, mar);
 
        switch (upm->width) {
        case 8:
@@ -172,3 +183,166 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
        return ret;
 }
 EXPORT_SYMBOL(fsl_upm_run_pattern);
+
+static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl)
+{
+       struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+
+       /* clear event registers */
+       setbits32(&lbc->ltesr, LTESR_CLEAR);
+       out_be32(&lbc->lteatr, 0);
+       out_be32(&lbc->ltear, 0);
+       out_be32(&lbc->lteccr, LTECCR_CLEAR);
+       out_be32(&lbc->ltedr, LTEDR_ENABLE);
+
+       /* Enable interrupts for any detected events */
+       out_be32(&lbc->lteir, LTEIR_ENABLE);
+
+       return 0;
+}
+
+/*
+ * NOTE: This interrupt is used to report localbus events of various kinds,
+ * such as transaction errors on the chipselects.
+ */
+
+static irqreturn_t fsl_lbc_ctrl_irq(int irqno, void *data)
+{
+       struct fsl_lbc_ctrl *ctrl = data;
+       struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+       u32 status;
+
+       status = in_be32(&lbc->ltesr);
+       if (!status)
+               return IRQ_NONE;
+
+       out_be32(&lbc->ltesr, LTESR_CLEAR);
+       out_be32(&lbc->lteatr, 0);
+       out_be32(&lbc->ltear, 0);
+       ctrl->irq_status = status;
+
+       if (status & LTESR_BM)
+               dev_err(ctrl->dev, "Local bus monitor time-out: "
+                       "LTESR 0x%08X\n", status);
+       if (status & LTESR_WP)
+               dev_err(ctrl->dev, "Write protect error: "
+                       "LTESR 0x%08X\n", status);
+       if (status & LTESR_ATMW)
+               dev_err(ctrl->dev, "Atomic write error: "
+                       "LTESR 0x%08X\n", status);
+       if (status & LTESR_ATMR)
+               dev_err(ctrl->dev, "Atomic read error: "
+                       "LTESR 0x%08X\n", status);
+       if (status & LTESR_CS)
+               dev_err(ctrl->dev, "Chip select error: "
+                       "LTESR 0x%08X\n", status);
+       if (status & LTESR_UPM)
+               ;
+       if (status & LTESR_FCT) {
+               dev_err(ctrl->dev, "FCM command time-out: "
+                       "LTESR 0x%08X\n", status);
+               smp_wmb();
+               wake_up(&ctrl->irq_wait);
+       }
+       if (status & LTESR_PAR) {
+               dev_err(ctrl->dev, "Parity or Uncorrectable ECC error: "
+                       "LTESR 0x%08X\n", status);
+               smp_wmb();
+               wake_up(&ctrl->irq_wait);
+       }
+       if (status & LTESR_CC) {
+               smp_wmb();
+               wake_up(&ctrl->irq_wait);
+       }
+       if (status & ~LTESR_MASK)
+               dev_err(ctrl->dev, "Unknown error: "
+                       "LTESR 0x%08X\n", status);
+       return IRQ_HANDLED;
+}
+
+/*
+ * fsl_lbc_ctrl_probe
+ *
+ * called by device layer when it finds a device matching
+ * one our driver can handled. This code allocates all of
+ * the resources needed for the controller only.  The
+ * resources for the NAND banks themselves are allocated
+ * in the chip probe function.
+*/
+
+static int __devinit fsl_lbc_ctrl_probe(struct platform_device *dev)
+{
+       int ret;
+
+       if (!dev->dev.of_node) {
+               dev_err(&dev->dev, "Device OF-Node is NULL");
+               return -EFAULT;
+       }
+
+       fsl_lbc_ctrl_dev = kzalloc(sizeof(*fsl_lbc_ctrl_dev), GFP_KERNEL);
+       if (!fsl_lbc_ctrl_dev)
+               return -ENOMEM;
+
+       dev_set_drvdata(&dev->dev, fsl_lbc_ctrl_dev);
+
+       spin_lock_init(&fsl_lbc_ctrl_dev->lock);
+       init_waitqueue_head(&fsl_lbc_ctrl_dev->irq_wait);
+
+       fsl_lbc_ctrl_dev->regs = of_iomap(dev->dev.of_node, 0);
+       if (!fsl_lbc_ctrl_dev->regs) {
+               dev_err(&dev->dev, "failed to get memory region\n");
+               ret = -ENODEV;
+               goto err;
+       }
+
+       fsl_lbc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0);
+       if (fsl_lbc_ctrl_dev->irq == NO_IRQ) {
+               dev_err(&dev->dev, "failed to get irq resource\n");
+               ret = -ENODEV;
+               goto err;
+       }
+
+       fsl_lbc_ctrl_dev->dev = &dev->dev;
+
+       ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev);
+       if (ret < 0)
+               goto err;
+
+       ret = request_irq(fsl_lbc_ctrl_dev->irq, fsl_lbc_ctrl_irq, 0,
+                               "fsl-lbc", fsl_lbc_ctrl_dev);
+       if (ret != 0) {
+               dev_err(&dev->dev, "failed to install irq (%d)\n",
+                       fsl_lbc_ctrl_dev->irq);
+               ret = fsl_lbc_ctrl_dev->irq;
+               goto err;
+       }
+
+       return 0;
+
+err:
+       iounmap(fsl_lbc_ctrl_dev->regs);
+       kfree(fsl_lbc_ctrl_dev);
+       return ret;
+}
+
+static const struct of_device_id fsl_lbc_match[] = {
+       { .compatible = "fsl,elbc", },
+       { .compatible = "fsl,pq3-localbus", },
+       { .compatible = "fsl,pq2-localbus", },
+       { .compatible = "fsl,pq2pro-localbus", },
+       {},
+};
+
+static struct platform_driver fsl_lbc_ctrl_driver = {
+       .driver = {
+               .name = "fsl-lbc",
+               .of_match_table = fsl_lbc_match,
+       },
+       .probe = fsl_lbc_ctrl_probe,
+};
+
+static int __init fsl_lbc_init(void)
+{
+       return platform_driver_register(&fsl_lbc_ctrl_driver);
+}
+module_init(fsl_lbc_init);
index fabb40bc4e196adcb578e86f6558e008c27f1199..e0b98e71ff4797e5807f9e5d99f674aeb90456b8 100644 (file)
@@ -80,6 +80,7 @@ config S390
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_FTRACE_MCOUNT_RECORD
+       select HAVE_C_RECORDMCOUNT
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FUNCTION_GRAPH_TRACER
@@ -144,7 +145,7 @@ source "kernel/time/Kconfig"
 config 64BIT
        bool "64 bit kernel"
        help
-         Select this option if you have a 64 bit IBM zSeries machine
+         Select this option if you have an IBM z/Architecture machine
          and want to use the 64 bit addressing mode.
 
 config 32BIT
@@ -196,9 +197,18 @@ config HOTPLUG_CPU
          can be controlled through /sys/devices/system/cpu/cpu#.
          Say N if you want to disable CPU hotplug.
 
+config SCHED_MC
+       def_bool y
+       prompt "Multi-core scheduler support"
+       depends on SMP
+       help
+         Multi-core scheduler support improves the CPU scheduler's decision
+         making when dealing with multi-core CPU chips at a cost of slightly
+         increased overhead in some places.
+
 config SCHED_BOOK
        bool "Book scheduler support"
-       depends on SMP
+       depends on SMP && SCHED_MC
        help
          Book scheduler support improves the CPU scheduler's decision making
          when dealing with machines that have several books.
@@ -208,7 +218,7 @@ config MATHEMU
        depends on MARCH_G5
        help
          This option is required for IEEE compliant floating point arithmetic
-         on older S/390 machines. Say Y unless you know your machine doesn't
+         on older ESA/390 machines. Say Y unless you know your machine doesn't
          need this.
 
 config COMPAT
@@ -237,8 +247,8 @@ config S390_EXEC_PROTECT
          space programs and it also selects the addressing mode option above.
          The kernel parameter noexec=on will enable this feature and also
          switch the addressing modes, default is disabled. Enabling this (via
-         kernel parameter) on machines earlier than IBM System z9-109 EC/BC
-         will reduce system performance.
+         kernel parameter) on machines earlier than IBM System z9 this will
+         reduce system performance.
 
 comment "Code generation options"
 
@@ -247,49 +257,46 @@ choice
        default MARCH_G5
 
 config MARCH_G5
-       bool "S/390 model G5 and G6"
+       bool "System/390 model G5 and G6"
        depends on !64BIT
        help
          Select this to build a 31 bit kernel that works
-         on all S/390 and zSeries machines.
+         on all ESA/390 and z/Architecture machines.
 
 config MARCH_Z900
-       bool "IBM eServer zSeries model z800 and z900"
+       bool "IBM zSeries model z800 and z900"
        help
-         Select this to optimize for zSeries machines. This
-         will enable some optimizations that are not available
-         on older 31 bit only CPUs.
+         Select this to enable optimizations for model z800/z900 (2064 and
+         2066 series). This will enable some optimizations that are not
+         available on older ESA/390 (31 Bit) only CPUs.
 
 config MARCH_Z990
-       bool "IBM eServer zSeries model z890 and z990"
+       bool "IBM zSeries model z890 and z990"
        help
-         Select this enable optimizations for model z890/z990.
-         This will be slightly faster but does not work on
-         older machines such as the z900.
+         Select this to enable optimizations for model z890/z990 (2084 and
+         2086 series). The kernel will be slightly faster but will not work
+         on older machines.
 
 config MARCH_Z9_109
        bool "IBM System z9"
        help
-         Select this to enable optimizations for IBM System z9-109, IBM
-         System z9 Enterprise Class (z9 EC), and IBM System z9 Business
-         Class (z9 BC). The kernel will be slightly faster but will not
-         work on older machines such as the z990, z890, z900, and z800.
+         Select this to enable optimizations for IBM System z9 (2094 and
+         2096 series). The kernel will be slightly faster but will not work
+         on older machines.
 
 config MARCH_Z10
        bool "IBM System z10"
        help
-         Select this to enable optimizations for IBM System z10. The
-         kernel will be slightly faster but will not work on older
-         machines such as the z990, z890, z900, z800, z9-109, z9-ec
-         and z9-bc.
+         Select this to enable optimizations for IBM System z10 (2097 and
+         2098 series). The kernel will be slightly faster but will not work
+         on older machines.
 
 config MARCH_Z196
        bool "IBM zEnterprise 196"
        help
-         Select this to enable optimizations for IBM zEnterprise 196.
-         The kernel will be slightly faster but will not work on older
-         machines such as the z990, z890, z900, z800, z9-109, z9-ec,
-         z9-bc, z10-ec and z10-bc.
+         Select this to enable optimizations for IBM zEnterprise 196
+         (2817 series). The kernel will be slightly faster but will not work
+         on older machines.
 
 endchoice
 
index 020e51c063d2d4d52c7c2f5a39690197a22979d7..cd4a81be9cf8eee9a579be8b544e616168c5a3ef 100644 (file)
@@ -638,18 +638,21 @@ __init int hypfs_diag_init(void)
                pr_err("The hardware system does not support hypfs\n");
                return -ENODATA;
        }
-       rc = diag224_get_name_table();
-       if (rc) {
-               diag204_free_buffer();
-               pr_err("The hardware system does not provide all "
-                      "functions required by hypfs\n");
-       }
        if (diag204_info_type == INFO_EXT) {
                rc = hypfs_dbfs_init();
                if (rc)
-                       diag204_free_buffer();
+                       return rc;
        }
-       return rc;
+       if (MACHINE_IS_LPAR) {
+               rc = diag224_get_name_table();
+               if (rc) {
+                       pr_err("The hardware system does not provide all "
+                              "functions required by hypfs\n");
+                       debugfs_remove(dbfs_d204_file);
+                       return rc;
+               }
+       }
+       return 0;
 }
 
 void hypfs_diag_exit(void)
index 74d98670be27023241aff6ba8a2b02c35a052e0b..47cc446dab8f1fee4e7305516cca315c8f6baac4 100644 (file)
@@ -316,10 +316,10 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 }
 
-static int hypfs_get_super(struct file_system_type *fst, int flags,
-                       const char *devname, void *data, struct vfsmount *mnt)
+static struct dentry *hypfs_mount(struct file_system_type *fst, int flags,
+                       const char *devname, void *data)
 {
-       return get_sb_single(fst, flags, data, hypfs_fill_super, mnt);
+       return mount_single(fst, flags, data, hypfs_fill_super);
 }
 
 static void hypfs_kill_super(struct super_block *sb)
@@ -455,7 +455,7 @@ static const struct file_operations hypfs_file_ops = {
 static struct file_system_type hypfs_type = {
        .owner          = THIS_MODULE,
        .name           = "s390_hypfs",
-       .get_sb         = hypfs_get_super,
+       .mount          = hypfs_mount,
        .kill_sb        = hypfs_kill_super
 };
 
index 218bce81ec70f05db21fde6b512ac7e6fe83447c..b604a9186f8e486c9841ae3cc2164fb5be69791b 100644 (file)
@@ -217,6 +217,25 @@ typedef struct dasd_symmio_parms {
        int rssd_result_len;
 } __attribute__ ((packed)) dasd_symmio_parms_t;
 
+/*
+ * Data returned by Sense Path Group ID (SNID)
+ */
+struct dasd_snid_data {
+       struct {
+               __u8 group:2;
+               __u8 reserve:2;
+               __u8 mode:1;
+               __u8 res:3;
+       } __attribute__ ((packed)) path_state;
+       __u8 pgid[11];
+} __attribute__ ((packed));
+
+struct dasd_snid_ioctl_data {
+       struct dasd_snid_data data;
+       __u8 path_mask;
+} __attribute__ ((packed));
+
+
 /********************************************************************************
  * SECTION: Definition of IOCTLs
  *
@@ -261,25 +280,10 @@ typedef struct dasd_symmio_parms {
 /* Set Attributes (cache operations) */
 #define BIODASDSATTR   _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) 
 
+/* Get Sense Path Group ID (SNID) data */
+#define BIODASDSNID    _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data)
+
 #define BIODASDSYMMIO  _IOWR(DASD_IOCTL_LETTER, 240, dasd_symmio_parms_t)
 
 #endif                         /* DASD_H */
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4 
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
index f3c1b823c9a83b3a4ed4a0c4a4359e11b5934af1..33982e7ce04d5847c23774ea06f27a9123d3a3ee 100644 (file)
@@ -66,9 +66,9 @@ int main(void)
        DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
        DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
        /* constants used by the vdso */
-       DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
-       DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
-       DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
+       DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
+       DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC);
+       DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
        BLANK();
        /* constants for SIGP */
        DEFINE(__SIGP_STOP, sigp_stop);
index d149609e46e63c0ebc518140fd9983a7d70a95ce..3b7e7dddc324a6985a09758ce9636da5e6cae8c6 100644 (file)
@@ -282,8 +282,6 @@ static noinline __init void setup_facility_list(void)
 static noinline __init void setup_hpage(void)
 {
 #ifndef CONFIG_DEBUG_PAGEALLOC
-       unsigned int facilities;
-
        if (!test_facility(2) || !test_facility(8))
                return;
        S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE;
index 5efce7202984ad969031922a21a39531014782de..1ecc337fb679045e968ef1915ea009c4777786de 100644 (file)
@@ -557,6 +557,7 @@ pgm_svcper:
 # per was called from kernel, must be kprobes
 #
 kernel_per:
+       REENABLE_IRQS
        mvi     SP_SVCNR(%r15),0xff     # set trap indication to pgm check
        mvi     SP_SVCNR+1(%r15),0xff
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
index a2be23922f4339849b97551e67f1c67fc0cbfbe7..8f3e802174db8382f7adc41bfc2949c4f231236b 100644 (file)
@@ -568,6 +568,7 @@ pgm_svcper:
 # per was called from kernel, must be kprobes
 #
 kernel_per:
+       REENABLE_IRQS
        xc      SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        brasl   %r14,do_single_step
index 2a3d2bf6f083070678f4c777b4cea0db00b9ff74..d60fc439851658761cd105d8d403be2e69fee0ad 100644 (file)
@@ -316,6 +316,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                return 1;
 
 ss_probe:
+       if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
+               local_irq_disable();
        prepare_singlestep(p, regs);
        kcb->kprobe_status = KPROBE_HIT_SS;
        return 1;
@@ -463,6 +465,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
                goto out;
        }
        reset_current_kprobe();
+       if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
+               local_irq_enable();
 out:
        preempt_enable_no_resched();
 
@@ -502,8 +506,11 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
                regs->psw.mask |= kcb->kprobe_saved_imask;
                if (kcb->kprobe_status == KPROBE_REENTER)
                        restore_previous_kprobe(kcb);
-               else
+               else {
                        reset_current_kprobe();
+                       if (regs->psw.mask & (PSW_MASK_PER | PSW_MASK_IO))
+                               local_irq_enable();
+               }
                preempt_enable_no_resched();
                break;
        case KPROBE_HIT_ACTIVE:
index e3ceb911dc75806c9acee85dfbd980502acf5563..6f6350826c81c1f7a1d81071ac0b4ed2df360e17 100644 (file)
@@ -761,6 +761,9 @@ static void __init setup_hwcaps(void)
        case 0x2098:
                strcpy(elf_platform, "z10");
                break;
+       case 0x2817:
+               strcpy(elf_platform, "z196");
+               break;
        }
 }
 
index f04d93aa48ec927f54f9f032ccedd5fa1f6e8d7a..5c9e439bf3f6d21983ebbdaa706bb7cfb8e3a6a6 100644 (file)
@@ -106,11 +106,13 @@ static int stsi_15_1_x(struct sysinfo_15_1_x *info, char *page, int len)
        for (i = 0; i < TOPOLOGY_NR_MAG; i++)
                len += sprintf(page + len, " %d", info->mag[i]);
        len += sprintf(page + len, "\n");
+#ifdef CONFIG_SCHED_MC
        store_topology(info);
        len += sprintf(page + len, "CPU Topology SW:     ");
        for (i = 0; i < TOPOLOGY_NR_MAG; i++)
                len += sprintf(page + len, " %d", info->mag[i]);
        len += sprintf(page + len, "\n");
+#endif
        return len;
 }
 
index a9dee9048ee58017bbd6cf03ac9377047dc09f8a..94b06c31fc8a389c752bcefe843d237ed1871a1a 100644 (file)
@@ -53,8 +53,10 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
        cpumask_t mask;
 
        cpus_clear(mask);
-       if (!topology_enabled || !MACHINE_HAS_TOPOLOGY)
-               return cpu_possible_map;
+       if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) {
+               cpumask_copy(&mask, cpumask_of(cpu));
+               return mask;
+       }
        while (info) {
                if (cpu_isset(cpu, info->mask)) {
                        mask = info->mask;
index 9532c4e6a9d2fb12e5cd77f5a7c05ae99fa99f8c..36aaa25d05daa4e1d785103d85a2bb5a078fc2cc 100644 (file)
@@ -19,9 +19,9 @@
        .type  __kernel_clock_getres,@function
 __kernel_clock_getres:
        .cfi_startproc
-       chi     %r2,CLOCK_REALTIME
+       chi     %r2,__CLOCK_REALTIME
        je      0f
-       chi     %r2,CLOCK_MONOTONIC
+       chi     %r2,__CLOCK_MONOTONIC
        jne     3f
 0:     ltr     %r3,%r3
        jz      2f                              /* res == NULL */
@@ -34,6 +34,6 @@ __kernel_clock_getres:
 3:     lhi     %r1,__NR_clock_getres           /* fallback to svc */
        svc     0
        br      %r14
-4:     .long   CLOCK_REALTIME_RES
+4:     .long   __CLOCK_REALTIME_RES
        .cfi_endproc
        .size   __kernel_clock_getres,.-__kernel_clock_getres
index 969643954273c2e1a3c75fe045985d3649e661c3..b2224e0b974ce5beff26c4d1e7838d48e0232ae9 100644 (file)
@@ -21,9 +21,9 @@ __kernel_clock_gettime:
        .cfi_startproc
        basr    %r5,0
 0:     al      %r5,21f-0b(%r5)                 /* get &_vdso_data */
-       chi     %r2,CLOCK_REALTIME
+       chi     %r2,__CLOCK_REALTIME
        je      10f
-       chi     %r2,CLOCK_MONOTONIC
+       chi     %r2,__CLOCK_MONOTONIC
        jne     19f
 
        /* CLOCK_MONOTONIC */
index 9ce8caafdb4ea98cef8e451aa6366d52100ef812..176e1f75f9aa6c1554dbf0818b7d4cd6661c0846 100644 (file)
@@ -19,9 +19,9 @@
        .type  __kernel_clock_getres,@function
 __kernel_clock_getres:
        .cfi_startproc
-       cghi    %r2,CLOCK_REALTIME
+       cghi    %r2,__CLOCK_REALTIME
        je      0f
-       cghi    %r2,CLOCK_MONOTONIC
+       cghi    %r2,__CLOCK_MONOTONIC
        je      0f
        cghi    %r2,-2          /* CLOCK_THREAD_CPUTIME_ID for this thread */
        jne     2f
@@ -39,6 +39,6 @@ __kernel_clock_getres:
 2:     lghi    %r1,__NR_clock_getres           /* fallback to svc */
        svc     0
        br      %r14
-3:     .quad   CLOCK_REALTIME_RES
+3:     .quad   __CLOCK_REALTIME_RES
        .cfi_endproc
        .size   __kernel_clock_getres,.-__kernel_clock_getres
index f40467884a03722c668b388591e976f71be8961d..d46c95ed5f19ae8c25f9255b32338e8cc3197906 100644 (file)
 __kernel_clock_gettime:
        .cfi_startproc
        larl    %r5,_vdso_data
-       cghi    %r2,CLOCK_REALTIME
+       cghi    %r2,__CLOCK_REALTIME
        je      4f
        cghi    %r2,-2          /* CLOCK_THREAD_CPUTIME_ID for this thread */
        je      9f
-       cghi    %r2,CLOCK_MONOTONIC
+       cghi    %r2,__CLOCK_MONOTONIC
        jne     12f
 
        /* CLOCK_MONOTONIC */
index 5c075f562ebae912476974f20faee1bfaeec707d..7f217b3a50a806b7347f991b588397011aa3388e 100644 (file)
@@ -193,6 +193,7 @@ config CPU_SH2
 config CPU_SH2A
        bool
        select CPU_SH2
+       select UNCACHED_MAPPING
 
 config CPU_SH3
        bool
index 307b3a4a790b98b61bd3cb893dfa155ff4983e0b..9c8c6e1a2a154d4dff50db8d0d532201c5f991be 100644 (file)
@@ -133,10 +133,7 @@ machdir-$(CONFIG_SOLUTION_ENGINE)          += mach-se
 machdir-$(CONFIG_SH_HP6XX)                     += mach-hp6xx
 machdir-$(CONFIG_SH_DREAMCAST)                 += mach-dreamcast
 machdir-$(CONFIG_SH_SH03)                      += mach-sh03
-machdir-$(CONFIG_SH_SECUREEDGE5410)            += mach-snapgear
 machdir-$(CONFIG_SH_RTS7751R2D)                        += mach-r2d
-machdir-$(CONFIG_SH_7751_SYSTEMH)              += mach-systemh
-machdir-$(CONFIG_SH_EDOSK7705)                 += mach-edosk7705
 machdir-$(CONFIG_SH_HIGHLANDER)                        += mach-highlander
 machdir-$(CONFIG_SH_MIGOR)                     += mach-migor
 machdir-$(CONFIG_SH_AP325RXA)                  += mach-ap325rxa
index 9c94711aa6caee785b152ba7be282b98a6b6d285..2018c7ea4c93f49d53d7f1ff82f32db2b85e85bc 100644 (file)
@@ -81,13 +81,6 @@ config SH_7343_SOLUTION_ENGINE
          Select 7343 SolutionEngine if configuring for a Hitachi
          SH7343 (SH-Mobile 3AS) evaluation board.
 
-config SH_7751_SYSTEMH
-       bool "SystemH7751R"
-       depends on CPU_SUBTYPE_SH7751R
-       help
-         Select SystemH if you are configuring for a Renesas SystemH
-         7751R evaluation board.
-
 config SH_HP6XX
        bool "HP6XX"
        select SYS_SUPPORTS_APM_EMULATION
index 38ef655cc0f08cfe0f881b053f421e9861412556..be7d11d04b26a3abcaeacde829e496f970903c33 100644 (file)
@@ -2,10 +2,12 @@
 # Specific board support, not covered by a mach group.
 #
 obj-$(CONFIG_SH_MAGIC_PANEL_R2)        += board-magicpanelr2.o
+obj-$(CONFIG_SH_SECUREEDGE5410)        += board-secureedge5410.o
 obj-$(CONFIG_SH_SH2007)                += board-sh2007.o
 obj-$(CONFIG_SH_SH7785LCR)     += board-sh7785lcr.o
 obj-$(CONFIG_SH_URQUELL)       += board-urquell.o
 obj-$(CONFIG_SH_SHMIN)         += board-shmin.o
+obj-$(CONFIG_SH_EDOSK7705)     += board-edosk7705.o
 obj-$(CONFIG_SH_EDOSK7760)     += board-edosk7760.o
 obj-$(CONFIG_SH_ESPT)          += board-espt.o
 obj-$(CONFIG_SH_POLARIS)       += board-polaris.o
diff --git a/arch/sh/boards/board-edosk7705.c b/arch/sh/boards/board-edosk7705.c
new file mode 100644 (file)
index 0000000..4cb3bb7
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * arch/sh/boards/renesas/edosk7705/setup.c
+ *
+ * Copyright (C) 2000  Kazumoto Kojima
+ *
+ * Hitachi SolutionEngine Support.
+ *
+ * Modified for edosk7705 development
+ * board by S. Dunn, 2003.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/smc91x.h>
+#include <asm/machvec.h>
+#include <asm/sizes.h>
+
+#define SMC_IOBASE     0xA2000000
+#define SMC_IO_OFFSET  0x300
+#define SMC_IOADDR     (SMC_IOBASE + SMC_IO_OFFSET)
+
+#define ETHERNET_IRQ   0x09
+
+static void __init sh_edosk7705_init_irq(void)
+{
+       make_imask_irq(ETHERNET_IRQ);
+}
+
+/* eth initialization functions */
+static struct smc91x_platdata smc91x_info = {
+       .flags = SMC91X_USE_16BIT | SMC91X_IO_SHIFT_1 | IORESOURCE_IRQ_LOWLEVEL,
+};
+
+static struct resource smc91x_res[] = {
+       [0] = {
+               .start  = SMC_IOADDR,
+               .end    = SMC_IOADDR + SZ_32 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = ETHERNET_IRQ,
+               .end    = ETHERNET_IRQ,
+               .flags  = IORESOURCE_IRQ ,
+       }
+};
+
+static struct platform_device smc91x_dev = {
+       .name           = "smc91x",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(smc91x_res),
+       .resource       = smc91x_res,
+
+       .dev    = {
+               .platform_data  = &smc91x_info,
+       },
+};
+
+/* platform init code */
+static struct platform_device *edosk7705_devices[] __initdata = {
+       &smc91x_dev,
+};
+
+static int __init init_edosk7705_devices(void)
+{
+       return platform_add_devices(edosk7705_devices,
+                                   ARRAY_SIZE(edosk7705_devices));
+}
+__initcall(init_edosk7705_devices);
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_edosk7705 __initmv = {
+       .mv_name                = "EDOSK7705",
+       .mv_nr_irqs             = 80,
+       .mv_init_irq            = sh_edosk7705_init_irq,
+};
diff --git a/arch/sh/boards/board-secureedge5410.c b/arch/sh/boards/board-secureedge5410.c
new file mode 100644 (file)
index 0000000..32f875e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2002  David McCullough <davidm@snapgear.com>
+ * Copyright (C) 2003  Paul Mundt <lethal@linux-sh.org>
+ *
+ * Based on files with the following comments:
+ *
+ *           Copyright (C) 2000  Kazumoto Kojima
+ *
+ *           Modified for 7751 Solution Engine by
+ *           Ian da Silva and Jeremy Siegel, 2001.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <asm/machvec.h>
+#include <mach/secureedge5410.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <cpu/timer.h>
+
+unsigned short secureedge5410_ioport;
+
+/*
+ * EraseConfig handling functions
+ */
+static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
+{
+       ctrl_delay();   /* dummy read */
+
+       printk("SnapGear: erase switch interrupt!\n");
+
+       return IRQ_HANDLED;
+}
+
+static int __init eraseconfig_init(void)
+{
+       unsigned int irq = evt2irq(0x240);
+
+       printk("SnapGear: EraseConfig init\n");
+
+       /* Setup "EraseConfig" switch on external IRQ 0 */
+       if (request_irq(irq, eraseconfig_interrupt, IRQF_DISABLED,
+                               "Erase Config", NULL))
+               printk("SnapGear: failed to register IRQ%d for Reset witch\n",
+                               irq);
+       else
+               printk("SnapGear: registered EraseConfig switch on IRQ%d\n",
+                               irq);
+       return 0;
+}
+module_init(eraseconfig_init);
+
+/*
+ * Initialize IRQ setting
+ *
+ * IRL0 = erase switch
+ * IRL1 = eth0
+ * IRL2 = eth1
+ * IRL3 = crypto
+ */
+static void __init init_snapgear_IRQ(void)
+{
+       printk("Setup SnapGear IRQ/IPR ...\n");
+       /* enable individual interrupt mode for externals */
+       plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_snapgear __initmv = {
+       .mv_name                = "SnapGear SecureEdge5410",
+       .mv_nr_irqs             = 72,
+       .mv_init_irq            = init_snapgear_IRQ,
+};
index 881a3a5f56472a0318d58a2e0068cb0a299eebe5..07ea908c510d08b680704fca70dd4250264a9daf 100644 (file)
@@ -176,6 +176,21 @@ static void ap320_wvga_power_off(void *board_data)
        __raw_writew(0, FPGA_LCDREG);
 }
 
+const static struct fb_videomode ap325rxa_lcdc_modes[] = {
+       {
+               .name = "LB070WV1",
+               .xres = 800,
+               .yres = 480,
+               .left_margin = 32,
+               .right_margin = 160,
+               .hsync_len = 8,
+               .upper_margin = 63,
+               .lower_margin = 80,
+               .vsync_len = 1,
+               .sync = 0, /* hsync and vsync are active low */
+       },
+};
+
 static struct sh_mobile_lcdc_info lcdc_info = {
        .clock_source = LCDC_CLK_EXTERNAL,
        .ch[0] = {
@@ -183,18 +198,8 @@ static struct sh_mobile_lcdc_info lcdc_info = {
                .bpp = 16,
                .interface_type = RGB18,
                .clock_divider = 1,
-               .lcd_cfg = {
-                       .name = "LB070WV1",
-                       .xres = 800,
-                       .yres = 480,
-                       .left_margin = 32,
-                       .right_margin = 160,
-                       .hsync_len = 8,
-                       .upper_margin = 63,
-                       .lower_margin = 80,
-                       .vsync_len = 1,
-                       .sync = 0, /* hsync and vsync are active low */
-               },
+               .lcd_cfg = ap325rxa_lcdc_modes,
+               .num_cfg = ARRAY_SIZE(ap325rxa_lcdc_modes),
                .lcd_size_cfg = { /* 7.0 inch */
                        .width = 152,
                        .height = 91,
index ddc7e4e4d2a0431ca0ca64a6300a5ab4288f7d03..2eaeb9e5958575f59f3dd1f8d40b54ae03f5de00 100644 (file)
@@ -231,14 +231,41 @@ static struct platform_device usb1_common_device = {
 };
 
 /* LCDC */
+const static struct fb_videomode ecovec_lcd_modes[] = {
+       {
+               .name           = "Panel",
+               .xres           = 800,
+               .yres           = 480,
+               .left_margin    = 220,
+               .right_margin   = 110,
+               .hsync_len      = 70,
+               .upper_margin   = 20,
+               .lower_margin   = 5,
+               .vsync_len      = 5,
+               .sync           = 0, /* hsync and vsync are active low */
+       },
+};
+
+const static struct fb_videomode ecovec_dvi_modes[] = {
+       {
+               .name           = "DVI",
+               .xres           = 1280,
+               .yres           = 720,
+               .left_margin    = 220,
+               .right_margin   = 110,
+               .hsync_len      = 40,
+               .upper_margin   = 20,
+               .lower_margin   = 5,
+               .vsync_len      = 5,
+               .sync = 0, /* hsync and vsync are active low */
+       },
+};
+
 static struct sh_mobile_lcdc_info lcdc_info = {
        .ch[0] = {
                .interface_type = RGB18,
                .chan = LCDC_CHAN_MAINLCD,
                .bpp = 16,
-               .lcd_cfg = {
-                       .sync = 0, /* hsync and vsync are active low */
-               },
                .lcd_size_cfg = { /* 7.0 inch */
                        .width = 152,
                        .height = 91,
@@ -1075,33 +1102,18 @@ static int __init arch_setup(void)
        if (gpio_get_value(GPIO_PTE6)) {
                /* DVI */
                lcdc_info.clock_source                  = LCDC_CLK_EXTERNAL;
-               lcdc_info.ch[0].clock_divider           = 1,
-               lcdc_info.ch[0].lcd_cfg.name            = "DVI";
-               lcdc_info.ch[0].lcd_cfg.xres            = 1280;
-               lcdc_info.ch[0].lcd_cfg.yres            = 720;
-               lcdc_info.ch[0].lcd_cfg.left_margin     = 220;
-               lcdc_info.ch[0].lcd_cfg.right_margin    = 110;
-               lcdc_info.ch[0].lcd_cfg.hsync_len       = 40;
-               lcdc_info.ch[0].lcd_cfg.upper_margin    = 20;
-               lcdc_info.ch[0].lcd_cfg.lower_margin    = 5;
-               lcdc_info.ch[0].lcd_cfg.vsync_len       = 5;
+               lcdc_info.ch[0].clock_divider           = 1;
+               lcdc_info.ch[0].lcd_cfg                 = ecovec_dvi_modes;
+               lcdc_info.ch[0].num_cfg                 = ARRAY_SIZE(ecovec_dvi_modes);
 
                gpio_set_value(GPIO_PTA2, 1);
                gpio_set_value(GPIO_PTU1, 1);
        } else {
                /* Panel */
-
                lcdc_info.clock_source                  = LCDC_CLK_PERIPHERAL;
-               lcdc_info.ch[0].clock_divider           = 2,
-               lcdc_info.ch[0].lcd_cfg.name            = "Panel";
-               lcdc_info.ch[0].lcd_cfg.xres            = 800;
-               lcdc_info.ch[0].lcd_cfg.yres            = 480;
-               lcdc_info.ch[0].lcd_cfg.left_margin     = 220;
-               lcdc_info.ch[0].lcd_cfg.right_margin    = 110;
-               lcdc_info.ch[0].lcd_cfg.hsync_len       = 70;
-               lcdc_info.ch[0].lcd_cfg.upper_margin    = 20;
-               lcdc_info.ch[0].lcd_cfg.lower_margin    = 5;
-               lcdc_info.ch[0].lcd_cfg.vsync_len       = 5;
+               lcdc_info.ch[0].clock_divider           = 2;
+               lcdc_info.ch[0].lcd_cfg                 = ecovec_lcd_modes;
+               lcdc_info.ch[0].num_cfg                 = ARRAY_SIZE(ecovec_lcd_modes);
 
                gpio_set_value(GPIO_PTR1, 1);
 
diff --git a/arch/sh/boards/mach-edosk7705/Makefile b/arch/sh/boards/mach-edosk7705/Makefile
deleted file mode 100644 (file)
index cd54acb..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for the EDOSK7705 specific parts of the kernel
-#
-
-obj-y   := setup.o io.o
diff --git a/arch/sh/boards/mach-edosk7705/io.c b/arch/sh/boards/mach-edosk7705/io.c
deleted file mode 100644 (file)
index 5b9c57c..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * arch/sh/boards/renesas/edosk7705/io.c
- *
- * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
- * Based largely on io_se.c.
- *
- * I/O routines for Hitachi EDOSK7705 board.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/io.h>
-#include <mach/edosk7705.h>
-#include <asm/addrspace.h>
-
-#define SMC_IOADDR     0xA2000000
-
-/* Map the Ethernet addresses as if it is at 0x300 - 0x320 */
-static unsigned long sh_edosk7705_isa_port2addr(unsigned long port)
-{
-       /*
-        * SMC91C96 registers are 4 byte aligned rather than the
-        * usual 2 byte!
-        */
-       if (port >= 0x300 && port < 0x320)
-               return SMC_IOADDR + ((port - 0x300) * 2);
-
-       maybebadio(port);
-       return port;
-}
-
-/* Trying to read / write bytes on odd-byte boundaries to the Ethernet
- * registers causes problems. So we bit-shift the value and read / write
- * in 2 byte chunks. Setting the low byte to 0 does not cause problems
- * now as odd byte writes are only made on the bit mask / interrupt
- * register. This may not be the case in future Mar-2003 SJD
- */
-unsigned char sh_edosk7705_inb(unsigned long port)
-{
-       if (port >= 0x300 && port < 0x320 && port & 0x01)
-               return __raw_readw(port - 1) >> 8;
-
-       return __raw_readb(sh_edosk7705_isa_port2addr(port));
-}
-
-void sh_edosk7705_outb(unsigned char value, unsigned long port)
-{
-       if (port >= 0x300 && port < 0x320 && port & 0x01) {
-               __raw_writew(((unsigned short)value << 8), port - 1);
-               return;
-       }
-
-       __raw_writeb(value, sh_edosk7705_isa_port2addr(port));
-}
-
-void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count)
-{
-       unsigned char *p = addr;
-
-       while (count--)
-               *p++ = sh_edosk7705_inb(port);
-}
-
-void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count)
-{
-       unsigned char *p = (unsigned char *)addr;
-
-       while (count--)
-               sh_edosk7705_outb(*p++, port);
-}
diff --git a/arch/sh/boards/mach-edosk7705/setup.c b/arch/sh/boards/mach-edosk7705/setup.c
deleted file mode 100644 (file)
index d59225e..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * arch/sh/boards/renesas/edosk7705/setup.c
- *
- * Copyright (C) 2000  Kazumoto Kojima
- *
- * Hitachi SolutionEngine Support.
- *
- * Modified for edosk7705 development
- * board by S. Dunn, 2003.
- */
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <asm/machvec.h>
-#include <mach/edosk7705.h>
-
-static void __init sh_edosk7705_init_irq(void)
-{
-       /* This is the Ethernet interrupt */
-       make_imask_irq(0x09);
-}
-
-/*
- * The Machine Vector
- */
-static struct sh_machine_vector mv_edosk7705 __initmv = {
-       .mv_name                = "EDOSK7705",
-       .mv_nr_irqs             = 80,
-
-       .mv_inb                 = sh_edosk7705_inb,
-       .mv_outb                = sh_edosk7705_outb,
-
-       .mv_insb                = sh_edosk7705_insb,
-       .mv_outsb               = sh_edosk7705_outsb,
-
-       .mv_init_irq            = sh_edosk7705_init_irq,
-};
index 1742849db6489e9533d646a6a2baf98977bc53d4..9b60eaabf8f3d40c508c39589634370e8cbb1811 100644 (file)
@@ -126,6 +126,21 @@ static struct platform_device kfr2r09_sh_keysc_device = {
        },
 };
 
+const static struct fb_videomode kfr2r09_lcdc_modes[] = {
+       {
+               .name = "TX07D34VM0AAA",
+               .xres = 240,
+               .yres = 400,
+               .left_margin = 0,
+               .right_margin = 16,
+               .hsync_len = 8,
+               .upper_margin = 0,
+               .lower_margin = 1,
+               .vsync_len = 1,
+               .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+       },
+};
+
 static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
        .clock_source = LCDC_CLK_BUS,
        .ch[0] = {
@@ -134,18 +149,8 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
                .interface_type = SYS18,
                .clock_divider = 6,
                .flags = LCDC_FLAGS_DWPOL,
-               .lcd_cfg = {
-                       .name = "TX07D34VM0AAA",
-                       .xres = 240,
-                       .yres = 400,
-                       .left_margin = 0,
-                       .right_margin = 16,
-                       .hsync_len = 8,
-                       .upper_margin = 0,
-                       .lower_margin = 1,
-                       .vsync_len = 1,
-                       .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-               },
+               .lcd_cfg = kfr2r09_lcdc_modes,
+               .num_cfg = ARRAY_SIZE(kfr2r09_lcdc_modes),
                .lcd_size_cfg = {
                        .width = 35,
                        .height = 58,
index 2960c659020ee92e6c60c5c1d16d8d05ab73e267..acdafb0c6404a153cc482e46c0a17287f15ea26e 100644 (file)
@@ -54,7 +54,7 @@
 /*
  * map I/O ports to memory-mapped addresses
  */
-static unsigned long microdev_isa_port2addr(unsigned long offset)
+void __iomem *microdev_ioport_map(unsigned long offset, unsigned int len)
 {
        unsigned long result;
 
@@ -72,16 +72,6 @@ static unsigned long microdev_isa_port2addr(unsigned long offset)
                         *      Configuration Registers
                         */
                result = IO_SUPERIO_PHYS + (offset << 1);
-#if 0
-       } else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG ||
-                  offset == KBD_STATUS_REG) {
-                       /*
-                        *      SMSC FDC37C93xAPM SuperIO chip
-                        *
-                        *      PS/2 Keyboard + Mouse (ports 0x60 and 0x64).
-                        */
-               result = IO_SUPERIO_PHYS + (offset << 1);
-#endif
        } else if (((offset >= IO_IDE1_BASE) &&
                    (offset <  IO_IDE1_BASE + IO_IDE_EXTENT)) ||
                    (offset == IO_IDE1_MISC)) {
@@ -131,237 +121,5 @@ static unsigned long microdev_isa_port2addr(unsigned long offset)
                result = PVR;
        }
 
-       return result;
-}
-
-#define PORT2ADDR(x) (microdev_isa_port2addr(x))
-
-static inline void delay(void)
-{
-#if defined(CONFIG_PCI)
-       /* System board present, just make a dummy SRAM access.  (CS0 will be
-          mapped to PCI memory, probably good to avoid it.) */
-       __raw_readw(0xa6800000);
-#else
-       /* CS0 will be mapped to flash, ROM etc so safe to access it. */
-       __raw_readw(0xa0000000);
-#endif
-}
-
-unsigned char microdev_inb(unsigned long port)
-{
-#ifdef CONFIG_PCI
-       if (port >= PCIBIOS_MIN_IO)
-               return microdev_pci_inb(port);
-#endif
-       return *(volatile unsigned char*)PORT2ADDR(port);
-}
-
-unsigned short microdev_inw(unsigned long port)
-{
-#ifdef CONFIG_PCI
-       if (port >= PCIBIOS_MIN_IO)
-               return microdev_pci_inw(port);
-#endif
-       return *(volatile unsigned short*)PORT2ADDR(port);
-}
-
-unsigned int microdev_inl(unsigned long port)
-{
-#ifdef CONFIG_PCI
-       if (port >= PCIBIOS_MIN_IO)
-               return microdev_pci_inl(port);
-#endif
-       return *(volatile unsigned int*)PORT2ADDR(port);
-}
-
-void microdev_outw(unsigned short b, unsigned long port)
-{
-#ifdef CONFIG_PCI
-       if (port >= PCIBIOS_MIN_IO) {
-               microdev_pci_outw(b, port);
-               return;
-       }
-#endif
-       *(volatile unsigned short*)PORT2ADDR(port) = b;
-}
-
-void microdev_outb(unsigned char b, unsigned long port)
-{
-#ifdef CONFIG_PCI
-       if (port >= PCIBIOS_MIN_IO) {
-               microdev_pci_outb(b, port);
-               return;
-       }
-#endif
-
-       /*
-        *      There is a board feature with the current SH4-202 MicroDev in
-        *      that the 2 byte enables (nBE0 and nBE1) are tied together (and
-        *      to the Chip Select Line (Ethernet_CS)). Due to this connectivity,
-        *      it is not possible to safely perform 8-bit writes to the
-        *      Ethernet registers, as 16-bits will be consumed from the Data
-        *      lines (corrupting the other byte).  Hence, this function is
-        *      written to implement 16-bit read/modify/write for all byte-wide
-        *      accesses.
-        *
-        *      Note: there is no problem with byte READS (even or odd).
-        *
-        *                      Sean McGoogan - 16th June 2003.
-        */
-       if ((port >= IO_LAN91C111_BASE) &&
-           (port <  IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) {
-                       /*
-                        * Then are trying to perform a byte-write to the
-                        * LAN91C111.  This needs special care.
-                        */
-               if (port % 2 == 1) {    /* is the port odd ? */
-                       /* unset bit-0, i.e. make even */
-                       const unsigned long evenPort = port-1;
-                       unsigned short word;
-
-                       /*
-                        * do a 16-bit read/write to write to 'port',
-                        * preserving even byte.
-                        *
-                        *      Even addresses are bits 0-7
-                        *      Odd  addresses are bits 8-15
-                        */
-                       word = microdev_inw(evenPort);
-                       word = (word & 0xffu) | (b << 8);
-                       microdev_outw(word, evenPort);
-               } else {
-                       /* else, we are trying to do an even byte write */
-                       unsigned short word;
-
-                       /*
-                        * do a 16-bit read/write to write to 'port',
-                        * preserving odd byte.
-                        *
-                        *      Even addresses are bits 0-7
-                        *      Odd  addresses are bits 8-15
-                        */
-                       word = microdev_inw(port);
-                       word = (word & 0xff00u) | (b);
-                       microdev_outw(word, port);
-               }
-       } else {
-               *(volatile unsigned char*)PORT2ADDR(port) = b;
-       }
-}
-
-void microdev_outl(unsigned int b, unsigned long port)
-{
-#ifdef CONFIG_PCI
-       if (port >= PCIBIOS_MIN_IO) {
-               microdev_pci_outl(b, port);
-               return;
-       }
-#endif
-       *(volatile unsigned int*)PORT2ADDR(port) = b;
-}
-
-unsigned char microdev_inb_p(unsigned long port)
-{
-       unsigned char v = microdev_inb(port);
-       delay();
-       return v;
-}
-
-unsigned short microdev_inw_p(unsigned long port)
-{
-       unsigned short v = microdev_inw(port);
-       delay();
-       return v;
-}
-
-unsigned int microdev_inl_p(unsigned long port)
-{
-       unsigned int v = microdev_inl(port);
-       delay();
-       return v;
-}
-
-void microdev_outb_p(unsigned char b, unsigned long port)
-{
-       microdev_outb(b, port);
-       delay();
-}
-
-void microdev_outw_p(unsigned short b, unsigned long port)
-{
-       microdev_outw(b, port);
-       delay();
-}
-
-void microdev_outl_p(unsigned int b, unsigned long port)
-{
-       microdev_outl(b, port);
-       delay();
-}
-
-void microdev_insb(unsigned long port, void *buffer, unsigned long count)
-{
-       volatile unsigned char *port_addr;
-       unsigned char *buf = buffer;
-
-       port_addr = (volatile unsigned char *)PORT2ADDR(port);
-
-       while (count--)
-               *buf++ = *port_addr;
-}
-
-void microdev_insw(unsigned long port, void *buffer, unsigned long count)
-{
-       volatile unsigned short *port_addr;
-       unsigned short *buf = buffer;
-
-       port_addr = (volatile unsigned short *)PORT2ADDR(port);
-
-       while (count--)
-               *buf++ = *port_addr;
-}
-
-void microdev_insl(unsigned long port, void *buffer, unsigned long count)
-{
-       volatile unsigned long *port_addr;
-       unsigned int *buf = buffer;
-
-       port_addr = (volatile unsigned long *)PORT2ADDR(port);
-
-       while (count--)
-               *buf++ = *port_addr;
-}
-
-void microdev_outsb(unsigned long port, const void *buffer, unsigned long count)
-{
-       volatile unsigned char *port_addr;
-       const unsigned char *buf = buffer;
-
-       port_addr = (volatile unsigned char *)PORT2ADDR(port);
-
-       while (count--)
-               *port_addr = *buf++;
-}
-
-void microdev_outsw(unsigned long port, const void *buffer, unsigned long count)
-{
-       volatile unsigned short *port_addr;
-       const unsigned short *buf = buffer;
-
-       port_addr = (volatile unsigned short *)PORT2ADDR(port);
-
-       while (count--)
-               *port_addr = *buf++;
-}
-
-void microdev_outsl(unsigned long port, const void *buffer, unsigned long count)
-{
-       volatile unsigned long *port_addr;
-       const unsigned int *buf = buffer;
-
-       port_addr = (volatile unsigned long *)PORT2ADDR(port);
-
-       while (count--)
-               *port_addr = *buf++;
+       return (void __iomem *)result;
 }
index d1df2a4fb9b885913d38a90c49ff44f7bb0ace50..d8a747291e03ed82a829e20e4e779013881f1197 100644 (file)
@@ -195,27 +195,6 @@ device_initcall(microdev_devices_setup);
 static struct sh_machine_vector mv_sh4202_microdev __initmv = {
        .mv_name                = "SH4-202 MicroDev",
        .mv_nr_irqs             = 72,
-
-       .mv_inb                 = microdev_inb,
-       .mv_inw                 = microdev_inw,
-       .mv_inl                 = microdev_inl,
-       .mv_outb                = microdev_outb,
-       .mv_outw                = microdev_outw,
-       .mv_outl                = microdev_outl,
-
-       .mv_inb_p               = microdev_inb_p,
-       .mv_inw_p               = microdev_inw_p,
-       .mv_inl_p               = microdev_inl_p,
-       .mv_outb_p              = microdev_outb_p,
-       .mv_outw_p              = microdev_outw_p,
-       .mv_outl_p              = microdev_outl_p,
-
-       .mv_insb                = microdev_insb,
-       .mv_insw                = microdev_insw,
-       .mv_insl                = microdev_insl,
-       .mv_outsb               = microdev_outsb,
-       .mv_outsw               = microdev_outsw,
-       .mv_outsl               = microdev_outsl,
-
+       .mv_ioport_map          = microdev_ioport_map,
        .mv_init_irq            = init_microdev_irq,
 };
index 03af84842559919eb43f16c354e97c82e699cc3a..c8acfec986955046db7b22cf7615f769a3613b07 100644 (file)
@@ -213,51 +213,55 @@ static struct platform_device migor_nand_flash_device = {
        }
 };
 
+const static struct fb_videomode migor_lcd_modes[] = {
+       {
+#if defined(CONFIG_SH_MIGOR_RTA_WVGA)
+               .name = "LB070WV1",
+               .xres = 800,
+               .yres = 480,
+               .left_margin = 64,
+               .right_margin = 16,
+               .hsync_len = 120,
+               .sync = 0,
+#elif defined(CONFIG_SH_MIGOR_QVGA)
+               .name = "PH240320T",
+               .xres = 320,
+               .yres = 240,
+               .left_margin = 0,
+               .right_margin = 16,
+               .hsync_len = 8,
+               .sync = FB_SYNC_HOR_HIGH_ACT,
+#endif
+               .upper_margin = 1,
+               .lower_margin = 17,
+               .vsync_len = 2,
+       },
+};
+
 static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
-#ifdef CONFIG_SH_MIGOR_RTA_WVGA
+#if defined(CONFIG_SH_MIGOR_RTA_WVGA)
        .clock_source = LCDC_CLK_BUS,
        .ch[0] = {
                .chan = LCDC_CHAN_MAINLCD,
                .bpp = 16,
                .interface_type = RGB16,
                .clock_divider = 2,
-               .lcd_cfg = {
-                       .name = "LB070WV1",
-                       .xres = 800,
-                       .yres = 480,
-                       .left_margin = 64,
-                       .right_margin = 16,
-                       .hsync_len = 120,
-                       .upper_margin = 1,
-                       .lower_margin = 17,
-                       .vsync_len = 2,
-                       .sync = 0,
-               },
+               .lcd_cfg = migor_lcd_modes,
+               .num_cfg = ARRAY_SIZE(migor_lcd_modes),
                .lcd_size_cfg = { /* 7.0 inch */
                        .width = 152,
                        .height = 91,
                },
        }
-#endif
-#ifdef CONFIG_SH_MIGOR_QVGA
+#elif defined(CONFIG_SH_MIGOR_QVGA)
        .clock_source = LCDC_CLK_PERIPHERAL,
        .ch[0] = {
                .chan = LCDC_CHAN_MAINLCD,
                .bpp = 16,
                .interface_type = SYS16A,
                .clock_divider = 10,
-               .lcd_cfg = {
-                       .name = "PH240320T",
-                       .xres = 320,
-                       .yres = 240,
-                       .left_margin = 0,
-                       .right_margin = 16,
-                       .hsync_len = 8,
-                       .upper_margin = 1,
-                       .lower_margin = 17,
-                       .vsync_len = 2,
-                       .sync = FB_SYNC_HOR_HIGH_ACT,
-               },
+               .lcd_cfg = migor_lcd_modes,
+               .num_cfg = ARRAY_SIZE(migor_lcd_modes),
                .lcd_size_cfg = { /* 2.4 inch */
                        .width = 49,
                        .height = 37,
index 63e7ed699f39b3c41d8578daa8b57ce31807c689..5c9eaa0535b935c5f90bde958b0ca79724e1dcc2 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for the 7206 SolutionEngine specific parts of the kernel
 #
 
-obj-y   := setup.o io.o irq.o
+obj-y   := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7206/io.c b/arch/sh/boards/mach-se/7206/io.c
deleted file mode 100644 (file)
index adadc77..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $
- *
- * linux/arch/sh/boards/se/7206/io.c
- *
- * Copyright (C) 2006 Yoshinori Sato
- *
- * I/O routine for Hitachi 7206 SolutionEngine.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <asm/io.h>
-#include <mach-se/mach/se7206.h>
-
-
-static inline void delay(void)
-{
-       __raw_readw(0x20000000);  /* P2 ROM Area */
-}
-
-/* MS7750 requires special versions of in*, out* routines, since
-   PC-like io ports are located at upper half byte of 16-bit word which
-   can be accessed only with 16-bit wide.  */
-
-static inline volatile __u16 *
-port2adr(unsigned int port)
-{
-       if (port >= 0x2000 && port < 0x2020)
-               return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
-       else if (port >= 0x300 && port < 0x310)
-               return (volatile __u16 *) (PA_SMSC + (port - 0x300));
-
-       return (volatile __u16 *)port;
-}
-
-unsigned char se7206_inb(unsigned long port)
-{
-       return (*port2adr(port)) & 0xff;
-}
-
-unsigned char se7206_inb_p(unsigned long port)
-{
-       unsigned long v;
-
-       v = (*port2adr(port)) & 0xff;
-       delay();
-       return v;
-}
-
-unsigned short se7206_inw(unsigned long port)
-{
-       return *port2adr(port);
-}
-
-void se7206_outb(unsigned char value, unsigned long port)
-{
-       *(port2adr(port)) = value;
-}
-
-void se7206_outb_p(unsigned char value, unsigned long port)
-{
-       *(port2adr(port)) = value;
-       delay();
-}
-
-void se7206_outw(unsigned short value, unsigned long port)
-{
-       *port2adr(port) = value;
-}
-
-void se7206_insb(unsigned long port, void *addr, unsigned long count)
-{
-       volatile __u16 *p = port2adr(port);
-       __u8 *ap = addr;
-
-       while (count--)
-               *ap++ = *p;
-}
-
-void se7206_insw(unsigned long port, void *addr, unsigned long count)
-{
-       volatile __u16 *p = port2adr(port);
-       __u16 *ap = addr;
-       while (count--)
-               *ap++ = *p;
-}
-
-void se7206_outsb(unsigned long port, const void *addr, unsigned long count)
-{
-       volatile __u16 *p = port2adr(port);
-       const __u8 *ap = addr;
-
-       while (count--)
-               *p = *ap++;
-}
-
-void se7206_outsw(unsigned long port, const void *addr, unsigned long count)
-{
-       volatile __u16 *p = port2adr(port);
-       const __u16 *ap = addr;
-       while (count--)
-               *p = *ap++;
-}
index 883b21eacaa686d00efbf822911dac79e6e220d5..d961949600fd462199f3d9706e86371e815e7b1b 100644 (file)
@@ -139,11 +139,13 @@ void __init init_se7206_IRQ(void)
        make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */
        make_se7206_irq(IRQ1_IRQ); /* ATA */
        make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
-       __raw_writew(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */
+
+       __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */
 
        /* FPGA System register setup*/
        __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */
        __raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */
+
        /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */
        __raw_writew(0x0001,INTSEL);
 }
index 8f5c65d43d1d85a6e1db054cd5f065ee3aa72119..7f4871c71a01813dbd11882d9c55469d46359ce0 100644 (file)
@@ -86,20 +86,5 @@ __initcall(se7206_devices_setup);
 static struct sh_machine_vector mv_se __initmv = {
        .mv_name                = "SolutionEngine",
        .mv_nr_irqs             = 256,
-       .mv_inb                 = se7206_inb,
-       .mv_inw                 = se7206_inw,
-       .mv_outb                = se7206_outb,
-       .mv_outw                = se7206_outw,
-
-       .mv_inb_p               = se7206_inb_p,
-       .mv_inw_p               = se7206_inw,
-       .mv_outb_p              = se7206_outb_p,
-       .mv_outw_p              = se7206_outw,
-
-       .mv_insb                = se7206_insb,
-       .mv_insw                = se7206_insw,
-       .mv_outsb               = se7206_outsb,
-       .mv_outsw               = se7206_outsw,
-
        .mv_init_irq            = init_se7206_IRQ,
 };
index 8e624b06d5ea67efc746ecab0716485d9a4742bc..43ea14feef51094d032c5b7eec98b35deff925f8 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for the 770x SolutionEngine specific parts of the kernel
 #
 
-obj-y   := setup.o io.o irq.o
+obj-y   := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/770x/io.c b/arch/sh/boards/mach-se/770x/io.c
deleted file mode 100644 (file)
index 28833c8..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2000  Kazumoto Kojima
- *
- * I/O routine for Hitachi SolutionEngine.
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <asm/io.h>
-#include <mach-se/mach/se.h>
-
-/* MS7750 requires special versions of in*, out* routines, since
-   PC-like io ports are located at upper half byte of 16-bit word which
-   can be accessed only with 16-bit wide.  */
-
-static inline volatile __u16 *
-port2adr(unsigned int port)
-{
-       if (port & 0xff000000)
-               return ( volatile __u16 *) port;
-       if (port >= 0x2000)
-               return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
-       else if (port >= 0x1000)
-               return (volatile __u16 *) (PA_83902 + (port << 1));
-       else
-               return (volatile __u16 *) (PA_SUPERIO + (port << 1));
-}
-
-static inline int
-shifted_port(unsigned long port)
-{
-       /* For IDE registers, value is not shifted */
-       if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
-               return 0;
-       else
-               return 1;
-}
-
-unsigned char se_inb(unsigned long port)
-{
-       if (shifted_port(port))
-               return (*port2adr(port) >> 8);
-       else
-               return (*port2adr(port))&0xff;
-}
-
-unsigned char se_inb_p(unsigned long port)
-{
-       unsigned long v;
-
-       if (shifted_port(port))
-               v = (*port2adr(port) >> 8);
-       else
-               v = (*port2adr(port))&0xff;
-       ctrl_delay();
-       return v;
-}
-
-unsigned short se_inw(unsigned long port)
-{
-       if (port >= 0x2000)
-               return *port2adr(port);
-       else
-               maybebadio(port);
-       return 0;
-}
-
-unsigned int se_inl(unsigned long port)
-{
-       maybebadio(port);
-       return 0;
-}
-
-void se_outb(unsigned char value, unsigned long port)
-{
-       if (shifted_port(port))
-               *(port2adr(port)) = value << 8;
-       else
-               *(port2adr(port)) = value;
-}
-
-void se_outb_p(unsigned char value, unsigned long port)
-{
-       if (shifted_port(port))
-               *(port2adr(port)) = value << 8;
-       else
-               *(port2adr(port)) = value;
-       ctrl_delay();
-}
-
-void se_outw(unsigned short value, unsigned long port)
-{
-       if (port >= 0x2000)
-               *port2adr(port) = value;
-       else
-               maybebadio(port);
-}
-
-void se_outl(unsigned int value, unsigned long port)
-{
-       maybebadio(port);
-}
-
-void se_insb(unsigned long port, void *addr, unsigned long count)
-{
-       volatile __u16 *p = port2adr(port);
-       __u8 *ap = addr;
-
-       if (shifted_port(port)) {
-               while (count--)
-                       *ap++ = *p >> 8;
-       } else {
-               while (count--)
-                       *ap++ = *p;
-       }
-}
-
-void se_insw(unsigned long port, void *addr, unsigned long count)
-{
-       volatile __u16 *p = port2adr(port);
-       __u16 *ap = addr;
-       while (count--)
-               *ap++ = *p;
-}
-
-void se_insl(unsigned long port, void *addr, unsigned long count)
-{
-       maybebadio(port);
-}
-
-void se_outsb(unsigned long port, const void *addr, unsigned long count)
-{
-       volatile __u16 *p = port2adr(port);
-       const __u8 *ap = addr;
-
-       if (shifted_port(port)) {
-               while (count--)
-                       *p = *ap++ << 8;
-       } else {
-               while (count--)
-                       *p = *ap++;
-       }
-}
-
-void se_outsw(unsigned long port, const void *addr, unsigned long count)
-{
-       volatile __u16 *p = port2adr(port);
-       const __u16 *ap = addr;
-
-       while (count--)
-               *p = *ap++;
-}
-
-void se_outsl(unsigned long port, const void *addr, unsigned long count)
-{
-       maybebadio(port);
-}
index 66d39d1b0901de5a9b6da4c7fb7978223b18b502..31330c65c0cec9aa1b78abb69e5bcb95c9c4cd80 100644 (file)
@@ -195,27 +195,5 @@ static struct sh_machine_vector mv_se __initmv = {
 #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
        .mv_nr_irqs             = 104,
 #endif
-
-       .mv_inb                 = se_inb,
-       .mv_inw                 = se_inw,
-       .mv_inl                 = se_inl,
-       .mv_outb                = se_outb,
-       .mv_outw                = se_outw,
-       .mv_outl                = se_outl,
-
-       .mv_inb_p               = se_inb_p,
-       .mv_inw_p               = se_inw,
-       .mv_inl_p               = se_inl,
-       .mv_outb_p              = se_outb_p,
-       .mv_outw_p              = se_outw,
-       .mv_outl_p              = se_outl,
-
-       .mv_insb                = se_insb,
-       .mv_insw                = se_insw,
-       .mv_insl                = se_insl,
-       .mv_outsb               = se_outsb,
-       .mv_outsw               = se_outsw,
-       .mv_outsl               = se_outsl,
-
        .mv_init_irq            = init_se_IRQ,
 };
index 8cc1d7295d8509eb27c6fa9e057c0f00609d4b0f..c31d228fdfc6257d248c28f0fac88ba274dc52b1 100644 (file)
@@ -144,16 +144,42 @@ static struct platform_device nor_flash_device = {
 };
 
 /* LCDC */
+const static struct fb_videomode lcdc_720p_modes[] = {
+       {
+               .name           = "LB070WV1",
+               .sync           = 0, /* hsync and vsync are active low */
+               .xres           = 1280,
+               .yres           = 720,
+               .left_margin    = 220,
+               .right_margin   = 110,
+               .hsync_len      = 40,
+               .upper_margin   = 20,
+               .lower_margin   = 5,
+               .vsync_len      = 5,
+       },
+};
+
+const static struct fb_videomode lcdc_vga_modes[] = {
+       {
+               .name           = "LB070WV1",
+               .sync           = 0, /* hsync and vsync are active low */
+               .xres           = 640,
+               .yres           = 480,
+               .left_margin    = 105,
+               .right_margin   = 50,
+               .hsync_len      = 96,
+               .upper_margin   = 33,
+               .lower_margin   = 10,
+               .vsync_len      = 2,
+       },
+};
+
 static struct sh_mobile_lcdc_info lcdc_info = {
        .clock_source = LCDC_CLK_EXTERNAL,
        .ch[0] = {
                .chan = LCDC_CHAN_MAINLCD,
                .bpp = 16,
                .clock_divider = 1,
-               .lcd_cfg = {
-                       .name = "LB070WV1",
-                       .sync = 0, /* hsync and vsync are active low */
-               },
                .lcd_size_cfg = { /* 7.0 inch */
                        .width = 152,
                        .height = 91,
@@ -908,24 +934,12 @@ static int __init devices_setup(void)
 
        if (sw & SW41_B) {
                /* 720p */
-               lcdc_info.ch[0].lcd_cfg.xres         = 1280;
-               lcdc_info.ch[0].lcd_cfg.yres         = 720;
-               lcdc_info.ch[0].lcd_cfg.left_margin  = 220;
-               lcdc_info.ch[0].lcd_cfg.right_margin = 110;
-               lcdc_info.ch[0].lcd_cfg.hsync_len    = 40;
-               lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
-               lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
-               lcdc_info.ch[0].lcd_cfg.vsync_len    = 5;
+               lcdc_info.ch[0].lcd_cfg = lcdc_720p_modes;
+               lcdc_info.ch[0].num_cfg = ARRAY_SIZE(lcdc_720p_modes);
        } else {
                /* VGA */
-               lcdc_info.ch[0].lcd_cfg.xres         = 640;
-               lcdc_info.ch[0].lcd_cfg.yres         = 480;
-               lcdc_info.ch[0].lcd_cfg.left_margin  = 105;
-               lcdc_info.ch[0].lcd_cfg.right_margin = 50;
-               lcdc_info.ch[0].lcd_cfg.hsync_len    = 96;
-               lcdc_info.ch[0].lcd_cfg.upper_margin = 33;
-               lcdc_info.ch[0].lcd_cfg.lower_margin = 10;
-               lcdc_info.ch[0].lcd_cfg.vsync_len    = 2;
+               lcdc_info.ch[0].lcd_cfg = lcdc_vga_modes;
+               lcdc_info.ch[0].num_cfg = ARRAY_SIZE(lcdc_vga_modes);
        }
 
        if (sw & SW41_A) {
index e6f4341bfe6eaa0467e60dfb56ae08688ea5a9c0..a338fd9d503944f84b4e84b5a3a3e7cccc4a5fcb 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for the 7751 SolutionEngine specific parts of the kernel
 #
 
-obj-y   := setup.o io.o irq.o
+obj-y   := setup.o irq.o
diff --git a/arch/sh/boards/mach-se/7751/io.c b/arch/sh/boards/mach-se/7751/io.c
deleted file mode 100644 (file)
index 6e75bd4..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
- * Based largely on io_se.c.
- *
- * I/O routine for Hitachi 7751 SolutionEngine.
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_se.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <mach-se/mach/se7751.h>
-#include <asm/addrspace.h>
-
-static inline volatile u16 *port2adr(unsigned int port)
-{
-       if (port >= 0x2000)
-               return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
-       maybebadio((unsigned long)port);
-       return (volatile __u16*)port;
-}
-
-/*
- * General outline: remap really low stuff [eventually] to SuperIO,
- * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
- * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
- * should be way beyond the window, and is used  w/o translation for
- * compatibility.
- */
-unsigned char sh7751se_inb(unsigned long port)
-{
-       if (PXSEG(port))
-               return *(volatile unsigned char *)port;
-       else
-               return (*port2adr(port)) & 0xff;
-}
-
-unsigned char sh7751se_inb_p(unsigned long port)
-{
-       unsigned char v;
-
-        if (PXSEG(port))
-                v = *(volatile unsigned char *)port;
-       else
-               v = (*port2adr(port)) & 0xff;
-       ctrl_delay();
-       return v;
-}
-
-unsigned short sh7751se_inw(unsigned long port)
-{
-        if (PXSEG(port))
-                return *(volatile unsigned short *)port;
-       else if (port >= 0x2000)
-               return *port2adr(port);
-       else
-               maybebadio(port);
-       return 0;
-}
-
-unsigned int sh7751se_inl(unsigned long port)
-{
-        if (PXSEG(port))
-                return *(volatile unsigned long *)port;
-       else if (port >= 0x2000)
-               return *port2adr(port);
-       else
-               maybebadio(port);
-       return 0;
-}
-
-void sh7751se_outb(unsigned char value, unsigned long port)
-{
-
-        if (PXSEG(port))
-                *(volatile unsigned char *)port = value;
-       else
-               *(port2adr(port)) = value;
-}
-
-void sh7751se_outb_p(unsigned char value, unsigned long port)
-{
-        if (PXSEG(port))
-                *(volatile unsigned char *)port = value;
-       else
-               *(port2adr(port)) = value;
-       ctrl_delay();
-}
-
-void sh7751se_outw(unsigned short value, unsigned long port)
-{
-        if (PXSEG(port))
-                *(volatile unsigned short *)port = value;
-       else if (port >= 0x2000)
-               *port2adr(port) = value;
-       else
-               maybebadio(port);
-}
-
-void sh7751se_outl(unsigned int value, unsigned long port)
-{
-        if (PXSEG(port))
-                *(volatile unsigned long *)port = value;
-       else
-               maybebadio(port);
-}
-
-void sh7751se_insl(unsigned long port, void *addr, unsigned long count)
-{
-       maybebadio(port);
-}
-
-void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count)
-{
-       maybebadio(port);
-}
index 50572512e3e84a6db630114a57415153fd4e0506..9fbc51beb1812dfafd10a91cf7b6c02c1cabfdce 100644 (file)
@@ -56,23 +56,5 @@ __initcall(se7751_devices_setup);
 static struct sh_machine_vector mv_7751se __initmv = {
        .mv_name                = "7751 SolutionEngine",
        .mv_nr_irqs             = 72,
-
-       .mv_inb                 = sh7751se_inb,
-       .mv_inw                 = sh7751se_inw,
-       .mv_inl                 = sh7751se_inl,
-       .mv_outb                = sh7751se_outb,
-       .mv_outw                = sh7751se_outw,
-       .mv_outl                = sh7751se_outl,
-
-       .mv_inb_p               = sh7751se_inb_p,
-       .mv_inw_p               = sh7751se_inw,
-       .mv_inl_p               = sh7751se_inl,
-       .mv_outb_p              = sh7751se_outb_p,
-       .mv_outw_p              = sh7751se_outw,
-       .mv_outl_p              = sh7751se_outl,
-
-       .mv_insl                = sh7751se_insl,
-       .mv_outsl               = sh7751se_outsl,
-
        .mv_init_irq            = init_7751se_IRQ,
 };
diff --git a/arch/sh/boards/mach-snapgear/Makefile b/arch/sh/boards/mach-snapgear/Makefile
deleted file mode 100644 (file)
index d2d2f4b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for the SnapGear specific parts of the kernel
-#
-
-obj-y   := setup.o io.o
diff --git a/arch/sh/boards/mach-snapgear/io.c b/arch/sh/boards/mach-snapgear/io.c
deleted file mode 100644 (file)
index 476650e..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2002  David McCullough <davidm@snapgear.com>
- * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
- * Based largely on io_se.c.
- *
- * I/O routine for Hitachi 7751 SolutionEngine.
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_se.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/addrspace.h>
-
-#ifdef CONFIG_SH_SECUREEDGE5410
-unsigned short secureedge5410_ioport;
-#endif
-
-static inline volatile __u16 *port2adr(unsigned int port)
-{
-       maybebadio((unsigned long)port);
-       return (volatile __u16*)port;
-}
-
-/*
- * General outline: remap really low stuff [eventually] to SuperIO,
- * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
- * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
- * should be way beyond the window, and is used  w/o translation for
- * compatibility.
- */
-unsigned char snapgear_inb(unsigned long port)
-{
-       if (PXSEG(port))
-               return *(volatile unsigned char *)port;
-       else
-               return (*port2adr(port)) & 0xff;
-}
-
-unsigned char snapgear_inb_p(unsigned long port)
-{
-       unsigned char v;
-
-       if (PXSEG(port))
-               v = *(volatile unsigned char *)port;
-       else
-               v = (*port2adr(port))&0xff;
-       ctrl_delay();
-       return v;
-}
-
-unsigned short snapgear_inw(unsigned long port)
-{
-       if (PXSEG(port))
-               return *(volatile unsigned short *)port;
-       else if (port >= 0x2000)
-               return *port2adr(port);
-       else
-               maybebadio(port);
-       return 0;
-}
-
-unsigned int snapgear_inl(unsigned long port)
-{
-       if (PXSEG(port))
-               return *(volatile unsigned long *)port;
-       else if (port >= 0x2000)
-               return *port2adr(port);
-       else
-               maybebadio(port);
-       return 0;
-}
-
-void snapgear_outb(unsigned char value, unsigned long port)
-{
-
-       if (PXSEG(port))
-               *(volatile unsigned char *)port = value;
-       else
-               *(port2adr(port)) = value;
-}
-
-void snapgear_outb_p(unsigned char value, unsigned long port)
-{
-       if (PXSEG(port))
-               *(volatile unsigned char *)port = value;
-       else
-               *(port2adr(port)) = value;
-       ctrl_delay();
-}
-
-void snapgear_outw(unsigned short value, unsigned long port)
-{
-       if (PXSEG(port))
-               *(volatile unsigned short *)port = value;
-       else if (port >= 0x2000)
-               *port2adr(port) = value;
-       else
-               maybebadio(port);
-}
-
-void snapgear_outl(unsigned int value, unsigned long port)
-{
-       if (PXSEG(port))
-               *(volatile unsigned long *)port = value;
-       else
-               maybebadio(port);
-}
-
-void snapgear_insl(unsigned long port, void *addr, unsigned long count)
-{
-       maybebadio(port);
-}
-
-void snapgear_outsl(unsigned long port, const void *addr, unsigned long count)
-{
-       maybebadio(port);
-}
diff --git a/arch/sh/boards/mach-snapgear/setup.c b/arch/sh/boards/mach-snapgear/setup.c
deleted file mode 100644 (file)
index 331745d..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * linux/arch/sh/boards/snapgear/setup.c
- *
- * Copyright (C) 2002  David McCullough <davidm@snapgear.com>
- * Copyright (C) 2003  Paul Mundt <lethal@linux-sh.org>
- *
- * Based on files with the following comments:
- *
- *           Copyright (C) 2000  Kazumoto Kojima
- *
- *           Modified for 7751 Solution Engine by
- *           Ian da Silva and Jeremy Siegel, 2001.
- */
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <asm/machvec.h>
-#include <mach/snapgear.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <cpu/timer.h>
-
-/*
- * EraseConfig handling functions
- */
-
-static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
-{
-       (void)__raw_readb(0xb8000000);  /* dummy read */
-
-       printk("SnapGear: erase switch interrupt!\n");
-
-       return IRQ_HANDLED;
-}
-
-static int __init eraseconfig_init(void)
-{
-       printk("SnapGear: EraseConfig init\n");
-       /* Setup "EraseConfig" switch on external IRQ 0 */
-       if (request_irq(IRL0_IRQ, eraseconfig_interrupt, IRQF_DISABLED,
-                               "Erase Config", NULL))
-               printk("SnapGear: failed to register IRQ%d for Reset witch\n",
-                               IRL0_IRQ);
-       else
-               printk("SnapGear: registered EraseConfig switch on IRQ%d\n",
-                               IRL0_IRQ);
-       return(0);
-}
-
-module_init(eraseconfig_init);
-
-/****************************************************************************/
-/*
- * Initialize IRQ setting
- *
- * IRL0 = erase switch
- * IRL1 = eth0
- * IRL2 = eth1
- * IRL3 = crypto
- */
-
-static void __init init_snapgear_IRQ(void)
-{
-       printk("Setup SnapGear IRQ/IPR ...\n");
-       /* enable individual interrupt mode for externals */
-       plat_irq_setup_pins(IRQ_MODE_IRQ);
-}
-
-/*
- * The Machine Vector
- */
-static struct sh_machine_vector mv_snapgear __initmv = {
-       .mv_name                = "SnapGear SecureEdge5410",
-       .mv_nr_irqs             = 72,
-
-       .mv_inb                 = snapgear_inb,
-       .mv_inw                 = snapgear_inw,
-       .mv_inl                 = snapgear_inl,
-       .mv_outb                = snapgear_outb,
-       .mv_outw                = snapgear_outw,
-       .mv_outl                = snapgear_outl,
-
-       .mv_inb_p               = snapgear_inb_p,
-       .mv_inw_p               = snapgear_inw,
-       .mv_inl_p               = snapgear_inl,
-       .mv_outb_p              = snapgear_outb_p,
-       .mv_outw_p              = snapgear_outw,
-       .mv_outl_p              = snapgear_outl,
-
-       .mv_init_irq            = init_snapgear_IRQ,
-};
diff --git a/arch/sh/boards/mach-systemh/Makefile b/arch/sh/boards/mach-systemh/Makefile
deleted file mode 100644 (file)
index 2cc6a23..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Makefile for the SystemH specific parts of the kernel
-#
-
-obj-y   := setup.o irq.o io.o
-
-# XXX: This wants to be consolidated in arch/sh/drivers/pci, and more
-# importantly, with the generic sh7751_pcic_init() code. For now, we'll
-# just abuse the hell out of kbuild, because we can..
-
-obj-$(CONFIG_PCI) += pci.o
-pci-y := ../../se/7751/pci.o
-
diff --git a/arch/sh/boards/mach-systemh/io.c b/arch/sh/boards/mach-systemh/io.c
deleted file mode 100644 (file)
index 15577ff..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * linux/arch/sh/boards/renesas/systemh/io.c
- *
- * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
- * Based largely on io_se.c.
- *
- * I/O routine for Hitachi 7751 Systemh.
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <mach/systemh7751.h>
-#include <asm/addrspace.h>
-#include <asm/io.h>
-
-#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area
-                                                of smc lan chip*/
-static inline volatile __u16 *
-port2adr(unsigned int port)
-{
-       if (port >= 0x2000)
-               return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
-       maybebadio((unsigned long)port);
-       return (volatile __u16*)port;
-}
-
-/*
- * General outline: remap really low stuff [eventually] to SuperIO,
- * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
- * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
- * should be way beyond the window, and is used  w/o translation for
- * compatibility.
- */
-unsigned char sh7751systemh_inb(unsigned long port)
-{
-       if (PXSEG(port))
-               return *(volatile unsigned char *)port;
-       else if (port <= 0x3F1)
-               return *(volatile unsigned char *)ETHER_IOMAP(port);
-       else
-               return (*port2adr(port))&0xff;
-}
-
-unsigned char sh7751systemh_inb_p(unsigned long port)
-{
-       unsigned char v;
-
-        if (PXSEG(port))
-                v = *(volatile unsigned char *)port;
-       else if (port <= 0x3F1)
-               v = *(volatile unsigned char *)ETHER_IOMAP(port);
-       else
-               v = (*port2adr(port))&0xff;
-       ctrl_delay();
-       return v;
-}
-
-unsigned short sh7751systemh_inw(unsigned long port)
-{
-        if (PXSEG(port))
-                return *(volatile unsigned short *)port;
-       else if (port >= 0x2000)
-               return *port2adr(port);
-       else if (port <= 0x3F1)
-               return *(volatile unsigned int *)ETHER_IOMAP(port);
-       else
-               maybebadio(port);
-       return 0;
-}
-
-unsigned int sh7751systemh_inl(unsigned long port)
-{
-        if (PXSEG(port))
-                return *(volatile unsigned long *)port;
-       else if (port >= 0x2000)
-               return *port2adr(port);
-       else if (port <= 0x3F1)
-               return *(volatile unsigned int *)ETHER_IOMAP(port);
-       else
-               maybebadio(port);
-       return 0;
-}
-
-void sh7751systemh_outb(unsigned char value, unsigned long port)
-{
-
-        if (PXSEG(port))
-                *(volatile unsigned char *)port = value;
-       else if (port <= 0x3F1)
-               *(volatile unsigned char *)ETHER_IOMAP(port) = value;
-       else
-               *(port2adr(port)) = value;
-}
-
-void sh7751systemh_outb_p(unsigned char value, unsigned long port)
-{
-        if (PXSEG(port))
-                *(volatile unsigned char *)port = value;
-       else if (port <= 0x3F1)
-               *(volatile unsigned char *)ETHER_IOMAP(port) = value;
-       else
-               *(port2adr(port)) = value;
-       ctrl_delay();
-}
-
-void sh7751systemh_outw(unsigned short value, unsigned long port)
-{
-        if (PXSEG(port))
-                *(volatile unsigned short *)port = value;
-       else if (port >= 0x2000)
-               *port2adr(port) = value;
-       else if (port <= 0x3F1)
-               *(volatile unsigned short *)ETHER_IOMAP(port) = value;
-       else
-               maybebadio(port);
-}
-
-void sh7751systemh_outl(unsigned int value, unsigned long port)
-{
-        if (PXSEG(port))
-                *(volatile unsigned long *)port = value;
-       else
-               maybebadio(port);
-}
-
-void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count)
-{
-       unsigned char *p = addr;
-       while (count--) *p++ = sh7751systemh_inb(port);
-}
-
-void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count)
-{
-       unsigned short *p = addr;
-       while (count--) *p++ = sh7751systemh_inw(port);
-}
-
-void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count)
-{
-       maybebadio(port);
-}
-
-void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count)
-{
-       unsigned char *p = (unsigned char*)addr;
-       while (count--) sh7751systemh_outb(*p++, port);
-}
-
-void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count)
-{
-       unsigned short *p = (unsigned short*)addr;
-       while (count--) sh7751systemh_outw(*p++, port);
-}
-
-void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count)
-{
-       maybebadio(port);
-}
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c
deleted file mode 100644 (file)
index e5ee13a..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * linux/arch/sh/boards/renesas/systemh/irq.c
- *
- * Copyright (C) 2000  Kazumoto Kojima
- *
- * Hitachi SystemH Support.
- *
- * Modified for 7751 SystemH by
- * Jonathan Short.
- */
-
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-
-#include <mach/systemh7751.h>
-#include <asm/smc37c93x.h>
-
-/* address of external interrupt mask register
- * address must be set prior to use these (maybe in init_XXX_irq())
- * XXX : is it better to use .config than specifying it in code? */
-static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004;
-static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000;
-
-static void disable_systemh_irq(struct irq_data *data)
-{
-       unsigned long val, mask = 0x01 << 1;
-
-       /* Clear the "irq"th bit in the mask and set it in the request */
-       val = __raw_readl((unsigned long)systemh_irq_mask_register);
-       val &= ~mask;
-       __raw_writel(val, (unsigned long)systemh_irq_mask_register);
-
-       val = __raw_readl((unsigned long)systemh_irq_request_register);
-       val |= mask;
-       __raw_writel(val, (unsigned long)systemh_irq_request_register);
-}
-
-static void enable_systemh_irq(struct irq_data *data)
-{
-       unsigned long val, mask = 0x01 << 1;
-
-       /* Set "irq"th bit in the mask register */
-       val = __raw_readl((unsigned long)systemh_irq_mask_register);
-       val |= mask;
-       __raw_writel(val, (unsigned long)systemh_irq_mask_register);
-}
-
-static struct irq_chip systemh_irq_type = {
-       .name           = "SystemH Register",
-       .irq_unmask     = enable_systemh_irq,
-       .irq_mask       = disable_systemh_irq,
-};
-
-void make_systemh_irq(unsigned int irq)
-{
-       disable_irq_nosync(irq);
-       set_irq_chip_and_handler(irq, &systemh_irq_type, handle_level_irq);
-       disable_systemh_irq(irq_get_irq_data(irq));
-}
diff --git a/arch/sh/boards/mach-systemh/setup.c b/arch/sh/boards/mach-systemh/setup.c
deleted file mode 100644 (file)
index 219fd80..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * linux/arch/sh/boards/renesas/systemh/setup.c
- *
- * Copyright (C) 2000  Kazumoto Kojima
- * Copyright (C) 2003  Paul Mundt
- *
- * Hitachi SystemH Support.
- *
- * Modified for 7751 SystemH by Jonathan Short.
- *
- * Rewritten for 2.6 by 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
- * for more details.
- */
-#include <linux/init.h>
-#include <asm/machvec.h>
-#include <mach/systemh7751.h>
-
-extern void make_systemh_irq(unsigned int irq);
-
-/*
- * Initialize IRQ setting
- */
-static void __init sh7751systemh_init_irq(void)
-{
-       make_systemh_irq(0xb);  /* Ethernet interrupt */
-}
-
-static struct sh_machine_vector mv_7751systemh __initmv = {
-       .mv_name                = "7751 SystemH",
-       .mv_nr_irqs             = 72,
-
-       .mv_inb                 = sh7751systemh_inb,
-       .mv_inw                 = sh7751systemh_inw,
-       .mv_inl                 = sh7751systemh_inl,
-       .mv_outb                = sh7751systemh_outb,
-       .mv_outw                = sh7751systemh_outw,
-       .mv_outl                = sh7751systemh_outl,
-
-       .mv_inb_p               = sh7751systemh_inb_p,
-       .mv_inw_p               = sh7751systemh_inw,
-       .mv_inl_p               = sh7751systemh_inl,
-       .mv_outb_p              = sh7751systemh_outb_p,
-       .mv_outw_p              = sh7751systemh_outw,
-       .mv_outl_p              = sh7751systemh_outl,
-
-       .mv_insb                = sh7751systemh_insb,
-       .mv_insw                = sh7751systemh_insw,
-       .mv_insl                = sh7751systemh_insl,
-       .mv_outsb               = sh7751systemh_outsb,
-       .mv_outsw               = sh7751systemh_outsw,
-       .mv_outsl               = sh7751systemh_outsl,
-
-       .mv_init_irq            = sh7751systemh_init_irq,
-};
diff --git a/arch/sh/configs/secureedge5410_defconfig b/arch/sh/configs/secureedge5410_defconfig
new file mode 100644 (file)
index 0000000..7eae4e5
--- /dev/null
@@ -0,0 +1,63 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_CPU_SUBTYPE_SH7751R=y
+CONFIG_MEMORY_SIZE=0x01000000
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_SH_SECUREEDGE5410=y
+CONFIG_SH_DMA=y
+CONFIG_SH_DMA_API=y
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_INET=y
+# 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_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK_RO=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_8139CP=y
+CONFIG_8139TOO=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1302=y
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
deleted file mode 100644 (file)
index 7eae4e5..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_SLAB=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_CPU_SUBTYPE_SH7751R=y
-CONFIG_MEMORY_SIZE=0x01000000
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_SH_SECUREEDGE5410=y
-CONFIG_SH_DMA=y
-CONFIG_SH_DMA_API=y
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_INET=y
-# 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_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK_RO=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
-# CONFIG_MTD_CFI_I2 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PLATRAM=y
-CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_NET_PCI=y
-CONFIG_8139CP=y
-CONFIG_8139TOO=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_DS1302=y
-CONFIG_EXT2_FS=y
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_ROMFS_FS=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
deleted file mode 100644 (file)
index b58dfc5..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_CPU_SUBTYPE_SH7751R=y
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x00400000
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_SH_7751_SYSTEMH=y
-CONFIG_PREEMPT=y
-# CONFIG_STANDALONE is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=1024
-# CONFIG_INPUT is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_VT is not set
-CONFIG_HW_RANDOM=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_ROMFS_FS=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
index 446b3831c2149380265476f47674d4ad4ea72b1e..3d1ae2bfaa6fd7056701e8ddc41538d94a4a1a71 100644 (file)
 /*
  * These will never work in 32-bit, don't even bother.
  */
-#define P1SEGADDR(a)   __futile_remapping_attempt
-#define P2SEGADDR(a)   __futile_remapping_attempt
-#define P3SEGADDR(a)   __futile_remapping_attempt
-#define P4SEGADDR(a)   __futile_remapping_attempt
+#define P1SEGADDR(a)   ({ (void)(a); BUG(); NULL; })
+#define P2SEGADDR(a)   ({ (void)(a); BUG(); NULL; })
+#define P3SEGADDR(a)   ({ (void)(a); BUG(); NULL; })
+#define P4SEGADDR(a)   ({ (void)(a); BUG(); NULL; })
 #endif
 #endif /* P1SEG */
 
index a15f1058bbf439b8895f1b3d277f7e1bcf05c6aa..083ea068e819e80a389d5610bc9e19243d4ed950 100644 (file)
@@ -66,7 +66,6 @@ static inline unsigned long long neff_sign_extend(unsigned long val)
 #define PHYS_ADDR_MASK29               0x1fffffff
 #define PHYS_ADDR_MASK32               0xffffffff
 
-#ifdef CONFIG_PMB
 static inline unsigned long phys_addr_mask(void)
 {
        /* Is the MMU in 29bit mode? */
@@ -75,17 +74,6 @@ static inline unsigned long phys_addr_mask(void)
 
        return PHYS_ADDR_MASK32;
 }
-#elif defined(CONFIG_32BIT)
-static inline unsigned long phys_addr_mask(void)
-{
-       return PHYS_ADDR_MASK32;
-}
-#else
-static inline unsigned long phys_addr_mask(void)
-{
-       return PHYS_ADDR_MASK29;
-}
-#endif
 
 #define PTE_PHYS_MASK          (phys_addr_mask() & PAGE_MASK)
 #define PTE_FLAGS_MASK         (~(PTE_PHYS_MASK) << PAGE_SHIFT)
index 1f1af5afff0374537f989911d4e98f51078a9c1e..10c8b1823a181ef6abd8f07766c801f7c2c6d3f1 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/compiler.h>
 #include <linux/linkage.h>
 #include <asm/types.h>
+#include <asm/uncached.h>
 
 #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */
 
@@ -137,9 +138,6 @@ extern unsigned int instruction_size(unsigned int insn);
 #define instruction_size(insn) (4)
 #endif
 
-extern unsigned long cached_to_uncached;
-extern unsigned long uncached_size;
-
 void per_cpu_trap_init(void);
 void default_idle(void);
 void cpu_idle_wait(void);
index c941b273940581bc4221458a8cabf639829e1500..a4ad1cd9bc4d02740bb8afcb1936a932b2ed3f35 100644 (file)
@@ -145,42 +145,6 @@ do {                                                               \
                __restore_dsp(prev);                            \
 } while (0)
 
-/*
- * Jump to uncached area.
- * When handling TLB or caches, we need to do it from an uncached area.
- */
-#define jump_to_uncached()                     \
-do {                                           \
-       unsigned long __dummy;                  \
-                                               \
-       __asm__ __volatile__(                   \
-               "mova   1f, %0\n\t"             \
-               "add    %1, %0\n\t"             \
-               "jmp    @%0\n\t"                \
-               " nop\n\t"                      \
-               ".balign 4\n"                   \
-               "1:"                            \
-               : "=&z" (__dummy)               \
-               : "r" (cached_to_uncached));    \
-} while (0)
-
-/*
- * Back to cached area.
- */
-#define back_to_cached()                               \
-do {                                                   \
-       unsigned long __dummy;                          \
-       ctrl_barrier();                                 \
-       __asm__ __volatile__(                           \
-               "mov.l  1f, %0\n\t"                     \
-               "jmp    @%0\n\t"                        \
-               " nop\n\t"                              \
-               ".balign 4\n"                           \
-               "1:     .long 2f\n"                     \
-               "2:"                                    \
-               : "=&r" (__dummy));                     \
-} while (0)
-
 #ifdef CONFIG_CPU_HAS_SR_RB
 #define lookup_exception_vector()      \
 ({                                     \
index 36338646dfc81832227e78d39ccf6cdc71df4963..8593bc8d1a4e74af89ace4cb2e767b9fd0567ea6 100644 (file)
@@ -34,9 +34,6 @@ do {                                                          \
                              &next->thread);                   \
 } while (0)
 
-#define jump_to_uncached()     do { } while (0)
-#define back_to_cached()       do { } while (0)
-
 #define __icbi(addr)   __asm__ __volatile__ ( "icbi %0, 0\n\t" : : "r" (addr))
 #define __ocbp(addr)   __asm__ __volatile__ ( "ocbp %0, 0\n\t" : : "r" (addr))
 #define __ocbi(addr)   __asm__ __volatile__ ( "ocbi %0, 0\n\t" : : "r" (addr))
index e3419f96626ad49719130f120bcb71bcbdb40c42..6f8816b79cf152091b1fc08e6cd4dc5d4390bfe2 100644 (file)
@@ -4,15 +4,55 @@
 #include <linux/bug.h>
 
 #ifdef CONFIG_UNCACHED_MAPPING
+extern unsigned long cached_to_uncached;
+extern unsigned long uncached_size;
 extern unsigned long uncached_start, uncached_end;
 
 extern int virt_addr_uncached(unsigned long kaddr);
 extern void uncached_init(void);
 extern void uncached_resize(unsigned long size);
+
+/*
+ * Jump to uncached area.
+ * When handling TLB or caches, we need to do it from an uncached area.
+ */
+#define jump_to_uncached()                     \
+do {                                           \
+       unsigned long __dummy;                  \
+                                               \
+       __asm__ __volatile__(                   \
+               "mova   1f, %0\n\t"             \
+               "add    %1, %0\n\t"             \
+               "jmp    @%0\n\t"                \
+               " nop\n\t"                      \
+               ".balign 4\n"                   \
+               "1:"                            \
+               : "=&z" (__dummy)               \
+               : "r" (cached_to_uncached));    \
+} while (0)
+
+/*
+ * Back to cached area.
+ */
+#define back_to_cached()                               \
+do {                                                   \
+       unsigned long __dummy;                          \
+       ctrl_barrier();                                 \
+       __asm__ __volatile__(                           \
+               "mov.l  1f, %0\n\t"                     \
+               "jmp    @%0\n\t"                        \
+               " nop\n\t"                              \
+               ".balign 4\n"                           \
+               "1:     .long 2f\n"                     \
+               "2:"                                    \
+               : "=&r" (__dummy));                     \
+} while (0)
 #else
 #define virt_addr_uncached(kaddr)      (0)
 #define uncached_init()                        do { } while (0)
 #define uncached_resize(size)          BUG()
+#define jump_to_uncached()             do { } while (0)
+#define back_to_cached()               do { } while (0)
 #endif
 
 #endif /* __ASM_SH_UNCACHED_H */
diff --git a/arch/sh/include/mach-common/mach/edosk7705.h b/arch/sh/include/mach-common/mach/edosk7705.h
deleted file mode 100644 (file)
index efc43b3..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __ASM_SH_EDOSK7705_H
-#define __ASM_SH_EDOSK7705_H
-
-#define __IO_PREFIX sh_edosk7705
-#include <asm/io_generic.h>
-
-#endif /* __ASM_SH_EDOSK7705_H */
index 1aed15856e11ff5bae72b2522f94f816084e0dee..dcb05fa8c164d9c9044df5ce85665953328f7e21 100644 (file)
@@ -68,13 +68,4 @@ extern void microdev_print_fpga_intc_status(void);
 #define __IO_PREFIX microdev
 #include <asm/io_generic.h>
 
-#if defined(CONFIG_PCI)
-unsigned char  microdev_pci_inb(unsigned long port);
-unsigned short microdev_pci_inw(unsigned long port);
-unsigned long  microdev_pci_inl(unsigned long port);
-void           microdev_pci_outb(unsigned char  data, unsigned long port);
-void           microdev_pci_outw(unsigned short data, unsigned long port);
-void           microdev_pci_outl(unsigned long  data, unsigned long port);
-#endif
-
 #endif /* __ASM_SH_MICRODEV_H */
diff --git a/arch/sh/include/mach-common/mach/secureedge5410.h b/arch/sh/include/mach-common/mach/secureedge5410.h
new file mode 100644 (file)
index 0000000..3653b9a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * include/asm-sh/snapgear.h
+ *
+ * Modified version of io_se.h for the snapgear-specific functions.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * IO functions for a SnapGear
+ */
+
+#ifndef _ASM_SH_IO_SNAPGEAR_H
+#define _ASM_SH_IO_SNAPGEAR_H
+
+#define __IO_PREFIX    snapgear
+#include <asm/io_generic.h>
+
+/*
+ * We need to remember what was written to the ioport as some bits
+ * are shared with other functions and you cannot read back what was
+ * written :-|
+ *
+ * Bit        Read                   Write
+ * -----------------------------------------------
+ * D0         DCD on ttySC1          power
+ * D1         Reset Switch           heatbeat
+ * D2         ttySC0 CTS (7100)      LAN
+ * D3         -                      WAN
+ * D4         ttySC0 DCD (7100)      CONSOLE
+ * D5         -                      ONLINE
+ * D6         -                      VPN
+ * D7         -                      DTR on ttySC1
+ * D8         -                      ttySC0 RTS (7100)
+ * D9         -                      ttySC0 DTR (7100)
+ * D10        -                      RTC SCLK
+ * D11        RTC DATA               RTC DATA
+ * D12        -                      RTS RESET
+ */
+
+#define SECUREEDGE_IOPORT_ADDR ((volatile short *) 0xb0000000)
+extern unsigned short secureedge5410_ioport;
+
+#define SECUREEDGE_WRITE_IOPORT(val, mask) (*SECUREEDGE_IOPORT_ADDR = \
+        (secureedge5410_ioport = \
+                       ((secureedge5410_ioport & ~(mask)) | ((val) & (mask)))))
+#define SECUREEDGE_READ_IOPORT() \
+        ((*SECUREEDGE_IOPORT_ADDR&0x0817) | (secureedge5410_ioport&~0x0817))
+
+#endif /* _ASM_SH_IO_SNAPGEAR_H */
diff --git a/arch/sh/include/mach-common/mach/snapgear.h b/arch/sh/include/mach-common/mach/snapgear.h
deleted file mode 100644 (file)
index 042d95f..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * include/asm-sh/snapgear.h
- *
- * Modified version of io_se.h for the snapgear-specific functions.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * IO functions for a SnapGear
- */
-
-#ifndef _ASM_SH_IO_SNAPGEAR_H
-#define _ASM_SH_IO_SNAPGEAR_H
-
-#if defined(CONFIG_CPU_SH4)
-/*
- * The external interrupt lines, these take up ints 0 - 15 inclusive
- * depending on the priority for the interrupt.  In fact the priority
- * is the interrupt :-)
- */
-
-#define IRL0_IRQ       2
-#define IRL0_PRIORITY  13
-
-#define IRL1_IRQ       5
-#define IRL1_PRIORITY  10
-
-#define IRL2_IRQ       8
-#define IRL2_PRIORITY  7
-
-#define IRL3_IRQ       11
-#define IRL3_PRIORITY  4
-#endif
-
-#define __IO_PREFIX    snapgear
-#include <asm/io_generic.h>
-
-#ifdef CONFIG_SH_SECUREEDGE5410
-/*
- * We need to remember what was written to the ioport as some bits
- * are shared with other functions and you cannot read back what was
- * written :-|
- *
- * Bit        Read                   Write
- * -----------------------------------------------
- * D0         DCD on ttySC1          power
- * D1         Reset Switch           heatbeat
- * D2         ttySC0 CTS (7100)      LAN
- * D3         -                      WAN
- * D4         ttySC0 DCD (7100)      CONSOLE
- * D5         -                      ONLINE
- * D6         -                      VPN
- * D7         -                      DTR on ttySC1
- * D8         -                      ttySC0 RTS (7100)
- * D9         -                      ttySC0 DTR (7100)
- * D10        -                      RTC SCLK
- * D11        RTC DATA               RTC DATA
- * D12        -                      RTS RESET
- */
-
-#define SECUREEDGE_IOPORT_ADDR ((volatile short *) 0xb0000000)
-extern unsigned short secureedge5410_ioport;
-
-#define SECUREEDGE_WRITE_IOPORT(val, mask) (*SECUREEDGE_IOPORT_ADDR = \
-        (secureedge5410_ioport = \
-                       ((secureedge5410_ioport & ~(mask)) | ((val) & (mask)))))
-#define SECUREEDGE_READ_IOPORT() \
-        ((*SECUREEDGE_IOPORT_ADDR&0x0817) | (secureedge5410_ioport&~0x0817))
-#endif
-
-#endif /* _ASM_SH_IO_SNAPGEAR_H */
diff --git a/arch/sh/include/mach-common/mach/systemh7751.h b/arch/sh/include/mach-common/mach/systemh7751.h
deleted file mode 100644 (file)
index 4161122..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef __ASM_SH_SYSTEMH_7751SYSTEMH_H
-#define __ASM_SH_SYSTEMH_7751SYSTEMH_H
-
-/*
- * linux/include/asm-sh/systemh/7751systemh.h
- *
- * Copyright (C) 2000  Kazumoto Kojima
- *
- * Hitachi SystemH support
-
- * Modified for 7751 SystemH by
- * Jonathan Short, 2002.
- */
-
-/* Box specific addresses.  */
-
-#define PA_ROM         0x00000000      /* EPROM */
-#define PA_ROM_SIZE    0x00400000      /* EPROM size 4M byte */
-#define PA_FROM                0x01000000      /* EPROM */
-#define PA_FROM_SIZE   0x00400000      /* EPROM size 4M byte */
-#define PA_EXT1                0x04000000
-#define PA_EXT1_SIZE   0x04000000
-#define PA_EXT2                0x08000000
-#define PA_EXT2_SIZE   0x04000000
-#define PA_SDRAM       0x0c000000
-#define PA_SDRAM_SIZE  0x04000000
-
-#define PA_EXT4                0x12000000
-#define PA_EXT4_SIZE   0x02000000
-#define PA_EXT5                0x14000000
-#define PA_EXT5_SIZE   0x04000000
-#define PA_PCIC                0x18000000      /* MR-SHPC-01 PCMCIA */
-
-#define PA_DIPSW0      0xb9000000      /* Dip switch 5,6 */
-#define PA_DIPSW1      0xb9000002      /* Dip switch 7,8 */
-#define PA_LED         0xba000000      /* LED */
-#define        PA_BCR          0xbb000000      /* FPGA on the MS7751SE01 */
-
-#define PA_MRSHPC      0xb83fffe0      /* MR-SHPC-01 PCMCIA controller */
-#define PA_MRSHPC_MW1  0xb8400000      /* MR-SHPC-01 memory window base */
-#define PA_MRSHPC_MW2  0xb8500000      /* MR-SHPC-01 attribute window base */
-#define PA_MRSHPC_IO   0xb8600000      /* MR-SHPC-01 I/O window base */
-#define MRSHPC_MODE     (PA_MRSHPC + 4)
-#define MRSHPC_OPTION   (PA_MRSHPC + 6)
-#define MRSHPC_CSR      (PA_MRSHPC + 8)
-#define MRSHPC_ISR      (PA_MRSHPC + 10)
-#define MRSHPC_ICR      (PA_MRSHPC + 12)
-#define MRSHPC_CPWCR    (PA_MRSHPC + 14)
-#define MRSHPC_MW0CR1   (PA_MRSHPC + 16)
-#define MRSHPC_MW1CR1   (PA_MRSHPC + 18)
-#define MRSHPC_IOWCR1   (PA_MRSHPC + 20)
-#define MRSHPC_MW0CR2   (PA_MRSHPC + 22)
-#define MRSHPC_MW1CR2   (PA_MRSHPC + 24)
-#define MRSHPC_IOWCR2   (PA_MRSHPC + 26)
-#define MRSHPC_CDCR     (PA_MRSHPC + 28)
-#define MRSHPC_PCIC_INFO (PA_MRSHPC + 30)
-
-#define BCR_ILCRA      (PA_BCR + 0)
-#define BCR_ILCRB      (PA_BCR + 2)
-#define BCR_ILCRC      (PA_BCR + 4)
-#define BCR_ILCRD      (PA_BCR + 6)
-#define BCR_ILCRE      (PA_BCR + 8)
-#define BCR_ILCRF      (PA_BCR + 10)
-#define BCR_ILCRG      (PA_BCR + 12)
-
-#define IRQ_79C973     13
-
-#define __IO_PREFIX    sh7751systemh
-#include <asm/io_generic.h>
-
-#endif  /* __ASM_SH_SYSTEMH_7751SYSTEMH_H */
index 2d9700c6b53a07426bdc6253e55a62effed962c0..0fe2e9329cb25f699acd433dd4f2d9b4b945f00b 100644 (file)
@@ -48,7 +48,7 @@ static struct clk r_clk = {
  * Default rate for the root input clock, reset this with clk_set_rate()
  * from the platform code.
  */
-struct clk extal_clk = {
+static struct clk extal_clk = {
        .rate           = 33333333,
 };
 
@@ -111,7 +111,7 @@ static struct clk div3_clk = {
        .parent         = &pll_clk,
 };
 
-struct clk *main_clks[] = {
+static struct clk *main_clks[] = {
        &r_clk,
        &extal_clk,
        &fll_clk,
@@ -156,7 +156,7 @@ struct clk div4_clks[DIV4_NR] = {
 
 enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR };
 
-struct clk div6_clks[DIV6_NR] = {
+static struct clk div6_clks[DIV6_NR] = {
        [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
        [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0),
        [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0),
index 09370392aff15d791d612ac57bcdf0c6031d8443..c3e61b36649380f5db818c5f6edb05bfc897de1c 100644 (file)
@@ -79,7 +79,7 @@ config 29BIT
 
 config 32BIT
        bool
-       default y if CPU_SH5
+       default y if CPU_SH5 || !MMU
 
 config PMB
        bool "Support 32-bit physical addressing through PMB"
index 0387932869904a042472cca19b65141b5b8bdc9f..40733a9524021d42d42ddc5a8d7e08ef77a1c155 100644 (file)
@@ -79,21 +79,20 @@ void dma_generic_free_coherent(struct device *dev, size_t size,
 void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                    enum dma_data_direction direction)
 {
-#if defined(CONFIG_CPU_SH5) || defined(CONFIG_PMB)
-       void *p1addr = vaddr;
-#else
-       void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
-#endif
+       void *addr;
+
+       addr = __in_29bit_mode() ?
+              (void *)P1SEGADDR((unsigned long)vaddr) : vaddr;
 
        switch (direction) {
        case DMA_FROM_DEVICE:           /* invalidate only */
-               __flush_invalidate_region(p1addr, size);
+               __flush_invalidate_region(addr, size);
                break;
        case DMA_TO_DEVICE:             /* writeback only */
-               __flush_wback_region(p1addr, size);
+               __flush_wback_region(addr, size);
                break;
        case DMA_BIDIRECTIONAL:         /* writeback and invalidate */
-               __flush_purge_region(p1addr, size);
+               __flush_purge_region(addr, size);
                break;
        default:
                BUG();
index 8a4eca551fc0a08542085faddeac7af373ad091b..a7767da815e91453c5b5526a05f4c72405e4afba 100644 (file)
@@ -28,7 +28,7 @@ EXPORT_SYMBOL(virt_addr_uncached);
 
 void __init uncached_init(void)
 {
-#ifdef CONFIG_29BIT
+#if defined(CONFIG_29BIT) || !defined(CONFIG_MMU)
        uncached_start = P2SEG;
 #else
        uncached_start = memory_end;
index 9f56eb978024ef2b6e93497a6580d00dbc7f62eb..0e68465e7b50920ffcaa8a832402fdfc3670226c 100644 (file)
@@ -26,7 +26,6 @@ HD64461                       HD64461
 7724SE                 SH_7724_SOLUTION_ENGINE
 7751SE                 SH_7751_SOLUTION_ENGINE
 7780SE                 SH_7780_SOLUTION_ENGINE
-7751SYSTEMH            SH_7751_SYSTEMH
 HP6XX                  SH_HP6XX
 DREAMCAST              SH_DREAMCAST
 SNAPGEAR               SH_SECUREEDGE5410
index a9aaed3c3d97b92be15c9fb024bba293a8970428..45d9c87d083ad89343b7c7862c5b62a911f86c2f 100644 (file)
@@ -22,8 +22,6 @@ config SPARC
        select RTC_CLASS
        select RTC_DRV_M48T59
        select HAVE_IRQ_WORK
-       select HAVE_PERF_EVENTS
-       select PERF_USE_VMALLOC
        select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
        select HAVE_ARCH_JUMP_LABEL
@@ -50,7 +48,6 @@ config SPARC64
        select RTC_DRV_BQ4802
        select RTC_DRV_SUN4V
        select RTC_DRV_STARFIRE
-       select HAVE_IRQ_WORK
        select HAVE_PERF_EVENTS
        select PERF_USE_VMALLOC
 
index 62e66d7b2fb62b40ed025b842e99e7d8382b017b..427d4684e0d239bbafe9238a01a2713e423ff9b7 100644 (file)
@@ -4,7 +4,6 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
-#include <asm/system.h>
 
 #define JUMP_LABEL_NOP_SIZE 4
 
@@ -14,6 +13,7 @@
                         "nop\n\t"                              \
                         "nop\n\t"                              \
                         ".pushsection __jump_table,  \"a\"\n\t"\
+                        ".align 4\n\t"                         \
                         ".word 1b, %l[" #label "], %c0\n\t"    \
                         ".popsection \n\t"                     \
                         : :  "i" (key) :  : label);\
index 0116d8d10def21a4ad9c3b73c27a95383ae4cdc2..5ad6e5c5dbb3b91cef1e6dfded9f4ca55552bd71 100644 (file)
@@ -365,7 +365,7 @@ static int request_fast_irq(unsigned int irq,
        unsigned long flags;
        unsigned int cpu_irq;
        int ret;
-#ifdef CONFIG_SMP
+#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
        struct tt_entry *trap_table;
        extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3;
 #endif
@@ -425,7 +425,7 @@ static int request_fast_irq(unsigned int irq,
        table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
 
        INSTANTIATE(sparc_ttable)
-#ifdef CONFIG_SMP
+#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
        trap_table = &trapbase_cpu1; INSTANTIATE(trap_table)
        trap_table = &trapbase_cpu2; INSTANTIATE(trap_table)
        trap_table = &trapbase_cpu3; INSTANTIATE(trap_table)
index e1656fc41ccbc275dece71ed001a2bead7005ac8..7524689b03d24465f78500f87e804803509b3367 100644 (file)
@@ -56,8 +56,8 @@ void __init leon_configure_cache_smp(void);
 static inline unsigned long do_swap(volatile unsigned long *ptr,
                                    unsigned long val)
 {
-       __asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val)
-                            : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
+       __asm__ __volatile__("swapa [%2] %3, %0\n\t" : "=&r"(val)
+                            : "0"(val), "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
                             : "memory");
        return val;
 }
index 4da2e1f6629091ea60e7bccd81fc95b495ae065d..5f5f74c2c2ca5ebf19f7acaca91559c487304533 100644 (file)
@@ -78,9 +78,9 @@ signal_p:
        call    do_notify_resume
         add    %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr
 
-       /* Fall through. */
-       ld      [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
-       clr     %l6
+       b       signal_p
+        ld     [%curptr + TI_FLAGS], %g2
+
 ret_trap_continue:
        sethi   %hi(PSR_SYSCALL), %g1
        andn    %t_psr, %g1, %t_psr
index 090b9e9ad5e36a416258e003be80556b49330a62..77f1b95e0806bb92dc19fd421acd6f159e7dfab0 100644 (file)
@@ -34,37 +34,9 @@ __handle_preemption:
 __handle_user_windows:
                call                    fault_in_user_windows
                 wrpr                   %g0, RTRAP_PSTATE, %pstate
-               wrpr                    %g0, RTRAP_PSTATE_IRQOFF, %pstate
-               /* Redo sched+sig checks */
-               ldx                     [%g6 + TI_FLAGS], %l0
-               andcc                   %l0, _TIF_NEED_RESCHED, %g0
-
-               be,pt                   %xcc, 1f
-                nop
-               call                    schedule
-                wrpr                   %g0, RTRAP_PSTATE, %pstate
-               wrpr                    %g0, RTRAP_PSTATE_IRQOFF, %pstate
-               ldx                     [%g6 + TI_FLAGS], %l0
-
-1:             andcc                   %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
-               be,pt                   %xcc, __handle_user_windows_continue
-                nop
-               mov                     %l5, %o1
-               add                     %sp, PTREGS_OFF, %o0
-               mov                     %l0, %o2
-
-               call                    do_notify_resume
-                wrpr                   %g0, RTRAP_PSTATE, %pstate
-               wrpr                    %g0, RTRAP_PSTATE_IRQOFF, %pstate
-               /* Signal delivery can modify pt_regs tstate, so we must
-                * reload it.
-                */
-               ldx                     [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
-               sethi                   %hi(0xf << 20), %l4
-               and                     %l1, %l4, %l4
-               ba,pt                   %xcc, __handle_user_windows_continue
+               ba,pt                   %xcc, __handle_preemption_continue
+                wrpr                   %g0, RTRAP_PSTATE_IRQOFF, %pstate
 
-                andn                   %l1, %l4, %l1
 __handle_userfpu:
                rd                      %fprs, %l5
                andcc                   %l5, FPRS_FEF, %g0
@@ -87,7 +59,7 @@ __handle_signal:
                ldx                     [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
                sethi                   %hi(0xf << 20), %l4
                and                     %l1, %l4, %l4
-               ba,pt                   %xcc, __handle_signal_continue
+               ba,pt                   %xcc, __handle_preemption_continue
                 andn                   %l1, %l4, %l1
 
                /* When returning from a NMI (%pil==15) interrupt we want to
@@ -177,11 +149,9 @@ __handle_preemption_continue:
                bne,pn                  %xcc, __handle_preemption
                 andcc                  %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
                bne,pn                  %xcc, __handle_signal
-__handle_signal_continue:
                 ldub                   [%g6 + TI_WSAVED], %o2
                brnz,pn                 %o2, __handle_user_windows
                 nop
-__handle_user_windows_continue:
                sethi                   %hi(TSTATE_PEF), %o0
                andcc                   %l1, %o0, %g0
 
index bd8601601afab05ffc9f0ff7d06021523355b69f..5b836f5aea90bcd94d4e4ba1b3114a8115291135 100644 (file)
@@ -539,6 +539,12 @@ do_sigbus:
        __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address);
 }
 
+static void check_stack_aligned(unsigned long sp)
+{
+       if (sp & 0x7UL)
+               force_sig(SIGILL, current);
+}
+
 void window_overflow_fault(void)
 {
        unsigned long sp;
@@ -547,6 +553,8 @@ void window_overflow_fault(void)
        if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
                force_user_fault(sp + 0x38, 1);
        force_user_fault(sp, 1);
+
+       check_stack_aligned(sp);
 }
 
 void window_underflow_fault(unsigned long sp)
@@ -554,6 +562,8 @@ void window_underflow_fault(unsigned long sp)
        if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
                force_user_fault(sp + 0x38, 0);
        force_user_fault(sp, 0);
+
+       check_stack_aligned(sp);
 }
 
 void window_ret_fault(struct pt_regs *regs)
@@ -564,4 +574,6 @@ void window_ret_fault(struct pt_regs *regs)
        if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
                force_user_fault(sp + 0x38, 0);
        force_user_fault(sp, 0);
+
+       check_stack_aligned(sp);
 }
index e0f7ee186721cf554dc142efdfc58350eaf6a7df..b2a6c5de79abf00ddad0354fca8b694937282131 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <linux/interrupt.h>
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
 #include <asm/tlbflush.h>
 #include <asm/homecache.h>
 
index 1480106d1c05c2572177058611ee655db569c41c..3d0f202462609e1401b4737b905cb324332d8b4c 100644 (file)
 #define _ASM_TILE_KMAP_TYPES_H
 
 /*
- * In TILE Linux each set of four of these uses another 16MB chunk of
- * address space, given 64 tiles and 64KB pages, so we only enable
- * ones that are required by the kernel configuration.
+ * In 32-bit TILE Linux we have to balance the desire to have a lot of
+ * nested atomic mappings with the fact that large page sizes and many
+ * processors chew up address space quickly.  In a typical
+ * 64-processor, 64KB-page layout build, making KM_TYPE_NR one larger
+ * adds 4MB of required address-space.  For now we leave KM_TYPE_NR
+ * set to depth 8.
  */
 enum km_type {
+       KM_TYPE_NR = 8
+};
+
+/*
+ * We provide dummy definitions of all the stray values that used to be
+ * required for kmap_atomic() and no longer are.
+ */
+enum {
        KM_BOUNCE_READ,
        KM_SKB_SUNRPC_DATA,
        KM_SKB_DATA_SOFTIRQ,
        KM_USER0,
        KM_USER1,
        KM_BIO_SRC_IRQ,
+       KM_BIO_DST_IRQ,
+       KM_PTE0,
+       KM_PTE1,
        KM_IRQ0,
        KM_IRQ1,
        KM_SOFTIRQ0,
        KM_SOFTIRQ1,
-       KM_MEMCPY0,
-       KM_MEMCPY1,
-#if defined(CONFIG_HIGHPTE)
-       KM_PTE0,
-       KM_PTE1,
-#endif
-       KM_TYPE_NR
+       KM_SYNC_ICACHE,
+       KM_SYNC_DCACHE,
+       KM_UML_USERCOPY,
+       KM_IRQ_PTE,
+       KM_NMI,
+       KM_NMI_PTE,
+       KM_KDB
 };
 
 #endif /* _ASM_TILE_KMAP_TYPES_H */
index dc4ccdd855bca293070ea8bff94a699821d5e01b..a6604e9485da2a188265d618eaaa8a75ec8a4828 100644 (file)
@@ -344,10 +344,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
 #if defined(CONFIG_HIGHPTE)
-extern pte_t *_pte_offset_map(pmd_t *, unsigned long address, enum km_type);
-#define pte_offset_map(dir, address) \
-       _pte_offset_map(dir, address, KM_PTE0)
-#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
+extern pte_t *pte_offset_map(pmd_t *, unsigned long address);
+#define pte_unmap(pte) kunmap_atomic(pte)
 #else
 #define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
 #define pte_unmap(pte) do { } while (0)
index 3dc90fa92c704d8fb07d66b034daadd44ee6376b..b16e5db8f0e7225f9e8789a747f9295d341d947d 100644 (file)
@@ -1 +1,4 @@
+#ifdef CONFIG_COMPAT
+#define __ARCH_WANT_STAT64     /* Used for compat_sys_stat64() etc. */
+#endif
 #include <asm-generic/stat.h>
index f2e3ff485333224f022344fad78f7c96b19d5243..b35c2db71199ae3d70fc2b1e29687dc350514a77 100644 (file)
@@ -41,6 +41,7 @@ __SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr)
 #ifdef CONFIG_COMPAT
 #define __ARCH_WANT_SYS_LLSEEK
 #endif
+#define __ARCH_WANT_SYS_NEWFSTATAT
 #endif
 
 #endif /* _ASM_TILE_UNISTD_H */
index 77739cdd9462dacf2a9188a0a0418c014e6379f9..67617a05e602380a7d1fba86dadba25db17a13ef 100644 (file)
@@ -148,11 +148,11 @@ long tile_compat_sys_msgrcv(int msqid,
 #define compat_sys_readahead sys32_readahead
 #define compat_sys_sync_file_range compat_sys_sync_file_range2
 
-/* The native 64-bit "struct stat" matches the 32-bit "struct stat64". */
-#define compat_sys_stat64 sys_newstat
-#define compat_sys_lstat64 sys_newlstat
-#define compat_sys_fstat64 sys_newfstat
-#define compat_sys_fstatat64 sys_newfstatat
+/* We leverage the "struct stat64" type for 32-bit time_t/nsec. */
+#define compat_sys_stat64 sys_stat64
+#define compat_sys_lstat64 sys_lstat64
+#define compat_sys_fstat64 sys_fstat64
+#define compat_sys_fstatat64 sys_fstatat64
 
 /* The native sys_ptrace dynamically handles compat binaries. */
 #define compat_sys_ptrace sys_ptrace
index 2c54fd43a8a0132533927ed5b5e373940f10ce18..493a0e66d916c618f867034db5647f72acd61999 100644 (file)
@@ -54,7 +54,7 @@ void early_printk(const char *fmt, ...)
 void early_panic(const char *fmt, ...)
 {
        va_list ap;
-       raw_local_irq_disable_all();
+       arch_local_irq_disable_all();
        va_start(ap, fmt);
        early_printk("Kernel panic - not syncing: ");
        early_vprintk(fmt, ap);
index 1e54a7843410e57d021dbac9921acf4f39e2f481..e910530436e64a4079ba65e22bdca13e6ad01bfa 100644 (file)
@@ -151,12 +151,12 @@ enum direction_protect {
 
 static void enable_firewall_interrupts(void)
 {
-       raw_local_irq_unmask_now(INT_UDN_FIREWALL);
+       arch_local_irq_unmask_now(INT_UDN_FIREWALL);
 }
 
 static void disable_firewall_interrupts(void)
 {
-       raw_local_irq_mask_now(INT_UDN_FIREWALL);
+       arch_local_irq_mask_now(INT_UDN_FIREWALL);
 }
 
 /* Set up hardwall on this cpu based on the passed hardwall_info. */
@@ -768,13 +768,13 @@ static int hardwall_release(struct inode *inode, struct file *file)
 }
 
 static const struct file_operations dev_hardwall_fops = {
+       .open           = nonseekable_open,
        .unlocked_ioctl = hardwall_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl   = hardwall_compat_ioctl,
 #endif
        .flush          = hardwall_flush,
        .release        = hardwall_release,
-       .llseek         = noop_llseek,
 };
 
 static struct cdev hardwall_dev;
index e63917687e998907824a62b1783ffef599418818..128805ef8f2c83c1a8b61cf03c5711e5fbb97ff1 100644 (file)
@@ -26,7 +26,7 @@
 #define IS_HW_CLEARED 1
 
 /*
- * The set of interrupts we enable for raw_local_irq_enable().
+ * The set of interrupts we enable for arch_local_irq_enable().
  * This is initialized to have just a single interrupt that the kernel
  * doesn't actually use as a sentinel.  During kernel init,
  * interrupts are added as the kernel gets prepared to support them.
@@ -225,7 +225,7 @@ void __cpuinit setup_irq_regs(void)
        /* Enable interrupt delivery. */
        unmask_irqs(~0UL);
 #if CHIP_HAS_IPI()
-       raw_local_irq_unmask(INT_IPI_K);
+       arch_local_irq_unmask(INT_IPI_K);
 #endif
 }
 
index ba7a265d61796a09168b6c35ed74af23f9fdb256..0d8b9e933487c2847824efc1637364cba8ec84d8 100644 (file)
@@ -182,13 +182,13 @@ static void kexec_find_and_set_command_line(struct kimage *image)
 
                if ((entry & IND_SOURCE)) {
                        void *va =
-                               kmap_atomic_pfn(entry >> PAGE_SHIFT, KM_USER0);
+                               kmap_atomic_pfn(entry >> PAGE_SHIFT);
                        r = kexec_bn2cl(va);
                        if (r) {
                                command_line = r;
                                break;
                        }
-                       kunmap_atomic(va, KM_USER0);
+                       kunmap_atomic(va);
                }
        }
 
@@ -198,7 +198,7 @@ static void kexec_find_and_set_command_line(struct kimage *image)
 
                hverr = hv_set_command_line(
                        (HV_VirtAddr) command_line, strlen(command_line));
-               kunmap_atomic(command_line, KM_USER0);
+               kunmap_atomic(command_line);
        } else {
                pr_info("%s: no command line found; making empty\n",
                       __func__);
index 997e3933f72679718583dae5a82c72c4d2f9fbdb..0858ee6b520f6acf4c23b3a27c8491267919b943 100644 (file)
@@ -34,7 +34,7 @@ void __cpuinit init_messaging(void)
                panic("hv_register_message_state: error %d", rc);
 
        /* Make sure downcall interrupts will be enabled. */
-       raw_local_irq_unmask(INT_INTCTRL_K);
+       arch_local_irq_unmask(INT_INTCTRL_K);
 }
 
 void hv_message_intr(struct pt_regs *regs, int intnum)
index 9cd29884c09f2bfec1cddbacb67579bbd1e821c6..e92e40527d6dcb9855625cafa13a83f08f56df9c 100644 (file)
@@ -50,10 +50,10 @@ long arch_ptrace(struct task_struct *child, long request,
 {
        unsigned long __user *datap = (long __user __force *)data;
        unsigned long tmp;
-       int i;
        long ret = -EIO;
-       unsigned long *childregs;
        char *childreg;
+       struct pt_regs copyregs;
+       int ex1_offset;
 
        switch (request) {
 
@@ -80,6 +80,16 @@ long arch_ptrace(struct task_struct *child, long request,
                if (addr >= PTREGS_SIZE)
                        break;
                childreg = (char *)task_pt_regs(child) + addr;
+
+               /* Guard against overwrites of the privilege level. */
+               ex1_offset = PTREGS_OFFSET_EX1;
+#if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN)
+               if (is_compat_task())   /* point at low word */
+                       ex1_offset += sizeof(compat_long_t);
+#endif
+               if (addr == ex1_offset)
+                       data = PL_ICS_EX1(USER_PL, EX1_ICS(data));
+
 #ifdef CONFIG_COMPAT
                if (is_compat_task()) {
                        if (addr & (sizeof(compat_long_t)-1))
@@ -96,26 +106,19 @@ long arch_ptrace(struct task_struct *child, long request,
                break;
 
        case PTRACE_GETREGS:  /* Get all registers from the child. */
-               if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE))
-                       break;
-               childregs = (long *)task_pt_regs(child);
-               for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long);
-                               ++i) {
-                       ret = __put_user(childregs[i], &datap[i]);
-                       if (ret != 0)
-                               break;
+               if (copy_to_user(datap, task_pt_regs(child),
+                                sizeof(struct pt_regs)) == 0) {
+                       ret = 0;
                }
                break;
 
        case PTRACE_SETREGS:  /* Set all registers in the child. */
-               if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE))
-                       break;
-               childregs = (long *)task_pt_regs(child);
-               for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long);
-                               ++i) {
-                       ret = __get_user(childregs[i], &datap[i]);
-                       if (ret != 0)
-                               break;
+               if (copy_from_user(&copyregs, datap,
+                                  sizeof(struct pt_regs)) == 0) {
+                       copyregs.ex1 =
+                               PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1));
+                       *task_pt_regs(child) = copyregs;
+                       ret = 0;
                }
                break;
 
index acd86d20beba7ab75aed0f484c3b980a836af282..baa3d905fee21c9fc2ef403449f7e4d671ad7e1e 100644 (file)
@@ -27,7 +27,7 @@
 void machine_halt(void)
 {
        warn_early_printk();
-       raw_local_irq_disable_all();
+       arch_local_irq_disable_all();
        smp_send_stop();
        hv_halt();
 }
@@ -35,14 +35,14 @@ void machine_halt(void)
 void machine_power_off(void)
 {
        warn_early_printk();
-       raw_local_irq_disable_all();
+       arch_local_irq_disable_all();
        smp_send_stop();
        hv_power_off();
 }
 
 void machine_restart(char *cmd)
 {
-       raw_local_irq_disable_all();
+       arch_local_irq_disable_all();
        smp_send_stop();
        hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd);
 }
index ae51cad12da0d6b445666d1796925816b8e7e285..fb0b3cbeae149081a5b3011f0230fbd48f4d56dd 100644 (file)
@@ -868,14 +868,14 @@ void __cpuinit setup_cpu(int boot)
 
        /* Allow asynchronous TLB interrupts. */
 #if CHIP_HAS_TILE_DMA()
-       raw_local_irq_unmask(INT_DMATLB_MISS);
-       raw_local_irq_unmask(INT_DMATLB_ACCESS);
+       arch_local_irq_unmask(INT_DMATLB_MISS);
+       arch_local_irq_unmask(INT_DMATLB_ACCESS);
 #endif
 #if CHIP_HAS_SN_PROC()
-       raw_local_irq_unmask(INT_SNITLB_MISS);
+       arch_local_irq_unmask(INT_SNITLB_MISS);
 #endif
 #ifdef __tilegx__
-       raw_local_irq_unmask(INT_SINGLE_STEP_K);
+       arch_local_irq_unmask(INT_SINGLE_STEP_K);
 #endif
 
        /*
index fb28e85ae3aea3698c7d2cd5da564bb0a5f7fb0d..687719d4abd1eba56fbd591852c8fab51950bc52 100644 (file)
@@ -71,6 +71,9 @@ int restore_sigcontext(struct pt_regs *regs,
        for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
                err |= __get_user(regs->regs[i], &sc->gregs[i]);
 
+       /* Ensure that the PL is always set to USER_PL. */
+       regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1));
+
        regs->faultnum = INT_SWINT_1_SIGRETURN;
 
        err |= __get_user(*pr0, &sc->gregs[0]);
@@ -330,7 +333,7 @@ void do_signal(struct pt_regs *regs)
                        current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
                }
 
-               return;
+               goto done;
        }
 
        /* Did we come from a system call? */
@@ -358,4 +361,8 @@ void do_signal(struct pt_regs *regs)
                current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
                sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
        }
+
+done:
+       /* Avoid double syscall restart if there are nested signals. */
+       regs->faultnum = INT_SWINT_1_SIGRETURN;
 }
index 75255d90aff309669b110dff32f2254ede9daa27..9575b37a8b75318d57cd061172d7cd09d0cf8049 100644 (file)
@@ -115,7 +115,7 @@ static void smp_start_cpu_interrupt(void)
 static void smp_stop_cpu_interrupt(void)
 {
        set_cpu_online(smp_processor_id(), 0);
-       raw_local_irq_disable_all();
+       arch_local_irq_disable_all();
        for (;;)
                asm("nap");
 }
index 6bed820e1421ae628c9ad162de3e50eb1f2884bf..f2e156e44692505e620c7e6c1a35e1ca948c3855 100644 (file)
@@ -132,7 +132,7 @@ static int tile_timer_set_next_event(unsigned long ticks,
 {
        BUG_ON(ticks > MAX_TICK);
        __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks);
-       raw_local_irq_unmask_now(INT_TILE_TIMER);
+       arch_local_irq_unmask_now(INT_TILE_TIMER);
        return 0;
 }
 
@@ -143,7 +143,7 @@ static int tile_timer_set_next_event(unsigned long ticks,
 static void tile_timer_set_mode(enum clock_event_mode mode,
                                struct clock_event_device *evt)
 {
-       raw_local_irq_mask_now(INT_TILE_TIMER);
+       arch_local_irq_mask_now(INT_TILE_TIMER);
 }
 
 /*
@@ -172,7 +172,7 @@ void __cpuinit setup_tile_timer(void)
        evt->cpumask = cpumask_of(smp_processor_id());
 
        /* Start out with timer not firing. */
-       raw_local_irq_mask_now(INT_TILE_TIMER);
+       arch_local_irq_mask_now(INT_TILE_TIMER);
 
        /* Register tile timer. */
        clockevents_register_device(evt);
@@ -188,7 +188,7 @@ void do_timer_interrupt(struct pt_regs *regs, int fault_num)
         * Mask the timer interrupt here, since we are a oneshot timer
         * and there are now by definition no events pending.
         */
-       raw_local_irq_mask(INT_TILE_TIMER);
+       arch_local_irq_mask(INT_TILE_TIMER);
 
        /* Track time spent here in an interrupt context */
        irq_enter();
index dfedea7b266b5d58e6cd445fa8ed0f8ae8fcaea8..f7d4a6ad61e811356ac6bec2b9f235c94f4355c6 100644 (file)
@@ -54,7 +54,7 @@ typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long);
  * we must run with interrupts disabled to avoid the risk of some
  * other code seeing the incoherent data in our cache.  (Recall that
  * our cache is indexed by PA, so even if the other code doesn't use
- * our KM_MEMCPY virtual addresses, they'll still hit in cache using
+ * our kmap_atomic virtual addresses, they'll still hit in cache using
  * the normal VAs that aren't supposed to hit in cache.)
  */
 static void memcpy_multicache(void *dest, const void *source,
@@ -64,6 +64,7 @@ static void memcpy_multicache(void *dest, const void *source,
        unsigned long flags, newsrc, newdst;
        pmd_t *pmdp;
        pte_t *ptep;
+       int type0, type1;
        int cpu = get_cpu();
 
        /*
@@ -77,7 +78,8 @@ static void memcpy_multicache(void *dest, const void *source,
        sim_allow_multiple_caching(1);
 
        /* Set up the new dest mapping */
-       idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + KM_MEMCPY0;
+       type0 = kmap_atomic_idx_push();
+       idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + type0;
        newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1));
        pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst);
        ptep = pte_offset_kernel(pmdp, newdst);
@@ -87,7 +89,8 @@ static void memcpy_multicache(void *dest, const void *source,
        }
 
        /* Set up the new source mapping */
-       idx += (KM_MEMCPY0 - KM_MEMCPY1);
+       type1 = kmap_atomic_idx_push();
+       idx += (type0 - type1);
        src_pte = hv_pte_set_nc(src_pte);
        src_pte = hv_pte_clear_writable(src_pte);  /* be paranoid */
        newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1));
@@ -119,6 +122,8 @@ static void memcpy_multicache(void *dest, const void *source,
         * We're done: notify the simulator that all is back to normal,
         * and re-enable interrupts and pre-emption.
         */
+       kmap_atomic_idx_pop();
+       kmap_atomic_idx_pop();
        sim_allow_multiple_caching(0);
        local_irq_restore(flags);
        put_cpu();
index abb57331cf6e1b25fdeccfd295e25ea7464ebbf5..31dbbd9afe47d5cb32590b96e1d7065e2ff5bf24 100644 (file)
@@ -227,7 +227,7 @@ EXPORT_SYMBOL(kmap_atomic_prot);
 void *__kmap_atomic(struct page *page)
 {
        /* PAGE_NONE is a magic value that tells us to check immutability. */
-       return kmap_atomic_prot(page, type, PAGE_NONE);
+       return kmap_atomic_prot(page, PAGE_NONE);
 }
 EXPORT_SYMBOL(__kmap_atomic);
 
index 78e1982cb6c9dc0385e258b81bfc233f23baaaac..0b9ce69b0ee5e755ea6186e1093269507cae156d 100644 (file)
@@ -988,8 +988,12 @@ static long __write_once initfree = 1;
 /* Select whether to free (1) or mark unusable (0) the __init pages. */
 static int __init set_initfree(char *str)
 {
-       strict_strtol(str, 0, &initfree);
-       pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't");
+       long val;
+       if (strict_strtol(str, 0, &val)) {
+               initfree = val;
+               pr_info("initfree: %s free init pages\n",
+                       initfree ? "will" : "won't");
+       }
        return 1;
 }
 __setup("initfree=", set_initfree);
index 335c24621c418b1a7bffdacc2723bbcee665c8e2..1f5430c53d0db4cf62c992c656de7e1b2e9769e6 100644 (file)
@@ -134,9 +134,9 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
 }
 
 #if defined(CONFIG_HIGHPTE)
-pte_t *_pte_offset_map(pmd_t *dir, unsigned long address, enum km_type type)
+pte_t *_pte_offset_map(pmd_t *dir, unsigned long address)
 {
-       pte_t *pte = kmap_atomic(pmd_page(*dir), type) +
+       pte_t *pte = kmap_atomic(pmd_page(*dir)) +
                (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK;
        return &pte[pte_index(address)];
 }
index 2cd899f75a3cc21f2e53e2f6b8d9b46368f496cc..b7c5bab9bd774db16b8eaaa31441a8aa45e45aea 100644 (file)
@@ -38,8 +38,8 @@ struct pt_regs {
 
 struct task_struct;
 
-extern long subarch_ptrace(struct task_struct *child, long request, long addr,
-                          long data);
+extern long subarch_ptrace(struct task_struct *child, long request,
+       unsigned long addr, unsigned long data);
 extern unsigned long getreg(struct task_struct *child, int regno);
 extern int putreg(struct task_struct *child, int regno, unsigned long value);
 extern int get_fpregs(struct user_i387_struct __user *buf,
index a5e33f29bbeb7ef71e9a25697e5c8bfd3e664370..701b672c11225aaf6ffcdd9fe9485bccacbd4726 100644 (file)
@@ -122,7 +122,7 @@ long arch_ptrace(struct task_struct *child, long request,
                break;
 
        case PTRACE_SET_THREAD_AREA:
-               ret = ptrace_set_thread_area(child, addr, datavp);
+               ret = ptrace_set_thread_area(child, addr, vp);
                break;
 
        case PTRACE_FAULTINFO: {
index 1255d953c65d8d544c52b287d4dc6cbf9482667f..f2ee1abb1df9df8704c052c4d76ed22cbb6bd5bf 100644 (file)
@@ -51,7 +51,18 @@ cflags-$(CONFIG_X86_GENERIC)         += $(call tune,generic,$(call tune,i686))
 # prologue (push %ebp, mov %esp, %ebp) which breaks the function graph
 # tracer assumptions. For i686, generic, core2 this is set by the
 # compiler anyway
-cflags-$(CONFIG_FUNCTION_GRAPH_TRACER) += $(call cc-option,-maccumulate-outgoing-args)
+ifeq ($(CONFIG_FUNCTION_GRAPH_TRACER), y)
+ADD_ACCUMULATE_OUTGOING_ARGS := y
+endif
+
+# Work around to a bug with asm goto with first implementations of it
+# in gcc causing gcc to mess up the push and pop of the stack in some
+# uses of asm goto.
+ifeq ($(CONFIG_JUMP_LABEL), y)
+ADD_ACCUMULATE_OUTGOING_ARGS := y
+endif
+
+cflags-$(ADD_ACCUMULATE_OUTGOING_ARGS) += $(call cc-option,-maccumulate-outgoing-args)
 
 # Bug fix for binutils: this option is required in order to keep
 # binutils from generating NOPL instructions against our will.
index 286de34b0ed6773c6ccb2b7b052023394b93396f..f6ce0bda3b98a74906cb1c8297f4ba150430699d 100644 (file)
@@ -141,13 +141,13 @@ static inline void native_apic_msr_write(u32 reg, u32 v)
 
 static inline u32 native_apic_msr_read(u32 reg)
 {
-       u32 low, high;
+       u64 msr;
 
        if (reg == APIC_DFR)
                return -1;
 
-       rdmsr(APIC_BASE_MSR + (reg >> 4), low, high);
-       return low;
+       rdmsrl(APIC_BASE_MSR + (reg >> 4), msr);
+       return (u32)msr;
 }
 
 static inline void native_x2apic_wait_icr_idle(void)
@@ -181,12 +181,12 @@ extern void enable_x2apic(void);
 extern void x2apic_icr_write(u32 low, u32 id);
 static inline int x2apic_enabled(void)
 {
-       int msr, msr2;
+       u64 msr;
 
        if (!cpu_has_x2apic)
                return 0;
 
-       rdmsr(MSR_IA32_APICBASE, msr, msr2);
+       rdmsrl(MSR_IA32_APICBASE, msr);
        if (msr & X2APIC_ENABLE)
                return 1;
        return 0;
index bf6b88ef8eebb17d273c8f75c82c77b24213f003..e969f691cbfde23c6ffd53a540d0e3841084255d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * SGI UV architectural definitions
  *
- * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_X86_UV_UV_HUB_H
@@ -77,7 +77,8 @@
  *
  *             1111110000000000
  *             5432109876543210
- *             pppppppppplc0cch
+ *             pppppppppplc0cch        Nehalem-EX
+ *             ppppppppplcc0cch        Westmere-EX
  *             sssssssssss
  *
  *                     p  = pnode bits
@@ -148,12 +149,25 @@ struct uv_hub_info_s {
        unsigned char           m_val;
        unsigned char           n_val;
        struct uv_scir_s        scir;
+       unsigned char           apic_pnode_shift;
 };
 
 DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
 #define uv_hub_info            (&__get_cpu_var(__uv_hub_info))
 #define uv_cpu_hub_info(cpu)   (&per_cpu(__uv_hub_info, cpu))
 
+union uvh_apicid {
+    unsigned long       v;
+    struct uvh_apicid_s {
+        unsigned long   local_apic_mask  : 24;
+        unsigned long   local_apic_shift :  5;
+        unsigned long   unused1          :  3;
+        unsigned long   pnode_mask       : 24;
+        unsigned long   pnode_shift      :  5;
+        unsigned long   unused2          :  3;
+    } s;
+};
+
 /*
  * Local & Global MMR space macros.
  *     Note: macros are intended to be used ONLY by inline functions
@@ -182,6 +196,7 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
 #define UV_GLOBAL_MMR64_PNODE_BITS(p)                                  \
        (((unsigned long)(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT)
 
+#define UVH_APICID             0x002D0E00L
 #define UV_APIC_PNODE_SHIFT    6
 
 /* Local Bus from cpu's perspective */
@@ -280,7 +295,7 @@ static inline void *uv_pnode_offset_to_vaddr(int pnode, unsigned long offset)
  */
 static inline int uv_apicid_to_pnode(int apicid)
 {
-       return (apicid >> UV_APIC_PNODE_SHIFT);
+       return (apicid >> uv_hub_info->apic_pnode_shift);
 }
 
 /*
index b2f2d2e05cec4eba8195b60ae053d4f81a5992ee..6d90adf4428a03d90d183dcd1a77cb2b630fc8e2 100644 (file)
@@ -805,6 +805,78 @@ union uvh_node_present_table_u {
     } s;
 };
 
+/* ========================================================================= */
+/*                 UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR                  */
+/* ========================================================================= */
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR 0x16000c8UL
+
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_SHFT 24
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_MASK 0x00000000ff000000UL
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_SHFT 48
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_MASK 0x001f000000000000UL
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_SHFT 63
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_MASK 0x8000000000000000UL
+
+union uvh_rh_gam_alias210_overlay_config_0_mmr_u {
+    unsigned long      v;
+    struct uvh_rh_gam_alias210_overlay_config_0_mmr_s {
+       unsigned long   rsvd_0_23: 24;  /*    */
+       unsigned long   base    :  8;  /* RW */
+       unsigned long   rsvd_32_47: 16;  /*    */
+       unsigned long   m_alias :  5;  /* RW */
+       unsigned long   rsvd_53_62: 10;  /*    */
+       unsigned long   enable  :  1;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                 UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR                  */
+/* ========================================================================= */
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR 0x16000d8UL
+
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_SHFT 24
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_MASK 0x00000000ff000000UL
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_SHFT 48
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_MASK 0x001f000000000000UL
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_SHFT 63
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_MASK 0x8000000000000000UL
+
+union uvh_rh_gam_alias210_overlay_config_1_mmr_u {
+    unsigned long      v;
+    struct uvh_rh_gam_alias210_overlay_config_1_mmr_s {
+       unsigned long   rsvd_0_23: 24;  /*    */
+       unsigned long   base    :  8;  /* RW */
+       unsigned long   rsvd_32_47: 16;  /*    */
+       unsigned long   m_alias :  5;  /* RW */
+       unsigned long   rsvd_53_62: 10;  /*    */
+       unsigned long   enable  :  1;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                 UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR                  */
+/* ========================================================================= */
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR 0x16000e8UL
+
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_SHFT 24
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_MASK 0x00000000ff000000UL
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_SHFT 48
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_MASK 0x001f000000000000UL
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_SHFT 63
+#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_MASK 0x8000000000000000UL
+
+union uvh_rh_gam_alias210_overlay_config_2_mmr_u {
+    unsigned long      v;
+    struct uvh_rh_gam_alias210_overlay_config_2_mmr_s {
+       unsigned long   rsvd_0_23: 24;  /*    */
+       unsigned long   base    :  8;  /* RW */
+       unsigned long   rsvd_32_47: 16;  /*    */
+       unsigned long   m_alias :  5;  /* RW */
+       unsigned long   rsvd_53_62: 10;  /*    */
+       unsigned long   enable  :  1;  /* RW */
+    } s;
+};
+
 /* ========================================================================= */
 /*                UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR                  */
 /* ========================================================================= */
@@ -856,6 +928,29 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u {
     } s;
 };
 
+/* ========================================================================= */
+/*                          UVH_RH_GAM_CONFIG_MMR                            */
+/* ========================================================================= */
+#define UVH_RH_GAM_CONFIG_MMR 0x1600000UL
+
+#define UVH_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0
+#define UVH_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL
+#define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6
+#define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL
+#define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12
+#define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL
+
+union uvh_rh_gam_config_mmr_u {
+    unsigned long      v;
+    struct uvh_rh_gam_config_mmr_s {
+       unsigned long   m_skt     :  6;  /* RW */
+       unsigned long   n_skt     :  4;  /* RW */
+       unsigned long   rsvd_10_11:  2;  /*    */
+       unsigned long   mmiol_cfg :  1;  /* RW */
+       unsigned long   rsvd_13_63: 51;  /*    */
+    } s;
+};
+
 /* ========================================================================= */
 /*                    UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR                      */
 /* ========================================================================= */
@@ -987,97 +1082,5 @@ union uvh_rtc1_int_config_u {
     } s;
 };
 
-/* ========================================================================= */
-/*                          UVH_SI_ADDR_MAP_CONFIG                           */
-/* ========================================================================= */
-#define UVH_SI_ADDR_MAP_CONFIG 0xc80000UL
-
-#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_SHFT 0
-#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_MASK 0x000000000000003fUL
-#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_SHFT 8
-#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_MASK 0x0000000000000f00UL
-
-union uvh_si_addr_map_config_u {
-    unsigned long      v;
-    struct uvh_si_addr_map_config_s {
-       unsigned long   m_skt :  6;  /* RW */
-       unsigned long   rsvd_6_7:  2;  /*    */
-       unsigned long   n_skt :  4;  /* RW */
-       unsigned long   rsvd_12_63: 52;  /*    */
-    } s;
-};
-
-/* ========================================================================= */
-/*                       UVH_SI_ALIAS0_OVERLAY_CONFIG                        */
-/* ========================================================================= */
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG 0xc80008UL
-
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_SHFT 24
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_SHFT 48
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_SHFT 63
-#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL
-
-union uvh_si_alias0_overlay_config_u {
-    unsigned long      v;
-    struct uvh_si_alias0_overlay_config_s {
-       unsigned long   rsvd_0_23: 24;  /*    */
-       unsigned long   base    :  8;  /* RW */
-       unsigned long   rsvd_32_47: 16;  /*    */
-       unsigned long   m_alias :  5;  /* RW */
-       unsigned long   rsvd_53_62: 10;  /*    */
-       unsigned long   enable  :  1;  /* RW */
-    } s;
-};
-
-/* ========================================================================= */
-/*                       UVH_SI_ALIAS1_OVERLAY_CONFIG                        */
-/* ========================================================================= */
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG 0xc80010UL
-
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_SHFT 24
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_SHFT 48
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_SHFT 63
-#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL
-
-union uvh_si_alias1_overlay_config_u {
-    unsigned long      v;
-    struct uvh_si_alias1_overlay_config_s {
-       unsigned long   rsvd_0_23: 24;  /*    */
-       unsigned long   base    :  8;  /* RW */
-       unsigned long   rsvd_32_47: 16;  /*    */
-       unsigned long   m_alias :  5;  /* RW */
-       unsigned long   rsvd_53_62: 10;  /*    */
-       unsigned long   enable  :  1;  /* RW */
-    } s;
-};
-
-/* ========================================================================= */
-/*                       UVH_SI_ALIAS2_OVERLAY_CONFIG                        */
-/* ========================================================================= */
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG 0xc80018UL
-
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_SHFT 24
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_SHFT 48
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_SHFT 63
-#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL
-
-union uvh_si_alias2_overlay_config_u {
-    unsigned long      v;
-    struct uvh_si_alias2_overlay_config_s {
-       unsigned long   rsvd_0_23: 24;  /*    */
-       unsigned long   base    :  8;  /* RW */
-       unsigned long   rsvd_32_47: 16;  /*    */
-       unsigned long   m_alias :  5;  /* RW */
-       unsigned long   rsvd_53_62: 10;  /*    */
-       unsigned long   enable  :  1;  /* RW */
-    } s;
-};
-
 
-#endif /* _ASM_X86_UV_UV_MMRS_H */
+#endif /* __ASM_UV_MMRS_X86_H__ */
index a36bb90aef5383d68bcf4af0b0c33749d572163a..5079f24c955a2d3b9b66532cd2c8cd45e5116d14 100644 (file)
@@ -638,71 +638,32 @@ void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len)
        atomic_set(&stop_machine_first, 1);
        wrote_text = 0;
        /* Use __stop_machine() because the caller already got online_cpus. */
-       __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
+       __stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask);
        return addr;
 }
 
 #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL)
 
-unsigned char ideal_nop5[IDEAL_NOP_SIZE_5];
+#ifdef CONFIG_X86_64
+unsigned char ideal_nop5[5] = { 0x66, 0x66, 0x66, 0x66, 0x90 };
+#else
+unsigned char ideal_nop5[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 };
+#endif
 
 void __init arch_init_ideal_nop5(void)
 {
-       extern const unsigned char ftrace_test_p6nop[];
-       extern const unsigned char ftrace_test_nop5[];
-       extern const unsigned char ftrace_test_jmp[];
-       int faulted = 0;
-
        /*
-        * There is no good nop for all x86 archs.
-        * We will default to using the P6_NOP5, but first we
-        * will test to make sure that the nop will actually
-        * work on this CPU. If it faults, we will then
-        * go to a lesser efficient 5 byte nop. If that fails
-        * we then just use a jmp as our nop. This isn't the most
-        * efficient nop, but we can not use a multi part nop
-        * since we would then risk being preempted in the middle
-        * of that nop, and if we enabled tracing then, it might
-        * cause a system crash.
+        * There is no good nop for all x86 archs.  This selection
+        * algorithm should be unified with the one in find_nop_table(),
+        * but this should be good enough for now.
         *
-        * TODO: check the cpuid to determine the best nop.
+        * For cases other than the ones below, use the safe (as in
+        * always functional) defaults above.
         */
-       asm volatile (
-               "ftrace_test_jmp:"
-               "jmp ftrace_test_p6nop\n"
-               "nop\n"
-               "nop\n"
-               "nop\n"  /* 2 byte jmp + 3 bytes */
-               "ftrace_test_p6nop:"
-               P6_NOP5
-               "jmp 1f\n"
-               "ftrace_test_nop5:"
-               ".byte 0x66,0x66,0x66,0x66,0x90\n"
-               "1:"
-               ".section .fixup, \"ax\"\n"
-               "2:     movl $1, %0\n"
-               "       jmp ftrace_test_nop5\n"
-               "3:     movl $2, %0\n"
-               "       jmp 1b\n"
-               ".previous\n"
-               _ASM_EXTABLE(ftrace_test_p6nop, 2b)
-               _ASM_EXTABLE(ftrace_test_nop5, 3b)
-               : "=r"(faulted) : "0" (faulted));
-
-       switch (faulted) {
-       case 0:
-               pr_info("converting mcount calls to 0f 1f 44 00 00\n");
-               memcpy(ideal_nop5, ftrace_test_p6nop, IDEAL_NOP_SIZE_5);
-               break;
-       case 1:
-               pr_info("converting mcount calls to 66 66 66 66 90\n");
-               memcpy(ideal_nop5, ftrace_test_nop5, IDEAL_NOP_SIZE_5);
-               break;
-       case 2:
-               pr_info("converting mcount calls to jmp . + 5\n");
-               memcpy(ideal_nop5, ftrace_test_jmp, IDEAL_NOP_SIZE_5);
-               break;
-       }
-
+#ifdef CONFIG_X86_64
+       /* Don't use these on 32 bits due to broken virtualizers */
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+               memcpy(ideal_nop5, p6_nops[5], 5);
+#endif
 }
 #endif
index 850657d1b0ed573e23552913d7aae230df30fe9a..3f838d537392b4ddb6d061e82bbf1ce8a2a3b9d2 100644 (file)
@@ -52,7 +52,6 @@
 #include <asm/mce.h>
 #include <asm/kvm_para.h>
 #include <asm/tsc.h>
-#include <asm/atomic.h>
 
 unsigned int num_processors;
 
index 0929191d83cf5264751fbfffd19554f78f986848..7cc0a721f628c302d0d420ba0bf3af1945d5a1c0 100644 (file)
@@ -3109,7 +3109,7 @@ void destroy_irq(unsigned int irq)
 
        irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE);
 
-       if (intr_remapping_enabled)
+       if (irq_remapped(cfg))
                free_irte(irq);
        raw_spin_lock_irqsave(&vector_lock, flags);
        __clear_irq_vector(irq, cfg);
index f744f54cb248e7ac0cd6defaa84a8e673468b30a..194539aea1757d79058e3ec17acbeaa68ae6432f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * SGI UV APIC functions (note: not an Intel compatible APIC)
  *
- * Copyright (C) 2007-2009 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved.
  */
 #include <linux/cpumask.h>
 #include <linux/hardirq.h>
@@ -41,6 +41,7 @@ DEFINE_PER_CPU(int, x2apic_extra_bits);
 
 static enum uv_system_type uv_system_type;
 static u64 gru_start_paddr, gru_end_paddr;
+static union uvh_apicid uvh_apicid;
 int uv_min_hub_revision_id;
 EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
 static DEFINE_SPINLOCK(uv_nmi_lock);
@@ -70,12 +71,27 @@ static int early_get_nodeid(void)
        return node_id.s.node_id;
 }
 
+static void __init early_get_apic_pnode_shift(void)
+{
+       unsigned long *mmr;
+
+       mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_APICID, sizeof(*mmr));
+       uvh_apicid.v = *mmr;
+       early_iounmap(mmr, sizeof(*mmr));
+       if (!uvh_apicid.v)
+               /*
+                * Old bios, use default value
+                */
+               uvh_apicid.s.pnode_shift = UV_APIC_PNODE_SHIFT;
+}
+
 static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
        int nodeid;
 
        if (!strcmp(oem_id, "SGI")) {
                nodeid = early_get_nodeid();
+               early_get_apic_pnode_shift();
                x86_platform.is_untracked_pat_range =  uv_is_untracked_pat_range;
                x86_platform.nmi_init = uv_nmi_init;
                if (!strcmp(oem_table_id, "UVL"))
@@ -84,7 +100,7 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
                        uv_system_type = UV_X2APIC;
                else if (!strcmp(oem_table_id, "UVH")) {
                        __get_cpu_var(x2apic_extra_bits) =
-                               nodeid << (UV_APIC_PNODE_SHIFT - 1);
+                               nodeid << (uvh_apicid.s.pnode_shift - 1);
                        uv_system_type = UV_NON_UNIQUE_APIC;
                        return 1;
                }
@@ -363,14 +379,14 @@ struct redir_addr {
 #define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT
 
 static __initdata struct redir_addr redir_addrs[] = {
-       {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG},
-       {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG},
-       {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG},
+       {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR},
+       {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR},
+       {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR},
 };
 
 static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
 {
-       union uvh_si_alias0_overlay_config_u alias;
+       union uvh_rh_gam_alias210_overlay_config_2_mmr_u alias;
        union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect;
        int i;
 
@@ -644,7 +660,7 @@ void uv_nmi_init(void)
 
 void __init uv_system_init(void)
 {
-       union uvh_si_addr_map_config_u m_n_config;
+       union uvh_rh_gam_config_mmr_u  m_n_config;
        union uvh_node_id_u node_id;
        unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size;
        int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val;
@@ -654,7 +670,7 @@ void __init uv_system_init(void)
 
        map_low_mmrs();
 
-       m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG);
+       m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR );
        m_val = m_n_config.s.m_skt;
        n_val = m_n_config.s.n_skt;
        mmr_base =
@@ -716,6 +732,10 @@ void __init uv_system_init(void)
                int apicid = per_cpu(x86_cpu_to_apicid, cpu);
 
                nid = cpu_to_node(cpu);
+               /*
+                * apic_pnode_shift must be set before calling uv_apicid_to_pnode();
+                */
+               uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift;
                pnode = uv_apicid_to_pnode(apicid);
                blade = boot_pnode_to_blade(pnode);
                lcpu = uv_blade_info[blade].nr_possible_cpus;
index 46d58448c3aff9039fdf0b909d069d00d80ef75e..e421b8cd6944af860c4b28a1a176a14320ac9f79 100644 (file)
@@ -280,11 +280,11 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
        struct amd_nb *nb;
        int i;
 
-       nb = kmalloc(sizeof(struct amd_nb), GFP_KERNEL);
+       nb = kmalloc_node(sizeof(struct amd_nb), GFP_KERNEL | __GFP_ZERO,
+                         cpu_to_node(cpu));
        if (!nb)
                return NULL;
 
-       memset(nb, 0, sizeof(*nb));
        nb->nb_id = nb_id;
 
        /*
index 64668dbf00a46185f7ef9d96a6a58996509e523d..96656f2077511bf280eec0010a087c96649fdaaa 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/percpu.h>
+#include <linux/mm.h>
 
 #include <asm/apic.h>
 
@@ -125,7 +126,9 @@ void __cpuinit irq_ctx_init(int cpu)
        if (per_cpu(hardirq_ctx, cpu))
                return;
 
-       irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER);
+       irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
+                                              THREAD_FLAGS,
+                                              THREAD_ORDER));
        irqctx->tinfo.task              = NULL;
        irqctx->tinfo.exec_domain       = NULL;
        irqctx->tinfo.cpu               = cpu;
@@ -134,7 +137,9 @@ void __cpuinit irq_ctx_init(int cpu)
 
        per_cpu(hardirq_ctx, cpu) = irqctx;
 
-       irqctx = (union irq_ctx *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER);
+       irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
+                                              THREAD_FLAGS,
+                                              THREAD_ORDER));
        irqctx->tinfo.task              = NULL;
        irqctx->tinfo.exec_domain       = NULL;
        irqctx->tinfo.cpu               = cpu;
index d81cfebb848f2fd5c61e7a4524a26c00d3d2f66d..ec592caac4b4e11b5d7ac0bc2986d6617ac4b90b 100644 (file)
@@ -387,7 +387,7 @@ kgdb_set_hw_break(unsigned long addr, int len, enum kgdb_bptype bptype)
  *     disable hardware debugging while it is processing gdb packets or
  *     handling exception.
  */
-void kgdb_disable_hw_debug(struct pt_regs *regs)
+static void kgdb_disable_hw_debug(struct pt_regs *regs)
 {
        int i;
        int cpu = raw_smp_processor_id();
@@ -724,6 +724,7 @@ struct kgdb_arch arch_kgdb_ops = {
        .flags                  = KGDB_HW_BREAKPOINT,
        .set_hw_breakpoint      = kgdb_set_hw_break,
        .remove_hw_breakpoint   = kgdb_remove_hw_break,
+       .disable_hw_break       = kgdb_disable_hw_debug,
        .remove_all_hw_break    = kgdb_remove_all_hw_break,
        .correct_hw_break       = kgdb_correct_hw_break,
 };
index e1af7c055c7d0c86c7e3a1fe789e597825185892..ce0cb4721c9ac9eec8869e64c1fcd1a1ef0fd379 100644 (file)
@@ -212,7 +212,7 @@ static int install_equiv_cpu_table(const u8 *buf)
                return 0;
        }
 
-       equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size);
+       equiv_cpu_table = vmalloc(size);
        if (!equiv_cpu_table) {
                pr_err("failed to allocate equivalent CPU table\n");
                return 0;
index 71825806cd44f14cf49e8381e22b5dbd3ac0b29d..6da143c2a6b8b27f03a611bad88047879c80f3bf 100644 (file)
@@ -217,13 +217,13 @@ void __cpuinit fam10h_check_enable_mmcfg(void)
        wrmsrl(address, val);
 }
 
-static int __devinit set_check_enable_amd_mmconf(const struct dmi_system_id *d)
+static int __init set_check_enable_amd_mmconf(const struct dmi_system_id *d)
 {
         pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF;
         return 0;
 }
 
-static const struct dmi_system_id __cpuinitconst mmconf_dmi_table[] = {
+static const struct dmi_system_id __initconst mmconf_dmi_table[] = {
         {
                 .callback = set_check_enable_amd_mmconf,
                 .ident = "Sun Microsystems Machine",
@@ -234,7 +234,8 @@ static const struct dmi_system_id __cpuinitconst mmconf_dmi_table[] = {
        {}
 };
 
-void __cpuinit check_enable_amd_mmconf_dmi(void)
+/* Called from a __cpuinit function, but only on the BSP. */
+void __ref check_enable_amd_mmconf_dmi(void)
 {
        dmi_check_system(mmconf_dmi_table);
 }
index bab3b9e6f66d0d4919f5f035848037ce5ccf7639..008b91eefa188139f57f7b77de6c7aef6240ef08 100644 (file)
@@ -41,44 +41,6 @@ void pvclock_set_flags(u8 flags)
        valid_flags = flags;
 }
 
-/*
- * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
- * yielding a 64-bit result.
- */
-static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
-{
-       u64 product;
-#ifdef __i386__
-       u32 tmp1, tmp2;
-#endif
-
-       if (shift < 0)
-               delta >>= -shift;
-       else
-               delta <<= shift;
-
-#ifdef __i386__
-       __asm__ (
-               "mul  %5       ; "
-               "mov  %4,%%eax ; "
-               "mov  %%edx,%4 ; "
-               "mul  %5       ; "
-               "xor  %5,%5    ; "
-               "add  %4,%%eax ; "
-               "adc  %5,%%edx ; "
-               : "=A" (product), "=r" (tmp1), "=r" (tmp2)
-               : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
-#elif defined(__x86_64__)
-       __asm__ (
-               "mul %%rdx ; shrd $32,%%rdx,%%rax"
-               : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
-#else
-#error implement me!
-#endif
-
-       return product;
-}
-
 static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow)
 {
        u64 delta = native_read_tsc() - shadow->tsc_timestamp;
index 908ea5464a518097958083156eb5b0b94f4d021c..fb8b376bf28cb3e04a6bb903900f32838ab02a14 100644 (file)
@@ -720,7 +720,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
        }
 }
 
-static void set_spte_track_bits(u64 *sptep, u64 new_spte)
+static int set_spte_track_bits(u64 *sptep, u64 new_spte)
 {
        pfn_t pfn;
        u64 old_spte = *sptep;
@@ -731,19 +731,20 @@ static void set_spte_track_bits(u64 *sptep, u64 new_spte)
                old_spte = __xchg_spte(sptep, new_spte);
 
        if (!is_rmap_spte(old_spte))
-               return;
+               return 0;
 
        pfn = spte_to_pfn(old_spte);
        if (!shadow_accessed_mask || old_spte & shadow_accessed_mask)
                kvm_set_pfn_accessed(pfn);
        if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask))
                kvm_set_pfn_dirty(pfn);
+       return 1;
 }
 
 static void drop_spte(struct kvm *kvm, u64 *sptep, u64 new_spte)
 {
-       set_spte_track_bits(sptep, new_spte);
-       rmap_remove(kvm, sptep);
+       if (set_spte_track_bits(sptep, new_spte))
+               rmap_remove(kvm, sptep);
 }
 
 static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte)
index 2288ad829b327bb68d0efa65c104dcc7f2bbe7b5..cdac9e592aa53ee84b7e184900601ab4730354e5 100644 (file)
@@ -2560,6 +2560,7 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
                !kvm_exception_is_soft(vcpu->arch.exception.nr);
        events->exception.nr = vcpu->arch.exception.nr;
        events->exception.has_error_code = vcpu->arch.exception.has_error_code;
+       events->exception.pad = 0;
        events->exception.error_code = vcpu->arch.exception.error_code;
 
        events->interrupt.injected =
@@ -2573,12 +2574,14 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
        events->nmi.injected = vcpu->arch.nmi_injected;
        events->nmi.pending = vcpu->arch.nmi_pending;
        events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu);
+       events->nmi.pad = 0;
 
        events->sipi_vector = vcpu->arch.sipi_vector;
 
        events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING
                         | KVM_VCPUEVENT_VALID_SIPI_VECTOR
                         | KVM_VCPUEVENT_VALID_SHADOW);
+       memset(&events->reserved, 0, sizeof(events->reserved));
 }
 
 static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
@@ -2623,6 +2626,7 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
        dbgregs->dr6 = vcpu->arch.dr6;
        dbgregs->dr7 = vcpu->arch.dr7;
        dbgregs->flags = 0;
+       memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved));
 }
 
 static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
@@ -3106,6 +3110,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
                sizeof(ps->channels));
        ps->flags = kvm->arch.vpit->pit_state.flags;
        mutex_unlock(&kvm->arch.vpit->pit_state.lock);
+       memset(&ps->reserved, 0, sizeof(ps->reserved));
        return r;
 }
 
@@ -3169,10 +3174,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                struct kvm_memslots *slots, *old_slots;
                unsigned long *dirty_bitmap;
 
-               spin_lock(&kvm->mmu_lock);
-               kvm_mmu_slot_remove_write_access(kvm, log->slot);
-               spin_unlock(&kvm->mmu_lock);
-
                r = -ENOMEM;
                dirty_bitmap = vmalloc(n);
                if (!dirty_bitmap)
@@ -3194,6 +3195,10 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap;
                kfree(old_slots);
 
+               spin_lock(&kvm->mmu_lock);
+               kvm_mmu_slot_remove_write_access(kvm, log->slot);
+               spin_unlock(&kvm->mmu_lock);
+
                r = -EFAULT;
                if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) {
                        vfree(dirty_bitmap);
@@ -3486,6 +3491,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
                user_ns.clock = kvm->arch.kvmclock_offset + now_ns;
                local_irq_enable();
                user_ns.flags = 0;
+               memset(&user_ns.pad, 0, sizeof(user_ns.pad));
 
                r = -EFAULT;
                if (copy_to_user(argp, &user_ns, sizeof(user_ns)))
@@ -3972,8 +3978,10 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu)
                return X86EMUL_CONTINUE;
 
        if (kvm_x86_ops->has_wbinvd_exit()) {
+               preempt_disable();
                smp_call_function_many(vcpu->arch.wbinvd_dirty_mask,
                                wbinvd_ipi, NULL, 1);
+               preempt_enable();
                cpumask_clear(vcpu->arch.wbinvd_dirty_mask);
        }
        wbinvd();
index 60f498511dd60b01a9eee62fdc0a69ba80d3082c..7ffc9b727efdc95ee6748acd1a1b646c8e164ffb 100644 (file)
@@ -178,11 +178,8 @@ static void * __init early_node_mem(int nodeid, unsigned long start,
 
        /* extend the search scope */
        end = max_pfn_mapped << PAGE_SHIFT;
-       if (end > (MAX_DMA32_PFN<<PAGE_SHIFT))
-               start = MAX_DMA32_PFN<<PAGE_SHIFT;
-       else
-               start = MAX_DMA_PFN<<PAGE_SHIFT;
-       mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align);
+       start = MAX_DMA_PFN << PAGE_SHIFT;
+       mem = memblock_find_in_range(start, end, size, align);
        if (mem != MEMBLOCK_ERROR)
                return __va(mem);
 
index 49358481c733235918cde7c576a3332fba50c364..12cdbb17ad181dfac805d60f4991ee1eacfb935c 100644 (file)
@@ -251,7 +251,7 @@ static void __cpuinit calculate_tlb_offset(void)
        }
 }
 
-static int tlb_cpuhp_notify(struct notifier_block *n,
+static int __cpuinit tlb_cpuhp_notify(struct notifier_block *n,
                unsigned long action, void *hcpu)
 {
        switch (action & 0xf) {
index 15466c096ba5f56fabc7f174eabd1c40996e4b6d..0972315c3860c40c719f1b03081b892c3e8f20bf 100644 (file)
@@ -138,7 +138,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        struct acpi_resource_address64 addr;
        acpi_status status;
        unsigned long flags;
-       struct resource *root, *conflict;
        u64 start, end;
 
        status = resource_to_addr(acpi_res, &addr);
@@ -146,12 +145,10 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
                return AE_OK;
 
        if (addr.resource_type == ACPI_MEMORY_RANGE) {
-               root = &iomem_resource;
                flags = IORESOURCE_MEM;
                if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
                        flags |= IORESOURCE_PREFETCH;
        } else if (addr.resource_type == ACPI_IO_RANGE) {
-               root = &ioport_resource;
                flags = IORESOURCE_IO;
        } else
                return AE_OK;
@@ -172,25 +169,90 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
                return AE_OK;
        }
 
-       conflict = insert_resource_conflict(root, res);
-       if (conflict) {
-               dev_err(&info->bridge->dev,
-                       "address space collision: host bridge window %pR "
-                       "conflicts with %s %pR\n",
-                       res, conflict->name, conflict);
-       } else {
-               pci_bus_add_resource(info->bus, res, 0);
-               info->res_num++;
-               if (addr.translation_offset)
-                       dev_info(&info->bridge->dev, "host bridge window %pR "
-                                "(PCI address [%#llx-%#llx])\n",
-                                res, res->start - addr.translation_offset,
-                                res->end - addr.translation_offset);
+       info->res_num++;
+       if (addr.translation_offset)
+               dev_info(&info->bridge->dev, "host bridge window %pR "
+                        "(PCI address [%#llx-%#llx])\n",
+                        res, res->start - addr.translation_offset,
+                        res->end - addr.translation_offset);
+       else
+               dev_info(&info->bridge->dev, "host bridge window %pR\n", res);
+
+       return AE_OK;
+}
+
+static bool resource_contains(struct resource *res, resource_size_t point)
+{
+       if (res->start <= point && point <= res->end)
+               return true;
+       return false;
+}
+
+static void coalesce_windows(struct pci_root_info *info, int type)
+{
+       int i, j;
+       struct resource *res1, *res2;
+
+       for (i = 0; i < info->res_num; i++) {
+               res1 = &info->res[i];
+               if (!(res1->flags & type))
+                       continue;
+
+               for (j = i + 1; j < info->res_num; j++) {
+                       res2 = &info->res[j];
+                       if (!(res2->flags & type))
+                               continue;
+
+                       /*
+                        * I don't like throwing away windows because then
+                        * our resources no longer match the ACPI _CRS, but
+                        * the kernel resource tree doesn't allow overlaps.
+                        */
+                       if (resource_contains(res1, res2->start) ||
+                           resource_contains(res1, res2->end) ||
+                           resource_contains(res2, res1->start) ||
+                           resource_contains(res2, res1->end)) {
+                               res1->start = min(res1->start, res2->start);
+                               res1->end = max(res1->end, res2->end);
+                               dev_info(&info->bridge->dev,
+                                        "host bridge window expanded to %pR; %pR ignored\n",
+                                        res1, res2);
+                               res2->flags = 0;
+                       }
+               }
+       }
+}
+
+static void add_resources(struct pci_root_info *info)
+{
+       int i;
+       struct resource *res, *root, *conflict;
+
+       if (!pci_use_crs)
+               return;
+
+       coalesce_windows(info, IORESOURCE_MEM);
+       coalesce_windows(info, IORESOURCE_IO);
+
+       for (i = 0; i < info->res_num; i++) {
+               res = &info->res[i];
+
+               if (res->flags & IORESOURCE_MEM)
+                       root = &iomem_resource;
+               else if (res->flags & IORESOURCE_IO)
+                       root = &ioport_resource;
                else
-                       dev_info(&info->bridge->dev,
-                                "host bridge window %pR\n", res);
+                       continue;
+
+               conflict = insert_resource_conflict(root, res);
+               if (conflict)
+                       dev_err(&info->bridge->dev,
+                               "address space collision: host bridge window %pR "
+                               "conflicts with %s %pR\n",
+                               res, conflict->name, conflict);
+               else
+                       pci_bus_add_resource(info->bus, res, 0);
        }
-       return AE_OK;
 }
 
 static void
@@ -224,6 +286,7 @@ get_current_resources(struct acpi_device *device, int busnum,
        acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
                                &info);
 
+       add_resources(&info);
        return;
 
 name_alloc_fail:
index 117f5b8daf7515bf8ac03deb5522a011c286280d..d7b5109f7a9c28b05e120da3eec295b1716f543e 100644 (file)
@@ -147,8 +147,10 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
                irq = xen_allocate_pirq(v[i], 0, /* not sharable */
                        (type == PCI_CAP_ID_MSIX) ?
                        "pcifront-msi-x" : "pcifront-msi");
-               if (irq < 0)
-                       return -1;
+               if (irq < 0) {
+                       ret = -1;
+                       goto free;
+               }
 
                ret = set_irq_msi(irq, msidesc);
                if (ret)
@@ -164,7 +166,7 @@ error:
        if (ret == -ENODEV)
                dev_err(&dev->dev, "Xen PCI frontend has not registered" \
                        " MSI/MSI-X support!\n");
-
+free:
        kfree(v);
        return ret;
 }
index 20ea20a39e2a2f4b2a0012edd532ebff368f3e5a..a318194002b56c3a953df57a9664c5f02745d2ba 100644 (file)
@@ -1343,8 +1343,8 @@ uv_activation_descriptor_init(int node, int pnode)
         * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR)
         * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub
         */
-       bau_desc = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)*
-               UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
+       bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE
+                               * UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
        BUG_ON(!bau_desc);
 
        pa = uv_gpa(bau_desc); /* need the real nasid*/
@@ -1402,9 +1402,9 @@ uv_payload_queue_init(int node, int pnode)
        struct bau_payload_queue_entry *pqp_malloc;
        struct bau_control *bcp;
 
-       pqp = (struct bau_payload_queue_entry *) kmalloc_node(
-               (DEST_Q_SIZE + 1) * sizeof(struct bau_payload_queue_entry),
-               GFP_KERNEL, node);
+       pqp = kmalloc_node((DEST_Q_SIZE + 1)
+                          * sizeof(struct bau_payload_queue_entry),
+                          GFP_KERNEL, node);
        BUG_ON(!pqp);
        pqp_malloc = pqp;
 
@@ -1520,8 +1520,7 @@ static void __init uv_init_per_cpu(int nuvhubs)
 
        timeout_us = calculate_destination_timeout();
 
-       uvhub_descs = (struct uvhub_desc *)
-               kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
+       uvhub_descs = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
        memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
        uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL);
        for_each_present_cpu(cpu) {
index bd2713a825716f88bb41f0762ca7c382da7a8cf8..790af908284e56424ce3c3b0c851b53eb1443b63 100644 (file)
@@ -2641,7 +2641,8 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
 
        prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP);
 
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+       BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_RESERVED | VM_IO)) ==
+                               (VM_PFNMAP | VM_RESERVED | VM_IO)));
 
        rmd.mfn = mfn;
        rmd.prot = prot;
index f0834e2f57275d8903f65b655645f66a9b2016ee..4ce953f1b3909f38f213adcc0a39251a34875330 100644 (file)
@@ -1194,13 +1194,6 @@ static int __make_request(struct request_queue *q, struct bio *bio)
        int where = ELEVATOR_INSERT_SORT;
        int rw_flags;
 
-       /* REQ_HARDBARRIER is no more */
-       if (WARN_ONCE(bio->bi_rw & REQ_HARDBARRIER,
-               "block: HARDBARRIER is deprecated, use FLUSH/FUA instead\n")) {
-               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
@@ -1351,7 +1344,7 @@ static void handle_bad_sector(struct bio *bio)
                        bdevname(bio->bi_bdev, b),
                        bio->bi_rw,
                        (unsigned long long)bio->bi_sector + bio_sectors(bio),
-                       (long long)(bio->bi_bdev->bd_inode->i_size >> 9));
+                       (long long)(i_size_read(bio->bi_bdev->bd_inode) >> 9));
 
        set_bit(BIO_EOF, &bio->bi_flags);
 }
@@ -1404,7 +1397,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
                return 0;
 
        /* Test device or partition size, when known. */
-       maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
+       maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9;
        if (maxsector) {
                sector_t sector = bio->bi_sector;
 
index d22c4c55c40689c23b7d275fbb76af17c0b23efa..3c7a339fe3813483155f31b05ea5aa5cd3224a36 100644 (file)
@@ -153,20 +153,6 @@ struct io_context *get_io_context(gfp_t gfp_flags, int node)
 }
 EXPORT_SYMBOL(get_io_context);
 
-void copy_io_context(struct io_context **pdst, struct io_context **psrc)
-{
-       struct io_context *src = *psrc;
-       struct io_context *dst = *pdst;
-
-       if (src) {
-               BUG_ON(atomic_long_read(&src->refcount) == 0);
-               atomic_long_inc(&src->refcount);
-               put_io_context(dst);
-               *pdst = src;
-       }
-}
-EXPORT_SYMBOL(copy_io_context);
-
 static int __init blk_ioc_init(void)
 {
        iocontext_cachep = kmem_cache_create("blkdev_ioc",
index d4a586d8691ec5ed37311d1e3fc76aa0c310828f..5d5dbe47c2285ee7ccb5f3ca784f9cdb8cb6df3e 100644 (file)
@@ -205,6 +205,8 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
                        unaligned = 1;
                        break;
                }
+               if (!iov[i].iov_len)
+                       return -EINVAL;
        }
 
        if (unaligned || (q->dma_pad_mask & len) || map_data)
index 119f07b74dc0c41d99c282c1299a80f5f0dfc8c0..58c6ee5b010c4fd4a22206e9c88c5cadedc1a1a2 100644 (file)
@@ -744,13 +744,13 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
                bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
                return 0;
        case BLKGETSIZE:
-               size = bdev->bd_inode->i_size;
+               size = i_size_read(bdev->bd_inode);
                if ((size >> 9) > ~0UL)
                        return -EFBIG;
                return compat_put_ulong(arg, size >> 9);
 
        case BLKGETSIZE64_32:
-               return compat_put_u64(arg, bdev->bd_inode->i_size);
+               return compat_put_u64(arg, i_size_read(bdev->bd_inode));
 
        case BLKTRACESETUP32:
        case BLKTRACESTART: /* compatible */
index 282e8308f7e2bbab837375daf5ad81cfae97ca5e..2569512830d3e65a8a73213879b591917bdd91c4 100644 (file)
@@ -429,7 +429,7 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq)
        q->nr_sorted--;
 
        boundary = q->end_sector;
-       stop_flags = REQ_SOFTBARRIER | REQ_HARDBARRIER | REQ_STARTED;
+       stop_flags = REQ_SOFTBARRIER | REQ_STARTED;
        list_for_each_prev(entry, &q->queue_head) {
                struct request *pos = list_entry_rq(entry);
 
@@ -691,7 +691,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
 void __elv_add_request(struct request_queue *q, struct request *rq, int where,
                       int plug)
 {
-       if (rq->cmd_flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
+       if (rq->cmd_flags & REQ_SOFTBARRIER) {
                /* barriers are scheduling boundary, update end_sector */
                if (rq->cmd_type == REQ_TYPE_FS ||
                    (rq->cmd_flags & REQ_DISCARD)) {
index d724ceb1d46535fee2fa3e65ca57cb09cb88997d..3d866d0037f240c8d636f8b8523df962e72ab123 100644 (file)
@@ -125,7 +125,7 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
        start >>= 9;
        len >>= 9;
 
-       if (start + len > (bdev->bd_inode->i_size >> 9))
+       if (start + len > (i_size_read(bdev->bd_inode) >> 9))
                return -EINVAL;
        if (secure)
                flags |= BLKDEV_DISCARD_SECURE;
@@ -242,6 +242,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
                 * We need to set the startsect first, the driver may
                 * want to override it.
                 */
+               memset(&geo, 0, sizeof(geo));
                geo.start = get_start_sect(bdev);
                ret = disk->fops->getgeo(bdev, &geo);
                if (ret)
@@ -307,12 +308,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
                ret = blkdev_reread_part(bdev);
                break;
        case BLKGETSIZE:
-               size = bdev->bd_inode->i_size;
+               size = i_size_read(bdev->bd_inode);
                if ((size >> 9) > ~0UL)
                        return -EFBIG;
                return put_ulong(arg, size >> 9);
        case BLKGETSIZE64:
-               return put_u64(arg, bdev->bd_inode->i_size);
+               return put_u64(arg, i_size_read(bdev->bd_inode));
        case BLKTRACESTART:
        case BLKTRACESTOP:
        case BLKTRACESETUP:
index a8b5a10eb5b04cc15cdd8ddd26ed23fe7c55bc78..4f4230b79bb6ee3c8164e462e40d4bdea3dc1fcd 100644 (file)
@@ -321,33 +321,47 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
        if (hdr->iovec_count) {
                const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
                size_t iov_data_len;
-               struct sg_iovec *iov;
+               struct sg_iovec *sg_iov;
+               struct iovec *iov;
+               int i;
 
-               iov = kmalloc(size, GFP_KERNEL);
-               if (!iov) {
+               sg_iov = kmalloc(size, GFP_KERNEL);
+               if (!sg_iov) {
                        ret = -ENOMEM;
                        goto out;
                }
 
-               if (copy_from_user(iov, hdr->dxferp, size)) {
-                       kfree(iov);
+               if (copy_from_user(sg_iov, hdr->dxferp, size)) {
+                       kfree(sg_iov);
                        ret = -EFAULT;
                        goto out;
                }
 
+               /*
+                * Sum up the vecs, making sure they don't overflow
+                */
+               iov = (struct iovec *) sg_iov;
+               iov_data_len = 0;
+               for (i = 0; i < hdr->iovec_count; i++) {
+                       if (iov_data_len + iov[i].iov_len < iov_data_len) {
+                               kfree(sg_iov);
+                               ret = -EINVAL;
+                               goto out;
+                       }
+                       iov_data_len += iov[i].iov_len;
+               }
+
                /* SG_IO howto says that the shorter of the two wins */
-               iov_data_len = iov_length((struct iovec *)iov,
-                                         hdr->iovec_count);
                if (hdr->dxfer_len < iov_data_len) {
-                       hdr->iovec_count = iov_shorten((struct iovec *)iov,
+                       hdr->iovec_count = iov_shorten(iov,
                                                       hdr->iovec_count,
                                                       hdr->dxfer_len);
                        iov_data_len = hdr->dxfer_len;
                }
 
-               ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count,
+               ret = blk_rq_map_user_iov(q, rq, NULL, sg_iov, hdr->iovec_count,
                                          iov_data_len, GFP_KERNEL);
-               kfree(iov);
+               kfree(sg_iov);
        } else if (hdr->dxfer_len)
                ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len,
                                      GFP_KERNEL);
index de3078215fe6eadd89f31bfd3a86f426a4a18015..75586f1f86e7b27632b1250b2e4572135bf03e1c 100644 (file)
@@ -504,7 +504,6 @@ err:
 
 static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt)
 {
-       kobject_put(&pcrypt->pinst->kobj);
        free_cpumask_var(pcrypt->cb_cpumask->mask);
        kfree(pcrypt->cb_cpumask);
 
index 14cf9077bb2bcf4f01025518b11b0e87e072e9b5..f3ebb30f1b7fd9c7ed93d6328dbe4d8c54b1fd87 100644 (file)
@@ -26,6 +26,7 @@ obj-$(CONFIG_REGULATOR)               += regulator/
 
 # char/ comes before serial/ etc so that the VT console is the boot-time
 # default.
+obj-y                          += tty/
 obj-y                          += char/
 
 # gpu/ comes after char for AGP vs DRM startup
index 6355b575ee5ac22498b32953e0955cb2811e81ba..5df67f1d6c612537f10ac2fd84b6720911d16723 100644 (file)
@@ -80,7 +80,7 @@ int __init acpi_debugfs_init(void)
        if (!acpi_dir)
                goto err;
 
-       cm_dentry = debugfs_create_file("custom_method", S_IWUGO,
+       cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
                                        acpi_dir, NULL, &cm_fops);
        if (!cm_dentry)
                goto err;
index d050e073e57035a99b969c50205a4227ed6a8812..3f91c01c217fe8179a58da9dd00c59465b700aba 100644 (file)
@@ -2552,8 +2552,11 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
                 *
                 * If door lock fails, always clear sdev->locked to
                 * avoid this infinite loop.
+                *
+                * This may happen before SCSI scan is complete.  Make
+                * sure qc->dev->sdev isn't NULL before dereferencing.
                 */
-               if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL)
+               if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev)
                        qc->dev->sdev->locked = 0;
 
                qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
index eaf194138f219f187e819fd56f4cce86b0cc90f7..6bd9425ba5ab593ab11372fb6e2e966bf43ecd81 100644 (file)
@@ -142,7 +142,7 @@ static int autospeed;               /* Chip present which snoops speed changes */
 static int pio_mask = ATA_PIO4;        /* PIO range for autospeed devices */
 static int iordy_mask = 0xFFFFFFFF;    /* Use iordy if available */
 
-#ifdef PATA_WINBOND_VLB_MODULE
+#ifdef CONFIG_PATA_WINBOND_VLB_MODULE
 static int winbond = 1;                /* Set to probe Winbond controllers,
                                        give I/O port if non standard */
 #else
index 06ddd91ffeda276f0ec5d0c0cfd2696f308a0cc1..fa1b95a9a7ff3268e6893877ac35718063368875 100644 (file)
@@ -60,7 +60,7 @@ static unsigned int ns_to_tim_reg(unsigned int tim_mult, unsigned int nsecs)
         * Compute # of eclock periods to get desired duration in
         * nanoseconds.
         */
-       val = DIV_ROUND_UP(nsecs * (octeon_get_clock_rate() / 1000000),
+       val = DIV_ROUND_UP(nsecs * (octeon_get_io_clock_rate() / 1000000),
                          1000 * tim_mult);
 
        return val;
@@ -652,8 +652,6 @@ static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance)
                struct octeon_cf_data *ocd;
 
                ap = host->ports[i];
-               ocd = ap->dev->platform_data;
-
                ocd = ap->dev->platform_data;
                cf_port = ap->private_data;
                dma_int.u64 =
index 1a9332e4efe0847aea86548b2e58e9fcd77b1268..9a676ee308249c038757e5fba35b29847e4fb538 100644 (file)
@@ -1,6 +1,7 @@
 SOLOS_ATTR_RO(DriverVersion)
 SOLOS_ATTR_RO(APIVersion)
 SOLOS_ATTR_RO(FirmwareVersion)
+SOLOS_ATTR_RO(Version)
 // SOLOS_ATTR_RO(DspVersion)
 // SOLOS_ATTR_RO(CommonHandshake)
 SOLOS_ATTR_RO(Connected)
index f46138ab38b6c310fffc589681f727840a05c646..2e08c996fd30a6156e8a0a19e46966824d3d89df 100644 (file)
@@ -1161,6 +1161,14 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
        dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n",
                 major_ver, minor_ver, fpga_ver);
 
+       if (fpga_ver < 37 && (fpga_upgrade || firmware_upgrade ||
+                             db_fpga_upgrade || db_firmware_upgrade)) {
+               dev_warn(&dev->dev,
+                        "FPGA too old; cannot upgrade flash. Use JTAG.\n");
+               fpga_upgrade = firmware_upgrade = 0;
+               db_fpga_upgrade = db_firmware_upgrade = 0;
+       }
+
        if (card->fpga_version >= DMA_SUPPORTED){
                card->using_dma = 1;
        } else {
index af0600143d1c506efb32d3d7f5038cf1af02aa7e..82bbb5967aa99ab94e8c0a64b97ae8a7cf4cd9b9 100644 (file)
 static struct vfsmount *dev_mnt;
 
 #if defined CONFIG_DEVTMPFS_MOUNT
-static int dev_mount = 1;
+static int mount_dev = 1;
 #else
-static int dev_mount;
+static int mount_dev;
 #endif
 
 static DEFINE_MUTEX(dirlock);
 
 static int __init mount_param(char *str)
 {
-       dev_mount = simple_strtoul(str, NULL, 0);
+       mount_dev = simple_strtoul(str, NULL, 0);
        return 1;
 }
 __setup("devtmpfs.mount=", mount_param);
 
-static int dev_get_sb(struct file_system_type *fs_type, int flags,
-                     const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *dev_mount(struct file_system_type *fs_type, int flags,
+                     const char *dev_name, void *data)
 {
 #ifdef CONFIG_TMPFS
-       return get_sb_single(fs_type, flags, data, shmem_fill_super, mnt);
+       return mount_single(fs_type, flags, data, shmem_fill_super);
 #else
-       return get_sb_single(fs_type, flags, data, ramfs_fill_super, mnt);
+       return mount_single(fs_type, flags, data, ramfs_fill_super);
 #endif
 }
 
 static struct file_system_type dev_fs_type = {
        .name = "devtmpfs",
-       .get_sb = dev_get_sb,
+       .mount = dev_mount,
        .kill_sb = kill_litter_super,
 };
 
@@ -351,7 +351,7 @@ int devtmpfs_mount(const char *mntdir)
 {
        int err;
 
-       if (!dev_mount)
+       if (!mount_dev)
                return 0;
 
        if (!dev_mnt)
index 126ca492dd08fe3694f0e78d823bbb8ec6a692b1..02c652be83e72ce09f5c1316cc3c8415a5894556 100644 (file)
@@ -143,7 +143,7 @@ static int rpm_check_suspend_allowed(struct device *dev)
 
        /* Pending resume requests take precedence over suspends. */
        else if ((dev->power.deferred_resume
-                       && dev->power.status == RPM_SUSPENDING)
+                       && dev->power.runtime_status == RPM_SUSPENDING)
            || (dev->power.request_pending
                        && dev->power.request == RPM_REQ_RESUME))
                retval = -EAGAIN;
index 541e18879965d01e74081701b50f3e70c78fb1b5..528f6318ded155f03d464f611f20240dd1a90c95 100644 (file)
@@ -180,9 +180,6 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio)
                BUG();
                bio_endio(bio, -ENXIO);
                return 0;
-       } else if (bio->bi_rw & REQ_HARDBARRIER) {
-               bio_endio(bio, -EOPNOTSUPP);
-               return 0;
        } else if (bio->bi_io_vec == NULL) {
                printk(KERN_ERR "aoe: bi_io_vec is NULL\n");
                BUG();
index 2cc4dda462794a3b2f304b0590880237511505b6..a67d0a611a8ac1d53ee16a00963ef19ade3487c8 100644 (file)
@@ -113,6 +113,8 @@ static struct board_type products[] = {
        {0x409D0E11, "Smart Array 6400 EM", &SA5_access},
        {0x40910E11, "Smart Array 6i", &SA5_access},
        {0x3225103C, "Smart Array P600", &SA5_access},
+       {0x3223103C, "Smart Array P800", &SA5_access},
+       {0x3234103C, "Smart Array P400", &SA5_access},
        {0x3235103C, "Smart Array P400i", &SA5_access},
        {0x3211103C, "Smart Array E200i", &SA5_access},
        {0x3212103C, "Smart Array E200", &SA5_access},
@@ -3753,7 +3755,7 @@ static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h)
        for (i = 0; i < MAX_CONFIG_WAIT; i++) {
                if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
                        break;
-               msleep(10);
+               usleep_range(10000, 20000);
        }
 }
 
@@ -3937,10 +3939,9 @@ static int __devinit cciss_lookup_board_id(struct pci_dev *pdev, u32 *board_id)
        *board_id = ((subsystem_device_id << 16) & 0xffff0000) |
                        subsystem_vendor_id;
 
-       for (i = 0; i < ARRAY_SIZE(products); i++) {
+       for (i = 0; i < ARRAY_SIZE(products); i++)
                if (*board_id == products[i].board_id)
                        return i;
-       }
        dev_warn(&pdev->dev, "unrecognized board ID: 0x%08x, ignoring.\n",
                *board_id);
        return -ENODEV;
@@ -3971,18 +3972,31 @@ static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev,
        return -ENODEV;
 }
 
-static int __devinit cciss_wait_for_board_ready(ctlr_info_t *h)
+static int __devinit cciss_wait_for_board_state(struct pci_dev *pdev,
+       void __iomem *vaddr, int wait_for_ready)
+#define BOARD_READY 1
+#define BOARD_NOT_READY 0
 {
-       int i;
+       int i, iterations;
        u32 scratchpad;
 
-       for (i = 0; i < CCISS_BOARD_READY_ITERATIONS; i++) {
-               scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
-               if (scratchpad == CCISS_FIRMWARE_READY)
-                       return 0;
+       if (wait_for_ready)
+               iterations = CCISS_BOARD_READY_ITERATIONS;
+       else
+               iterations = CCISS_BOARD_NOT_READY_ITERATIONS;
+
+       for (i = 0; i < iterations; i++) {
+               scratchpad = readl(vaddr + SA5_SCRATCHPAD_OFFSET);
+               if (wait_for_ready) {
+                       if (scratchpad == CCISS_FIRMWARE_READY)
+                               return 0;
+               } else {
+                       if (scratchpad != CCISS_FIRMWARE_READY)
+                               return 0;
+               }
                msleep(CCISS_BOARD_READY_POLL_INTERVAL_MSECS);
        }
-       dev_warn(&h->pdev->dev, "board not ready, timed out.\n");
+       dev_warn(&pdev->dev, "board not ready, timed out.\n");
        return -ENODEV;
 }
 
@@ -4031,6 +4045,11 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h)
 static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h)
 {
        h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+
+       /* Limit commands in memory limited kdump scenario. */
+       if (reset_devices && h->max_commands > 32)
+               h->max_commands = 32;
+
        if (h->max_commands < 16) {
                dev_warn(&h->pdev->dev, "Controller reports "
                        "max supported commands of %d, an obvious lie. "
@@ -4148,7 +4167,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *h)
                err = -ENOMEM;
                goto err_out_free_res;
        }
-       err = cciss_wait_for_board_ready(h);
+       err = cciss_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY);
        if (err)
                goto err_out_free_res;
        err = cciss_find_cfgtables(h);
@@ -4313,36 +4332,6 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u
 #define cciss_soft_reset_controller(p) cciss_message(p, 1, 0)
 #define cciss_noop(p) cciss_message(p, 3, 0)
 
-static __devinit int cciss_reset_msi(struct pci_dev *pdev)
-{
-/* the #defines are stolen from drivers/pci/msi.h. */
-#define msi_control_reg(base)          (base + PCI_MSI_FLAGS)
-#define PCI_MSIX_FLAGS_ENABLE          (1 << 15)
-
-       int pos;
-       u16 control = 0;
-
-       pos = pci_find_capability(pdev, PCI_CAP_ID_MSI);
-       if (pos) {
-               pci_read_config_word(pdev, msi_control_reg(pos), &control);
-               if (control & PCI_MSI_FLAGS_ENABLE) {
-                       dev_info(&pdev->dev, "resetting MSI\n");
-                       pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE);
-               }
-       }
-
-       pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
-       if (pos) {
-               pci_read_config_word(pdev, msi_control_reg(pos), &control);
-               if (control & PCI_MSIX_FLAGS_ENABLE) {
-                       dev_info(&pdev->dev, "resetting MSI-X\n");
-                       pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE);
-               }
-       }
-
-       return 0;
-}
-
 static int cciss_controller_hard_reset(struct pci_dev *pdev,
        void * __iomem vaddr, bool use_doorbell)
 {
@@ -4397,17 +4386,17 @@ static int cciss_controller_hard_reset(struct pci_dev *pdev,
  * states or using the doorbell register. */
 static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
 {
-       u16 saved_config_space[32];
        u64 cfg_offset;
        u32 cfg_base_addr;
        u64 cfg_base_addr_index;
        void __iomem *vaddr;
        unsigned long paddr;
        u32 misc_fw_support, active_transport;
-       int rc, i;
+       int rc;
        CfgTable_struct __iomem *cfgtable;
        bool use_doorbell;
        u32 board_id;
+       u16 command_register;
 
        /* For controllers as old a the p600, this is very nearly
         * the same thing as
@@ -4417,14 +4406,6 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
         * pci_set_power_state(pci_dev, PCI_D0);
         * pci_restore_state(pci_dev);
         *
-        * but we can't use these nice canned kernel routines on
-        * kexec, because they also check the MSI/MSI-X state in PCI
-        * configuration space and do the wrong thing when it is
-        * set/cleared.  Also, the pci_save/restore_state functions
-        * violate the ordering requirements for restoring the
-        * configuration space from the CCISS document (see the
-        * comment below).  So we roll our own ....
-        *
         * For controllers newer than the P600, the pci power state
         * method of resetting doesn't work so we have another way
         * using the doorbell register.
@@ -4443,8 +4424,13 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
                return -ENODEV;
        }
 
-       for (i = 0; i < 32; i++)
-               pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
+       /* Save the PCI command register */
+       pci_read_config_word(pdev, 4, &command_register);
+       /* Turn the board off.  This is so that later pci_restore_state()
+        * won't turn the board on before the rest of config space is ready.
+        */
+       pci_disable_device(pdev);
+       pci_save_state(pdev);
 
        /* find the first memory BAR, so we can find the cfg table */
        rc = cciss_pci_find_memory_BAR(pdev, &paddr);
@@ -4479,26 +4465,32 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
        rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell);
        if (rc)
                goto unmap_cfgtable;
-
-       /* Restore the PCI configuration space.  The Open CISS
-        * Specification says, "Restore the PCI Configuration
-        * Registers, offsets 00h through 60h. It is important to
-        * restore the command register, 16-bits at offset 04h,
-        * last. Do not restore the configuration status register,
-        * 16-bits at offset 06h."  Note that the offset is 2*i.
-        */
-       for (i = 0; i < 32; i++) {
-               if (i == 2 || i == 3)
-                       continue;
-               pci_write_config_word(pdev, 2*i, saved_config_space[i]);
+       pci_restore_state(pdev);
+       rc = pci_enable_device(pdev);
+       if (rc) {
+               dev_warn(&pdev->dev, "failed to enable device.\n");
+               goto unmap_cfgtable;
        }
-       wmb();
-       pci_write_config_word(pdev, 4, saved_config_space[2]);
+       pci_write_config_word(pdev, 4, command_register);
 
        /* Some devices (notably the HP Smart Array 5i Controller)
           need a little pause here */
        msleep(CCISS_POST_RESET_PAUSE_MSECS);
 
+       /* Wait for board to become not ready, then ready. */
+       dev_info(&pdev->dev, "Waiting for board to become ready.\n");
+       rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY);
+       if (rc) /* Don't bail, might be E500, etc. which can't be reset */
+               dev_warn(&pdev->dev,
+                       "failed waiting for board to become not ready\n");
+       rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_READY);
+       if (rc) {
+               dev_warn(&pdev->dev,
+                       "failed waiting for board to become ready\n");
+               goto unmap_cfgtable;
+       }
+       dev_info(&pdev->dev, "board ready.\n");
+
        /* Controller should be in simple mode at this point.  If it's not,
         * It means we're on one of those controllers which doesn't support
         * the doorbell reset method and on which the PCI power management reset
@@ -4539,8 +4531,6 @@ static __devinit int cciss_init_reset_devices(struct pci_dev *pdev)
                return 0; /* just try to do the kdump anyhow. */
        if (rc)
                return -ENODEV;
-       if (cciss_reset_msi(pdev))
-               return -ENODEV;
 
        /* Now try to get the controller to respond to a no-op */
        for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) {
@@ -4936,7 +4926,8 @@ static void __exit cciss_cleanup(void)
                }
        }
        kthread_stop(cciss_scan_thread);
-       remove_proc_entry("driver/cciss", NULL);
+       if (proc_cciss)
+               remove_proc_entry("driver/cciss", NULL);
        bus_unregister(&cciss_bus_type);
 }
 
index ae340ffc8f815de7cf1fdae7518890556826852d..4b8933d778f154169e191938d83c3b4115d291cc 100644 (file)
@@ -200,10 +200,14 @@ struct ctlr_info
  * the above.
  */
 #define CCISS_BOARD_READY_WAIT_SECS (120)
+#define CCISS_BOARD_NOT_READY_WAIT_SECS (10)
 #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100)
 #define CCISS_BOARD_READY_ITERATIONS \
        ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \
                CCISS_BOARD_READY_POLL_INTERVAL_MSECS)
+#define CCISS_BOARD_NOT_READY_ITERATIONS \
+       ((CCISS_BOARD_NOT_READY_WAIT_SECS * 1000) / \
+               CCISS_BOARD_READY_POLL_INTERVAL_MSECS)
 #define CCISS_POST_RESET_PAUSE_MSECS (3000)
 #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000)
 #define CCISS_POST_RESET_NOOP_RETRIES (12)
index ac04ef97eac29a0203e38d08a942c1733e5d9285..ba95cba192be8d1d00f7b7e9b47f1cb05d460470 100644 (file)
@@ -78,11 +78,10 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
        init_completion(&md_io.event);
        md_io.error = 0;
 
-       if ((rw & WRITE) && !test_bit(MD_NO_BARRIER, &mdev->flags))
-               rw |= REQ_HARDBARRIER;
+       if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags))
+               rw |= REQ_FUA;
        rw |= REQ_UNPLUG | REQ_SYNC;
 
- retry:
        bio = bio_alloc(GFP_NOIO, 1);
        bio->bi_bdev = bdev->md_bdev;
        bio->bi_sector = sector;
@@ -100,17 +99,6 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
        wait_for_completion(&md_io.event);
        ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0;
 
-       /* check for unsupported barrier op.
-        * would rather check on EOPNOTSUPP, but that is not reliable.
-        * don't try again for ANY return value != 0 */
-       if (unlikely((bio->bi_rw & REQ_HARDBARRIER) && !ok)) {
-               /* Try again with no barrier */
-               dev_warn(DEV, "Barriers not supported on meta data device - disabling\n");
-               set_bit(MD_NO_BARRIER, &mdev->flags);
-               rw &= ~REQ_HARDBARRIER;
-               bio_put(bio);
-               goto retry;
-       }
  out:
        bio_put(bio);
        return ok;
@@ -284,18 +272,32 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused)
        u32 xor_sum = 0;
 
        if (!get_ldev(mdev)) {
-               dev_err(DEV, "get_ldev() failed in w_al_write_transaction\n");
+               dev_err(DEV,
+                       "disk is %s, cannot start al transaction (-%d +%d)\n",
+                       drbd_disk_str(mdev->state.disk), evicted, new_enr);
                complete(&((struct update_al_work *)w)->event);
                return 1;
        }
        /* do we have to do a bitmap write, first?
         * TODO reduce maximum latency:
         * submit both bios, then wait for both,
-        * instead of doing two synchronous sector writes. */
+        * instead of doing two synchronous sector writes.
+        * For now, we must not write the transaction,
+        * if we cannot write out the bitmap of the evicted extent. */
        if (mdev->state.conn < C_CONNECTED && evicted != LC_FREE)
                drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT);
 
-       mutex_lock(&mdev->md_io_mutex); /* protects md_io_page, al_tr_cycle, ... */
+       /* The bitmap write may have failed, causing a state change. */
+       if (mdev->state.disk < D_INCONSISTENT) {
+               dev_err(DEV,
+                       "disk is %s, cannot write al transaction (-%d +%d)\n",
+                       drbd_disk_str(mdev->state.disk), evicted, new_enr);
+               complete(&((struct update_al_work *)w)->event);
+               put_ldev(mdev);
+               return 1;
+       }
+
+       mutex_lock(&mdev->md_io_mutex); /* protects md_io_buffer, al_tr_cycle, ... */
        buffer = (struct al_transaction *)page_address(mdev->md_io_page);
 
        buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC);
@@ -739,7 +741,7 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev)
        unsigned int enr;
        unsigned long add = 0;
        char ppb[10];
-       int i;
+       int i, tmp;
 
        wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
 
@@ -747,7 +749,9 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev)
                enr = lc_element_by_index(mdev->act_log, i)->lc_number;
                if (enr == LC_FREE)
                        continue;
-               add += drbd_bm_ALe_set_all(mdev, enr);
+               tmp = drbd_bm_ALe_set_all(mdev, enr);
+               dynamic_dev_dbg(DEV, "AL: set %d bits in extent %u\n", tmp, enr);
+               add += tmp;
        }
 
        lc_unlock(mdev->act_log);
index 9bdcf4393c0aa9525c9c7918355cb9b985809a73..1ea1a34e78b281d8ff8658028b38e2f423716917 100644 (file)
@@ -114,11 +114,11 @@ struct drbd_conf;
 #define D_ASSERT(exp)  if (!(exp)) \
         dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__)
 
-#define ERR_IF(exp) if (({                             \
-       int _b = (exp) != 0;                            \
-       if (_b) dev_err(DEV, "%s: (%s) in %s:%d\n",     \
-               __func__, #exp, __FILE__, __LINE__);    \
-        _b;                                            \
+#define ERR_IF(exp) if (({                                             \
+       int _b = (exp) != 0;                                            \
+       if (_b) dev_err(DEV, "ASSERT FAILED: %s: (%s) in %s:%d\n",      \
+                       __func__, #exp, __FILE__, __LINE__);            \
+       _b;                                                             \
        }))
 
 /* Defines to control fault insertion */
@@ -749,17 +749,12 @@ struct drbd_epoch {
 
 /* drbd_epoch flag bits */
 enum {
-       DE_BARRIER_IN_NEXT_EPOCH_ISSUED,
-       DE_BARRIER_IN_NEXT_EPOCH_DONE,
-       DE_CONTAINS_A_BARRIER,
        DE_HAVE_BARRIER_NUMBER,
-       DE_IS_FINISHING,
 };
 
 enum epoch_event {
        EV_PUT,
        EV_GOT_BARRIER_NR,
-       EV_BARRIER_DONE,
        EV_BECAME_LAST,
        EV_CLEANUP = 32, /* used as flag */
 };
@@ -801,11 +796,6 @@ enum {
        __EE_CALL_AL_COMPLETE_IO,
        __EE_MAY_SET_IN_SYNC,
 
-       /* This epoch entry closes an epoch using a barrier.
-        * On sucessful completion, the epoch is released,
-        * and the P_BARRIER_ACK send. */
-       __EE_IS_BARRIER,
-
        /* In case a barrier failed,
         * we need to resubmit without the barrier flag. */
        __EE_RESUBMITTED,
@@ -820,7 +810,6 @@ enum {
 };
 #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO)
 #define EE_MAY_SET_IN_SYNC     (1<<__EE_MAY_SET_IN_SYNC)
-#define EE_IS_BARRIER          (1<<__EE_IS_BARRIER)
 #define        EE_RESUBMITTED         (1<<__EE_RESUBMITTED)
 #define EE_WAS_ERROR           (1<<__EE_WAS_ERROR)
 #define EE_HAS_DIGEST          (1<<__EE_HAS_DIGEST)
@@ -843,16 +832,15 @@ enum {
                                 * Gets cleared when the state.conn
                                 * goes into C_CONNECTED state. */
        WRITE_BM_AFTER_RESYNC,  /* A kmalloc() during resync failed */
-       NO_BARRIER_SUPP,        /* underlying block device doesn't implement barriers */
        CONSIDER_RESYNC,
 
-       MD_NO_BARRIER,          /* meta data device does not support barriers,
-                                  so don't even try */
+       MD_NO_FUA,              /* Users wants us to not use FUA/FLUSH on meta data dev */
        SUSPEND_IO,             /* suspend application io */
        BITMAP_IO,              /* suspend application io;
                                   once no more io in flight, start bitmap io */
        BITMAP_IO_QUEUED,       /* Started bitmap IO */
-       GO_DISKLESS,            /* Disk failed, local_cnt reached zero, we are going diskless */
+       GO_DISKLESS,            /* Disk is being detached, on io-error or admin request. */
+       WAS_IO_ERROR,           /* Local disk failed returned IO error */
        RESYNC_AFTER_NEG,       /* Resync after online grow after the attach&negotiate finished. */
        NET_CONGESTED,          /* The data socket is congested */
 
@@ -947,7 +935,6 @@ enum write_ordering_e {
        WO_none,
        WO_drain_io,
        WO_bdev_flush,
-       WO_bio_barrier
 };
 
 struct fifo_buffer {
@@ -1281,6 +1268,7 @@ extern int drbd_bmio_set_n_write(struct drbd_conf *mdev);
 extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev);
 extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why);
 extern void drbd_go_diskless(struct drbd_conf *mdev);
+extern void drbd_ldev_destroy(struct drbd_conf *mdev);
 
 
 /* Meta data layout
@@ -1798,17 +1786,17 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach,
        case EP_PASS_ON:
                if (!forcedetach) {
                        if (__ratelimit(&drbd_ratelimit_state))
-                               dev_err(DEV, "Local IO failed in %s."
-                                            "Passing error on...\n", where);
+                               dev_err(DEV, "Local IO failed in %s.\n", where);
                        break;
                }
                /* NOTE fall through to detach case if forcedetach set */
        case EP_DETACH:
        case EP_CALL_HELPER:
+               set_bit(WAS_IO_ERROR, &mdev->flags);
                if (mdev->state.disk > D_FAILED) {
                        _drbd_set_state(_NS(mdev, disk, D_FAILED), CS_HARD, NULL);
-                       dev_err(DEV, "Local IO failed in %s."
-                                    "Detaching...\n", where);
+                       dev_err(DEV,
+                               "Local IO failed in %s. Detaching...\n", where);
                }
                break;
        }
@@ -1874,7 +1862,7 @@ static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev)
 static inline sector_t drbd_get_capacity(struct block_device *bdev)
 {
        /* return bdev ? get_capacity(bdev->bd_disk) : 0; */
-       return bdev ? bdev->bd_inode->i_size >> 9 : 0;
+       return bdev ? i_size_read(bdev->bd_inode) >> 9 : 0;
 }
 
 /**
@@ -2127,7 +2115,11 @@ static inline void put_ldev(struct drbd_conf *mdev)
        __release(local);
        D_ASSERT(i >= 0);
        if (i == 0) {
+               if (mdev->state.disk == D_DISKLESS)
+                       /* even internal references gone, safe to destroy */
+                       drbd_ldev_destroy(mdev);
                if (mdev->state.disk == D_FAILED)
+                       /* all application IO references gone. */
                        drbd_go_diskless(mdev);
                wake_up(&mdev->misc_wait);
        }
@@ -2138,6 +2130,10 @@ static inline int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_stat
 {
        int io_allowed;
 
+       /* never get a reference while D_DISKLESS */
+       if (mdev->state.disk == D_DISKLESS)
+               return 0;
+
        atomic_inc(&mdev->local_cnt);
        io_allowed = (mdev->state.disk >= mins);
        if (!io_allowed)
@@ -2406,12 +2402,12 @@ static inline void drbd_md_flush(struct drbd_conf *mdev)
 {
        int r;
 
-       if (test_bit(MD_NO_BARRIER, &mdev->flags))
+       if (test_bit(MD_NO_FUA, &mdev->flags))
                return;
 
        r = blkdev_issue_flush(mdev->ldev->md_bdev, GFP_KERNEL, NULL);
        if (r) {
-               set_bit(MD_NO_BARRIER, &mdev->flags);
+               set_bit(MD_NO_FUA, &mdev->flags);
                dev_err(DEV, "meta data flush failed with status %d, disabling md-flushes\n", r);
        }
 }
index 25c7a73c50621734cf22fda0654e93825e08e0ca..6be5401d0e88fd193b1af75c303c8140d4f6ccd3 100644 (file)
@@ -835,6 +835,15 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
            ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN)
                ns.conn = os.conn;
 
+       /* we cannot fail (again) if we already detached */
+       if (ns.disk == D_FAILED && os.disk == D_DISKLESS)
+               ns.disk = D_DISKLESS;
+
+       /* if we are only D_ATTACHING yet,
+        * we can (and should) go directly to D_DISKLESS. */
+       if (ns.disk == D_FAILED && os.disk == D_ATTACHING)
+               ns.disk = D_DISKLESS;
+
        /* After C_DISCONNECTING only C_STANDALONE may follow */
        if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE)
                ns.conn = os.conn;
@@ -1056,7 +1065,15 @@ int __drbd_set_state(struct drbd_conf *mdev,
            !test_and_set_bit(CONFIG_PENDING, &mdev->flags))
                set_bit(DEVICE_DYING, &mdev->flags);
 
-       mdev->state.i = ns.i;
+       /* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference
+        * on the ldev here, to be sure the transition -> D_DISKLESS resp.
+        * drbd_ldev_destroy() won't happen before our corresponding
+        * after_state_ch works run, where we put_ldev again. */
+       if ((os.disk != D_FAILED && ns.disk == D_FAILED) ||
+           (os.disk != D_DISKLESS && ns.disk == D_DISKLESS))
+               atomic_inc(&mdev->local_cnt);
+
+       mdev->state = ns;
        wake_up(&mdev->misc_wait);
        wake_up(&mdev->state_wait);
 
@@ -1268,7 +1285,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
                        if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
                                drbd_uuid_new_current(mdev);
                                clear_bit(NEW_CUR_UUID, &mdev->flags);
-                               drbd_md_sync(mdev);
                        }
                        spin_lock_irq(&mdev->req_lock);
                        _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL);
@@ -1365,63 +1381,64 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
            os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT)
                drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate");
 
-       /* first half of local IO error */
-       if (os.disk > D_FAILED && ns.disk == D_FAILED) {
-               enum drbd_io_error_p eh = EP_PASS_ON;
+       /* first half of local IO error, failure to attach,
+        * or administrative detach */
+       if (os.disk != D_FAILED && ns.disk == D_FAILED) {
+               enum drbd_io_error_p eh;
+               int was_io_error;
+               /* corresponding get_ldev was in __drbd_set_state, to serialize
+                * our cleanup here with the transition to D_DISKLESS,
+                * so it is safe to dreference ldev here. */
+               eh = mdev->ldev->dc.on_io_error;
+               was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags);
+
+               /* current state still has to be D_FAILED,
+                * there is only one way out: to D_DISKLESS,
+                * and that may only happen after our put_ldev below. */
+               if (mdev->state.disk != D_FAILED)
+                       dev_err(DEV,
+                               "ASSERT FAILED: disk is %s during detach\n",
+                               drbd_disk_str(mdev->state.disk));
 
                if (drbd_send_state(mdev))
-                       dev_warn(DEV, "Notified peer that my disk is broken.\n");
+                       dev_warn(DEV, "Notified peer that I am detaching my disk\n");
                else
-                       dev_err(DEV, "Sending state for drbd_io_error() failed\n");
+                       dev_err(DEV, "Sending state for detaching disk failed\n");
 
                drbd_rs_cancel_all(mdev);
 
-               if (get_ldev_if_state(mdev, D_FAILED)) {
-                       eh = mdev->ldev->dc.on_io_error;
-                       put_ldev(mdev);
-               }
-               if (eh == EP_CALL_HELPER)
+               /* In case we want to get something to stable storage still,
+                * this may be the last chance.
+                * Following put_ldev may transition to D_DISKLESS. */
+               drbd_md_sync(mdev);
+               put_ldev(mdev);
+
+               if (was_io_error && eh == EP_CALL_HELPER)
                        drbd_khelper(mdev, "local-io-error");
        }
 
+        /* second half of local IO error, failure to attach,
+         * or administrative detach,
+         * after local_cnt references have reached zero again */
+        if (os.disk != D_DISKLESS && ns.disk == D_DISKLESS) {
+                /* We must still be diskless,
+                 * re-attach has to be serialized with this! */
+                if (mdev->state.disk != D_DISKLESS)
+                        dev_err(DEV,
+                                "ASSERT FAILED: disk is %s while going diskless\n",
+                                drbd_disk_str(mdev->state.disk));
 
-       /* second half of local IO error handling,
-        * after local_cnt references have reached zero: */
-       if (os.disk == D_FAILED && ns.disk == D_DISKLESS) {
-               mdev->rs_total = 0;
-               mdev->rs_failed = 0;
-               atomic_set(&mdev->rs_pending_cnt, 0);
-       }
-
-       if (os.disk > D_DISKLESS && ns.disk == D_DISKLESS) {
-               /* We must still be diskless,
-                * re-attach has to be serialized with this! */
-               if (mdev->state.disk != D_DISKLESS)
-                       dev_err(DEV,
-                               "ASSERT FAILED: disk is %s while going diskless\n",
-                               drbd_disk_str(mdev->state.disk));
+                mdev->rs_total = 0;
+                mdev->rs_failed = 0;
+                atomic_set(&mdev->rs_pending_cnt, 0);
 
-               /* we cannot assert local_cnt == 0 here, as get_ldev_if_state
-                * will inc/dec it frequently. Since we became D_DISKLESS, no
-                * one has touched the protected members anymore, though, so we
-                * are safe to free them here. */
                if (drbd_send_state(mdev))
-                       dev_warn(DEV, "Notified peer that I detached my disk.\n");
+                       dev_warn(DEV, "Notified peer that I'm now diskless.\n");
                else
-                       dev_err(DEV, "Sending state for detach failed\n");
-
-               lc_destroy(mdev->resync);
-               mdev->resync = NULL;
-               lc_destroy(mdev->act_log);
-               mdev->act_log = NULL;
-               __no_warn(local,
-                       drbd_free_bc(mdev->ldev);
-                       mdev->ldev = NULL;);
-
-               if (mdev->md_io_tmpp) {
-                       __free_page(mdev->md_io_tmpp);
-                       mdev->md_io_tmpp = NULL;
-               }
+                       dev_err(DEV, "Sending state for being diskless failed\n");
+               /* corresponding get_ldev in __drbd_set_state
+                * this may finaly trigger drbd_ldev_destroy. */
+               put_ldev(mdev);
        }
 
        /* Disks got bigger while they were detached */
@@ -2772,11 +2789,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
 
        drbd_set_defaults(mdev);
 
-       /* for now, we do NOT yet support it,
-        * even though we start some framework
-        * to eventually support barriers */
-       set_bit(NO_BARRIER_SUPP, &mdev->flags);
-
        atomic_set(&mdev->ap_bio_cnt, 0);
        atomic_set(&mdev->ap_pending_cnt, 0);
        atomic_set(&mdev->rs_pending_cnt, 0);
@@ -2842,7 +2854,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
        drbd_thread_init(mdev, &mdev->asender, drbd_asender);
 
        mdev->agreed_pro_version = PRO_VERSION_MAX;
-       mdev->write_ordering = WO_bio_barrier;
+       mdev->write_ordering = WO_bdev_flush;
        mdev->resync_wenr = LC_FREE;
 }
 
@@ -2899,7 +2911,6 @@ void drbd_mdev_cleanup(struct drbd_conf *mdev)
        D_ASSERT(list_empty(&mdev->resync_work.list));
        D_ASSERT(list_empty(&mdev->unplug_work.list));
        D_ASSERT(list_empty(&mdev->go_diskless.list));
-
 }
 
 
@@ -3660,6 +3671,8 @@ void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local)
 
        get_random_bytes(&val, sizeof(u64));
        _drbd_uuid_set(mdev, UI_CURRENT, val);
+       /* get it to stable storage _now_ */
+       drbd_md_sync(mdev);
 }
 
 void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local)
@@ -3756,19 +3769,31 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused)
        return 1;
 }
 
+void drbd_ldev_destroy(struct drbd_conf *mdev)
+{
+       lc_destroy(mdev->resync);
+       mdev->resync = NULL;
+       lc_destroy(mdev->act_log);
+       mdev->act_log = NULL;
+       __no_warn(local,
+               drbd_free_bc(mdev->ldev);
+               mdev->ldev = NULL;);
+
+       if (mdev->md_io_tmpp) {
+               __free_page(mdev->md_io_tmpp);
+               mdev->md_io_tmpp = NULL;
+       }
+       clear_bit(GO_DISKLESS, &mdev->flags);
+}
+
 static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused)
 {
        D_ASSERT(mdev->state.disk == D_FAILED);
        /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will
         * inc/dec it frequently. Once we are D_DISKLESS, no one will touch
-        * the protected members anymore, though, so in the after_state_ch work
-        * it will be safe to free them. */
+        * the protected members anymore, though, so once put_ldev reaches zero
+        * again, it will be safe to free them. */
        drbd_force_state(mdev, NS(disk, D_DISKLESS));
-       /* We need to wait for return of references checked out while we still
-        * have been D_FAILED, though (drbd_md_sync, bitmap io). */
-       wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
-
-       clear_bit(GO_DISKLESS, &mdev->flags);
        return 1;
 }
 
@@ -3777,9 +3802,6 @@ void drbd_go_diskless(struct drbd_conf *mdev)
        D_ASSERT(mdev->state.disk == D_FAILED);
        if (!test_and_set_bit(GO_DISKLESS, &mdev->flags))
                drbd_queue_work(&mdev->data.work, &mdev->go_diskless);
-               /* don't drbd_queue_work_front,
-                * we need to serialize with the after_state_ch work
-                * of the -> D_FAILED transition. */
 }
 
 /**
index 87925e97e613ac34de1bc6edad9d54b8de5c47bf..29e5c70e4e26c7f6e35b8bb1bec0b7f65442f3a0 100644 (file)
@@ -870,6 +870,11 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
                retcode = ERR_DISK_CONFIGURED;
                goto fail;
        }
+       /* It may just now have detached because of IO error.  Make sure
+        * drbd_ldev_destroy is done already, we may end up here very fast,
+        * e.g. if someone calls attach from the on-io-error handler,
+        * to realize a "hot spare" feature (not that I'd recommend that) */
+       wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
 
        /* allocation not in the IO path, cqueue thread context */
        nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL);
@@ -1098,9 +1103,9 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
        /* Reset the "barriers don't work" bits here, then force meta data to
         * be written, to ensure we determine if barriers are supported. */
        if (nbc->dc.no_md_flush)
-               set_bit(MD_NO_BARRIER, &mdev->flags);
+               set_bit(MD_NO_FUA, &mdev->flags);
        else
-               clear_bit(MD_NO_BARRIER, &mdev->flags);
+               clear_bit(MD_NO_FUA, &mdev->flags);
 
        /* Point of no return reached.
         * Devices and memory are no longer released by error cleanup below.
@@ -1112,8 +1117,8 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
        nbc = NULL;
        resync_lru = NULL;
 
-       mdev->write_ordering = WO_bio_barrier;
-       drbd_bump_write_ordering(mdev, WO_bio_barrier);
+       mdev->write_ordering = WO_bdev_flush;
+       drbd_bump_write_ordering(mdev, WO_bdev_flush);
 
        if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY))
                set_bit(CRASHED_PRIMARY, &mdev->flags);
@@ -1262,7 +1267,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
  force_diskless_dec:
        put_ldev(mdev);
  force_diskless:
-       drbd_force_state(mdev, NS(disk, D_DISKLESS));
+       drbd_force_state(mdev, NS(disk, D_FAILED));
        drbd_md_sync(mdev);
  release_bdev2_fail:
        if (nbc)
@@ -1285,10 +1290,19 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
        return 0;
 }
 
+/* Detaching the disk is a process in multiple stages.  First we need to lock
+ * out application IO, in-flight IO, IO stuck in drbd_al_begin_io.
+ * Then we transition to D_DISKLESS, and wait for put_ldev() to return all
+ * internal references as well.
+ * Only then we have finally detached. */
 static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
                          struct drbd_nl_cfg_reply *reply)
 {
+       drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */
        reply->ret_code = drbd_request_state(mdev, NS(disk, D_DISKLESS));
+       if (mdev->state.disk == D_DISKLESS)
+               wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
+       drbd_resume_io(mdev);
        return 0;
 }
 
@@ -1953,7 +1967,6 @@ static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
        if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
                drbd_uuid_new_current(mdev);
                clear_bit(NEW_CUR_UUID, &mdev->flags);
-               drbd_md_sync(mdev);
        }
        drbd_suspend_io(mdev);
        reply->ret_code = drbd_request_state(mdev, NS3(susp, 0, susp_nod, 0, susp_fen, 0));
index ad325c5d0ce19c48612b68cc22f096bf602319c0..7e6ac307e2dec3ba1c9de2f825d0b1c9cbbbf9af 100644 (file)
@@ -158,7 +158,6 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
                [WO_none] = 'n',
                [WO_drain_io] = 'd',
                [WO_bdev_flush] = 'f',
-               [WO_bio_barrier] = 'b',
        };
 
        seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
index efd6169acf2f04bf758c68ceee419549351c7e64..d299fe9e78c8acc80b3a3f2fb370675bf7b299be 100644 (file)
 
 #include "drbd_vli.h"
 
-struct flush_work {
-       struct drbd_work w;
-       struct drbd_epoch *epoch;
-};
-
 enum finish_epoch {
        FE_STILL_LIVE,
        FE_DESTROYED,
@@ -66,16 +61,6 @@ static int drbd_do_auth(struct drbd_conf *mdev);
 static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event);
 static int e_end_block(struct drbd_conf *, struct drbd_work *, int);
 
-static struct drbd_epoch *previous_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch)
-{
-       struct drbd_epoch *prev;
-       spin_lock(&mdev->epoch_lock);
-       prev = list_entry(epoch->list.prev, struct drbd_epoch, list);
-       if (prev == epoch || prev == mdev->current_epoch)
-               prev = NULL;
-       spin_unlock(&mdev->epoch_lock);
-       return prev;
-}
 
 #define GFP_TRY        (__GFP_HIGHMEM | __GFP_NOWARN)
 
@@ -981,7 +966,7 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi
        return TRUE;
 }
 
-static enum finish_epoch drbd_flush_after_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch)
+static void drbd_flush(struct drbd_conf *mdev)
 {
        int rv;
 
@@ -997,24 +982,6 @@ static enum finish_epoch drbd_flush_after_epoch(struct drbd_conf *mdev, struct d
                }
                put_ldev(mdev);
        }
-
-       return drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE);
-}
-
-static int w_flush(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
-{
-       struct flush_work *fw = (struct flush_work *)w;
-       struct drbd_epoch *epoch = fw->epoch;
-
-       kfree(w);
-
-       if (!test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags))
-               drbd_flush_after_epoch(mdev, epoch);
-
-       drbd_may_finish_epoch(mdev, epoch, EV_PUT |
-                             (mdev->state.conn < C_CONNECTED ? EV_CLEANUP : 0));
-
-       return 1;
 }
 
 /**
@@ -1027,15 +994,13 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
                                               struct drbd_epoch *epoch,
                                               enum epoch_event ev)
 {
-       int finish, epoch_size;
+       int epoch_size;
        struct drbd_epoch *next_epoch;
-       int schedule_flush = 0;
        enum finish_epoch rv = FE_STILL_LIVE;
 
        spin_lock(&mdev->epoch_lock);
        do {
                next_epoch = NULL;
-               finish = 0;
 
                epoch_size = atomic_read(&epoch->epoch_size);
 
@@ -1045,16 +1010,6 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
                        break;
                case EV_GOT_BARRIER_NR:
                        set_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags);
-
-                       /* Special case: If we just switched from WO_bio_barrier to
-                          WO_bdev_flush we should not finish the current epoch */
-                       if (test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags) && epoch_size == 1 &&
-                           mdev->write_ordering != WO_bio_barrier &&
-                           epoch == mdev->current_epoch)
-                               clear_bit(DE_CONTAINS_A_BARRIER, &epoch->flags);
-                       break;
-               case EV_BARRIER_DONE:
-                       set_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags);
                        break;
                case EV_BECAME_LAST:
                        /* nothing to do*/
@@ -1063,23 +1018,7 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
 
                if (epoch_size != 0 &&
                    atomic_read(&epoch->active) == 0 &&
-                   test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) &&
-                   epoch->list.prev == &mdev->current_epoch->list &&
-                   !test_bit(DE_IS_FINISHING, &epoch->flags)) {
-                       /* Nearly all conditions are met to finish that epoch... */
-                       if (test_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags) ||
-                           mdev->write_ordering == WO_none ||
-                           (epoch_size == 1 && test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) ||
-                           ev & EV_CLEANUP) {
-                               finish = 1;
-                               set_bit(DE_IS_FINISHING, &epoch->flags);
-                       } else if (!test_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags) &&
-                                mdev->write_ordering == WO_bio_barrier) {
-                               atomic_inc(&epoch->active);
-                               schedule_flush = 1;
-                       }
-               }
-               if (finish) {
+                   test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags)) {
                        if (!(ev & EV_CLEANUP)) {
                                spin_unlock(&mdev->epoch_lock);
                                drbd_send_b_ack(mdev, epoch->barrier_nr, epoch_size);
@@ -1102,6 +1041,7 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
                                /* atomic_set(&epoch->active, 0); is already zero */
                                if (rv == FE_STILL_LIVE)
                                        rv = FE_RECYCLED;
+                               wake_up(&mdev->ee_wait);
                        }
                }
 
@@ -1113,22 +1053,6 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
 
        spin_unlock(&mdev->epoch_lock);
 
-       if (schedule_flush) {
-               struct flush_work *fw;
-               fw = kmalloc(sizeof(*fw), GFP_ATOMIC);
-               if (fw) {
-                       fw->w.cb = w_flush;
-                       fw->epoch = epoch;
-                       drbd_queue_work(&mdev->data.work, &fw->w);
-               } else {
-                       dev_warn(DEV, "Could not kmalloc a flush_work obj\n");
-                       set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags);
-                       /* That is not a recursion, only one level */
-                       drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE);
-                       drbd_may_finish_epoch(mdev, epoch, EV_PUT);
-               }
-       }
-
        return rv;
 }
 
@@ -1144,19 +1068,16 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo)
                [WO_none] = "none",
                [WO_drain_io] = "drain",
                [WO_bdev_flush] = "flush",
-               [WO_bio_barrier] = "barrier",
        };
 
        pwo = mdev->write_ordering;
        wo = min(pwo, wo);
-       if (wo == WO_bio_barrier && mdev->ldev->dc.no_disk_barrier)
-               wo = WO_bdev_flush;
        if (wo == WO_bdev_flush && mdev->ldev->dc.no_disk_flush)
                wo = WO_drain_io;
        if (wo == WO_drain_io && mdev->ldev->dc.no_disk_drain)
                wo = WO_none;
        mdev->write_ordering = wo;
-       if (pwo != mdev->write_ordering || wo == WO_bio_barrier)
+       if (pwo != mdev->write_ordering || wo == WO_bdev_flush)
                dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]);
 }
 
@@ -1192,7 +1113,7 @@ next_bio:
        bio->bi_sector = sector;
        bio->bi_bdev = mdev->ldev->backing_bdev;
        /* we special case some flags in the multi-bio case, see below
-        * (REQ_UNPLUG, REQ_HARDBARRIER) */
+        * (REQ_UNPLUG) */
        bio->bi_rw = rw;
        bio->bi_private = e;
        bio->bi_end_io = drbd_endio_sec;
@@ -1226,11 +1147,6 @@ next_bio:
                        bio->bi_rw &= ~REQ_UNPLUG;
 
                drbd_generic_make_request(mdev, fault_type, bio);
-
-               /* strip off REQ_HARDBARRIER,
-                * unless it is the first or last bio */
-               if (bios && bios->bi_next)
-                       bios->bi_rw &= ~REQ_HARDBARRIER;
        } while (bios);
        maybe_kick_lo(mdev);
        return 0;
@@ -1244,45 +1160,9 @@ fail:
        return -ENOMEM;
 }
 
-/**
- * w_e_reissue() - Worker callback; Resubmit a bio, without REQ_HARDBARRIER set
- * @mdev:      DRBD device.
- * @w:         work object.
- * @cancel:    The connection will be closed anyways (unused in this callback)
- */
-int w_e_reissue(struct drbd_conf *mdev, struct drbd_work *w, int cancel) __releases(local)
-{
-       struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
-       /* We leave DE_CONTAINS_A_BARRIER and EE_IS_BARRIER in place,
-          (and DE_BARRIER_IN_NEXT_EPOCH_ISSUED in the previous Epoch)
-          so that we can finish that epoch in drbd_may_finish_epoch().
-          That is necessary if we already have a long chain of Epochs, before
-          we realize that REQ_HARDBARRIER is actually not supported */
-
-       /* As long as the -ENOTSUPP on the barrier is reported immediately
-          that will never trigger. If it is reported late, we will just
-          print that warning and continue correctly for all future requests
-          with WO_bdev_flush */
-       if (previous_epoch(mdev, e->epoch))
-               dev_warn(DEV, "Write ordering was not enforced (one time event)\n");
-
-       /* we still have a local reference,
-        * get_ldev was done in receive_Data. */
-
-       e->w.cb = e_end_block;
-       if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_DT_WR) != 0) {
-               /* drbd_submit_ee fails for one reason only:
-                * if was not able to allocate sufficient bios.
-                * requeue, try again later. */
-               e->w.cb = w_e_reissue;
-               drbd_queue_work(&mdev->data.work, &e->w);
-       }
-       return 1;
-}
-
 static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size)
 {
-       int rv, issue_flush;
+       int rv;
        struct p_barrier *p = &mdev->data.rbuf.barrier;
        struct drbd_epoch *epoch;
 
@@ -1300,44 +1180,40 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsign
         * Therefore we must send the barrier_ack after the barrier request was
         * completed. */
        switch (mdev->write_ordering) {
-       case WO_bio_barrier:
        case WO_none:
                if (rv == FE_RECYCLED)
                        return TRUE;
-               break;
+
+               /* receiver context, in the writeout path of the other node.
+                * avoid potential distributed deadlock */
+               epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
+               if (epoch)
+                       break;
+               else
+                       dev_warn(DEV, "Allocation of an epoch failed, slowing down\n");
+                       /* Fall through */
 
        case WO_bdev_flush:
        case WO_drain_io:
-               if (rv == FE_STILL_LIVE) {
-                       set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags);
-                       drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
-                       rv = drbd_flush_after_epoch(mdev, mdev->current_epoch);
-               }
-               if (rv == FE_RECYCLED)
-                       return TRUE;
-
-               /* The asender will send all the ACKs and barrier ACKs out, since
-                  all EEs moved from the active_ee to the done_ee. We need to
-                  provide a new epoch object for the EEs that come in soon */
-               break;
-       }
-
-       /* receiver context, in the writeout path of the other node.
-        * avoid potential distributed deadlock */
-       epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
-       if (!epoch) {
-               dev_warn(DEV, "Allocation of an epoch failed, slowing down\n");
-               issue_flush = !test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags);
                drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
-               if (issue_flush) {
-                       rv = drbd_flush_after_epoch(mdev, mdev->current_epoch);
-                       if (rv == FE_RECYCLED)
-                               return TRUE;
+               drbd_flush(mdev);
+
+               if (atomic_read(&mdev->current_epoch->epoch_size)) {
+                       epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
+                       if (epoch)
+                               break;
                }
 
-               drbd_wait_ee_list_empty(mdev, &mdev->done_ee);
+               epoch = mdev->current_epoch;
+               wait_event(mdev->ee_wait, atomic_read(&epoch->epoch_size) == 0);
+
+               D_ASSERT(atomic_read(&epoch->active) == 0);
+               D_ASSERT(epoch->flags == 0);
 
                return TRUE;
+       default:
+               dev_err(DEV, "Strangeness in mdev->write_ordering %d\n", mdev->write_ordering);
+               return FALSE;
        }
 
        epoch->flags = 0;
@@ -1652,15 +1528,8 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
        struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w;
        sector_t sector = e->sector;
-       struct drbd_epoch *epoch;
        int ok = 1, pcmd;
 
-       if (e->flags & EE_IS_BARRIER) {
-               epoch = previous_epoch(mdev, e->epoch);
-               if (epoch)
-                       drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE + (cancel ? EV_CLEANUP : 0));
-       }
-
        if (mdev->net_conf->wire_protocol == DRBD_PROT_C) {
                if (likely((e->flags & EE_WAS_ERROR) == 0)) {
                        pcmd = (mdev->state.conn >= C_SYNC_SOURCE &&
@@ -1817,27 +1686,6 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
        e->epoch = mdev->current_epoch;
        atomic_inc(&e->epoch->epoch_size);
        atomic_inc(&e->epoch->active);
-
-       if (mdev->write_ordering == WO_bio_barrier && atomic_read(&e->epoch->epoch_size) == 1) {
-               struct drbd_epoch *epoch;
-               /* Issue a barrier if we start a new epoch, and the previous epoch
-                  was not a epoch containing a single request which already was
-                  a Barrier. */
-               epoch = list_entry(e->epoch->list.prev, struct drbd_epoch, list);
-               if (epoch == e->epoch) {
-                       set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags);
-                       rw |= REQ_HARDBARRIER;
-                       e->flags |= EE_IS_BARRIER;
-               } else {
-                       if (atomic_read(&epoch->epoch_size) > 1 ||
-                           !test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) {
-                               set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags);
-                               set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags);
-                               rw |= REQ_HARDBARRIER;
-                               e->flags |= EE_IS_BARRIER;
-                       }
-               }
-       }
        spin_unlock(&mdev->epoch_lock);
 
        dp_flags = be32_to_cpu(p->dp_flags);
@@ -1995,10 +1843,11 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
                break;
        }
 
-       if (mdev->state.pdsk == D_DISKLESS) {
+       if (mdev->state.pdsk < D_INCONSISTENT) {
                /* In case we have the only disk of the cluster, */
                drbd_set_out_of_sync(mdev, e->sector, e->size);
                e->flags |= EE_CALL_AL_COMPLETE_IO;
+               e->flags &= ~EE_MAY_SET_IN_SYNC;
                drbd_al_begin_io(mdev, e->sector);
        }
 
@@ -3362,7 +3211,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
                if (ns.conn == C_MASK) {
                        ns.conn = C_CONNECTED;
                        if (mdev->state.disk == D_NEGOTIATING) {
-                               drbd_force_state(mdev, NS(disk, D_DISKLESS));
+                               drbd_force_state(mdev, NS(disk, D_FAILED));
                        } else if (peer_state.disk == D_NEGOTIATING) {
                                dev_err(DEV, "Disk attach process on the peer node was aborted.\n");
                                peer_state.disk = D_DISKLESS;
index 9e91a2545fc869273d39ca9737904e56d5f203b9..11a75d32a2e27f0d78c26b511921780f4d336264 100644 (file)
@@ -258,7 +258,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m)
                if (!hlist_unhashed(&req->colision))
                        hlist_del(&req->colision);
                else
-                       D_ASSERT((s & RQ_NET_MASK) == 0);
+                       D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
 
                /* for writes we need to do some extra housekeeping */
                if (rw == WRITE)
@@ -813,7 +813,8 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio)
                             mdev->state.conn >= C_CONNECTED));
 
        if (!(local || remote) && !is_susp(mdev->state)) {
-               dev_err(DEV, "IO ERROR: neither local nor remote disk\n");
+               if (__ratelimit(&drbd_ratelimit_state))
+                       dev_err(DEV, "IO ERROR: neither local nor remote disk\n");
                goto fail_free_complete;
        }
 
@@ -942,12 +943,21 @@ allocate_barrier:
        if (local) {
                req->private_bio->bi_bdev = mdev->ldev->backing_bdev;
 
-               if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR
-                                    : rw == READ  ? DRBD_FAULT_DT_RD
-                                    :               DRBD_FAULT_DT_RA))
+               /* State may have changed since we grabbed our reference on the
+                * mdev->ldev member. Double check, and short-circuit to endio.
+                * In case the last activity log transaction failed to get on
+                * stable storage, and this is a WRITE, we may not even submit
+                * this bio. */
+               if (get_ldev(mdev)) {
+                       if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR
+                                            : rw == READ  ? DRBD_FAULT_DT_RD
+                                            :               DRBD_FAULT_DT_RA))
+                               bio_endio(req->private_bio, -EIO);
+                       else
+                               generic_make_request(req->private_bio);
+                       put_ldev(mdev);
+               } else
                        bio_endio(req->private_bio, -EIO);
-               else
-                       generic_make_request(req->private_bio);
        }
 
        /* we need to plug ALWAYS since we possibly need to kick lo_dev.
@@ -1022,20 +1032,6 @@ int drbd_make_request_26(struct request_queue *q, struct bio *bio)
                return 0;
        }
 
-       /* Reject barrier requests if we know the underlying device does
-        * not support them.
-        * XXX: Need to get this info from peer as well some how so we
-        * XXX: reject if EITHER side/data/metadata area does not support them.
-        *
-        * because of those XXX, this is not yet enabled,
-        * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit.
-        */
-       if (unlikely(bio->bi_rw & REQ_HARDBARRIER) && test_bit(NO_BARRIER_SUPP, &mdev->flags)) {
-               /* dev_warn(DEV, "Rejecting barrier request as underlying device does not support\n"); */
-               bio_endio(bio, -EOPNOTSUPP);
-               return 0;
-       }
-
        /*
         * what we "blindly" assume:
         */
index 108d58015cd119a6e85873095acab12ab011a6cc..b0551ba7ad0c9355a36621d3a6405ba76a8ab9d0 100644 (file)
@@ -102,12 +102,6 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local)
        put_ldev(mdev);
 }
 
-static int is_failed_barrier(int ee_flags)
-{
-       return (ee_flags & (EE_IS_BARRIER|EE_WAS_ERROR|EE_RESUBMITTED))
-                       == (EE_IS_BARRIER|EE_WAS_ERROR);
-}
-
 /* writes on behalf of the partner, or resync writes,
  * "submitted" by the receiver, final stage.  */
 static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(local)
@@ -119,21 +113,6 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo
        int is_syncer_req;
        int do_al_complete_io;
 
-       /* if this is a failed barrier request, disable use of barriers,
-        * and schedule for resubmission */
-       if (is_failed_barrier(e->flags)) {
-               drbd_bump_write_ordering(mdev, WO_bdev_flush);
-               spin_lock_irqsave(&mdev->req_lock, flags);
-               list_del(&e->w.list);
-               e->flags = (e->flags & ~EE_WAS_ERROR) | EE_RESUBMITTED;
-               e->w.cb = w_e_reissue;
-               /* put_ldev actually happens below, once we come here again. */
-               __release(local);
-               spin_unlock_irqrestore(&mdev->req_lock, flags);
-               drbd_queue_work(&mdev->data.work, &e->w);
-               return;
-       }
-
        D_ASSERT(e->block_id != ID_VACANT);
 
        /* after we moved e to done_ee,
@@ -925,7 +904,7 @@ out:
        drbd_md_sync(mdev);
 
        if (test_and_clear_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags)) {
-               dev_warn(DEV, "Writing the whole bitmap, due to failed kmalloc\n");
+               dev_info(DEV, "Writing the whole bitmap\n");
                drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished");
        }
 
index 767107cce982bfdcb651797eb2fb634dde4f2356..3951020e494ac803001083b186a5b7614eb6d42f 100644 (file)
@@ -4363,9 +4363,9 @@ out_unreg_blkdev:
 out_put_disk:
        while (dr--) {
                del_timer(&motor_off_timer[dr]);
-               put_disk(disks[dr]);
                if (disks[dr]->queue)
                        blk_cleanup_queue(disks[dr]->queue);
+               put_disk(disks[dr]);
        }
        return err;
 }
@@ -4573,8 +4573,8 @@ static void __exit floppy_module_exit(void)
                        device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
                        platform_device_unregister(&floppy_device[drive]);
                }
-               put_disk(disks[drive]);
                blk_cleanup_queue(disks[drive]->queue);
+               put_disk(disks[drive]);
        }
 
        del_timer_sync(&fd_timeout);
index 1e5284ef65fa47313d4a6609526b6dfecf00615e..7ea0bea2f7e3f7a0ecc2a2d4b5df15a9b5a7cccc 100644 (file)
@@ -481,12 +481,6 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
        if (bio_rw(bio) == WRITE) {
                struct file *file = lo->lo_backing_file;
 
-               /* REQ_HARDBARRIER is deprecated */
-               if (bio->bi_rw & REQ_HARDBARRIER) {
-                       ret = -EOPNOTSUPP;
-                       goto out;
-               }
-
                if (bio->bi_rw & REQ_FLUSH) {
                        ret = vfs_fsync(file, 0);
                        if (unlikely(ret && ret != -EINVAL)) {
index 06e2812ba12405dc0a63eea531943b53c4aa067b..255035cfc88ab8ff3a279578487facd6d17a113f 100644 (file)
@@ -289,8 +289,6 @@ static int blkif_queue_request(struct request *req)
 
        ring_req->operation = rq_data_dir(req) ?
                BLKIF_OP_WRITE : BLKIF_OP_READ;
-       if (req->cmd_flags & REQ_HARDBARRIER)
-               ring_req->operation = BLKIF_OP_WRITE_BARRIER;
 
        ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
        BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
index d120a5c1c0939b1061aae61b6c983da76cf37446..ab3894f742c3002a90a98b89f116ab30c75cdb28 100644 (file)
@@ -68,6 +68,9 @@ static struct usb_device_id btusb_table[] = {
        /* Apple MacBookPro6,2 */
        { USB_DEVICE(0x05ac, 0x8218) },
 
+       /* Apple MacBookAir3,1, MacBookAir3,2 */
+       { USB_DEVICE(0x05ac, 0x821b) },
+
        /* AVM BlueFRITZ! USB v2.0 */
        { USB_DEVICE(0x057c, 0x3800) },
 
@@ -1029,6 +1032,8 @@ static int btusb_probe(struct usb_interface *intf,
 
        usb_set_intfdata(intf, data);
 
+       usb_enable_autosuspend(interface_to_usbdev(intf));
+
        return 0;
 }
 
diff --git a/drivers/char/.gitignore b/drivers/char/.gitignore
deleted file mode 100644 (file)
index 83683a2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-consolemap_deftbl.c
-defkeymap.c
index 3a9c01416839ebc785abcdec1405135fce3df817..ba53ec956c95627ff03695a3bbb363f9f5f2f400 100644 (file)
@@ -2,24 +2,10 @@
 # Makefile for the kernel character device drivers.
 #
 
-#
-# This file contains the font map for the default (hardware) font
-#
-FONTMAPFILE = cp437.uni
-
-obj-y   += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o
-
-obj-y                          += tty_mutex.o
-obj-$(CONFIG_LEGACY_PTYS)      += pty.o
-obj-$(CONFIG_UNIX98_PTYS)      += pty.o
+obj-y                          += mem.o random.o
 obj-$(CONFIG_TTY_PRINTK)       += ttyprintk.o
 obj-y                          += misc.o
-obj-$(CONFIG_VT)               += vt_ioctl.o vc_screen.o selection.o keyboard.o
 obj-$(CONFIG_BFIN_JTAG_COMM)   += bfin_jtag_comm.o
-obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o
-obj-$(CONFIG_HW_CONSOLE)       += vt.o defkeymap.o
-obj-$(CONFIG_AUDIT)            += tty_audit.o
-obj-$(CONFIG_MAGIC_SYSRQ)      += sysrq.o
 obj-$(CONFIG_MVME147_SCC)      += generic_serial.o vme_scc.o
 obj-$(CONFIG_MVME162_SCC)      += generic_serial.o vme_scc.o
 obj-$(CONFIG_BVME6000_SCC)     += generic_serial.o vme_scc.o
@@ -41,8 +27,6 @@ obj-$(CONFIG_ISI)             += isicom.o
 obj-$(CONFIG_SYNCLINK)         += synclink.o
 obj-$(CONFIG_SYNCLINKMP)       += synclinkmp.o
 obj-$(CONFIG_SYNCLINK_GT)      += synclink_gt.o
-obj-$(CONFIG_N_HDLC)           += n_hdlc.o
-obj-$(CONFIG_N_GSM)            += n_gsm.o
 obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
 obj-$(CONFIG_SX)               += sx.o generic_serial.o
 obj-$(CONFIG_RIO)              += rio/ generic_serial.o
@@ -74,7 +58,6 @@ obj-$(CONFIG_PRINTER)         += lp.o
 obj-$(CONFIG_APM_EMULATION)    += apm-emulation.o
 
 obj-$(CONFIG_DTLK)             += dtlk.o
-obj-$(CONFIG_R3964)            += n_r3964.o
 obj-$(CONFIG_APPLICOM)         += applicom.o
 obj-$(CONFIG_SONYPI)           += sonypi.o
 obj-$(CONFIG_RTC)              += rtc.o
@@ -115,28 +98,3 @@ obj-$(CONFIG_RAMOOPS)               += ramoops.o
 
 obj-$(CONFIG_JS_RTC)           += js-rtc.o
 js-rtc-y = rtc.o
-
-# Files generated that shall be removed upon make clean
-clean-files := consolemap_deftbl.c defkeymap.c
-
-quiet_cmd_conmk = CONMK   $@
-      cmd_conmk = scripts/conmakehash $< > $@
-
-$(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE)
-       $(call cmd,conmk)
-
-$(obj)/defkeymap.o:  $(obj)/defkeymap.c
-
-# Uncomment if you're changing the keymap and have an appropriate
-# loadkeys version for the map. By default, we'll use the shipped
-# versions.
-# GENERATE_KEYMAP := 1
-
-ifdef GENERATE_KEYMAP
-
-$(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map
-       loadkeys --mktable $< > $@.tmp
-       sed -e 's/^static *//' $@.tmp > $@
-       rm $@.tmp
-
-endif
index 6b6760ea2435bac1865325aec74d579f9687f87e..9272c38dd3c6ce8a66e9e0d2b0a5085ddd2973a7 100644 (file)
@@ -1210,14 +1210,14 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry,
        unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT;
        u32 pte_flags;
 
-       if (type_mask == AGP_USER_UNCACHED_MEMORY)
+       if (type_mask == AGP_USER_MEMORY)
                pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID;
        else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) {
-               pte_flags = GEN6_PTE_LLC | I810_PTE_VALID;
+               pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID;
                if (gfdt)
                        pte_flags |= GEN6_PTE_GFDT;
        } else { /* set 'normal'/'cached' to LLC by default */
-               pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID;
+               pte_flags = GEN6_PTE_LLC | I810_PTE_VALID;
                if (gfdt)
                        pte_flags |= GEN6_PTE_GFDT;
        }
index 17e380f5f818f6d0aa3ada75d3dc614975b51781..94821ab01c6d6ae1803201c27217c69a30357329 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/klist.h>
 #include <linux/agp_backend.h>
 #include <linux/log2.h>
+#include <linux/slab.h>
 
 #include <asm/parisc-device.h>
 #include <asm/ropes.h>
index b0a70461a12c9c19269b8fe6c443251960c131b1..c0bd6f472c523a377f4d6efef8d90f8f6fbfe373 100644 (file)
@@ -1299,7 +1299,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
 {
        struct async_struct * info = tty->driver_data;
        struct async_icount cprev, cnow;        /* kernel counter temps */
-       struct serial_icounter_struct icount;
        void __user *argp = (void __user *)arg;
        unsigned long flags;
 
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
deleted file mode 100644 (file)
index 45d3e80..0000000
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * consolemap.c
- *
- * Mapping from internal code (such as Latin-1 or Unicode or IBM PC code)
- * to font positions.
- *
- * aeb, 950210
- *
- * Support for multiple unimaps by Jakub Jelinek <jj@ultra.linux.cz>, July 1998
- *
- * Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998
- */
-
-#include <linux/module.h>
-#include <linux/kd.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <asm/uaccess.h>
-#include <linux/consolemap.h>
-#include <linux/vt_kern.h>
-
-static unsigned short translations[][256] = {
-  /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
-  {
-    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
-    0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
-    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
-    0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
-    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
-    0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
-    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
-    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
-    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
-    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
-    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
-    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
-    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
-    0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
-    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
-    0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
-    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
-    0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
-    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
-    0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
-    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
-    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
-    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
-    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
-    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
-    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
-    0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
-    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
-  }, 
-  /* VT100 graphics mapped to Unicode */
-  {
-    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
-    0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
-    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
-    0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
-    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
-    0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
-    0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
-    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
-    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
-    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
-    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
-    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
-    0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
-    0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
-    0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
-    0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
-    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
-    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
-    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
-    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
-    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
-    0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
-    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
-    0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
-    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
-    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
-    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
-    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
-    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
-    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
-    0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
-    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
-  },
-  /* IBM Codepage 437 mapped to Unicode */
-  {
-    0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 
-    0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
-    0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
-    0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
-    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
-    0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
-    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
-    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
-    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
-    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
-    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
-    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
-    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
-    0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
-    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
-    0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
-    0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
-    0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
-    0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
-    0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
-    0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
-    0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
-    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
-    0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
-    0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
-    0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
-    0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
-    0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
-    0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
-    0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
-    0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
-    0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
-  }, 
-  /* User mapping -- default to codes for direct font mapping */
-  {
-    0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
-    0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
-    0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
-    0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
-    0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
-    0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f,
-    0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
-    0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f,
-    0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047,
-    0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f,
-    0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057,
-    0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f,
-    0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067,
-    0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f,
-    0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077,
-    0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f,
-    0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
-    0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
-    0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
-    0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
-    0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7,
-    0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af,
-    0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7,
-    0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf,
-    0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7,
-    0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf,
-    0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7,
-    0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df,
-    0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
-    0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
-    0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
-    0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
-  }
-};
-
-/* The standard kernel character-to-font mappings are not invertible
-   -- this is just a best effort. */
-
-#define MAX_GLYPH 512          /* Max possible glyph value */
-
-static int inv_translate[MAX_NR_CONSOLES];
-
-struct uni_pagedir {
-       u16             **uni_pgdir[32];
-       unsigned long   refcount;
-       unsigned long   sum;
-       unsigned char   *inverse_translations[4];
-       u16             *inverse_trans_unicode;
-       int             readonly;
-};
-
-static struct uni_pagedir *dflt;
-
-static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int i)
-{
-       int j, glyph;
-       unsigned short *t = translations[i];
-       unsigned char *q;
-       
-       if (!p) return;
-       q = p->inverse_translations[i];
-
-       if (!q) {
-               q = p->inverse_translations[i] = (unsigned char *) 
-                       kmalloc(MAX_GLYPH, GFP_KERNEL);
-               if (!q) return;
-       }
-       memset(q, 0, MAX_GLYPH);
-
-       for (j = 0; j < E_TABSZ; j++) {
-               glyph = conv_uni_to_pc(conp, t[j]);
-               if (glyph >= 0 && glyph < MAX_GLYPH && q[glyph] < 32) {
-                       /* prefer '-' above SHY etc. */
-                       q[glyph] = j;
-               }
-       }
-}
-
-static void set_inverse_trans_unicode(struct vc_data *conp,
-                                     struct uni_pagedir *p)
-{
-       int i, j, k, glyph;
-       u16 **p1, *p2;
-       u16 *q;
-
-       if (!p) return;
-       q = p->inverse_trans_unicode;
-       if (!q) {
-               q = p->inverse_trans_unicode =
-                       kmalloc(MAX_GLYPH * sizeof(u16), GFP_KERNEL);
-               if (!q)
-                       return;
-       }
-       memset(q, 0, MAX_GLYPH * sizeof(u16));
-
-       for (i = 0; i < 32; i++) {
-               p1 = p->uni_pgdir[i];
-               if (!p1)
-                       continue;
-               for (j = 0; j < 32; j++) {
-                       p2 = p1[j];
-                       if (!p2)
-                               continue;
-                       for (k = 0; k < 64; k++) {
-                               glyph = p2[k];
-                               if (glyph >= 0 && glyph < MAX_GLYPH
-                                              && q[glyph] < 32)
-                                       q[glyph] = (i << 11) + (j << 6) + k;
-                       }
-               }
-       }
-}
-
-unsigned short *set_translate(int m, struct vc_data *vc)
-{
-       inv_translate[vc->vc_num] = m;
-       return translations[m];
-}
-
-/*
- * Inverse translation is impossible for several reasons:
- * 1. The font<->character maps are not 1-1.
- * 2. The text may have been written while a different translation map
- *    was active.
- * Still, it is now possible to a certain extent to cut and paste non-ASCII.
- */
-u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
-{
-       struct uni_pagedir *p;
-       int m;
-       if (glyph < 0 || glyph >= MAX_GLYPH)
-               return 0;
-       else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc))
-               return glyph;
-       else if (use_unicode) {
-               if (!p->inverse_trans_unicode)
-                       return glyph;
-               else
-                       return p->inverse_trans_unicode[glyph];
-       } else {
-               m = inv_translate[conp->vc_num];
-               if (!p->inverse_translations[m])
-                       return glyph;
-               else
-                       return p->inverse_translations[m][glyph];
-       }
-}
-EXPORT_SYMBOL_GPL(inverse_translate);
-
-static void update_user_maps(void)
-{
-       int i;
-       struct uni_pagedir *p, *q = NULL;
-       
-       for (i = 0; i < MAX_NR_CONSOLES; i++) {
-               if (!vc_cons_allocated(i))
-                       continue;
-               p = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc;
-               if (p && p != q) {
-                       set_inverse_transl(vc_cons[i].d, p, USER_MAP);
-                       set_inverse_trans_unicode(vc_cons[i].d, p);
-                       q = p;
-               }
-       }
-}
-
-/*
- * Load customizable translation table
- * arg points to a 256 byte translation table.
- *
- * The "old" variants are for translation directly to font (using the
- * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
- * Unicodes explicitly.
- */
-int con_set_trans_old(unsigned char __user * arg)
-{
-       int i;
-       unsigned short *p = translations[USER_MAP];
-
-       if (!access_ok(VERIFY_READ, arg, E_TABSZ))
-               return -EFAULT;
-
-       for (i=0; i<E_TABSZ ; i++) {
-               unsigned char uc;
-               __get_user(uc, arg+i);
-               p[i] = UNI_DIRECT_BASE | uc;
-       }
-
-       update_user_maps();
-       return 0;
-}
-
-int con_get_trans_old(unsigned char __user * arg)
-{
-       int i, ch;
-       unsigned short *p = translations[USER_MAP];
-
-       if (!access_ok(VERIFY_WRITE, arg, E_TABSZ))
-               return -EFAULT;
-
-       for (i=0; i<E_TABSZ ; i++)
-         {
-           ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
-           __put_user((ch & ~0xff) ? 0 : ch, arg+i);
-         }
-       return 0;
-}
-
-int con_set_trans_new(ushort __user * arg)
-{
-       int i;
-       unsigned short *p = translations[USER_MAP];
-
-       if (!access_ok(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short)))
-               return -EFAULT;
-
-       for (i=0; i<E_TABSZ ; i++) {
-               unsigned short us;
-               __get_user(us, arg+i);
-               p[i] = us;
-       }
-
-       update_user_maps();
-       return 0;
-}
-
-int con_get_trans_new(ushort __user * arg)
-{
-       int i;
-       unsigned short *p = translations[USER_MAP];
-
-       if (!access_ok(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short)))
-               return -EFAULT;
-
-       for (i=0; i<E_TABSZ ; i++)
-         __put_user(p[i], arg+i);
-       
-       return 0;
-}
-
-/*
- * Unicode -> current font conversion 
- *
- * A font has at most 512 chars, usually 256.
- * But one font position may represent several Unicode chars.
- * A hashtable is somewhat of a pain to deal with, so use a
- * "paged table" instead.  Simulation has shown the memory cost of
- * this 3-level paged table scheme to be comparable to a hash table.
- */
-
-extern u8 dfont_unicount[];    /* Defined in console_defmap.c */
-extern u16 dfont_unitable[];
-
-static void con_release_unimap(struct uni_pagedir *p)
-{
-       u16 **p1;
-       int i, j;
-
-       if (p == dflt) dflt = NULL;  
-       for (i = 0; i < 32; i++) {
-               if ((p1 = p->uni_pgdir[i]) != NULL) {
-                       for (j = 0; j < 32; j++)
-                               kfree(p1[j]);
-                       kfree(p1);
-               }
-               p->uni_pgdir[i] = NULL;
-       }
-       for (i = 0; i < 4; i++) {
-               kfree(p->inverse_translations[i]);
-               p->inverse_translations[i] = NULL;
-       }
-       if (p->inverse_trans_unicode) {
-               kfree(p->inverse_trans_unicode);
-               p->inverse_trans_unicode = NULL;
-       }
-}
-
-void con_free_unimap(struct vc_data *vc)
-{
-       struct uni_pagedir *p;
-
-       p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
-       if (!p)
-               return;
-       *vc->vc_uni_pagedir_loc = 0;
-       if (--p->refcount)
-               return;
-       con_release_unimap(p);
-       kfree(p);
-}
-  
-static int con_unify_unimap(struct vc_data *conp, struct uni_pagedir *p)
-{
-       int i, j, k;
-       struct uni_pagedir *q;
-       
-       for (i = 0; i < MAX_NR_CONSOLES; i++) {
-               if (!vc_cons_allocated(i))
-                       continue;
-               q = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc;
-               if (!q || q == p || q->sum != p->sum)
-                       continue;
-               for (j = 0; j < 32; j++) {
-                       u16 **p1, **q1;
-                       p1 = p->uni_pgdir[j]; q1 = q->uni_pgdir[j];
-                       if (!p1 && !q1)
-                               continue;
-                       if (!p1 || !q1)
-                               break;
-                       for (k = 0; k < 32; k++) {
-                               if (!p1[k] && !q1[k])
-                                       continue;
-                               if (!p1[k] || !q1[k])
-                                       break;
-                               if (memcmp(p1[k], q1[k], 64*sizeof(u16)))
-                                       break;
-                       }
-                       if (k < 32)
-                               break;
-               }
-               if (j == 32) {
-                       q->refcount++;
-                       *conp->vc_uni_pagedir_loc = (unsigned long)q;
-                       con_release_unimap(p);
-                       kfree(p);
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-static int
-con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
-{
-       int i, n;
-       u16 **p1, *p2;
-
-       if (!(p1 = p->uni_pgdir[n = unicode >> 11])) {
-               p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL);
-               if (!p1) return -ENOMEM;
-               for (i = 0; i < 32; i++)
-                       p1[i] = NULL;
-       }
-
-       if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) {
-               p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL);
-               if (!p2) return -ENOMEM;
-               memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */
-       }
-
-       p2[unicode & 0x3f] = fontpos;
-       
-       p->sum += (fontpos << 20) + unicode;
-
-       return 0;
-}
-
-/* ui is a leftover from using a hashtable, but might be used again */
-int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
-{
-       struct uni_pagedir *p, *q;
-  
-       p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
-       if (p && p->readonly) return -EIO;
-       if (!p || --p->refcount) {
-               q = kzalloc(sizeof(*p), GFP_KERNEL);
-               if (!q) {
-                       if (p) p->refcount++;
-                       return -ENOMEM;
-               }
-               q->refcount=1;
-               *vc->vc_uni_pagedir_loc = (unsigned long)q;
-       } else {
-               if (p == dflt) dflt = NULL;
-               p->refcount++;
-               p->sum = 0;
-               con_release_unimap(p);
-       }
-       return 0;
-}
-
-int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
-{
-       int err = 0, err1, i;
-       struct uni_pagedir *p, *q;
-
-       p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
-       if (p->readonly) return -EIO;
-       
-       if (!ct) return 0;
-       
-       if (p->refcount > 1) {
-               int j, k;
-               u16 **p1, *p2, l;
-               
-               err1 = con_clear_unimap(vc, NULL);
-               if (err1) return err1;
-               
-               q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
-               for (i = 0, l = 0; i < 32; i++)
-               if ((p1 = p->uni_pgdir[i]))
-                       for (j = 0; j < 32; j++)
-                       if ((p2 = p1[j]))
-                               for (k = 0; k < 64; k++, l++)
-                               if (p2[k] != 0xffff) {
-                                       err1 = con_insert_unipair(q, l, p2[k]);
-                                       if (err1) {
-                                               p->refcount++;
-                                               *vc->vc_uni_pagedir_loc = (unsigned long)p;
-                                               con_release_unimap(q);
-                                               kfree(q);
-                                               return err1; 
-                                       }
-                               }
-               p = q;
-       } else if (p == dflt)
-               dflt = NULL;
-       
-       while (ct--) {
-               unsigned short unicode, fontpos;
-               __get_user(unicode, &list->unicode);
-               __get_user(fontpos, &list->fontpos);
-               if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0)
-                       err = err1;
-               list++;
-       }
-       
-       if (con_unify_unimap(vc, p))
-               return err;
-
-       for (i = 0; i <= 3; i++)
-               set_inverse_transl(vc, p, i); /* Update all inverse translations */
-       set_inverse_trans_unicode(vc, p);
-  
-       return err;
-}
-
-/* Loads the unimap for the hardware font, as defined in uni_hash.tbl.
-   The representation used was the most compact I could come up
-   with.  This routine is executed at sys_setup time, and when the
-   PIO_FONTRESET ioctl is called. */
-
-int con_set_default_unimap(struct vc_data *vc)
-{
-       int i, j, err = 0, err1;
-       u16 *q;
-       struct uni_pagedir *p;
-
-       if (dflt) {
-               p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
-               if (p == dflt)
-                       return 0;
-               dflt->refcount++;
-               *vc->vc_uni_pagedir_loc = (unsigned long)dflt;
-               if (p && --p->refcount) {
-                       con_release_unimap(p);
-                       kfree(p);
-               }
-               return 0;
-       }
-       
-       /* The default font is always 256 characters */
-
-       err = con_clear_unimap(vc, NULL);
-       if (err) return err;
-    
-       p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
-       q = dfont_unitable;
-       
-       for (i = 0; i < 256; i++)
-               for (j = dfont_unicount[i]; j; j--) {
-                       err1 = con_insert_unipair(p, *(q++), i);
-                       if (err1)
-                               err = err1;
-               }
-                       
-       if (con_unify_unimap(vc, p)) {
-               dflt = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
-               return err;
-       }
-
-       for (i = 0; i <= 3; i++)
-               set_inverse_transl(vc, p, i);   /* Update all inverse translations */
-       set_inverse_trans_unicode(vc, p);
-       dflt = p;
-       return err;
-}
-EXPORT_SYMBOL(con_set_default_unimap);
-
-int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
-{
-       struct uni_pagedir *q;
-
-       if (!*src_vc->vc_uni_pagedir_loc)
-               return -EINVAL;
-       if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc)
-               return 0;
-       con_free_unimap(dst_vc);
-       q = (struct uni_pagedir *)*src_vc->vc_uni_pagedir_loc;
-       q->refcount++;
-       *dst_vc->vc_uni_pagedir_loc = (long)q;
-       return 0;
-}
-
-int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list)
-{
-       int i, j, k, ect;
-       u16 **p1, *p2;
-       struct uni_pagedir *p;
-
-       ect = 0;
-       if (*vc->vc_uni_pagedir_loc) {
-               p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
-               for (i = 0; i < 32; i++)
-               if ((p1 = p->uni_pgdir[i]))
-                       for (j = 0; j < 32; j++)
-                       if ((p2 = *(p1++)))
-                               for (k = 0; k < 64; k++) {
-                                       if (*p2 < MAX_GLYPH && ect++ < ct) {
-                                               __put_user((u_short)((i<<11)+(j<<6)+k),
-                                                          &list->unicode);
-                                               __put_user((u_short) *p2, 
-                                                          &list->fontpos);
-                                               list++;
-                                       }
-                                       p2++;
-                               }
-       }
-       __put_user(ect, uct);
-       return ((ect <= ct) ? 0 : -ENOMEM);
-}
-
-void con_protect_unimap(struct vc_data *vc, int rdonly)
-{
-       struct uni_pagedir *p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
-       
-       if (p)
-               p->readonly = rdonly;
-}
-
-/*
- * Always use USER_MAP. These functions are used by the keyboard,
- * which shouldn't be affected by G0/G1 switching, etc.
- * If the user map still contains default values, i.e. the
- * direct-to-font mapping, then assume user is using Latin1.
- */
-/* may be called during an interrupt */
-u32 conv_8bit_to_uni(unsigned char c)
-{
-       unsigned short uni = translations[USER_MAP][c];
-       return uni == (0xf000 | c) ? c : uni;
-}
-
-int conv_uni_to_8bit(u32 uni)
-{
-       int c;
-       for (c = 0; c < 0x100; c++)
-               if (translations[USER_MAP][c] == uni ||
-                  (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
-                       return c;
-       return -1;
-}
-
-int
-conv_uni_to_pc(struct vc_data *conp, long ucs) 
-{
-       int h;
-       u16 **p1, *p2;
-       struct uni_pagedir *p;
-  
-       /* Only 16-bit codes supported at this time */
-       if (ucs > 0xffff)
-               return -4;              /* Not found */
-       else if (ucs < 0x20)
-               return -1;              /* Not a printable character */
-       else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
-               return -2;                      /* Zero-width space */
-       /*
-        * UNI_DIRECT_BASE indicates the start of the region in the User Zone
-        * which always has a 1:1 mapping to the currently loaded font.  The
-        * UNI_DIRECT_MASK indicates the bit span of the region.
-        */
-       else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
-               return ucs & UNI_DIRECT_MASK;
-  
-       if (!*conp->vc_uni_pagedir_loc)
-               return -3;
-
-       p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;  
-       if ((p1 = p->uni_pgdir[ucs >> 11]) &&
-           (p2 = p1[(ucs >> 6) & 0x1f]) &&
-           (h = p2[ucs & 0x3f]) < MAX_GLYPH)
-               return h;
-
-       return -4;              /* not found */
-}
-
-/*
- * This is called at sys_setup time, after memory and the console are
- * initialized.  It must be possible to call kmalloc(..., GFP_KERNEL)
- * from this function, hence the call from sys_setup.
- */
-void __init 
-console_map_init(void)
-{
-       int i;
-       
-       for (i = 0; i < MAX_NR_CONSOLES; i++)
-               if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
-                       con_set_default_unimap(vc_cons[i].d);
-}
-
-EXPORT_SYMBOL(con_copy_unimap);
diff --git a/drivers/char/cp437.uni b/drivers/char/cp437.uni
deleted file mode 100644 (file)
index bc61634..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-#
-# Unicode table for IBM Codepage 437.  Note that there are many more
-# substitutions that could be conceived (for example, thick-line
-# graphs probably should be replaced with double-line ones, accented
-# Latin characters should replaced with their nonaccented versions,
-# and some upper case Greek characters could be replaced by Latin), however,
-# I have limited myself to the Unicodes used by the kernel ISO 8859-1,
-# DEC VT, and IBM CP 437 tables.
-#
-# --------------------------------
-#
-# Basic IBM dingbats, some of which will never have a purpose clear
-# to mankind
-#
-0x00   U+0000
-0x01   U+263a
-0x02   U+263b
-0x03   U+2665
-0x04   U+2666 U+25c6
-0x05   U+2663
-0x06   U+2660
-0x07   U+2022
-0x08   U+25d8
-0x09   U+25cb
-0x0a   U+25d9
-0x0b   U+2642
-0x0c   U+2640
-0x0d   U+266a
-0x0e   U+266b
-0x0f   U+263c U+00a4
-0x10   U+25b6 U+25ba
-0x11   U+25c0 U+25c4
-0x12   U+2195
-0x13   U+203c
-0x14   U+00b6
-0x15   U+00a7
-0x16   U+25ac
-0x17   U+21a8
-0x18   U+2191
-0x19   U+2193
-0x1a   U+2192
-0x1b   U+2190
-0x1c   U+221f
-0x1d   U+2194
-0x1e   U+25b2
-0x1f   U+25bc
-#
-# The ASCII range is identity-mapped, but some of the characters also
-# have to act as substitutes, especially the upper-case characters.
-#
-0x20   U+0020
-0x21   U+0021
-0x22   U+0022 U+00a8
-0x23   U+0023
-0x24   U+0024
-0x25   U+0025
-0x26   U+0026
-0x27   U+0027 U+00b4
-0x28   U+0028
-0x29   U+0029
-0x2a   U+002a
-0x2b   U+002b
-0x2c   U+002c U+00b8
-0x2d   U+002d U+00ad
-0x2e   U+002e
-0x2f   U+002f
-0x30   U+0030
-0x31   U+0031
-0x32   U+0032
-0x33   U+0033
-0x34   U+0034
-0x35   U+0035
-0x36   U+0036
-0x37   U+0037
-0x38   U+0038
-0x39   U+0039
-0x3a   U+003a
-0x3b   U+003b
-0x3c   U+003c
-0x3d   U+003d
-0x3e   U+003e
-0x3f   U+003f
-0x40   U+0040
-0x41   U+0041 U+00c0 U+00c1 U+00c2 U+00c3
-0x42   U+0042
-0x43   U+0043 U+00a9
-0x44   U+0044 U+00d0
-0x45   U+0045 U+00c8 U+00ca U+00cb
-0x46   U+0046
-0x47   U+0047
-0x48   U+0048
-0x49   U+0049 U+00cc U+00cd U+00ce U+00cf
-0x4a   U+004a
-0x4b   U+004b U+212a
-0x4c   U+004c
-0x4d   U+004d
-0x4e   U+004e
-0x4f   U+004f U+00d2 U+00d3 U+00d4 U+00d5
-0x50   U+0050
-0x51   U+0051
-0x52   U+0052 U+00ae
-0x53   U+0053
-0x54   U+0054
-0x55   U+0055 U+00d9 U+00da U+00db
-0x56   U+0056
-0x57   U+0057
-0x58   U+0058
-0x59   U+0059 U+00dd
-0x5a   U+005a
-0x5b   U+005b
-0x5c   U+005c
-0x5d   U+005d
-0x5e   U+005e
-0x5f   U+005f U+23bd U+f804
-0x60   U+0060
-0x61   U+0061 U+00e3
-0x62   U+0062
-0x63   U+0063
-0x64   U+0064
-0x65   U+0065
-0x66   U+0066
-0x67   U+0067
-0x68   U+0068
-0x69   U+0069
-0x6a   U+006a
-0x6b   U+006b
-0x6c   U+006c
-0x6d   U+006d
-0x6e   U+006e
-0x6f   U+006f U+00f5
-0x70   U+0070
-0x71   U+0071
-0x72   U+0072
-0x73   U+0073
-0x74   U+0074
-0x75   U+0075
-0x76   U+0076
-0x77   U+0077
-0x78   U+0078 U+00d7
-0x79   U+0079 U+00fd
-0x7a   U+007a
-0x7b   U+007b
-0x7c   U+007c U+00a6
-0x7d   U+007d
-0x7e   U+007e
-#
-# Okay, what on Earth is this one supposed to be used for?
-#
-0x7f   U+2302
-#
-# Non-English characters, mostly lower case letters...
-#
-0x80   U+00c7
-0x81   U+00fc
-0x82   U+00e9
-0x83   U+00e2
-0x84   U+00e4
-0x85   U+00e0
-0x86   U+00e5
-0x87   U+00e7
-0x88   U+00ea
-0x89   U+00eb
-0x8a   U+00e8
-0x8b   U+00ef
-0x8c   U+00ee
-0x8d   U+00ec
-0x8e   U+00c4
-0x8f   U+00c5 U+212b
-0x90   U+00c9
-0x91   U+00e6
-0x92   U+00c6
-0x93   U+00f4
-0x94   U+00f6
-0x95   U+00f2
-0x96   U+00fb
-0x97   U+00f9
-0x98   U+00ff
-0x99   U+00d6
-0x9a   U+00dc
-0x9b   U+00a2
-0x9c   U+00a3
-0x9d   U+00a5
-0x9e   U+20a7
-0x9f   U+0192
-0xa0   U+00e1
-0xa1   U+00ed
-0xa2   U+00f3
-0xa3   U+00fa
-0xa4   U+00f1
-0xa5   U+00d1
-0xa6   U+00aa
-0xa7   U+00ba
-0xa8   U+00bf
-0xa9   U+2310
-0xaa   U+00ac
-0xab   U+00bd
-0xac   U+00bc
-0xad   U+00a1
-0xae   U+00ab
-0xaf   U+00bb
-#
-# Block graphics
-#
-0xb0   U+2591
-0xb1   U+2592
-0xb2   U+2593
-0xb3   U+2502
-0xb4   U+2524
-0xb5   U+2561
-0xb6   U+2562
-0xb7   U+2556
-0xb8   U+2555
-0xb9   U+2563
-0xba   U+2551
-0xbb   U+2557
-0xbc   U+255d
-0xbd   U+255c
-0xbe   U+255b
-0xbf   U+2510
-0xc0   U+2514
-0xc1   U+2534
-0xc2   U+252c
-0xc3   U+251c
-0xc4   U+2500
-0xc5   U+253c
-0xc6   U+255e
-0xc7   U+255f
-0xc8   U+255a
-0xc9   U+2554
-0xca   U+2569
-0xcb   U+2566
-0xcc   U+2560
-0xcd   U+2550
-0xce   U+256c
-0xcf   U+2567
-0xd0   U+2568
-0xd1   U+2564
-0xd2   U+2565
-0xd3   U+2559
-0xd4   U+2558
-0xd5   U+2552
-0xd6   U+2553
-0xd7   U+256b
-0xd8   U+256a
-0xd9   U+2518
-0xda   U+250c
-0xdb   U+2588
-0xdc   U+2584
-0xdd   U+258c
-0xde   U+2590
-0xdf   U+2580
-#
-# Greek letters and mathematical symbols
-#
-0xe0   U+03b1
-0xe1   U+03b2 U+00df
-0xe2   U+0393
-0xe3   U+03c0
-0xe4   U+03a3
-0xe5   U+03c3
-0xe6   U+00b5 U+03bc
-0xe7   U+03c4
-0xe8   U+03a6 U+00d8
-0xe9   U+0398
-0xea   U+03a9 U+2126
-0xeb   U+03b4 U+00f0
-0xec   U+221e
-0xed   U+03c6 U+00f8
-0xee   U+03b5 U+2208
-0xef   U+2229
-0xf0   U+2261
-0xf1   U+00b1
-0xf2   U+2265
-0xf3   U+2264
-0xf4   U+2320
-0xf5   U+2321
-0xf6   U+00f7
-0xf7   U+2248
-0xf8   U+00b0
-0xf9   U+2219
-0xfa   U+00b7
-0xfb   U+221a
-0xfc   U+207f
-0xfd   U+00b2
-#
-# Square bullet, non-spacing blank
-# Mapping U+fffd to the square bullet means it is the substitution
-# character
-# 
-0xfe   U+25a0 U+fffd
-0xff   U+00a0
diff --git a/drivers/char/defkeymap.c_shipped b/drivers/char/defkeymap.c_shipped
deleted file mode 100644 (file)
index d2208df..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/* Do not edit this file! It was automatically generated by   */
-/*    loadkeys --mktable defkeymap.map > defkeymap.c          */
-
-#include <linux/types.h>
-#include <linux/keyboard.h>
-#include <linux/kd.h>
-
-u_short plain_map[NR_KEYS] = {
-       0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
-       0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
-       0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
-       0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
-       0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
-       0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
-       0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
-       0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
-       0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
-       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-       0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
-       0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
-       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-u_short shift_map[NR_KEYS] = {
-       0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
-       0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
-       0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
-       0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
-       0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
-       0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
-       0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
-       0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
-       0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
-       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-       0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
-       0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
-       0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
-       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-u_short altgr_map[NR_KEYS] = {
-       0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
-       0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
-       0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
-       0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
-       0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
-       0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
-       0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
-       0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
-       0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
-       0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
-       0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
-       0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
-       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-u_short ctrl_map[NR_KEYS] = {
-       0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
-       0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
-       0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
-       0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
-       0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
-       0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
-       0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
-       0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
-       0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
-       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-       0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
-       0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
-       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-u_short shift_ctrl_map[NR_KEYS] = {
-       0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
-       0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
-       0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
-       0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
-       0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
-       0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
-       0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
-       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-       0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
-       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-u_short alt_map[NR_KEYS] = {
-       0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
-       0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
-       0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
-       0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
-       0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
-       0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
-       0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
-       0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
-       0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
-       0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
-       0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
-       0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
-       0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-u_short ctrl_alt_map[NR_KEYS] = {
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
-       0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
-       0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
-       0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
-       0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
-       0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
-       0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
-       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-       0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
-       0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-       0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
-       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
-       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-ushort *key_maps[MAX_NR_KEYMAPS] = {
-       plain_map, shift_map, altgr_map, NULL,
-       ctrl_map, shift_ctrl_map, NULL, NULL,
-       alt_map, NULL, NULL, NULL,
-       ctrl_alt_map, NULL
-};
-
-unsigned int keymap_count = 7;
-
-/*
- * Philosophy: most people do not define more strings, but they who do
- * often want quite a lot of string space. So, we statically allocate
- * the default and allocate dynamically in chunks of 512 bytes.
- */
-
-char func_buf[] = {
-       '\033', '[', '[', 'A', 0, 
-       '\033', '[', '[', 'B', 0, 
-       '\033', '[', '[', 'C', 0, 
-       '\033', '[', '[', 'D', 0, 
-       '\033', '[', '[', 'E', 0, 
-       '\033', '[', '1', '7', '~', 0, 
-       '\033', '[', '1', '8', '~', 0, 
-       '\033', '[', '1', '9', '~', 0, 
-       '\033', '[', '2', '0', '~', 0, 
-       '\033', '[', '2', '1', '~', 0, 
-       '\033', '[', '2', '3', '~', 0, 
-       '\033', '[', '2', '4', '~', 0, 
-       '\033', '[', '2', '5', '~', 0, 
-       '\033', '[', '2', '6', '~', 0, 
-       '\033', '[', '2', '8', '~', 0, 
-       '\033', '[', '2', '9', '~', 0, 
-       '\033', '[', '3', '1', '~', 0, 
-       '\033', '[', '3', '2', '~', 0, 
-       '\033', '[', '3', '3', '~', 0, 
-       '\033', '[', '3', '4', '~', 0, 
-       '\033', '[', '1', '~', 0, 
-       '\033', '[', '2', '~', 0, 
-       '\033', '[', '3', '~', 0, 
-       '\033', '[', '4', '~', 0, 
-       '\033', '[', '5', '~', 0, 
-       '\033', '[', '6', '~', 0, 
-       '\033', '[', 'M', 0, 
-       '\033', '[', 'P', 0, 
-};
-
-char *funcbufptr = func_buf;
-int funcbufsize = sizeof(func_buf);
-int funcbufleft = 0;          /* space left */
-
-char *func_table[MAX_NR_FUNC] = {
-       func_buf + 0,
-       func_buf + 5,
-       func_buf + 10,
-       func_buf + 15,
-       func_buf + 20,
-       func_buf + 25,
-       func_buf + 31,
-       func_buf + 37,
-       func_buf + 43,
-       func_buf + 49,
-       func_buf + 55,
-       func_buf + 61,
-       func_buf + 67,
-       func_buf + 73,
-       func_buf + 79,
-       func_buf + 85,
-       func_buf + 91,
-       func_buf + 97,
-       func_buf + 103,
-       func_buf + 109,
-       func_buf + 115,
-       func_buf + 120,
-       func_buf + 125,
-       func_buf + 130,
-       func_buf + 135,
-       func_buf + 140,
-       func_buf + 145,
-       NULL,
-       NULL,
-       func_buf + 149,
-       NULL,
-};
-
-struct kbdiacruc accent_table[MAX_DIACR] = {
-       {'`', 'A', 0300},       {'`', 'a', 0340},
-       {'\'', 'A', 0301},      {'\'', 'a', 0341},
-       {'^', 'A', 0302},       {'^', 'a', 0342},
-       {'~', 'A', 0303},       {'~', 'a', 0343},
-       {'"', 'A', 0304},       {'"', 'a', 0344},
-       {'O', 'A', 0305},       {'o', 'a', 0345},
-       {'0', 'A', 0305},       {'0', 'a', 0345},
-       {'A', 'A', 0305},       {'a', 'a', 0345},
-       {'A', 'E', 0306},       {'a', 'e', 0346},
-       {',', 'C', 0307},       {',', 'c', 0347},
-       {'`', 'E', 0310},       {'`', 'e', 0350},
-       {'\'', 'E', 0311},      {'\'', 'e', 0351},
-       {'^', 'E', 0312},       {'^', 'e', 0352},
-       {'"', 'E', 0313},       {'"', 'e', 0353},
-       {'`', 'I', 0314},       {'`', 'i', 0354},
-       {'\'', 'I', 0315},      {'\'', 'i', 0355},
-       {'^', 'I', 0316},       {'^', 'i', 0356},
-       {'"', 'I', 0317},       {'"', 'i', 0357},
-       {'-', 'D', 0320},       {'-', 'd', 0360},
-       {'~', 'N', 0321},       {'~', 'n', 0361},
-       {'`', 'O', 0322},       {'`', 'o', 0362},
-       {'\'', 'O', 0323},      {'\'', 'o', 0363},
-       {'^', 'O', 0324},       {'^', 'o', 0364},
-       {'~', 'O', 0325},       {'~', 'o', 0365},
-       {'"', 'O', 0326},       {'"', 'o', 0366},
-       {'/', 'O', 0330},       {'/', 'o', 0370},
-       {'`', 'U', 0331},       {'`', 'u', 0371},
-       {'\'', 'U', 0332},      {'\'', 'u', 0372},
-       {'^', 'U', 0333},       {'^', 'u', 0373},
-       {'"', 'U', 0334},       {'"', 'u', 0374},
-       {'\'', 'Y', 0335},      {'\'', 'y', 0375},
-       {'T', 'H', 0336},       {'t', 'h', 0376},
-       {'s', 's', 0337},       {'"', 'y', 0377},
-       {'s', 'z', 0337},       {'i', 'j', 0377},
-};
-
-unsigned int accent_table_size = 68;
diff --git a/drivers/char/defkeymap.map b/drivers/char/defkeymap.map
deleted file mode 100644 (file)
index 50b30ca..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-# Default kernel keymap. This uses 7 modifier combinations.
-keymaps 0-2,4-5,8,12
-# Change the above line into
-#      keymaps 0-2,4-6,8,12
-# in case you want the entries
-#      altgr   control keycode  83 = Boot            
-#      altgr   control keycode 111 = Boot            
-# below.
-#
-# In fact AltGr is used very little, and one more keymap can
-# be saved by mapping AltGr to Alt (and adapting a few entries):
-# keycode 100 = Alt
-#
-keycode   1 = Escape           Escape          
-       alt     keycode   1 = Meta_Escape     
-keycode   2 = one              exclam          
-       alt     keycode   2 = Meta_one        
-keycode   3 = two              at               at              
-       control keycode   3 = nul             
-       shift   control keycode   3 = nul             
-       alt     keycode   3 = Meta_two        
-keycode   4 = three            numbersign      
-       control keycode   4 = Escape          
-       alt     keycode   4 = Meta_three      
-keycode   5 = four             dollar           dollar          
-       control keycode   5 = Control_backslash
-       alt     keycode   5 = Meta_four       
-keycode   6 = five             percent         
-       control keycode   6 = Control_bracketright
-       alt     keycode   6 = Meta_five       
-keycode   7 = six              asciicircum     
-       control keycode   7 = Control_asciicircum
-       alt     keycode   7 = Meta_six        
-keycode   8 = seven            ampersand        braceleft       
-       control keycode   8 = Control_underscore
-       alt     keycode   8 = Meta_seven      
-keycode   9 = eight            asterisk         bracketleft     
-       control keycode   9 = Delete          
-       alt     keycode   9 = Meta_eight      
-keycode  10 = nine             parenleft        bracketright    
-       alt     keycode  10 = Meta_nine       
-keycode  11 = zero             parenright       braceright      
-       alt     keycode  11 = Meta_zero       
-keycode  12 = minus            underscore       backslash       
-       control keycode  12 = Control_underscore
-       shift   control keycode  12 = Control_underscore
-       alt     keycode  12 = Meta_minus      
-keycode  13 = equal            plus            
-       alt     keycode  13 = Meta_equal      
-keycode  14 = Delete           Delete          
-       control keycode  14 = BackSpace
-       alt     keycode  14 = Meta_Delete     
-keycode  15 = Tab              Tab             
-       alt     keycode  15 = Meta_Tab        
-keycode  16 = q               
-keycode  17 = w               
-keycode  18 = e
-       altgr   keycode  18 = Hex_E   
-keycode  19 = r               
-keycode  20 = t               
-keycode  21 = y               
-keycode  22 = u               
-keycode  23 = i               
-keycode  24 = o               
-keycode  25 = p               
-keycode  26 = bracketleft      braceleft       
-       control keycode  26 = Escape          
-       alt     keycode  26 = Meta_bracketleft
-keycode  27 = bracketright     braceright       asciitilde      
-       control keycode  27 = Control_bracketright
-       alt     keycode  27 = Meta_bracketright
-keycode  28 = Return          
-       alt     keycode  28 = Meta_Control_m  
-keycode  29 = Control         
-keycode  30 = a
-       altgr   keycode  30 = Hex_A
-keycode  31 = s               
-keycode  32 = d
-       altgr   keycode  32 = Hex_D   
-keycode  33 = f
-       altgr   keycode  33 = Hex_F               
-keycode  34 = g               
-keycode  35 = h               
-keycode  36 = j               
-keycode  37 = k               
-keycode  38 = l               
-keycode  39 = semicolon        colon           
-       alt     keycode  39 = Meta_semicolon  
-keycode  40 = apostrophe       quotedbl        
-       control keycode  40 = Control_g       
-       alt     keycode  40 = Meta_apostrophe 
-keycode  41 = grave            asciitilde      
-       control keycode  41 = nul             
-       alt     keycode  41 = Meta_grave      
-keycode  42 = Shift           
-keycode  43 = backslash        bar             
-       control keycode  43 = Control_backslash
-       alt     keycode  43 = Meta_backslash  
-keycode  44 = z               
-keycode  45 = x               
-keycode  46 = c
-       altgr   keycode  46 = Hex_C   
-keycode  47 = v               
-keycode  48 = b
-       altgr   keycode  48 = Hex_B
-keycode  49 = n               
-keycode  50 = m               
-keycode  51 = comma            less            
-       alt     keycode  51 = Meta_comma      
-keycode  52 = period           greater         
-       control keycode  52 = Compose         
-       alt     keycode  52 = Meta_period     
-keycode  53 = slash            question        
-       control keycode  53 = Delete          
-       alt     keycode  53 = Meta_slash      
-keycode  54 = Shift           
-keycode  55 = KP_Multiply     
-keycode  56 = Alt             
-keycode  57 = space            space           
-       control keycode  57 = nul             
-       alt     keycode  57 = Meta_space      
-keycode  58 = Caps_Lock       
-keycode  59 = F1               F11              Console_13      
-       control keycode  59 = F1              
-       alt     keycode  59 = Console_1       
-       control alt     keycode  59 = Console_1       
-keycode  60 = F2               F12              Console_14      
-       control keycode  60 = F2              
-       alt     keycode  60 = Console_2       
-       control alt     keycode  60 = Console_2       
-keycode  61 = F3               F13              Console_15      
-       control keycode  61 = F3              
-       alt     keycode  61 = Console_3       
-       control alt     keycode  61 = Console_3       
-keycode  62 = F4               F14              Console_16      
-       control keycode  62 = F4              
-       alt     keycode  62 = Console_4       
-       control alt     keycode  62 = Console_4       
-keycode  63 = F5               F15              Console_17      
-       control keycode  63 = F5              
-       alt     keycode  63 = Console_5       
-       control alt     keycode  63 = Console_5       
-keycode  64 = F6               F16              Console_18      
-       control keycode  64 = F6              
-       alt     keycode  64 = Console_6       
-       control alt     keycode  64 = Console_6       
-keycode  65 = F7               F17              Console_19      
-       control keycode  65 = F7              
-       alt     keycode  65 = Console_7       
-       control alt     keycode  65 = Console_7       
-keycode  66 = F8               F18              Console_20      
-       control keycode  66 = F8              
-       alt     keycode  66 = Console_8       
-       control alt     keycode  66 = Console_8       
-keycode  67 = F9               F19              Console_21      
-       control keycode  67 = F9              
-       alt     keycode  67 = Console_9       
-       control alt     keycode  67 = Console_9       
-keycode  68 = F10              F20              Console_22      
-       control keycode  68 = F10             
-       alt     keycode  68 = Console_10      
-       control alt     keycode  68 = Console_10      
-keycode  69 = Num_Lock
-       shift   keycode  69 = Bare_Num_Lock
-keycode  70 = Scroll_Lock      Show_Memory      Show_Registers  
-       control keycode  70 = Show_State      
-       alt     keycode  70 = Scroll_Lock     
-keycode  71 = KP_7            
-       alt     keycode  71 = Ascii_7         
-       altgr   keycode  71 = Hex_7         
-keycode  72 = KP_8            
-       alt     keycode  72 = Ascii_8         
-       altgr   keycode  72 = Hex_8         
-keycode  73 = KP_9            
-       alt     keycode  73 = Ascii_9         
-       altgr   keycode  73 = Hex_9         
-keycode  74 = KP_Subtract     
-keycode  75 = KP_4            
-       alt     keycode  75 = Ascii_4         
-       altgr   keycode  75 = Hex_4         
-keycode  76 = KP_5            
-       alt     keycode  76 = Ascii_5         
-       altgr   keycode  76 = Hex_5         
-keycode  77 = KP_6            
-       alt     keycode  77 = Ascii_6         
-       altgr   keycode  77 = Hex_6         
-keycode  78 = KP_Add          
-keycode  79 = KP_1            
-       alt     keycode  79 = Ascii_1         
-       altgr   keycode  79 = Hex_1         
-keycode  80 = KP_2            
-       alt     keycode  80 = Ascii_2         
-       altgr   keycode  80 = Hex_2         
-keycode  81 = KP_3            
-       alt     keycode  81 = Ascii_3         
-       altgr   keycode  81 = Hex_3         
-keycode  82 = KP_0            
-       alt     keycode  82 = Ascii_0         
-       altgr   keycode  82 = Hex_0         
-keycode  83 = KP_Period       
-#      altgr   control keycode  83 = Boot            
-       control alt     keycode  83 = Boot            
-keycode  84 = Last_Console    
-keycode  85 =
-keycode  86 = less             greater          bar             
-       alt     keycode  86 = Meta_less       
-keycode  87 = F11              F11              Console_23      
-       control keycode  87 = F11             
-       alt     keycode  87 = Console_11      
-       control alt     keycode  87 = Console_11      
-keycode  88 = F12              F12              Console_24      
-       control keycode  88 = F12             
-       alt     keycode  88 = Console_12      
-       control alt     keycode  88 = Console_12      
-keycode  89 =
-keycode  90 =
-keycode  91 =
-keycode  92 =
-keycode  93 =
-keycode  94 =
-keycode  95 =
-keycode  96 = KP_Enter        
-keycode  97 = Control         
-keycode  98 = KP_Divide       
-keycode  99 = Control_backslash
-       control keycode  99 = Control_backslash
-       alt     keycode  99 = Control_backslash
-keycode 100 = AltGr           
-keycode 101 = Break           
-keycode 102 = Find            
-keycode 103 = Up              
-keycode 104 = Prior           
-       shift   keycode 104 = Scroll_Backward 
-keycode 105 = Left            
-       alt     keycode 105 = Decr_Console
-keycode 106 = Right           
-       alt     keycode 106 = Incr_Console
-keycode 107 = Select          
-keycode 108 = Down            
-keycode 109 = Next            
-       shift   keycode 109 = Scroll_Forward  
-keycode 110 = Insert          
-keycode 111 = Remove          
-#      altgr   control keycode 111 = Boot            
-       control alt     keycode 111 = Boot            
-keycode 112 = Macro           
-keycode 113 = F13             
-keycode 114 = F14             
-keycode 115 = Help            
-keycode 116 = Do              
-keycode 117 = F17             
-keycode 118 = KP_MinPlus      
-keycode 119 = Pause           
-keycode 120 =
-keycode 121 =
-keycode 122 =
-keycode 123 =
-keycode 124 =
-keycode 125 =
-keycode 126 =
-keycode 127 =
-string F1 = "\033[[A"
-string F2 = "\033[[B"
-string F3 = "\033[[C"
-string F4 = "\033[[D"
-string F5 = "\033[[E"
-string F6 = "\033[17~"
-string F7 = "\033[18~"
-string F8 = "\033[19~"
-string F9 = "\033[20~"
-string F10 = "\033[21~"
-string F11 = "\033[23~"
-string F12 = "\033[24~"
-string F13 = "\033[25~"
-string F14 = "\033[26~"
-string F15 = "\033[28~"
-string F16 = "\033[29~"
-string F17 = "\033[31~"
-string F18 = "\033[32~"
-string F19 = "\033[33~"
-string F20 = "\033[34~"
-string Find = "\033[1~"
-string Insert = "\033[2~"
-string Remove = "\033[3~"
-string Select = "\033[4~"
-string Prior = "\033[5~"
-string Next = "\033[6~"
-string Macro = "\033[M"
-string Pause = "\033[P"
-compose '`' 'A' to 'À'
-compose '`' 'a' to 'à'
-compose '\'' 'A' to 'Á'
-compose '\'' 'a' to 'á'
-compose '^' 'A' to 'Â'
-compose '^' 'a' to 'â'
-compose '~' 'A' to 'Ã'
-compose '~' 'a' to 'ã'
-compose '"' 'A' to 'Ä'
-compose '"' 'a' to 'ä'
-compose 'O' 'A' to 'Å'
-compose 'o' 'a' to 'å'
-compose '0' 'A' to 'Å'
-compose '0' 'a' to 'å'
-compose 'A' 'A' to 'Å'
-compose 'a' 'a' to 'å'
-compose 'A' 'E' to 'Æ'
-compose 'a' 'e' to 'æ'
-compose ',' 'C' to 'Ç'
-compose ',' 'c' to 'ç'
-compose '`' 'E' to 'È'
-compose '`' 'e' to 'è'
-compose '\'' 'E' to 'É'
-compose '\'' 'e' to 'é'
-compose '^' 'E' to 'Ê'
-compose '^' 'e' to 'ê'
-compose '"' 'E' to 'Ë'
-compose '"' 'e' to 'ë'
-compose '`' 'I' to 'Ì'
-compose '`' 'i' to 'ì'
-compose '\'' 'I' to 'Í'
-compose '\'' 'i' to 'í'
-compose '^' 'I' to 'Î'
-compose '^' 'i' to 'î'
-compose '"' 'I' to 'Ï'
-compose '"' 'i' to 'ï'
-compose '-' 'D' to 'Ð'
-compose '-' 'd' to 'ð'
-compose '~' 'N' to 'Ñ'
-compose '~' 'n' to 'ñ'
-compose '`' 'O' to 'Ò'
-compose '`' 'o' to 'ò'
-compose '\'' 'O' to 'Ó'
-compose '\'' 'o' to 'ó'
-compose '^' 'O' to 'Ô'
-compose '^' 'o' to 'ô'
-compose '~' 'O' to 'Õ'
-compose '~' 'o' to 'õ'
-compose '"' 'O' to 'Ö'
-compose '"' 'o' to 'ö'
-compose '/' 'O' to 'Ø'
-compose '/' 'o' to 'ø'
-compose '`' 'U' to 'Ù'
-compose '`' 'u' to 'ù'
-compose '\'' 'U' to 'Ú'
-compose '\'' 'u' to 'ú'
-compose '^' 'U' to 'Û'
-compose '^' 'u' to 'û'
-compose '"' 'U' to 'Ü'
-compose '"' 'u' to 'ü'
-compose '\'' 'Y' to 'Ý'
-compose '\'' 'y' to 'ý'
-compose 'T' 'H' to 'Þ'
-compose 't' 'h' to 'þ'
-compose 's' 's' to 'ß'
-compose '"' 'y' to 'ÿ'
-compose 's' 'z' to 'ß'
-compose 'i' 'j' to 'ÿ'
index 3bc0eef88717136342564976a8e18aa534732284..d72433f2d310deb6cf909cb1feb30e92919887cd 100644 (file)
@@ -120,7 +120,7 @@ static int i8k_smm(struct smm_regs *regs)
        int eax = regs->eax;
 
 #if defined(CONFIG_X86_64)
-       asm("pushq %%rax\n\t"
+       asm volatile("pushq %%rax\n\t"
                "movl 0(%%rax),%%edx\n\t"
                "pushq %%rdx\n\t"
                "movl 4(%%rax),%%ebx\n\t"
@@ -146,7 +146,7 @@ static int i8k_smm(struct smm_regs *regs)
                :    "a"(regs)
                :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 #else
-       asm("pushl %%eax\n\t"
+       asm volatile("pushl %%eax\n\t"
            "movl 0(%%eax),%%edx\n\t"
            "push %%edx\n\t"
            "movl 4(%%eax),%%ebx\n\t"
@@ -167,7 +167,8 @@ static int i8k_smm(struct smm_regs *regs)
            "movl %%edx,0(%%eax)\n\t"
            "lahf\n\t"
            "shrl $8,%%eax\n\t"
-           "andl $1,%%eax\n":"=a"(rc)
+           "andl $1,%%eax\n"
+           :"=a"(rc)
            :    "a"(regs)
            :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 #endif
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
deleted file mode 100644 (file)
index e95d787..0000000
+++ /dev/null
@@ -1,1454 +0,0 @@
-/*
- * linux/drivers/char/keyboard.c
- *
- * Written for linux by Johan Myreen as a translation from
- * the assembly version by Linus (with diacriticals added)
- *
- * Some additional features added by Christoph Niemann (ChN), March 1993
- *
- * Loadable keymaps by Risto Kankkunen, May 1993
- *
- * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
- * Added decr/incr_console, dynamic keymaps, Unicode support,
- * dynamic function/string keys, led setting,  Sept 1994
- * `Sticky' modifier keys, 951006.
- *
- * 11-11-96: SAK should now work in the raw mode (Martin Mares)
- *
- * Modified to provide 'generic' keyboard support by Hamish Macdonald
- * Merge with the m68k keyboard driver and split-off of the PC low-level
- * parts by Geert Uytterhoeven, May 1997
- *
- * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
- * 30-07-98: Dead keys redone, aeb@cwi.nl.
- * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/consolemap.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/kbd_diacr.h>
-#include <linux/vt_kern.h>
-#include <linux/input.h>
-#include <linux/reboot.h>
-#include <linux/notifier.h>
-#include <linux/jiffies.h>
-
-extern void ctrl_alt_del(void);
-
-/*
- * Exported functions/variables
- */
-
-#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
-
-/*
- * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
- * This seems a good reason to start with NumLock off. On HIL keyboards
- * of PARISC machines however there is no NumLock key and everyone expects the keypad
- * to be used for numbers.
- */
-
-#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
-#define KBD_DEFLEDS (1 << VC_NUMLOCK)
-#else
-#define KBD_DEFLEDS 0
-#endif
-
-#define KBD_DEFLOCK 0
-
-void compute_shiftstate(void);
-
-/*
- * Handler Tables.
- */
-
-#define K_HANDLERS\
-       k_self,         k_fn,           k_spec,         k_pad,\
-       k_dead,         k_cons,         k_cur,          k_shift,\
-       k_meta,         k_ascii,        k_lock,         k_lowercase,\
-       k_slock,        k_dead2,        k_brl,          k_ignore
-
-typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
-                           char up_flag);
-static k_handler_fn K_HANDLERS;
-static k_handler_fn *k_handler[16] = { K_HANDLERS };
-
-#define FN_HANDLERS\
-       fn_null,        fn_enter,       fn_show_ptregs, fn_show_mem,\
-       fn_show_state,  fn_send_intr,   fn_lastcons,    fn_caps_toggle,\
-       fn_num,         fn_hold,        fn_scroll_forw, fn_scroll_back,\
-       fn_boot_it,     fn_caps_on,     fn_compose,     fn_SAK,\
-       fn_dec_console, fn_inc_console, fn_spawn_con,   fn_bare_num
-
-typedef void (fn_handler_fn)(struct vc_data *vc);
-static fn_handler_fn FN_HANDLERS;
-static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
-
-/*
- * Variables exported for vt_ioctl.c
- */
-
-/* maximum values each key_handler can handle */
-const int max_vals[] = {
-       255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
-       NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
-       255, NR_LOCK - 1, 255, NR_BRL - 1
-};
-
-const int NR_TYPES = ARRAY_SIZE(max_vals);
-
-struct kbd_struct kbd_table[MAX_NR_CONSOLES];
-EXPORT_SYMBOL_GPL(kbd_table);
-static struct kbd_struct *kbd = kbd_table;
-
-struct vt_spawn_console vt_spawn_con = {
-       .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
-       .pid  = NULL,
-       .sig  = 0,
-};
-
-/*
- * Variables exported for vt.c
- */
-
-int shift_state = 0;
-
-/*
- * Internal Data.
- */
-
-static struct input_handler kbd_handler;
-static DEFINE_SPINLOCK(kbd_event_lock);
-static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
-static unsigned char shift_down[NR_SHIFT];             /* shift state counters.. */
-static bool dead_key_next;
-static int npadch = -1;                                        /* -1 or number assembled on pad */
-static unsigned int diacr;
-static char rep;                                       /* flag telling character repeat */
-
-static unsigned char ledstate = 0xff;                  /* undefined */
-static unsigned char ledioctl;
-
-static struct ledptr {
-       unsigned int *addr;
-       unsigned int mask;
-       unsigned char valid:1;
-} ledptrs[3];
-
-/*
- * Notifier list for console keyboard events
- */
-static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
-
-int register_keyboard_notifier(struct notifier_block *nb)
-{
-       return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(register_keyboard_notifier);
-
-int unregister_keyboard_notifier(struct notifier_block *nb)
-{
-       return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
-
-/*
- * Translation of scancodes to keycodes. We set them on only the first
- * keyboard in the list that accepts the scancode and keycode.
- * Explanation for not choosing the first attached keyboard anymore:
- *  USB keyboards for example have two event devices: one for all "normal"
- *  keys and one for extra function keys (like "volume up", "make coffee",
- *  etc.). So this means that scancodes for the extra function keys won't
- *  be valid for the first event device, but will be for the second.
- */
-
-struct getset_keycode_data {
-       struct input_keymap_entry ke;
-       int error;
-};
-
-static int getkeycode_helper(struct input_handle *handle, void *data)
-{
-       struct getset_keycode_data *d = data;
-
-       d->error = input_get_keycode(handle->dev, &d->ke);
-
-       return d->error == 0; /* stop as soon as we successfully get one */
-}
-
-int getkeycode(unsigned int scancode)
-{
-       struct getset_keycode_data d = {
-               .ke     = {
-                       .flags          = 0,
-                       .len            = sizeof(scancode),
-                       .keycode        = 0,
-               },
-               .error  = -ENODEV,
-       };
-
-       memcpy(d.ke.scancode, &scancode, sizeof(scancode));
-
-       input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
-
-       return d.error ?: d.ke.keycode;
-}
-
-static int setkeycode_helper(struct input_handle *handle, void *data)
-{
-       struct getset_keycode_data *d = data;
-
-       d->error = input_set_keycode(handle->dev, &d->ke);
-
-       return d->error == 0; /* stop as soon as we successfully set one */
-}
-
-int setkeycode(unsigned int scancode, unsigned int keycode)
-{
-       struct getset_keycode_data d = {
-               .ke     = {
-                       .flags          = 0,
-                       .len            = sizeof(scancode),
-                       .keycode        = keycode,
-               },
-               .error  = -ENODEV,
-       };
-
-       memcpy(d.ke.scancode, &scancode, sizeof(scancode));
-
-       input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
-
-       return d.error;
-}
-
-/*
- * Making beeps and bells. Note that we prefer beeps to bells, but when
- * shutting the sound off we do both.
- */
-
-static int kd_sound_helper(struct input_handle *handle, void *data)
-{
-       unsigned int *hz = data;
-       struct input_dev *dev = handle->dev;
-
-       if (test_bit(EV_SND, dev->evbit)) {
-               if (test_bit(SND_TONE, dev->sndbit)) {
-                       input_inject_event(handle, EV_SND, SND_TONE, *hz);
-                       if (*hz)
-                               return 0;
-               }
-               if (test_bit(SND_BELL, dev->sndbit))
-                       input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
-       }
-
-       return 0;
-}
-
-static void kd_nosound(unsigned long ignored)
-{
-       static unsigned int zero;
-
-       input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
-}
-
-static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
-
-void kd_mksound(unsigned int hz, unsigned int ticks)
-{
-       del_timer_sync(&kd_mksound_timer);
-
-       input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
-
-       if (hz && ticks)
-               mod_timer(&kd_mksound_timer, jiffies + ticks);
-}
-EXPORT_SYMBOL(kd_mksound);
-
-/*
- * Setting the keyboard rate.
- */
-
-static int kbd_rate_helper(struct input_handle *handle, void *data)
-{
-       struct input_dev *dev = handle->dev;
-       struct kbd_repeat *rep = data;
-
-       if (test_bit(EV_REP, dev->evbit)) {
-
-               if (rep[0].delay > 0)
-                       input_inject_event(handle,
-                                          EV_REP, REP_DELAY, rep[0].delay);
-               if (rep[0].period > 0)
-                       input_inject_event(handle,
-                                          EV_REP, REP_PERIOD, rep[0].period);
-
-               rep[1].delay = dev->rep[REP_DELAY];
-               rep[1].period = dev->rep[REP_PERIOD];
-       }
-
-       return 0;
-}
-
-int kbd_rate(struct kbd_repeat *rep)
-{
-       struct kbd_repeat data[2] = { *rep };
-
-       input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
-       *rep = data[1]; /* Copy currently used settings */
-
-       return 0;
-}
-
-/*
- * Helper Functions.
- */
-static void put_queue(struct vc_data *vc, int ch)
-{
-       struct tty_struct *tty = vc->port.tty;
-
-       if (tty) {
-               tty_insert_flip_char(tty, ch, 0);
-               con_schedule_flip(tty);
-       }
-}
-
-static void puts_queue(struct vc_data *vc, char *cp)
-{
-       struct tty_struct *tty = vc->port.tty;
-
-       if (!tty)
-               return;
-
-       while (*cp) {
-               tty_insert_flip_char(tty, *cp, 0);
-               cp++;
-       }
-       con_schedule_flip(tty);
-}
-
-static void applkey(struct vc_data *vc, int key, char mode)
-{
-       static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
-
-       buf[1] = (mode ? 'O' : '[');
-       buf[2] = key;
-       puts_queue(vc, buf);
-}
-
-/*
- * Many other routines do put_queue, but I think either
- * they produce ASCII, or they produce some user-assigned
- * string, and in both cases we might assume that it is
- * in utf-8 already.
- */
-static void to_utf8(struct vc_data *vc, uint c)
-{
-       if (c < 0x80)
-               /*  0******* */
-               put_queue(vc, c);
-       else if (c < 0x800) {
-               /* 110***** 10****** */
-               put_queue(vc, 0xc0 | (c >> 6));
-               put_queue(vc, 0x80 | (c & 0x3f));
-       } else if (c < 0x10000) {
-               if (c >= 0xD800 && c < 0xE000)
-                       return;
-               if (c == 0xFFFF)
-                       return;
-               /* 1110**** 10****** 10****** */
-               put_queue(vc, 0xe0 | (c >> 12));
-               put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
-               put_queue(vc, 0x80 | (c & 0x3f));
-       } else if (c < 0x110000) {
-               /* 11110*** 10****** 10****** 10****** */
-               put_queue(vc, 0xf0 | (c >> 18));
-               put_queue(vc, 0x80 | ((c >> 12) & 0x3f));
-               put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
-               put_queue(vc, 0x80 | (c & 0x3f));
-       }
-}
-
-/*
- * Called after returning from RAW mode or when changing consoles - recompute
- * shift_down[] and shift_state from key_down[] maybe called when keymap is
- * undefined, so that shiftkey release is seen
- */
-void compute_shiftstate(void)
-{
-       unsigned int i, j, k, sym, val;
-
-       shift_state = 0;
-       memset(shift_down, 0, sizeof(shift_down));
-
-       for (i = 0; i < ARRAY_SIZE(key_down); i++) {
-
-               if (!key_down[i])
-                       continue;
-
-               k = i * BITS_PER_LONG;
-
-               for (j = 0; j < BITS_PER_LONG; j++, k++) {
-
-                       if (!test_bit(k, key_down))
-                               continue;
-
-                       sym = U(key_maps[0][k]);
-                       if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
-                               continue;
-
-                       val = KVAL(sym);
-                       if (val == KVAL(K_CAPSSHIFT))
-                               val = KVAL(K_SHIFT);
-
-                       shift_down[val]++;
-                       shift_state |= (1 << val);
-               }
-       }
-}
-
-/*
- * We have a combining character DIACR here, followed by the character CH.
- * If the combination occurs in the table, return the corresponding value.
- * Otherwise, if CH is a space or equals DIACR, return DIACR.
- * Otherwise, conclude that DIACR was not combining after all,
- * queue it and return CH.
- */
-static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
-{
-       unsigned int d = diacr;
-       unsigned int i;
-
-       diacr = 0;
-
-       if ((d & ~0xff) == BRL_UC_ROW) {
-               if ((ch & ~0xff) == BRL_UC_ROW)
-                       return d | ch;
-       } else {
-               for (i = 0; i < accent_table_size; i++)
-                       if (accent_table[i].diacr == d && accent_table[i].base == ch)
-                               return accent_table[i].result;
-       }
-
-       if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
-               return d;
-
-       if (kbd->kbdmode == VC_UNICODE)
-               to_utf8(vc, d);
-       else {
-               int c = conv_uni_to_8bit(d);
-               if (c != -1)
-                       put_queue(vc, c);
-       }
-
-       return ch;
-}
-
-/*
- * Special function handlers
- */
-static void fn_enter(struct vc_data *vc)
-{
-       if (diacr) {
-               if (kbd->kbdmode == VC_UNICODE)
-                       to_utf8(vc, diacr);
-               else {
-                       int c = conv_uni_to_8bit(diacr);
-                       if (c != -1)
-                               put_queue(vc, c);
-               }
-               diacr = 0;
-       }
-
-       put_queue(vc, 13);
-       if (vc_kbd_mode(kbd, VC_CRLF))
-               put_queue(vc, 10);
-}
-
-static void fn_caps_toggle(struct vc_data *vc)
-{
-       if (rep)
-               return;
-
-       chg_vc_kbd_led(kbd, VC_CAPSLOCK);
-}
-
-static void fn_caps_on(struct vc_data *vc)
-{
-       if (rep)
-               return;
-
-       set_vc_kbd_led(kbd, VC_CAPSLOCK);
-}
-
-static void fn_show_ptregs(struct vc_data *vc)
-{
-       struct pt_regs *regs = get_irq_regs();
-
-       if (regs)
-               show_regs(regs);
-}
-
-static void fn_hold(struct vc_data *vc)
-{
-       struct tty_struct *tty = vc->port.tty;
-
-       if (rep || !tty)
-               return;
-
-       /*
-        * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
-        * these routines are also activated by ^S/^Q.
-        * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
-        */
-       if (tty->stopped)
-               start_tty(tty);
-       else
-               stop_tty(tty);
-}
-
-static void fn_num(struct vc_data *vc)
-{
-       if (vc_kbd_mode(kbd, VC_APPLIC))
-               applkey(vc, 'P', 1);
-       else
-               fn_bare_num(vc);
-}
-
-/*
- * Bind this to Shift-NumLock if you work in application keypad mode
- * but want to be able to change the NumLock flag.
- * Bind this to NumLock if you prefer that the NumLock key always
- * changes the NumLock flag.
- */
-static void fn_bare_num(struct vc_data *vc)
-{
-       if (!rep)
-               chg_vc_kbd_led(kbd, VC_NUMLOCK);
-}
-
-static void fn_lastcons(struct vc_data *vc)
-{
-       /* switch to the last used console, ChN */
-       set_console(last_console);
-}
-
-static void fn_dec_console(struct vc_data *vc)
-{
-       int i, cur = fg_console;
-
-       /* Currently switching?  Queue this next switch relative to that. */
-       if (want_console != -1)
-               cur = want_console;
-
-       for (i = cur - 1; i != cur; i--) {
-               if (i == -1)
-                       i = MAX_NR_CONSOLES - 1;
-               if (vc_cons_allocated(i))
-                       break;
-       }
-       set_console(i);
-}
-
-static void fn_inc_console(struct vc_data *vc)
-{
-       int i, cur = fg_console;
-
-       /* Currently switching?  Queue this next switch relative to that. */
-       if (want_console != -1)
-               cur = want_console;
-
-       for (i = cur+1; i != cur; i++) {
-               if (i == MAX_NR_CONSOLES)
-                       i = 0;
-               if (vc_cons_allocated(i))
-                       break;
-       }
-       set_console(i);
-}
-
-static void fn_send_intr(struct vc_data *vc)
-{
-       struct tty_struct *tty = vc->port.tty;
-
-       if (!tty)
-               return;
-       tty_insert_flip_char(tty, 0, TTY_BREAK);
-       con_schedule_flip(tty);
-}
-
-static void fn_scroll_forw(struct vc_data *vc)
-{
-       scrollfront(vc, 0);
-}
-
-static void fn_scroll_back(struct vc_data *vc)
-{
-       scrollback(vc, 0);
-}
-
-static void fn_show_mem(struct vc_data *vc)
-{
-       show_mem();
-}
-
-static void fn_show_state(struct vc_data *vc)
-{
-       show_state();
-}
-
-static void fn_boot_it(struct vc_data *vc)
-{
-       ctrl_alt_del();
-}
-
-static void fn_compose(struct vc_data *vc)
-{
-       dead_key_next = true;
-}
-
-static void fn_spawn_con(struct vc_data *vc)
-{
-       spin_lock(&vt_spawn_con.lock);
-       if (vt_spawn_con.pid)
-               if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
-                       put_pid(vt_spawn_con.pid);
-                       vt_spawn_con.pid = NULL;
-               }
-       spin_unlock(&vt_spawn_con.lock);
-}
-
-static void fn_SAK(struct vc_data *vc)
-{
-       struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
-       schedule_work(SAK_work);
-}
-
-static void fn_null(struct vc_data *vc)
-{
-       compute_shiftstate();
-}
-
-/*
- * Special key handlers
- */
-static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag)
-{
-}
-
-static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       if (up_flag)
-               return;
-       if (value >= ARRAY_SIZE(fn_handler))
-               return;
-       if ((kbd->kbdmode == VC_RAW ||
-            kbd->kbdmode == VC_MEDIUMRAW) &&
-            value != KVAL(K_SAK))
-               return;         /* SAK is allowed even in raw mode */
-       fn_handler[value](vc);
-}
-
-static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       pr_err("k_lowercase was called - impossible\n");
-}
-
-static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
-{
-       if (up_flag)
-               return;         /* no action, if this is a key release */
-
-       if (diacr)
-               value = handle_diacr(vc, value);
-
-       if (dead_key_next) {
-               dead_key_next = false;
-               diacr = value;
-               return;
-       }
-       if (kbd->kbdmode == VC_UNICODE)
-               to_utf8(vc, value);
-       else {
-               int c = conv_uni_to_8bit(value);
-               if (c != -1)
-                       put_queue(vc, c);
-       }
-}
-
-/*
- * Handle dead key. Note that we now may have several
- * dead keys modifying the same character. Very useful
- * for Vietnamese.
- */
-static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
-{
-       if (up_flag)
-               return;
-
-       diacr = (diacr ? handle_diacr(vc, value) : value);
-}
-
-static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       k_unicode(vc, conv_8bit_to_uni(value), up_flag);
-}
-
-static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       k_deadunicode(vc, value, up_flag);
-}
-
-/*
- * Obsolete - for backwards compatibility only
- */
-static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
-
-       k_deadunicode(vc, ret_diacr[value], up_flag);
-}
-
-static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       if (up_flag)
-               return;
-
-       set_console(value);
-}
-
-static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       if (up_flag)
-               return;
-
-       if ((unsigned)value < ARRAY_SIZE(func_table)) {
-               if (func_table[value])
-                       puts_queue(vc, func_table[value]);
-       } else
-               pr_err("k_fn called with value=%d\n", value);
-}
-
-static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       static const char cur_chars[] = "BDCA";
-
-       if (up_flag)
-               return;
-
-       applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
-}
-
-static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       static const char pad_chars[] = "0123456789+-*/\015,.?()#";
-       static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
-
-       if (up_flag)
-               return;         /* no action, if this is a key release */
-
-       /* kludge... shift forces cursor/number keys */
-       if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) {
-               applkey(vc, app_map[value], 1);
-               return;
-       }
-
-       if (!vc_kbd_led(kbd, VC_NUMLOCK)) {
-
-               switch (value) {
-               case KVAL(K_PCOMMA):
-               case KVAL(K_PDOT):
-                       k_fn(vc, KVAL(K_REMOVE), 0);
-                       return;
-               case KVAL(K_P0):
-                       k_fn(vc, KVAL(K_INSERT), 0);
-                       return;
-               case KVAL(K_P1):
-                       k_fn(vc, KVAL(K_SELECT), 0);
-                       return;
-               case KVAL(K_P2):
-                       k_cur(vc, KVAL(K_DOWN), 0);
-                       return;
-               case KVAL(K_P3):
-                       k_fn(vc, KVAL(K_PGDN), 0);
-                       return;
-               case KVAL(K_P4):
-                       k_cur(vc, KVAL(K_LEFT), 0);
-                       return;
-               case KVAL(K_P6):
-                       k_cur(vc, KVAL(K_RIGHT), 0);
-                       return;
-               case KVAL(K_P7):
-                       k_fn(vc, KVAL(K_FIND), 0);
-                       return;
-               case KVAL(K_P8):
-                       k_cur(vc, KVAL(K_UP), 0);
-                       return;
-               case KVAL(K_P9):
-                       k_fn(vc, KVAL(K_PGUP), 0);
-                       return;
-               case KVAL(K_P5):
-                       applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
-                       return;
-               }
-       }
-
-       put_queue(vc, pad_chars[value]);
-       if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
-               put_queue(vc, 10);
-}
-
-static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       int old_state = shift_state;
-
-       if (rep)
-               return;
-       /*
-        * Mimic typewriter:
-        * a CapsShift key acts like Shift but undoes CapsLock
-        */
-       if (value == KVAL(K_CAPSSHIFT)) {
-               value = KVAL(K_SHIFT);
-               if (!up_flag)
-                       clr_vc_kbd_led(kbd, VC_CAPSLOCK);
-       }
-
-       if (up_flag) {
-               /*
-                * handle the case that two shift or control
-                * keys are depressed simultaneously
-                */
-               if (shift_down[value])
-                       shift_down[value]--;
-       } else
-               shift_down[value]++;
-
-       if (shift_down[value])
-               shift_state |= (1 << value);
-       else
-               shift_state &= ~(1 << value);
-
-       /* kludge */
-       if (up_flag && shift_state != old_state && npadch != -1) {
-               if (kbd->kbdmode == VC_UNICODE)
-                       to_utf8(vc, npadch);
-               else
-                       put_queue(vc, npadch & 0xff);
-               npadch = -1;
-       }
-}
-
-static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       if (up_flag)
-               return;
-
-       if (vc_kbd_mode(kbd, VC_META)) {
-               put_queue(vc, '\033');
-               put_queue(vc, value);
-       } else
-               put_queue(vc, value | 0x80);
-}
-
-static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       int base;
-
-       if (up_flag)
-               return;
-
-       if (value < 10) {
-               /* decimal input of code, while Alt depressed */
-               base = 10;
-       } else {
-               /* hexadecimal input of code, while AltGr depressed */
-               value -= 10;
-               base = 16;
-       }
-
-       if (npadch == -1)
-               npadch = value;
-       else
-               npadch = npadch * base + value;
-}
-
-static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       if (up_flag || rep)
-               return;
-
-       chg_vc_kbd_lock(kbd, value);
-}
-
-static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       k_shift(vc, value, up_flag);
-       if (up_flag || rep)
-               return;
-
-       chg_vc_kbd_slock(kbd, value);
-       /* try to make Alt, oops, AltGr and such work */
-       if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
-               kbd->slockstate = 0;
-               chg_vc_kbd_slock(kbd, value);
-       }
-}
-
-/* by default, 300ms interval for combination release */
-static unsigned brl_timeout = 300;
-MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");
-module_param(brl_timeout, uint, 0644);
-
-static unsigned brl_nbchords = 1;
-MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
-module_param(brl_nbchords, uint, 0644);
-
-static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag)
-{
-       static unsigned long chords;
-       static unsigned committed;
-
-       if (!brl_nbchords)
-               k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag);
-       else {
-               committed |= pattern;
-               chords++;
-               if (chords == brl_nbchords) {
-                       k_unicode(vc, BRL_UC_ROW | committed, up_flag);
-                       chords = 0;
-                       committed = 0;
-               }
-       }
-}
-
-static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
-{
-       static unsigned pressed, committing;
-       static unsigned long releasestart;
-
-       if (kbd->kbdmode != VC_UNICODE) {
-               if (!up_flag)
-                       pr_warning("keyboard mode must be unicode for braille patterns\n");
-               return;
-       }
-
-       if (!value) {
-               k_unicode(vc, BRL_UC_ROW, up_flag);
-               return;
-       }
-
-       if (value > 8)
-               return;
-
-       if (!up_flag) {
-               pressed |= 1 << (value - 1);
-               if (!brl_timeout)
-                       committing = pressed;
-       } else if (brl_timeout) {
-               if (!committing ||
-                   time_after(jiffies,
-                              releasestart + msecs_to_jiffies(brl_timeout))) {
-                       committing = pressed;
-                       releasestart = jiffies;
-               }
-               pressed &= ~(1 << (value - 1));
-               if (!pressed && committing) {
-                       k_brlcommit(vc, committing, 0);
-                       committing = 0;
-               }
-       } else {
-               if (committing) {
-                       k_brlcommit(vc, committing, 0);
-                       committing = 0;
-               }
-               pressed &= ~(1 << (value - 1));
-       }
-}
-
-/*
- * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
- * or (ii) whatever pattern of lights people want to show using KDSETLED,
- * or (iii) specified bits of specified words in kernel memory.
- */
-unsigned char getledstate(void)
-{
-       return ledstate;
-}
-
-void setledstate(struct kbd_struct *kbd, unsigned int led)
-{
-       if (!(led & ~7)) {
-               ledioctl = led;
-               kbd->ledmode = LED_SHOW_IOCTL;
-       } else
-               kbd->ledmode = LED_SHOW_FLAGS;
-
-       set_leds();
-}
-
-static inline unsigned char getleds(void)
-{
-       struct kbd_struct *kbd = kbd_table + fg_console;
-       unsigned char leds;
-       int i;
-
-       if (kbd->ledmode == LED_SHOW_IOCTL)
-               return ledioctl;
-
-       leds = kbd->ledflagstate;
-
-       if (kbd->ledmode == LED_SHOW_MEM) {
-               for (i = 0; i < 3; i++)
-                       if (ledptrs[i].valid) {
-                               if (*ledptrs[i].addr & ledptrs[i].mask)
-                                       leds |= (1 << i);
-                               else
-                                       leds &= ~(1 << i);
-                       }
-       }
-       return leds;
-}
-
-static int kbd_update_leds_helper(struct input_handle *handle, void *data)
-{
-       unsigned char leds = *(unsigned char *)data;
-
-       if (test_bit(EV_LED, handle->dev->evbit)) {
-               input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
-               input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
-               input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
-               input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
-       }
-
-       return 0;
-}
-
-/*
- * This is the tasklet that updates LED state on all keyboards
- * attached to the box. The reason we use tasklet is that we
- * need to handle the scenario when keyboard handler is not
- * registered yet but we already getting updates form VT to
- * update led state.
- */
-static void kbd_bh(unsigned long dummy)
-{
-       unsigned char leds = getleds();
-
-       if (leds != ledstate) {
-               input_handler_for_each_handle(&kbd_handler, &leds,
-                                             kbd_update_leds_helper);
-               ledstate = leds;
-       }
-}
-
-DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
-
-#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
-    defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
-    defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
-    (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) ||\
-    defined(CONFIG_AVR32)
-
-#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
-                       ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
-
-static const unsigned short x86_keycodes[256] =
-       { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-        64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
-        80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92,
-       284,285,309,  0,312, 91,327,328,329,331,333,335,336,337,338,339,
-       367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
-       360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
-       103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
-       291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
-       264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
-       377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
-       308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
-       332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
-
-#ifdef CONFIG_SPARC
-static int sparc_l1_a_state;
-extern void sun_do_break(void);
-#endif
-
-static int emulate_raw(struct vc_data *vc, unsigned int keycode,
-                      unsigned char up_flag)
-{
-       int code;
-
-       switch (keycode) {
-
-       case KEY_PAUSE:
-               put_queue(vc, 0xe1);
-               put_queue(vc, 0x1d | up_flag);
-               put_queue(vc, 0x45 | up_flag);
-               break;
-
-       case KEY_HANGEUL:
-               if (!up_flag)
-                       put_queue(vc, 0xf2);
-               break;
-
-       case KEY_HANJA:
-               if (!up_flag)
-                       put_queue(vc, 0xf1);
-               break;
-
-       case KEY_SYSRQ:
-               /*
-                * Real AT keyboards (that's what we're trying
-                * to emulate here emit 0xe0 0x2a 0xe0 0x37 when
-                * pressing PrtSc/SysRq alone, but simply 0x54
-                * when pressing Alt+PrtSc/SysRq.
-                */
-               if (test_bit(KEY_LEFTALT, key_down) ||
-                   test_bit(KEY_RIGHTALT, key_down)) {
-                       put_queue(vc, 0x54 | up_flag);
-               } else {
-                       put_queue(vc, 0xe0);
-                       put_queue(vc, 0x2a | up_flag);
-                       put_queue(vc, 0xe0);
-                       put_queue(vc, 0x37 | up_flag);
-               }
-               break;
-
-       default:
-               if (keycode > 255)
-                       return -1;
-
-               code = x86_keycodes[keycode];
-               if (!code)
-                       return -1;
-
-               if (code & 0x100)
-                       put_queue(vc, 0xe0);
-               put_queue(vc, (code & 0x7f) | up_flag);
-
-               break;
-       }
-
-       return 0;
-}
-
-#else
-
-#define HW_RAW(dev)    0
-
-static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
-{
-       if (keycode > 127)
-               return -1;
-
-       put_queue(vc, keycode | up_flag);
-       return 0;
-}
-#endif
-
-static void kbd_rawcode(unsigned char data)
-{
-       struct vc_data *vc = vc_cons[fg_console].d;
-
-       kbd = kbd_table + vc->vc_num;
-       if (kbd->kbdmode == VC_RAW)
-               put_queue(vc, data);
-}
-
-static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
-{
-       struct vc_data *vc = vc_cons[fg_console].d;
-       unsigned short keysym, *key_map;
-       unsigned char type;
-       bool raw_mode;
-       struct tty_struct *tty;
-       int shift_final;
-       struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
-       int rc;
-
-       tty = vc->port.tty;
-
-       if (tty && (!tty->driver_data)) {
-               /* No driver data? Strange. Okay we fix it then. */
-               tty->driver_data = vc;
-       }
-
-       kbd = kbd_table + vc->vc_num;
-
-#ifdef CONFIG_SPARC
-       if (keycode == KEY_STOP)
-               sparc_l1_a_state = down;
-#endif
-
-       rep = (down == 2);
-
-       raw_mode = (kbd->kbdmode == VC_RAW);
-       if (raw_mode && !hw_raw)
-               if (emulate_raw(vc, keycode, !down << 7))
-                       if (keycode < BTN_MISC && printk_ratelimit())
-                               pr_warning("can't emulate rawmode for keycode %d\n",
-                                          keycode);
-
-#ifdef CONFIG_SPARC
-       if (keycode == KEY_A && sparc_l1_a_state) {
-               sparc_l1_a_state = false;
-               sun_do_break();
-       }
-#endif
-
-       if (kbd->kbdmode == VC_MEDIUMRAW) {
-               /*
-                * This is extended medium raw mode, with keys above 127
-                * encoded as 0, high 7 bits, low 7 bits, with the 0 bearing
-                * the 'up' flag if needed. 0 is reserved, so this shouldn't
-                * interfere with anything else. The two bytes after 0 will
-                * always have the up flag set not to interfere with older
-                * applications. This allows for 16384 different keycodes,
-                * which should be enough.
-                */
-               if (keycode < 128) {
-                       put_queue(vc, keycode | (!down << 7));
-               } else {
-                       put_queue(vc, !down << 7);
-                       put_queue(vc, (keycode >> 7) | 0x80);
-                       put_queue(vc, keycode | 0x80);
-               }
-               raw_mode = true;
-       }
-
-       if (down)
-               set_bit(keycode, key_down);
-       else
-               clear_bit(keycode, key_down);
-
-       if (rep &&
-           (!vc_kbd_mode(kbd, VC_REPEAT) ||
-            (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) {
-               /*
-                * Don't repeat a key if the input buffers are not empty and the
-                * characters get aren't echoed locally. This makes key repeat
-                * usable with slow applications and under heavy loads.
-                */
-               return;
-       }
-
-       param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
-       param.ledstate = kbd->ledflagstate;
-       key_map = key_maps[shift_final];
-
-       rc = atomic_notifier_call_chain(&keyboard_notifier_list,
-                                       KBD_KEYCODE, &param);
-       if (rc == NOTIFY_STOP || !key_map) {
-               atomic_notifier_call_chain(&keyboard_notifier_list,
-                                          KBD_UNBOUND_KEYCODE, &param);
-               compute_shiftstate();
-               kbd->slockstate = 0;
-               return;
-       }
-
-       if (keycode < NR_KEYS)
-               keysym = key_map[keycode];
-       else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
-               keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
-       else
-               return;
-
-       type = KTYP(keysym);
-
-       if (type < 0xf0) {
-               param.value = keysym;
-               rc = atomic_notifier_call_chain(&keyboard_notifier_list,
-                                               KBD_UNICODE, &param);
-               if (rc != NOTIFY_STOP)
-                       if (down && !raw_mode)
-                               to_utf8(vc, keysym);
-               return;
-       }
-
-       type -= 0xf0;
-
-       if (type == KT_LETTER) {
-               type = KT_LATIN;
-               if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
-                       key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
-                       if (key_map)
-                               keysym = key_map[keycode];
-               }
-       }
-
-       param.value = keysym;
-       rc = atomic_notifier_call_chain(&keyboard_notifier_list,
-                                       KBD_KEYSYM, &param);
-       if (rc == NOTIFY_STOP)
-               return;
-
-       if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
-               return;
-
-       (*k_handler[type])(vc, keysym & 0xff, !down);
-
-       param.ledstate = kbd->ledflagstate;
-       atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, &param);
-
-       if (type != KT_SLOCK)
-               kbd->slockstate = 0;
-}
-
-static void kbd_event(struct input_handle *handle, unsigned int event_type,
-                     unsigned int event_code, int value)
-{
-       /* We are called with interrupts disabled, just take the lock */
-       spin_lock(&kbd_event_lock);
-
-       if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
-               kbd_rawcode(value);
-       if (event_type == EV_KEY)
-               kbd_keycode(event_code, value, HW_RAW(handle->dev));
-
-       spin_unlock(&kbd_event_lock);
-
-       tasklet_schedule(&keyboard_tasklet);
-       do_poke_blanked_console = 1;
-       schedule_console_callback();
-}
-
-static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
-{
-       int i;
-
-       if (test_bit(EV_SND, dev->evbit))
-               return true;
-
-       if (test_bit(EV_KEY, dev->evbit)) {
-               for (i = KEY_RESERVED; i < BTN_MISC; i++)
-                       if (test_bit(i, dev->keybit))
-                               return true;
-               for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
-                       if (test_bit(i, dev->keybit))
-                               return true;
-       }
-
-       return false;
-}
-
-/*
- * When a keyboard (or other input device) is found, the kbd_connect
- * function is called. The function then looks at the device, and if it
- * likes it, it can open it and get events from it. In this (kbd_connect)
- * function, we should decide which VT to bind that keyboard to initially.
- */
-static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
-                       const struct input_device_id *id)
-{
-       struct input_handle *handle;
-       int error;
-
-       handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
-       if (!handle)
-               return -ENOMEM;
-
-       handle->dev = dev;
-       handle->handler = handler;
-       handle->name = "kbd";
-
-       error = input_register_handle(handle);
-       if (error)
-               goto err_free_handle;
-
-       error = input_open_device(handle);
-       if (error)
-               goto err_unregister_handle;
-
-       return 0;
-
- err_unregister_handle:
-       input_unregister_handle(handle);
- err_free_handle:
-       kfree(handle);
-       return error;
-}
-
-static void kbd_disconnect(struct input_handle *handle)
-{
-       input_close_device(handle);
-       input_unregister_handle(handle);
-       kfree(handle);
-}
-
-/*
- * Start keyboard handler on the new keyboard by refreshing LED state to
- * match the rest of the system.
- */
-static void kbd_start(struct input_handle *handle)
-{
-       tasklet_disable(&keyboard_tasklet);
-
-       if (ledstate != 0xff)
-               kbd_update_leds_helper(handle, &ledstate);
-
-       tasklet_enable(&keyboard_tasklet);
-}
-
-static const struct input_device_id kbd_ids[] = {
-       {
-                .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-                .evbit = { BIT_MASK(EV_KEY) },
-        },
-
-       {
-                .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-                .evbit = { BIT_MASK(EV_SND) },
-        },
-
-       { },    /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(input, kbd_ids);
-
-static struct input_handler kbd_handler = {
-       .event          = kbd_event,
-       .match          = kbd_match,
-       .connect        = kbd_connect,
-       .disconnect     = kbd_disconnect,
-       .start          = kbd_start,
-       .name           = "kbd",
-       .id_table       = kbd_ids,
-};
-
-int __init kbd_init(void)
-{
-       int i;
-       int error;
-
-        for (i = 0; i < MAX_NR_CONSOLES; i++) {
-               kbd_table[i].ledflagstate = KBD_DEFLEDS;
-               kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
-               kbd_table[i].ledmode = LED_SHOW_FLAGS;
-               kbd_table[i].lockstate = KBD_DEFLOCK;
-               kbd_table[i].slockstate = 0;
-               kbd_table[i].modeflags = KBD_DEFMODE;
-               kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
-       }
-
-       error = input_register_handler(&kbd_handler);
-       if (error)
-               return error;
-
-       tasklet_enable(&keyboard_tasklet);
-       tasklet_schedule(&keyboard_tasklet);
-
-       return 0;
-}
diff --git a/drivers/char/n_gsm.c b/drivers/char/n_gsm.c
deleted file mode 100644 (file)
index 04ef3ef..0000000
+++ /dev/null
@@ -1,2763 +0,0 @@
-/*
- * n_gsm.c GSM 0710 tty multiplexor
- * Copyright (c) 2009/10 Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *     * THIS IS A DEVELOPMENT SNAPSHOT IT IS NOT A FINAL RELEASE *
- *
- * TO DO:
- *     Mostly done:    ioctls for setting modes/timing
- *     Partly done:    hooks so you can pull off frames to non tty devs
- *     Restart DLCI 0 when it closes ?
- *     Test basic encoding
- *     Improve the tx engine
- *     Resolve tx side locking by adding a queue_head and routing
- *             all control traffic via it
- *     General tidy/document
- *     Review the locking/move to refcounts more (mux now moved to an
- *             alloc/free model ready)
- *     Use newest tty open/close port helpers and install hooks
- *     What to do about power functions ?
- *     Termios setting and negotiation
- *     Do we need a 'which mux are you' ioctl to correlate mux and tty sets
- *
- */
-
-#include <linux/types.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/fcntl.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/ctype.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/bitops.h>
-#include <linux/file.h>
-#include <linux/uaccess.h>
-#include <linux/module.h>
-#include <linux/timer.h>
-#include <linux/tty_flip.h>
-#include <linux/tty_driver.h>
-#include <linux/serial.h>
-#include <linux/kfifo.h>
-#include <linux/skbuff.h>
-#include <linux/gsmmux.h>
-
-static int debug;
-module_param(debug, int, 0600);
-
-#define T1     (HZ/10)
-#define T2     (HZ/3)
-#define N2     3
-
-/* Use long timers for testing at low speed with debug on */
-#ifdef DEBUG_TIMING
-#define T1     HZ
-#define T2     (2 * HZ)
-#endif
-
-/* Semi-arbitary buffer size limits. 0710 is normally run with 32-64 byte
-   limits so this is plenty */
-#define MAX_MRU 512
-#define MAX_MTU 512
-
-/*
- *     Each block of data we have queued to go out is in the form of
- *     a gsm_msg which holds everything we need in a link layer independant
- *     format
- */
-
-struct gsm_msg {
-       struct gsm_msg *next;
-       u8 addr;                /* DLCI address + flags */
-       u8 ctrl;                /* Control byte + flags */
-       unsigned int len;       /* Length of data block (can be zero) */
-       unsigned char *data;    /* Points into buffer but not at the start */
-       unsigned char buffer[0];
-};
-
-/*
- *     Each active data link has a gsm_dlci structure associated which ties
- *     the link layer to an optional tty (if the tty side is open). To avoid
- *     complexity right now these are only ever freed up when the mux is
- *     shut down.
- *
- *     At the moment we don't free DLCI objects until the mux is torn down
- *     this avoid object life time issues but might be worth review later.
- */
-
-struct gsm_dlci {
-       struct gsm_mux *gsm;
-       int addr;
-       int state;
-#define DLCI_CLOSED            0
-#define DLCI_OPENING           1       /* Sending SABM not seen UA */
-#define DLCI_OPEN              2       /* SABM/UA complete */
-#define DLCI_CLOSING           3       /* Sending DISC not seen UA/DM */
-
-       /* Link layer */
-       spinlock_t lock;        /* Protects the internal state */
-       struct timer_list t1;   /* Retransmit timer for SABM and UA */
-       int retries;
-       /* Uplink tty if active */
-       struct tty_port port;   /* The tty bound to this DLCI if there is one */
-       struct kfifo *fifo;     /* Queue fifo for the DLCI */
-       struct kfifo _fifo;     /* For new fifo API porting only */
-       int adaption;           /* Adaption layer in use */
-       u32 modem_rx;           /* Our incoming virtual modem lines */
-       u32 modem_tx;           /* Our outgoing modem lines */
-       int dead;               /* Refuse re-open */
-       /* Flow control */
-       int throttled;          /* Private copy of throttle state */
-       int constipated;        /* Throttle status for outgoing */
-       /* Packetised I/O */
-       struct sk_buff *skb;    /* Frame being sent */
-       struct sk_buff_head skb_list;   /* Queued frames */
-       /* Data handling callback */
-       void (*data)(struct gsm_dlci *dlci, u8 *data, int len);
-};
-
-/* DLCI 0, 62/63 are special or reseved see gsmtty_open */
-
-#define NUM_DLCI               64
-
-/*
- *     DLCI 0 is used to pass control blocks out of band of the data
- *     flow (and with a higher link priority). One command can be outstanding
- *     at a time and we use this structure to manage them. They are created
- *     and destroyed by the user context, and updated by the receive paths
- *     and timers
- */
-
-struct gsm_control {
-       u8 cmd;         /* Command we are issuing */
-       u8 *data;       /* Data for the command in case we retransmit */
-       int len;        /* Length of block for retransmission */
-       int done;       /* Done flag */
-       int error;      /* Error if any */
-};
-
-/*
- *     Each GSM mux we have is represented by this structure. If we are
- *     operating as an ldisc then we use this structure as our ldisc
- *     state. We need to sort out lifetimes and locking with respect
- *     to the gsm mux array. For now we don't free DLCI objects that
- *     have been instantiated until the mux itself is terminated.
- *
- *     To consider further: tty open versus mux shutdown.
- */
-
-struct gsm_mux {
-       struct tty_struct *tty;         /* The tty our ldisc is bound to */
-       spinlock_t lock;
-
-       /* Events on the GSM channel */
-       wait_queue_head_t event;
-
-       /* Bits for GSM mode decoding */
-
-       /* Framing Layer */
-       unsigned char *buf;
-       int state;
-#define GSM_SEARCH             0
-#define GSM_START              1
-#define GSM_ADDRESS            2
-#define GSM_CONTROL            3
-#define GSM_LEN                        4
-#define GSM_DATA               5
-#define GSM_FCS                        6
-#define GSM_OVERRUN            7
-       unsigned int len;
-       unsigned int address;
-       unsigned int count;
-       int escape;
-       int encoding;
-       u8 control;
-       u8 fcs;
-       u8 *txframe;                    /* TX framing buffer */
-
-       /* Methods for the receiver side */
-       void (*receive)(struct gsm_mux *gsm, u8 ch);
-       void (*error)(struct gsm_mux *gsm, u8 ch, u8 flag);
-       /* And transmit side */
-       int (*output)(struct gsm_mux *mux, u8 *data, int len);
-
-       /* Link Layer */
-       unsigned int mru;
-       unsigned int mtu;
-       int initiator;                  /* Did we initiate connection */
-       int dead;                       /* Has the mux been shut down */
-       struct gsm_dlci *dlci[NUM_DLCI];
-       int constipated;                /* Asked by remote to shut up */
-
-       spinlock_t tx_lock;
-       unsigned int tx_bytes;          /* TX data outstanding */
-#define TX_THRESH_HI           8192
-#define TX_THRESH_LO           2048
-       struct gsm_msg *tx_head;        /* Pending data packets */
-       struct gsm_msg *tx_tail;
-
-       /* Control messages */
-       struct timer_list t2_timer;     /* Retransmit timer for commands */
-       int cretries;                   /* Command retry counter */
-       struct gsm_control *pending_cmd;/* Our current pending command */
-       spinlock_t control_lock;        /* Protects the pending command */
-
-       /* Configuration */
-       int adaption;           /* 1 or 2 supported */
-       u8 ftype;               /* UI or UIH */
-       int t1, t2;             /* Timers in 1/100th of a sec */
-       int n2;                 /* Retry count */
-
-       /* Statistics (not currently exposed) */
-       unsigned long bad_fcs;
-       unsigned long malformed;
-       unsigned long io_error;
-       unsigned long bad_size;
-       unsigned long unsupported;
-};
-
-
-/*
- *     Mux objects - needed so that we can translate a tty index into the
- *     relevant mux and DLCI.
- */
-
-#define MAX_MUX                4                       /* 256 minors */
-static struct gsm_mux *gsm_mux[MAX_MUX];       /* GSM muxes */
-static spinlock_t gsm_mux_lock;
-
-/*
- *     This section of the driver logic implements the GSM encodings
- *     both the basic and the 'advanced'. Reliable transport is not
- *     supported.
- */
-
-#define CR                     0x02
-#define EA                     0x01
-#define        PF                      0x10
-
-/* I is special: the rest are ..*/
-#define RR                     0x01
-#define UI                     0x03
-#define RNR                    0x05
-#define REJ                    0x09
-#define DM                     0x0F
-#define SABM                   0x2F
-#define DISC                   0x43
-#define UA                     0x63
-#define        UIH                     0xEF
-
-/* Channel commands */
-#define CMD_NSC                        0x09
-#define CMD_TEST               0x11
-#define CMD_PSC                        0x21
-#define CMD_RLS                        0x29
-#define CMD_FCOFF              0x31
-#define CMD_PN                 0x41
-#define CMD_RPN                        0x49
-#define CMD_FCON               0x51
-#define CMD_CLD                        0x61
-#define CMD_SNC                        0x69
-#define CMD_MSC                        0x71
-
-/* Virtual modem bits */
-#define MDM_FC                 0x01
-#define MDM_RTC                        0x02
-#define MDM_RTR                        0x04
-#define MDM_IC                 0x20
-#define MDM_DV                 0x40
-
-#define GSM0_SOF               0xF9
-#define GSM1_SOF               0x7E
-#define GSM1_ESCAPE            0x7D
-#define GSM1_ESCAPE_BITS       0x20
-#define XON                    0x11
-#define XOFF                   0x13
-
-static const struct tty_port_operations gsm_port_ops;
-
-/*
- *     CRC table for GSM 0710
- */
-
-static const u8 gsm_fcs8[256] = {
-       0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75,
-       0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
-       0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69,
-       0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
-       0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D,
-       0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
-       0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51,
-       0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,
-       0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05,
-       0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,
-       0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19,
-       0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,
-       0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D,
-       0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,
-       0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21,
-       0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,
-       0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95,
-       0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,
-       0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89,
-       0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,
-       0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD,
-       0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
-       0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1,
-       0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,
-       0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5,
-       0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,
-       0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9,
-       0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,
-       0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD,
-       0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
-       0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1,
-       0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
-};
-
-#define INIT_FCS       0xFF
-#define GOOD_FCS       0xCF
-
-/**
- *     gsm_fcs_add     -       update FCS
- *     @fcs: Current FCS
- *     @c: Next data
- *
- *     Update the FCS to include c. Uses the algorithm in the specification
- *     notes.
- */
-
-static inline u8 gsm_fcs_add(u8 fcs, u8 c)
-{
-       return gsm_fcs8[fcs ^ c];
-}
-
-/**
- *     gsm_fcs_add_block       -       update FCS for a block
- *     @fcs: Current FCS
- *     @c: buffer of data
- *     @len: length of buffer
- *
- *     Update the FCS to include c. Uses the algorithm in the specification
- *     notes.
- */
-
-static inline u8 gsm_fcs_add_block(u8 fcs, u8 *c, int len)
-{
-       while (len--)
-               fcs = gsm_fcs8[fcs ^ *c++];
-       return fcs;
-}
-
-/**
- *     gsm_read_ea             -       read a byte into an EA
- *     @val: variable holding value
- *     c: byte going into the EA
- *
- *     Processes one byte of an EA. Updates the passed variable
- *     and returns 1 if the EA is now completely read
- */
-
-static int gsm_read_ea(unsigned int *val, u8 c)
-{
-       /* Add the next 7 bits into the value */
-       *val <<= 7;
-       *val |= c >> 1;
-       /* Was this the last byte of the EA 1 = yes*/
-       return c & EA;
-}
-
-/**
- *     gsm_encode_modem        -       encode modem data bits
- *     @dlci: DLCI to encode from
- *
- *     Returns the correct GSM encoded modem status bits (6 bit field) for
- *     the current status of the DLCI and attached tty object
- */
-
-static u8 gsm_encode_modem(const struct gsm_dlci *dlci)
-{
-       u8 modembits = 0;
-       /* FC is true flow control not modem bits */
-       if (dlci->throttled)
-               modembits |= MDM_FC;
-       if (dlci->modem_tx & TIOCM_DTR)
-               modembits |= MDM_RTC;
-       if (dlci->modem_tx & TIOCM_RTS)
-               modembits |= MDM_RTR;
-       if (dlci->modem_tx & TIOCM_RI)
-               modembits |= MDM_IC;
-       if (dlci->modem_tx & TIOCM_CD)
-               modembits |= MDM_DV;
-       return modembits;
-}
-
-/**
- *     gsm_print_packet        -       display a frame for debug
- *     @hdr: header to print before decode
- *     @addr: address EA from the frame
- *     @cr: C/R bit from the frame
- *     @control: control including PF bit
- *     @data: following data bytes
- *     @dlen: length of data
- *
- *     Displays a packet in human readable format for debugging purposes. The
- *     style is based on amateur radio LAP-B dump display.
- */
-
-static void gsm_print_packet(const char *hdr, int addr, int cr,
-                                       u8 control, const u8 *data, int dlen)
-{
-       if (!(debug & 1))
-               return;
-
-       printk(KERN_INFO "%s %d) %c: ", hdr, addr, "RC"[cr]);
-
-       switch (control & ~PF) {
-       case SABM:
-               printk(KERN_CONT "SABM");
-               break;
-       case UA:
-               printk(KERN_CONT "UA");
-               break;
-       case DISC:
-               printk(KERN_CONT "DISC");
-               break;
-       case DM:
-               printk(KERN_CONT "DM");
-               break;
-       case UI:
-               printk(KERN_CONT "UI");
-               break;
-       case UIH:
-               printk(KERN_CONT "UIH");
-               break;
-       default:
-               if (!(control & 0x01)) {
-                       printk(KERN_CONT "I N(S)%d N(R)%d",
-                               (control & 0x0E) >> 1, (control & 0xE)>> 5);
-               } else switch (control & 0x0F) {
-               case RR:
-                       printk("RR(%d)", (control & 0xE0) >> 5);
-                       break;
-               case RNR:
-                       printk("RNR(%d)", (control & 0xE0) >> 5);
-                       break;
-               case REJ:
-                       printk("REJ(%d)", (control & 0xE0) >> 5);
-                       break;
-               default:
-                       printk(KERN_CONT "[%02X]", control);
-               }
-       }
-
-       if (control & PF)
-               printk(KERN_CONT "(P)");
-       else
-               printk(KERN_CONT "(F)");
-
-       if (dlen) {
-               int ct = 0;
-               while (dlen--) {
-                       if (ct % 8 == 0)
-                               printk(KERN_CONT "\n    ");
-                       printk(KERN_CONT "%02X ", *data++);
-                       ct++;
-               }
-       }
-       printk(KERN_CONT "\n");
-}
-
-
-/*
- *     Link level transmission side
- */
-
-/**
- *     gsm_stuff_packet        -       bytestuff a packet
- *     @ibuf: input
- *     @obuf: output
- *     @len: length of input
- *
- *     Expand a buffer by bytestuffing it. The worst case size change
- *     is doubling and the caller is responsible for handing out
- *     suitable sized buffers.
- */
-
-static int gsm_stuff_frame(const u8 *input, u8 *output, int len)
-{
-       int olen = 0;
-       while (len--) {
-               if (*input == GSM1_SOF || *input == GSM1_ESCAPE
-                   || *input == XON || *input == XOFF) {
-                       *output++ = GSM1_ESCAPE;
-                       *output++ = *input++ ^ GSM1_ESCAPE_BITS;
-                       olen++;
-               } else
-                       *output++ = *input++;
-               olen++;
-       }
-       return olen;
-}
-
-static void hex_packet(const unsigned char *p, int len)
-{
-       int i;
-       for (i = 0; i < len; i++) {
-               if (i && (i % 16) == 0)
-                       printk("\n");
-               printk("%02X ", *p++);
-       }
-       printk("\n");
-}
-
-/**
- *     gsm_send        -       send a control frame
- *     @gsm: our GSM mux
- *     @addr: address for control frame
- *     @cr: command/response bit
- *     @control:  control byte including PF bit
- *
- *     Format up and transmit a control frame. These do not go via the
- *     queueing logic as they should be transmitted ahead of data when
- *     they are needed.
- *
- *     FIXME: Lock versus data TX path
- */
-
-static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
-{
-       int len;
-       u8 cbuf[10];
-       u8 ibuf[3];
-
-       switch (gsm->encoding) {
-       case 0:
-               cbuf[0] = GSM0_SOF;
-               cbuf[1] = (addr << 2) | (cr << 1) | EA;
-               cbuf[2] = control;
-               cbuf[3] = EA;   /* Length of data = 0 */
-               cbuf[4] = 0xFF - gsm_fcs_add_block(INIT_FCS, cbuf + 1, 3);
-               cbuf[5] = GSM0_SOF;
-               len = 6;
-               break;
-       case 1:
-       case 2:
-               /* Control frame + packing (but not frame stuffing) in mode 1 */
-               ibuf[0] = (addr << 2) | (cr << 1) | EA;
-               ibuf[1] = control;
-               ibuf[2] = 0xFF - gsm_fcs_add_block(INIT_FCS, ibuf, 2);
-               /* Stuffing may double the size worst case */
-               len = gsm_stuff_frame(ibuf, cbuf + 1, 3);
-               /* Now add the SOF markers */
-               cbuf[0] = GSM1_SOF;
-               cbuf[len + 1] = GSM1_SOF;
-               /* FIXME: we can omit the lead one in many cases */
-               len += 2;
-               break;
-       default:
-               WARN_ON(1);
-               return;
-       }
-       gsm->output(gsm, cbuf, len);
-       gsm_print_packet("-->", addr, cr, control, NULL, 0);
-}
-
-/**
- *     gsm_response    -       send a control response
- *     @gsm: our GSM mux
- *     @addr: address for control frame
- *     @control:  control byte including PF bit
- *
- *     Format up and transmit a link level response frame.
- */
-
-static inline void gsm_response(struct gsm_mux *gsm, int addr, int control)
-{
-       gsm_send(gsm, addr, 0, control);
-}
-
-/**
- *     gsm_command     -       send a control command
- *     @gsm: our GSM mux
- *     @addr: address for control frame
- *     @control:  control byte including PF bit
- *
- *     Format up and transmit a link level command frame.
- */
-
-static inline void gsm_command(struct gsm_mux *gsm, int addr, int control)
-{
-       gsm_send(gsm, addr, 1, control);
-}
-
-/* Data transmission */
-
-#define HDR_LEN                6       /* ADDR CTRL [LEN.2] DATA FCS */
-
-/**
- *     gsm_data_alloc          -       allocate data frame
- *     @gsm: GSM mux
- *     @addr: DLCI address
- *     @len: length excluding header and FCS
- *     @ctrl: control byte
- *
- *     Allocate a new data buffer for sending frames with data. Space is left
- *     at the front for header bytes but that is treated as an implementation
- *     detail and not for the high level code to use
- */
-
-static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
-                                                               u8 ctrl)
-{
-       struct gsm_msg *m = kmalloc(sizeof(struct gsm_msg) + len + HDR_LEN,
-                                                               GFP_ATOMIC);
-       if (m == NULL)
-               return NULL;
-       m->data = m->buffer + HDR_LEN - 1;      /* Allow for FCS */
-       m->len = len;
-       m->addr = addr;
-       m->ctrl = ctrl;
-       m->next = NULL;
-       return m;
-}
-
-/**
- *     gsm_data_kick           -       poke the queue
- *     @gsm: GSM Mux
- *
- *     The tty device has called us to indicate that room has appeared in
- *     the transmit queue. Ram more data into the pipe if we have any
- *
- *     FIXME: lock against link layer control transmissions
- */
-
-static void gsm_data_kick(struct gsm_mux *gsm)
-{
-       struct gsm_msg *msg = gsm->tx_head;
-       int len;
-       int skip_sof = 0;
-
-       /* FIXME: We need to apply this solely to data messages */
-       if (gsm->constipated)
-               return;
-
-       while (gsm->tx_head != NULL) {
-               msg = gsm->tx_head;
-               if (gsm->encoding != 0) {
-                       gsm->txframe[0] = GSM1_SOF;
-                       len = gsm_stuff_frame(msg->data,
-                                               gsm->txframe + 1, msg->len);
-                       gsm->txframe[len + 1] = GSM1_SOF;
-                       len += 2;
-               } else {
-                       gsm->txframe[0] = GSM0_SOF;
-                       memcpy(gsm->txframe + 1 , msg->data, msg->len);
-                       gsm->txframe[msg->len + 1] = GSM0_SOF;
-                       len = msg->len + 2;
-               }
-
-               if (debug & 4) {
-                       printk("gsm_data_kick: \n");
-                       hex_packet(gsm->txframe, len);
-               }
-
-               if (gsm->output(gsm, gsm->txframe + skip_sof,
-                                               len - skip_sof) < 0)
-                       break;
-               /* FIXME: Can eliminate one SOF in many more cases */
-               gsm->tx_head = msg->next;
-               if (gsm->tx_head == NULL)
-                       gsm->tx_tail = NULL;
-               gsm->tx_bytes -= msg->len;
-               kfree(msg);
-               /* For a burst of frames skip the extra SOF within the
-                  burst */
-               skip_sof = 1;
-       }
-}
-
-/**
- *     __gsm_data_queue                -       queue a UI or UIH frame
- *     @dlci: DLCI sending the data
- *     @msg: message queued
- *
- *     Add data to the transmit queue and try and get stuff moving
- *     out of the mux tty if not already doing so. The Caller must hold
- *     the gsm tx lock.
- */
-
-static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
-{
-       struct gsm_mux *gsm = dlci->gsm;
-       u8 *dp = msg->data;
-       u8 *fcs = dp + msg->len;
-
-       /* Fill in the header */
-       if (gsm->encoding == 0) {
-               if (msg->len < 128)
-                       *--dp = (msg->len << 1) | EA;
-               else {
-                       *--dp = (msg->len >> 6) | EA;
-                       *--dp = (msg->len & 127) << 1;
-               }
-       }
-
-       *--dp = msg->ctrl;
-       if (gsm->initiator)
-               *--dp = (msg->addr << 2) | 2 | EA;
-       else
-               *--dp = (msg->addr << 2) | EA;
-       *fcs = gsm_fcs_add_block(INIT_FCS, dp , msg->data - dp);
-       /* Ugly protocol layering violation */
-       if (msg->ctrl == UI || msg->ctrl == (UI|PF))
-               *fcs = gsm_fcs_add_block(*fcs, msg->data, msg->len);
-       *fcs = 0xFF - *fcs;
-
-       gsm_print_packet("Q> ", msg->addr, gsm->initiator, msg->ctrl,
-                                                       msg->data, msg->len);
-
-       /* Move the header back and adjust the length, also allow for the FCS
-          now tacked on the end */
-       msg->len += (msg->data - dp) + 1;
-       msg->data = dp;
-
-       /* Add to the actual output queue */
-       if (gsm->tx_tail)
-               gsm->tx_tail->next = msg;
-       else
-               gsm->tx_head = msg;
-       gsm->tx_tail = msg;
-       gsm->tx_bytes += msg->len;
-       gsm_data_kick(gsm);
-}
-
-/**
- *     gsm_data_queue          -       queue a UI or UIH frame
- *     @dlci: DLCI sending the data
- *     @msg: message queued
- *
- *     Add data to the transmit queue and try and get stuff moving
- *     out of the mux tty if not already doing so. Take the
- *     the gsm tx lock and dlci lock.
- */
-
-static void gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
-       __gsm_data_queue(dlci, msg);
-       spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
-}
-
-/**
- *     gsm_dlci_data_output    -       try and push data out of a DLCI
- *     @gsm: mux
- *     @dlci: the DLCI to pull data from
- *
- *     Pull data from a DLCI and send it into the transmit queue if there
- *     is data. Keep to the MRU of the mux. This path handles the usual tty
- *     interface which is a byte stream with optional modem data.
- *
- *     Caller must hold the tx_lock of the mux.
- */
-
-static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
-{
-       struct gsm_msg *msg;
-       u8 *dp;
-       int len, size;
-       int h = dlci->adaption - 1;
-
-       len = kfifo_len(dlci->fifo);
-       if (len == 0)
-               return 0;
-
-       /* MTU/MRU count only the data bits */
-       if (len > gsm->mtu)
-               len = gsm->mtu;
-
-       size = len + h;
-
-       msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
-       /* FIXME: need a timer or something to kick this so it can't
-          get stuck with no work outstanding and no buffer free */
-       if (msg == NULL)
-               return -ENOMEM;
-       dp = msg->data;
-       switch (dlci->adaption) {
-       case 1: /* Unstructured */
-               break;
-       case 2: /* Unstructed with modem bits. Always one byte as we never
-                  send inline break data */
-               *dp += gsm_encode_modem(dlci);
-               len--;
-               break;
-       }
-       WARN_ON(kfifo_out_locked(dlci->fifo, dp , len, &dlci->lock) != len);
-       __gsm_data_queue(dlci, msg);
-       /* Bytes of data we used up */
-       return size;
-}
-
-/**
- *     gsm_dlci_data_output_framed  -  try and push data out of a DLCI
- *     @gsm: mux
- *     @dlci: the DLCI to pull data from
- *
- *     Pull data from a DLCI and send it into the transmit queue if there
- *     is data. Keep to the MRU of the mux. This path handles framed data
- *     queued as skbuffs to the DLCI.
- *
- *     Caller must hold the tx_lock of the mux.
- */
-
-static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
-                                               struct gsm_dlci *dlci)
-{
-       struct gsm_msg *msg;
-       u8 *dp;
-       int len, size;
-       int last = 0, first = 0;
-       int overhead = 0;
-
-       /* One byte per frame is used for B/F flags */
-       if (dlci->adaption == 4)
-               overhead = 1;
-
-       /* dlci->skb is locked by tx_lock */
-       if (dlci->skb == NULL) {
-               dlci->skb = skb_dequeue(&dlci->skb_list);
-               if (dlci->skb == NULL)
-                       return 0;
-               first = 1;
-       }
-       len = dlci->skb->len + overhead;
-
-       /* MTU/MRU count only the data bits */
-       if (len > gsm->mtu) {
-               if (dlci->adaption == 3) {
-                       /* Over long frame, bin it */
-                       kfree_skb(dlci->skb);
-                       dlci->skb = NULL;
-                       return 0;
-               }
-               len = gsm->mtu;
-       } else
-               last = 1;
-
-       size = len + overhead;
-       msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
-
-       /* FIXME: need a timer or something to kick this so it can't
-          get stuck with no work outstanding and no buffer free */
-       if (msg == NULL)
-               return -ENOMEM;
-       dp = msg->data;
-
-       if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */
-               /* Flag byte to carry the start/end info */
-               *dp++ = last << 7 | first << 6 | 1;     /* EA */
-               len--;
-       }
-       memcpy(dp, skb_pull(dlci->skb, len), len);
-       __gsm_data_queue(dlci, msg);
-       if (last)
-               dlci->skb = NULL;
-       return size;
-}
-
-/**
- *     gsm_dlci_data_sweep             -       look for data to send
- *     @gsm: the GSM mux
- *
- *     Sweep the GSM mux channels in priority order looking for ones with
- *     data to send. We could do with optimising this scan a bit. We aim
- *     to fill the queue totally or up to TX_THRESH_HI bytes. Once we hit
- *     TX_THRESH_LO we get called again
- *
- *     FIXME: We should round robin between groups and in theory you can
- *     renegotiate DLCI priorities with optional stuff. Needs optimising.
- */
-
-static void gsm_dlci_data_sweep(struct gsm_mux *gsm)
-{
-       int len;
-       /* Priority ordering: We should do priority with RR of the groups */
-       int i = 1;
-
-       while (i < NUM_DLCI) {
-               struct gsm_dlci *dlci;
-
-               if (gsm->tx_bytes > TX_THRESH_HI)
-                       break;
-               dlci = gsm->dlci[i];
-               if (dlci == NULL || dlci->constipated) {
-                       i++;
-                       continue;
-               }
-               if (dlci->adaption < 3)
-                       len = gsm_dlci_data_output(gsm, dlci);
-               else
-                       len = gsm_dlci_data_output_framed(gsm, dlci);
-               if (len < 0)
-                       break;
-               /* DLCI empty - try the next */
-               if (len == 0)
-                       i++;
-       }
-}
-
-/**
- *     gsm_dlci_data_kick      -       transmit if possible
- *     @dlci: DLCI to kick
- *
- *     Transmit data from this DLCI if the queue is empty. We can't rely on
- *     a tty wakeup except when we filled the pipe so we need to fire off
- *     new data ourselves in other cases.
- */
-
-static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
-       /* If we have nothing running then we need to fire up */
-       if (dlci->gsm->tx_bytes == 0)
-               gsm_dlci_data_output(dlci->gsm, dlci);
-       else if (dlci->gsm->tx_bytes < TX_THRESH_LO)
-               gsm_dlci_data_sweep(dlci->gsm);
-       spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
-}
-
-/*
- *     Control message processing
- */
-
-
-/**
- *     gsm_control_reply       -       send a response frame to a control
- *     @gsm: gsm channel
- *     @cmd: the command to use
- *     @data: data to follow encoded info
- *     @dlen: length of data
- *
- *     Encode up and queue a UI/UIH frame containing our response.
- */
-
-static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data,
-                                       int dlen)
-{
-       struct gsm_msg *msg;
-       msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype);
-       msg->data[0] = (cmd & 0xFE) << 1 | EA;  /* Clear C/R */
-       msg->data[1] = (dlen << 1) | EA;
-       memcpy(msg->data + 2, data, dlen);
-       gsm_data_queue(gsm->dlci[0], msg);
-}
-
-/**
- *     gsm_process_modem       -       process received modem status
- *     @tty: virtual tty bound to the DLCI
- *     @dlci: DLCI to affect
- *     @modem: modem bits (full EA)
- *
- *     Used when a modem control message or line state inline in adaption
- *     layer 2 is processed. Sort out the local modem state and throttles
- */
-
-static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
-                                                       u32 modem)
-{
-       int  mlines = 0;
-       u8 brk = modem >> 6;
-
-       /* Flow control/ready to communicate */
-       if (modem & MDM_FC) {
-               /* Need to throttle our output on this device */
-               dlci->constipated = 1;
-       }
-       if (modem & MDM_RTC) {
-               mlines |= TIOCM_DSR | TIOCM_DTR;
-               dlci->constipated = 0;
-               gsm_dlci_data_kick(dlci);
-       }
-       /* Map modem bits */
-       if (modem & MDM_RTR)
-               mlines |= TIOCM_RTS | TIOCM_CTS;
-       if (modem & MDM_IC)
-               mlines |= TIOCM_RI;
-       if (modem & MDM_DV)
-               mlines |= TIOCM_CD;
-
-       /* Carrier drop -> hangup */
-       if (tty) {
-               if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD))
-                       if (!(tty->termios->c_cflag & CLOCAL))
-                               tty_hangup(tty);
-               if (brk & 0x01)
-                       tty_insert_flip_char(tty, 0, TTY_BREAK);
-       }
-       dlci->modem_rx = mlines;
-}
-
-/**
- *     gsm_control_modem       -       modem status received
- *     @gsm: GSM channel
- *     @data: data following command
- *     @clen: command length
- *
- *     We have received a modem status control message. This is used by
- *     the GSM mux protocol to pass virtual modem line status and optionally
- *     to indicate break signals. Unpack it, convert to Linux representation
- *     and if need be stuff a break message down the tty.
- */
-
-static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
-{
-       unsigned int addr = 0;
-       unsigned int modem = 0;
-       struct gsm_dlci *dlci;
-       int len = clen;
-       u8 *dp = data;
-       struct tty_struct *tty;
-
-       while (gsm_read_ea(&addr, *dp++) == 0) {
-               len--;
-               if (len == 0)
-                       return;
-       }
-       /* Must be at least one byte following the EA */
-       len--;
-       if (len <= 0)
-               return;
-
-       addr >>= 1;
-       /* Closed port, or invalid ? */
-       if (addr == 0 || addr >= NUM_DLCI || gsm->dlci[addr] == NULL)
-               return;
-       dlci = gsm->dlci[addr];
-
-       while (gsm_read_ea(&modem, *dp++) == 0) {
-               len--;
-               if (len == 0)
-                       return;
-       }
-       tty = tty_port_tty_get(&dlci->port);
-       gsm_process_modem(tty, dlci, modem);
-       if (tty) {
-               tty_wakeup(tty);
-               tty_kref_put(tty);
-       }
-       gsm_control_reply(gsm, CMD_MSC, data, clen);
-}
-
-/**
- *     gsm_control_rls         -       remote line status
- *     @gsm: GSM channel
- *     @data: data bytes
- *     @clen: data length
- *
- *     The modem sends us a two byte message on the control channel whenever
- *     it wishes to send us an error state from the virtual link. Stuff
- *     this into the uplink tty if present
- */
-
-static void gsm_control_rls(struct gsm_mux *gsm, u8 *data, int clen)
-{
-       struct tty_struct *tty;
-       unsigned int addr = 0 ;
-       u8 bits;
-       int len = clen;
-       u8 *dp = data;
-
-       while (gsm_read_ea(&addr, *dp++) == 0) {
-               len--;
-               if (len == 0)
-                       return;
-       }
-       /* Must be at least one byte following ea */
-       len--;
-       if (len <= 0)
-               return;
-       addr >>= 1;
-       /* Closed port, or invalid ? */
-       if (addr == 0 || addr >= NUM_DLCI || gsm->dlci[addr] == NULL)
-               return;
-       /* No error ? */
-       bits = *dp;
-       if ((bits & 1) == 0)
-               return;
-       /* See if we have an uplink tty */
-       tty = tty_port_tty_get(&gsm->dlci[addr]->port);
-
-       if (tty) {
-               if (bits & 2)
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               if (bits & 4)
-                       tty_insert_flip_char(tty, 0, TTY_PARITY);
-               if (bits & 8)
-                       tty_insert_flip_char(tty, 0, TTY_FRAME);
-               tty_flip_buffer_push(tty);
-               tty_kref_put(tty);
-       }
-       gsm_control_reply(gsm, CMD_RLS, data, clen);
-}
-
-static void gsm_dlci_begin_close(struct gsm_dlci *dlci);
-
-/**
- *     gsm_control_message     -       DLCI 0 control processing
- *     @gsm: our GSM mux
- *     @command:  the command EA
- *     @data: data beyond the command/length EAs
- *     @clen: length
- *
- *     Input processor for control messages from the other end of the link.
- *     Processes the incoming request and queues a response frame or an
- *     NSC response if not supported
- */
-
-static void gsm_control_message(struct gsm_mux *gsm, unsigned int command,
-                                                       u8 *data, int clen)
-{
-       u8 buf[1];
-       switch (command) {
-       case CMD_CLD: {
-               struct gsm_dlci *dlci = gsm->dlci[0];
-               /* Modem wishes to close down */
-               if (dlci) {
-                       dlci->dead = 1;
-                       gsm->dead = 1;
-                       gsm_dlci_begin_close(dlci);
-               }
-               }
-               break;
-       case CMD_TEST:
-               /* Modem wishes to test, reply with the data */
-               gsm_control_reply(gsm, CMD_TEST, data, clen);
-               break;
-       case CMD_FCON:
-               /* Modem wants us to STFU */
-               gsm->constipated = 1;
-               gsm_control_reply(gsm, CMD_FCON, NULL, 0);
-               break;
-       case CMD_FCOFF:
-               /* Modem can accept data again */
-               gsm->constipated = 0;
-               gsm_control_reply(gsm, CMD_FCOFF, NULL, 0);
-               /* Kick the link in case it is idling */
-               gsm_data_kick(gsm);
-               break;
-       case CMD_MSC:
-               /* Out of band modem line change indicator for a DLCI */
-               gsm_control_modem(gsm, data, clen);
-               break;
-       case CMD_RLS:
-               /* Out of band error reception for a DLCI */
-               gsm_control_rls(gsm, data, clen);
-               break;
-       case CMD_PSC:
-               /* Modem wishes to enter power saving state */
-               gsm_control_reply(gsm, CMD_PSC, NULL, 0);
-               break;
-               /* Optional unsupported commands */
-       case CMD_PN:    /* Parameter negotiation */
-       case CMD_RPN:   /* Remote port negotation */
-       case CMD_SNC:   /* Service negotation command */
-       default:
-               /* Reply to bad commands with an NSC */
-               buf[0] = command;
-               gsm_control_reply(gsm, CMD_NSC, buf, 1);
-               break;
-       }
-}
-
-/**
- *     gsm_control_response    -       process a response to our control
- *     @gsm: our GSM mux
- *     @command: the command (response) EA
- *     @data: data beyond the command/length EA
- *     @clen: length
- *
- *     Process a response to an outstanding command. We only allow a single
- *     control message in flight so this is fairly easy. All the clean up
- *     is done by the caller, we just update the fields, flag it as done
- *     and return
- */
-
-static void gsm_control_response(struct gsm_mux *gsm, unsigned int command,
-                                                       u8 *data, int clen)
-{
-       struct gsm_control *ctrl;
-       unsigned long flags;
-
-       spin_lock_irqsave(&gsm->control_lock, flags);
-
-       ctrl = gsm->pending_cmd;
-       /* Does the reply match our command */
-       command |= 1;
-       if (ctrl != NULL && (command == ctrl->cmd || command == CMD_NSC)) {
-               /* Our command was replied to, kill the retry timer */
-               del_timer(&gsm->t2_timer);
-               gsm->pending_cmd = NULL;
-               /* Rejected by the other end */
-               if (command == CMD_NSC)
-                       ctrl->error = -EOPNOTSUPP;
-               ctrl->done = 1;
-               wake_up(&gsm->event);
-       }
-       spin_unlock_irqrestore(&gsm->control_lock, flags);
-}
-
-/**
- *     gsm_control_transmit    -       send control packet
- *     @gsm: gsm mux
- *     @ctrl: frame to send
- *
- *     Send out a pending control command (called under control lock)
- */
-
-static void gsm_control_transmit(struct gsm_mux *gsm, struct gsm_control *ctrl)
-{
-       struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 1,
-                                                       gsm->ftype|PF);
-       if (msg == NULL)
-               return;
-       msg->data[0] = (ctrl->cmd << 1) | 2 | EA;       /* command */
-       memcpy(msg->data + 1, ctrl->data, ctrl->len);
-       gsm_data_queue(gsm->dlci[0], msg);
-}
-
-/**
- *     gsm_control_retransmit  -       retransmit a control frame
- *     @data: pointer to our gsm object
- *
- *     Called off the T2 timer expiry in order to retransmit control frames
- *     that have been lost in the system somewhere. The control_lock protects
- *     us from colliding with another sender or a receive completion event.
- *     In that situation the timer may still occur in a small window but
- *     gsm->pending_cmd will be NULL and we just let the timer expire.
- */
-
-static void gsm_control_retransmit(unsigned long data)
-{
-       struct gsm_mux *gsm = (struct gsm_mux *)data;
-       struct gsm_control *ctrl;
-       unsigned long flags;
-       spin_lock_irqsave(&gsm->control_lock, flags);
-       ctrl = gsm->pending_cmd;
-       if (ctrl) {
-               gsm->cretries--;
-               if (gsm->cretries == 0) {
-                       gsm->pending_cmd = NULL;
-                       ctrl->error = -ETIMEDOUT;
-                       ctrl->done = 1;
-                       spin_unlock_irqrestore(&gsm->control_lock, flags);
-                       wake_up(&gsm->event);
-                       return;
-               }
-               gsm_control_transmit(gsm, ctrl);
-               mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
-       }
-       spin_unlock_irqrestore(&gsm->control_lock, flags);
-}
-
-/**
- *     gsm_control_send        -       send a control frame on DLCI 0
- *     @gsm: the GSM channel
- *     @command: command  to send including CR bit
- *     @data: bytes of data (must be kmalloced)
- *     @len: length of the block to send
- *
- *     Queue and dispatch a control command. Only one command can be
- *     active at a time. In theory more can be outstanding but the matching
- *     gets really complicated so for now stick to one outstanding.
- */
-
-static struct gsm_control *gsm_control_send(struct gsm_mux *gsm,
-               unsigned int command, u8 *data, int clen)
-{
-       struct gsm_control *ctrl = kzalloc(sizeof(struct gsm_control),
-                                               GFP_KERNEL);
-       unsigned long flags;
-       if (ctrl == NULL)
-               return NULL;
-retry:
-       wait_event(gsm->event, gsm->pending_cmd == NULL);
-       spin_lock_irqsave(&gsm->control_lock, flags);
-       if (gsm->pending_cmd != NULL) {
-               spin_unlock_irqrestore(&gsm->control_lock, flags);
-               goto retry;
-       }
-       ctrl->cmd = command;
-       ctrl->data = data;
-       ctrl->len = clen;
-       gsm->pending_cmd = ctrl;
-       gsm->cretries = gsm->n2;
-       mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
-       gsm_control_transmit(gsm, ctrl);
-       spin_unlock_irqrestore(&gsm->control_lock, flags);
-       return ctrl;
-}
-
-/**
- *     gsm_control_wait        -       wait for a control to finish
- *     @gsm: GSM mux
- *     @control: control we are waiting on
- *
- *     Waits for the control to complete or time out. Frees any used
- *     resources and returns 0 for success, or an error if the remote
- *     rejected or ignored the request.
- */
-
-static int gsm_control_wait(struct gsm_mux *gsm, struct gsm_control *control)
-{
-       int err;
-       wait_event(gsm->event, control->done == 1);
-       err = control->error;
-       kfree(control);
-       return err;
-}
-
-
-/*
- *     DLCI level handling: Needs krefs
- */
-
-/*
- *     State transitions and timers
- */
-
-/**
- *     gsm_dlci_close          -       a DLCI has closed
- *     @dlci: DLCI that closed
- *
- *     Perform processing when moving a DLCI into closed state. If there
- *     is an attached tty this is hung up
- */
-
-static void gsm_dlci_close(struct gsm_dlci *dlci)
-{
-       del_timer(&dlci->t1);
-       if (debug & 8)
-               printk("DLCI %d goes closed.\n", dlci->addr);
-       dlci->state = DLCI_CLOSED;
-       if (dlci->addr != 0) {
-               struct tty_struct  *tty = tty_port_tty_get(&dlci->port);
-               if (tty) {
-                       tty_hangup(tty);
-                       tty_kref_put(tty);
-               }
-               kfifo_reset(dlci->fifo);
-       } else
-               dlci->gsm->dead = 1;
-       wake_up(&dlci->gsm->event);
-       /* A DLCI 0 close is a MUX termination so we need to kick that
-          back to userspace somehow */
-}
-
-/**
- *     gsm_dlci_open           -       a DLCI has opened
- *     @dlci: DLCI that opened
- *
- *     Perform processing when moving a DLCI into open state.
- */
-
-static void gsm_dlci_open(struct gsm_dlci *dlci)
-{
-       /* Note that SABM UA .. SABM UA first UA lost can mean that we go
-          open -> open */
-       del_timer(&dlci->t1);
-       /* This will let a tty open continue */
-       dlci->state = DLCI_OPEN;
-       if (debug & 8)
-               printk("DLCI %d goes open.\n", dlci->addr);
-       wake_up(&dlci->gsm->event);
-}
-
-/**
- *     gsm_dlci_t1             -       T1 timer expiry
- *     @dlci: DLCI that opened
- *
- *     The T1 timer handles retransmits of control frames (essentially of
- *     SABM and DISC). We resend the command until the retry count runs out
- *     in which case an opening port goes back to closed and a closing port
- *     is simply put into closed state (any further frames from the other
- *     end will get a DM response)
- */
-
-static void gsm_dlci_t1(unsigned long data)
-{
-       struct gsm_dlci *dlci = (struct gsm_dlci *)data;
-       struct gsm_mux *gsm = dlci->gsm;
-
-       switch (dlci->state) {
-       case DLCI_OPENING:
-               dlci->retries--;
-               if (dlci->retries) {
-                       gsm_command(dlci->gsm, dlci->addr, SABM|PF);
-                       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
-               } else
-                       gsm_dlci_close(dlci);
-               break;
-       case DLCI_CLOSING:
-               dlci->retries--;
-               if (dlci->retries) {
-                       gsm_command(dlci->gsm, dlci->addr, DISC|PF);
-                       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
-               } else
-                       gsm_dlci_close(dlci);
-               break;
-       }
-}
-
-/**
- *     gsm_dlci_begin_open     -       start channel open procedure
- *     @dlci: DLCI to open
- *
- *     Commence opening a DLCI from the Linux side. We issue SABM messages
- *     to the modem which should then reply with a UA, at which point we
- *     will move into open state. Opening is done asynchronously with retry
- *     running off timers and the responses.
- */
-
-static void gsm_dlci_begin_open(struct gsm_dlci *dlci)
-{
-       struct gsm_mux *gsm = dlci->gsm;
-       if (dlci->state == DLCI_OPEN || dlci->state == DLCI_OPENING)
-               return;
-       dlci->retries = gsm->n2;
-       dlci->state = DLCI_OPENING;
-       gsm_command(dlci->gsm, dlci->addr, SABM|PF);
-       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
-}
-
-/**
- *     gsm_dlci_begin_close    -       start channel open procedure
- *     @dlci: DLCI to open
- *
- *     Commence closing a DLCI from the Linux side. We issue DISC messages
- *     to the modem which should then reply with a UA, at which point we
- *     will move into closed state. Closing is done asynchronously with retry
- *     off timers. We may also receive a DM reply from the other end which
- *     indicates the channel was already closed.
- */
-
-static void gsm_dlci_begin_close(struct gsm_dlci *dlci)
-{
-       struct gsm_mux *gsm = dlci->gsm;
-       if (dlci->state == DLCI_CLOSED || dlci->state == DLCI_CLOSING)
-               return;
-       dlci->retries = gsm->n2;
-       dlci->state = DLCI_CLOSING;
-       gsm_command(dlci->gsm, dlci->addr, DISC|PF);
-       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
-}
-
-/**
- *     gsm_dlci_data           -       data arrived
- *     @dlci: channel
- *     @data: block of bytes received
- *     @len: length of received block
- *
- *     A UI or UIH frame has arrived which contains data for a channel
- *     other than the control channel. If the relevant virtual tty is
- *     open we shovel the bits down it, if not we drop them.
- */
-
-static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len)
-{
-       /* krefs .. */
-       struct tty_port *port = &dlci->port;
-       struct tty_struct *tty = tty_port_tty_get(port);
-       unsigned int modem = 0;
-
-       if (debug & 16)
-               printk("%d bytes for tty %p\n", len, tty);
-       if (tty) {
-               switch (dlci->adaption)  {
-                       /* Unsupported types */
-                       /* Packetised interruptible data */
-                       case 4:
-                               break;
-                       /* Packetised uininterruptible voice/data */
-                       case 3:
-                               break;
-                       /* Asynchronous serial with line state in each frame */
-                       case 2:
-                               while (gsm_read_ea(&modem, *data++) == 0) {
-                                       len--;
-                                       if (len == 0)
-                                               return;
-                               }
-                               gsm_process_modem(tty, dlci, modem);
-                       /* Line state will go via DLCI 0 controls only */
-                       case 1:
-                       default:
-                               tty_insert_flip_string(tty, data, len);
-                               tty_flip_buffer_push(tty);
-               }
-               tty_kref_put(tty);
-       }
-}
-
-/**
- *     gsm_dlci_control        -       data arrived on control channel
- *     @dlci: channel
- *     @data: block of bytes received
- *     @len: length of received block
- *
- *     A UI or UIH frame has arrived which contains data for DLCI 0 the
- *     control channel. This should contain a command EA followed by
- *     control data bytes. The command EA contains a command/response bit
- *     and we divide up the work accordingly.
- */
-
-static void gsm_dlci_command(struct gsm_dlci *dlci, u8 *data, int len)
-{
-       /* See what command is involved */
-       unsigned int command = 0;
-       while (len-- > 0) {
-               if (gsm_read_ea(&command, *data++) == 1) {
-                       int clen = *data++;
-                       len--;
-                       /* FIXME: this is properly an EA */
-                       clen >>= 1;
-                       /* Malformed command ? */
-                       if (clen > len)
-                               return;
-                       if (command & 1)
-                               gsm_control_message(dlci->gsm, command,
-                                                               data, clen);
-                       else
-                               gsm_control_response(dlci->gsm, command,
-                                                               data, clen);
-                       return;
-               }
-       }
-}
-
-/*
- *     Allocate/Free DLCI channels
- */
-
-/**
- *     gsm_dlci_alloc          -       allocate a DLCI
- *     @gsm: GSM mux
- *     @addr: address of the DLCI
- *
- *     Allocate and install a new DLCI object into the GSM mux.
- *
- *     FIXME: review locking races
- */
-
-static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
-{
-       struct gsm_dlci *dlci = kzalloc(sizeof(struct gsm_dlci), GFP_ATOMIC);
-       if (dlci == NULL)
-               return NULL;
-       spin_lock_init(&dlci->lock);
-       dlci->fifo = &dlci->_fifo;
-       if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) {
-               kfree(dlci);
-               return NULL;
-       }
-
-       skb_queue_head_init(&dlci->skb_list);
-       init_timer(&dlci->t1);
-       dlci->t1.function = gsm_dlci_t1;
-       dlci->t1.data = (unsigned long)dlci;
-       tty_port_init(&dlci->port);
-       dlci->port.ops = &gsm_port_ops;
-       dlci->gsm = gsm;
-       dlci->addr = addr;
-       dlci->adaption = gsm->adaption;
-       dlci->state = DLCI_CLOSED;
-       if (addr)
-               dlci->data = gsm_dlci_data;
-       else
-               dlci->data = gsm_dlci_command;
-       gsm->dlci[addr] = dlci;
-       return dlci;
-}
-
-/**
- *     gsm_dlci_free           -       release DLCI
- *     @dlci: DLCI to destroy
- *
- *     Free up a DLCI. Currently to keep the lifetime rules sane we only
- *     clean up DLCI objects when the MUX closes rather than as the port
- *     is closed down on both the tty and mux levels.
- *
- *     Can sleep.
- */
-static void gsm_dlci_free(struct gsm_dlci *dlci)
-{
-       struct tty_struct *tty = tty_port_tty_get(&dlci->port);
-       if (tty) {
-               tty_vhangup(tty);
-               tty_kref_put(tty);
-       }
-       del_timer_sync(&dlci->t1);
-       dlci->gsm->dlci[dlci->addr] = NULL;
-       kfifo_free(dlci->fifo);
-       kfree(dlci);
-}
-
-
-/*
- *     LAPBish link layer logic
- */
-
-/**
- *     gsm_queue               -       a GSM frame is ready to process
- *     @gsm: pointer to our gsm mux
- *
- *     At this point in time a frame has arrived and been demangled from
- *     the line encoding. All the differences between the encodings have
- *     been handled below us and the frame is unpacked into the structures.
- *     The fcs holds the header FCS but any data FCS must be added here.
- */
-
-static void gsm_queue(struct gsm_mux *gsm)
-{
-       struct gsm_dlci *dlci;
-       u8 cr;
-       int address;
-       /* We have to sneak a look at the packet body to do the FCS.
-          A somewhat layering violation in the spec */
-
-       if ((gsm->control & ~PF) == UI)
-               gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len);
-       if (gsm->fcs != GOOD_FCS) {
-               gsm->bad_fcs++;
-               if (debug & 4)
-                       printk("BAD FCS %02x\n", gsm->fcs);
-               return;
-       }
-       address = gsm->address >> 1;
-       if (address >= NUM_DLCI)
-               goto invalid;
-
-       cr = gsm->address & 1;          /* C/R bit */
-
-       gsm_print_packet("<--", address, cr, gsm->control, gsm->buf, gsm->len);
-
-       cr ^= 1 - gsm->initiator;       /* Flip so 1 always means command */
-       dlci = gsm->dlci[address];
-
-       switch (gsm->control) {
-       case SABM|PF:
-               if (cr == 0)
-                       goto invalid;
-               if (dlci == NULL)
-                       dlci = gsm_dlci_alloc(gsm, address);
-               if (dlci == NULL)
-                       return;
-               if (dlci->dead)
-                       gsm_response(gsm, address, DM);
-               else {
-                       gsm_response(gsm, address, UA);
-                       gsm_dlci_open(dlci);
-               }
-               break;
-       case DISC|PF:
-               if (cr == 0)
-                       goto invalid;
-               if (dlci == NULL || dlci->state == DLCI_CLOSED) {
-                       gsm_response(gsm, address, DM);
-                       return;
-               }
-               /* Real close complete */
-               gsm_response(gsm, address, UA);
-               gsm_dlci_close(dlci);
-               break;
-       case UA:
-       case UA|PF:
-               if (cr == 0 || dlci == NULL)
-                       break;
-               switch (dlci->state) {
-               case DLCI_CLOSING:
-                       gsm_dlci_close(dlci);
-                       break;
-               case DLCI_OPENING:
-                       gsm_dlci_open(dlci);
-                       break;
-               }
-               break;
-       case DM:        /* DM can be valid unsolicited */
-       case DM|PF:
-               if (cr)
-                       goto invalid;
-               if (dlci == NULL)
-                       return;
-               gsm_dlci_close(dlci);
-               break;
-       case UI:
-       case UI|PF:
-       case UIH:
-       case UIH|PF:
-#if 0
-               if (cr)
-                       goto invalid;
-#endif
-               if (dlci == NULL || dlci->state != DLCI_OPEN) {
-                       gsm_command(gsm, address, DM|PF);
-                       return;
-               }
-               dlci->data(dlci, gsm->buf, gsm->len);
-               break;
-       default:
-               goto invalid;
-       }
-       return;
-invalid:
-       gsm->malformed++;
-       return;
-}
-
-
-/**
- *     gsm0_receive    -       perform processing for non-transparency
- *     @gsm: gsm data for this ldisc instance
- *     @c: character
- *
- *     Receive bytes in gsm mode 0
- */
-
-static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
-{
-       switch (gsm->state) {
-       case GSM_SEARCH:        /* SOF marker */
-               if (c == GSM0_SOF) {
-                       gsm->state = GSM_ADDRESS;
-                       gsm->address = 0;
-                       gsm->len = 0;
-                       gsm->fcs = INIT_FCS;
-               }
-               break;          /* Address EA */
-       case GSM_ADDRESS:
-               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
-               if (gsm_read_ea(&gsm->address, c))
-                       gsm->state = GSM_CONTROL;
-               break;
-       case GSM_CONTROL:       /* Control Byte */
-               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
-               gsm->control = c;
-               gsm->state = GSM_LEN;
-               break;
-       case GSM_LEN:           /* Length EA */
-               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
-               if (gsm_read_ea(&gsm->len, c)) {
-                       if (gsm->len > gsm->mru) {
-                               gsm->bad_size++;
-                               gsm->state = GSM_SEARCH;
-                               break;
-                       }
-                       gsm->count = 0;
-                       gsm->state = GSM_DATA;
-               }
-               break;
-       case GSM_DATA:          /* Data */
-               gsm->buf[gsm->count++] = c;
-               if (gsm->count == gsm->len)
-                       gsm->state = GSM_FCS;
-               break;
-       case GSM_FCS:           /* FCS follows the packet */
-               gsm->fcs = c;
-               gsm_queue(gsm);
-               /* And then back for the next frame */
-               gsm->state = GSM_SEARCH;
-               break;
-       }
-}
-
-/**
- *     gsm0_receive    -       perform processing for non-transparency
- *     @gsm: gsm data for this ldisc instance
- *     @c: character
- *
- *     Receive bytes in mode 1 (Advanced option)
- */
-
-static void gsm1_receive(struct gsm_mux *gsm, unsigned char c)
-{
-       if (c == GSM1_SOF) {
-               /* EOF is only valid in frame if we have got to the data state
-                  and received at least one byte (the FCS) */
-               if (gsm->state == GSM_DATA && gsm->count) {
-                       /* Extract the FCS */
-                       gsm->count--;
-                       gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->buf[gsm->count]);
-                       gsm->len = gsm->count;
-                       gsm_queue(gsm);
-                       gsm->state  = GSM_START;
-                       return;
-               }
-               /* Any partial frame was a runt so go back to start */
-               if (gsm->state != GSM_START) {
-                       gsm->malformed++;
-                       gsm->state = GSM_START;
-               }
-               /* A SOF in GSM_START means we are still reading idling or
-                  framing bytes */
-               return;
-       }
-
-       if (c == GSM1_ESCAPE) {
-               gsm->escape = 1;
-               return;
-       }
-
-       /* Only an unescaped SOF gets us out of GSM search */
-       if (gsm->state == GSM_SEARCH)
-               return;
-
-       if (gsm->escape) {
-               c ^= GSM1_ESCAPE_BITS;
-               gsm->escape = 0;
-       }
-       switch (gsm->state) {
-       case GSM_START:         /* First byte after SOF */
-               gsm->address = 0;
-               gsm->state = GSM_ADDRESS;
-               gsm->fcs = INIT_FCS;
-               /* Drop through */
-       case GSM_ADDRESS:       /* Address continuation */
-               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
-               if (gsm_read_ea(&gsm->address, c))
-                       gsm->state = GSM_CONTROL;
-               break;
-       case GSM_CONTROL:       /* Control Byte */
-               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
-               gsm->control = c;
-               gsm->count = 0;
-               gsm->state = GSM_DATA;
-               break;
-       case GSM_DATA:          /* Data */
-               if (gsm->count > gsm->mru ) {   /* Allow one for the FCS */
-                       gsm->state = GSM_OVERRUN;
-                       gsm->bad_size++;
-               } else
-                       gsm->buf[gsm->count++] = c;
-               break;
-       case GSM_OVERRUN:       /* Over-long - eg a dropped SOF */
-               break;
-       }
-}
-
-/**
- *     gsm_error               -       handle tty error
- *     @gsm: ldisc data
- *     @data: byte received (may be invalid)
- *     @flag: error received
- *
- *     Handle an error in the receipt of data for a frame. Currently we just
- *     go back to hunting for a SOF.
- *
- *     FIXME: better diagnostics ?
- */
-
-static void gsm_error(struct gsm_mux *gsm,
-                               unsigned char data, unsigned char flag)
-{
-       gsm->state = GSM_SEARCH;
-       gsm->io_error++;
-}
-
-/**
- *     gsm_cleanup_mux         -       generic GSM protocol cleanup
- *     @gsm: our mux
- *
- *     Clean up the bits of the mux which are the same for all framing
- *     protocols. Remove the mux from the mux table, stop all the timers
- *     and then shut down each device hanging up the channels as we go.
- */
-
-void gsm_cleanup_mux(struct gsm_mux *gsm)
-{
-       int i;
-       struct gsm_dlci *dlci = gsm->dlci[0];
-       struct gsm_msg *txq;
-
-       gsm->dead = 1;
-
-       spin_lock(&gsm_mux_lock);
-       for (i = 0; i < MAX_MUX; i++) {
-               if (gsm_mux[i] == gsm) {
-                       gsm_mux[i] = NULL;
-                       break;
-               }
-       }
-       spin_unlock(&gsm_mux_lock);
-       WARN_ON(i == MAX_MUX);
-
-       del_timer_sync(&gsm->t2_timer);
-       /* Now we are sure T2 has stopped */
-       if (dlci) {
-               dlci->dead = 1;
-               gsm_dlci_begin_close(dlci);
-               wait_event_interruptible(gsm->event,
-                                       dlci->state == DLCI_CLOSED);
-       }
-       /* Free up any link layer users */
-       for (i = 0; i < NUM_DLCI; i++)
-               if (gsm->dlci[i])
-                       gsm_dlci_free(gsm->dlci[i]);
-       /* Now wipe the queues */
-       for (txq = gsm->tx_head; txq != NULL; txq = gsm->tx_head) {
-               gsm->tx_head = txq->next;
-               kfree(txq);
-       }
-       gsm->tx_tail = NULL;
-}
-EXPORT_SYMBOL_GPL(gsm_cleanup_mux);
-
-/**
- *     gsm_activate_mux        -       generic GSM setup
- *     @gsm: our mux
- *
- *     Set up the bits of the mux which are the same for all framing
- *     protocols. Add the mux to the mux table so it can be opened and
- *     finally kick off connecting to DLCI 0 on the modem.
- */
-
-int gsm_activate_mux(struct gsm_mux *gsm)
-{
-       struct gsm_dlci *dlci;
-       int i = 0;
-
-       init_timer(&gsm->t2_timer);
-       gsm->t2_timer.function = gsm_control_retransmit;
-       gsm->t2_timer.data = (unsigned long)gsm;
-       init_waitqueue_head(&gsm->event);
-       spin_lock_init(&gsm->control_lock);
-       spin_lock_init(&gsm->tx_lock);
-
-       if (gsm->encoding == 0)
-               gsm->receive = gsm0_receive;
-       else
-               gsm->receive = gsm1_receive;
-       gsm->error = gsm_error;
-
-       spin_lock(&gsm_mux_lock);
-       for (i = 0; i < MAX_MUX; i++) {
-               if (gsm_mux[i] == NULL) {
-                       gsm_mux[i] = gsm;
-                       break;
-               }
-       }
-       spin_unlock(&gsm_mux_lock);
-       if (i == MAX_MUX)
-               return -EBUSY;
-
-       dlci = gsm_dlci_alloc(gsm, 0);
-       if (dlci == NULL)
-               return -ENOMEM;
-       gsm->dead = 0;          /* Tty opens are now permissible */
-       return 0;
-}
-EXPORT_SYMBOL_GPL(gsm_activate_mux);
-
-/**
- *     gsm_free_mux            -       free up a mux
- *     @mux: mux to free
- *
- *     Dispose of allocated resources for a dead mux. No refcounting
- *     at present so the mux must be truely dead.
- */
-void gsm_free_mux(struct gsm_mux *gsm)
-{
-       kfree(gsm->txframe);
-       kfree(gsm->buf);
-       kfree(gsm);
-}
-EXPORT_SYMBOL_GPL(gsm_free_mux);
-
-/**
- *     gsm_alloc_mux           -       allocate a mux
- *
- *     Creates a new mux ready for activation.
- */
-
-struct gsm_mux *gsm_alloc_mux(void)
-{
-       struct gsm_mux *gsm = kzalloc(sizeof(struct gsm_mux), GFP_KERNEL);
-       if (gsm == NULL)
-               return NULL;
-       gsm->buf = kmalloc(MAX_MRU + 1, GFP_KERNEL);
-       if (gsm->buf == NULL) {
-               kfree(gsm);
-               return NULL;
-       }
-       gsm->txframe = kmalloc(2 * MAX_MRU + 2, GFP_KERNEL);
-       if (gsm->txframe == NULL) {
-               kfree(gsm->buf);
-               kfree(gsm);
-               return NULL;
-       }
-       spin_lock_init(&gsm->lock);
-
-       gsm->t1 = T1;
-       gsm->t2 = T2;
-       gsm->n2 = N2;
-       gsm->ftype = UIH;
-       gsm->initiator = 0;
-       gsm->adaption = 1;
-       gsm->encoding = 1;
-       gsm->mru = 64;  /* Default to encoding 1 so these should be 64 */
-       gsm->mtu = 64;
-       gsm->dead = 1;  /* Avoid early tty opens */
-
-       return gsm;
-}
-EXPORT_SYMBOL_GPL(gsm_alloc_mux);
-
-
-
-
-/**
- *     gsmld_output            -       write to link
- *     @gsm: our mux
- *     @data: bytes to output
- *     @len: size
- *
- *     Write a block of data from the GSM mux to the data channel. This
- *     will eventually be serialized from above but at the moment isn't.
- */
-
-static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len)
-{
-       if (tty_write_room(gsm->tty) < len) {
-               set_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
-               return -ENOSPC;
-       }
-       if (debug & 4) {
-               printk("-->%d bytes out\n", len);
-               hex_packet(data, len);
-       }
-       gsm->tty->ops->write(gsm->tty, data, len);
-       return len;
-}
-
-/**
- *     gsmld_attach_gsm        -       mode set up
- *     @tty: our tty structure
- *     @gsm: our mux
- *
- *     Set up the MUX for basic mode and commence connecting to the
- *     modem. Currently called from the line discipline set up but
- *     will need moving to an ioctl path.
- */
-
-static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
-{
-       int ret;
-
-       gsm->tty = tty_kref_get(tty);
-       gsm->output = gsmld_output;
-       ret =  gsm_activate_mux(gsm);
-       if (ret != 0)
-               tty_kref_put(gsm->tty);
-       return ret;
-}
-
-
-/**
- *     gsmld_detach_gsm        -       stop doing 0710 mux
- *     @tty: tty atttached to the mux
- *     @gsm: mux
- *
- *     Shutdown and then clean up the resources used by the line discipline
- */
-
-static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
-{
-       WARN_ON(tty != gsm->tty);
-       gsm_cleanup_mux(gsm);
-       tty_kref_put(gsm->tty);
-       gsm->tty = NULL;
-}
-
-static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
-                             char *fp, int count)
-{
-       struct gsm_mux *gsm = tty->disc_data;
-       const unsigned char *dp;
-       char *f;
-       int i;
-       char buf[64];
-       char flags;
-
-       if (debug & 4) {
-               printk("Inbytes %dd\n", count);
-               hex_packet(cp, count);
-       }
-
-       for (i = count, dp = cp, f = fp; i; i--, dp++) {
-               flags = *f++;
-               switch (flags) {
-               case TTY_NORMAL:
-                       gsm->receive(gsm, *dp);
-                       break;
-               case TTY_OVERRUN:
-               case TTY_BREAK:
-               case TTY_PARITY:
-               case TTY_FRAME:
-                       gsm->error(gsm, *dp, flags);
-                       break;
-               default:
-                       printk(KERN_ERR "%s: unknown flag %d\n",
-                              tty_name(tty, buf), flags);
-                       break;
-               }
-       }
-       /* FASYNC if needed ? */
-       /* If clogged call tty_throttle(tty); */
-}
-
-/**
- *     gsmld_chars_in_buffer   -       report available bytes
- *     @tty: tty device
- *
- *     Report the number of characters buffered to be delivered to user
- *     at this instant in time.
- *
- *     Locking: gsm lock
- */
-
-static ssize_t gsmld_chars_in_buffer(struct tty_struct *tty)
-{
-       return 0;
-}
-
-/**
- *     gsmld_flush_buffer      -       clean input queue
- *     @tty:   terminal device
- *
- *     Flush the input buffer. Called when the line discipline is
- *     being closed, when the tty layer wants the buffer flushed (eg
- *     at hangup).
- */
-
-static void gsmld_flush_buffer(struct tty_struct *tty)
-{
-}
-
-/**
- *     gsmld_close             -       close the ldisc for this tty
- *     @tty: device
- *
- *     Called from the terminal layer when this line discipline is
- *     being shut down, either because of a close or becsuse of a
- *     discipline change. The function will not be called while other
- *     ldisc methods are in progress.
- */
-
-static void gsmld_close(struct tty_struct *tty)
-{
-       struct gsm_mux *gsm = tty->disc_data;
-
-       gsmld_detach_gsm(tty, gsm);
-
-       gsmld_flush_buffer(tty);
-       /* Do other clean up here */
-       gsm_free_mux(gsm);
-}
-
-/**
- *     gsmld_open              -       open an ldisc
- *     @tty: terminal to open
- *
- *     Called when this line discipline is being attached to the
- *     terminal device. Can sleep. Called serialized so that no
- *     other events will occur in parallel. No further open will occur
- *     until a close.
- */
-
-static int gsmld_open(struct tty_struct *tty)
-{
-       struct gsm_mux *gsm;
-
-       if (tty->ops->write == NULL)
-               return -EINVAL;
-
-       /* Attach our ldisc data */
-       gsm = gsm_alloc_mux();
-       if (gsm == NULL)
-               return -ENOMEM;
-
-       tty->disc_data = gsm;
-       tty->receive_room = 65536;
-
-       /* Attach the initial passive connection */
-       gsm->encoding = 1;
-       return gsmld_attach_gsm(tty, gsm);
-}
-
-/**
- *     gsmld_write_wakeup      -       asynchronous I/O notifier
- *     @tty: tty device
- *
- *     Required for the ptys, serial driver etc. since processes
- *     that attach themselves to the master and rely on ASYNC
- *     IO must be woken up
- */
-
-static void gsmld_write_wakeup(struct tty_struct *tty)
-{
-       struct gsm_mux *gsm = tty->disc_data;
-       unsigned long flags;
-
-       /* Queue poll */
-       clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-       gsm_data_kick(gsm);
-       if (gsm->tx_bytes < TX_THRESH_LO) {
-               spin_lock_irqsave(&gsm->tx_lock, flags);
-               gsm_dlci_data_sweep(gsm);
-               spin_unlock_irqrestore(&gsm->tx_lock, flags);
-       }
-}
-
-/**
- *     gsmld_read              -       read function for tty
- *     @tty: tty device
- *     @file: file object
- *     @buf: userspace buffer pointer
- *     @nr: size of I/O
- *
- *     Perform reads for the line discipline. We are guaranteed that the
- *     line discipline will not be closed under us but we may get multiple
- *     parallel readers and must handle this ourselves. We may also get
- *     a hangup. Always called in user context, may sleep.
- *
- *     This code must be sure never to sleep through a hangup.
- */
-
-static ssize_t gsmld_read(struct tty_struct *tty, struct file *file,
-                        unsigned char __user *buf, size_t nr)
-{
-       return -EOPNOTSUPP;
-}
-
-/**
- *     gsmld_write             -       write function for tty
- *     @tty: tty device
- *     @file: file object
- *     @buf: userspace buffer pointer
- *     @nr: size of I/O
- *
- *     Called when the owner of the device wants to send a frame
- *     itself (or some other control data). The data is transferred
- *     as-is and must be properly framed and checksummed as appropriate
- *     by userspace. Frames are either sent whole or not at all as this
- *     avoids pain user side.
- */
-
-static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
-                          const unsigned char *buf, size_t nr)
-{
-       int space = tty_write_room(tty);
-       if (space >= nr)
-               return tty->ops->write(tty, buf, nr);
-       set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-       return -ENOBUFS;
-}
-
-/**
- *     gsmld_poll              -       poll method for N_GSM0710
- *     @tty: terminal device
- *     @file: file accessing it
- *     @wait: poll table
- *
- *     Called when the line discipline is asked to poll() for data or
- *     for special events. This code is not serialized with respect to
- *     other events save open/close.
- *
- *     This code must be sure never to sleep through a hangup.
- *     Called without the kernel lock held - fine
- */
-
-static unsigned int gsmld_poll(struct tty_struct *tty, struct file *file,
-                                                       poll_table *wait)
-{
-       unsigned int mask = 0;
-       struct gsm_mux *gsm = tty->disc_data;
-
-       poll_wait(file, &tty->read_wait, wait);
-       poll_wait(file, &tty->write_wait, wait);
-       if (tty_hung_up_p(file))
-               mask |= POLLHUP;
-       if (!tty_is_writelocked(tty) && tty_write_room(tty) > 0)
-               mask |= POLLOUT | POLLWRNORM;
-       if (gsm->dead)
-               mask |= POLLHUP;
-       return mask;
-}
-
-static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm,
-                                                       struct gsm_config *c)
-{
-       int need_close = 0;
-       int need_restart = 0;
-
-       /* Stuff we don't support yet - UI or I frame transport, windowing */
-       if ((c->adaption !=1 && c->adaption != 2) || c->k)
-               return -EOPNOTSUPP;
-       /* Check the MRU/MTU range looks sane */
-       if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8)
-               return -EINVAL;
-       if (c->n2 < 3)
-               return -EINVAL;
-       if (c->encapsulation > 1)       /* Basic, advanced, no I */
-               return -EINVAL;
-       if (c->initiator > 1)
-               return -EINVAL;
-       if (c->i == 0 || c->i > 2)      /* UIH and UI only */
-               return -EINVAL;
-       /*
-        *      See what is needed for reconfiguration
-        */
-
-       /* Timing fields */
-       if (c->t1 != 0 && c->t1 != gsm->t1)
-               need_restart = 1;
-       if (c->t2 != 0 && c->t2 != gsm->t2)
-               need_restart = 1;
-       if (c->encapsulation != gsm->encoding)
-               need_restart = 1;
-       if (c->adaption != gsm->adaption)
-               need_restart = 1;
-       /* Requires care */
-       if (c->initiator != gsm->initiator)
-               need_close = 1;
-       if (c->mru != gsm->mru)
-               need_restart = 1;
-       if (c->mtu != gsm->mtu)
-               need_restart = 1;
-
-       /*
-        *      Close down what is needed, restart and initiate the new
-        *      configuration
-        */
-
-       if (need_close || need_restart) {
-               gsm_dlci_begin_close(gsm->dlci[0]);
-               /* This will timeout if the link is down due to N2 expiring */
-               wait_event_interruptible(gsm->event,
-                               gsm->dlci[0]->state == DLCI_CLOSED);
-               if (signal_pending(current))
-                       return -EINTR;
-       }
-       if (need_restart)
-               gsm_cleanup_mux(gsm);
-
-       gsm->initiator = c->initiator;
-       gsm->mru = c->mru;
-       gsm->encoding = c->encapsulation;
-       gsm->adaption = c->adaption;
-
-       if (c->i == 1)
-               gsm->ftype = UIH;
-       else if (c->i == 2)
-               gsm->ftype = UI;
-
-       if (c->t1)
-               gsm->t1 = c->t1;
-       if (c->t2)
-               gsm->t2 = c->t2;
-
-       /* FIXME: We need to separate activation/deactivation from adding
-          and removing from the mux array */
-       if (need_restart)
-               gsm_activate_mux(gsm);
-       if (gsm->initiator && need_close)
-               gsm_dlci_begin_open(gsm->dlci[0]);
-       return 0;
-}
-
-static int gsmld_ioctl(struct tty_struct *tty, struct file *file,
-                      unsigned int cmd, unsigned long arg)
-{
-       struct gsm_config c;
-       struct gsm_mux *gsm = tty->disc_data;
-
-       switch (cmd) {
-       case GSMIOC_GETCONF:
-               memset(&c, 0, sizeof(c));
-               c.adaption = gsm->adaption;
-               c.encapsulation = gsm->encoding;
-               c.initiator = gsm->initiator;
-               c.t1 = gsm->t1;
-               c.t2 = gsm->t2;
-               c.t3 = 0;       /* Not supported */
-               c.n2 = gsm->n2;
-               if (gsm->ftype == UIH)
-                       c.i = 1;
-               else
-                       c.i = 2;
-               printk("Ftype %d i %d\n", gsm->ftype, c.i);
-               c.mru = gsm->mru;
-               c.mtu = gsm->mtu;
-               c.k = 0;
-               if (copy_to_user((void *)arg, &c, sizeof(c)))
-                       return -EFAULT;
-               return 0;
-       case GSMIOC_SETCONF:
-               if (copy_from_user(&c, (void *)arg, sizeof(c)))
-                       return -EFAULT;
-               return gsmld_config(tty, gsm, &c);
-       default:
-               return n_tty_ioctl_helper(tty, file, cmd, arg);
-       }
-}
-
-
-/* Line discipline for real tty */
-struct tty_ldisc_ops tty_ldisc_packet = {
-       .owner           = THIS_MODULE,
-       .magic           = TTY_LDISC_MAGIC,
-       .name            = "n_gsm",
-       .open            = gsmld_open,
-       .close           = gsmld_close,
-       .flush_buffer    = gsmld_flush_buffer,
-       .chars_in_buffer = gsmld_chars_in_buffer,
-       .read            = gsmld_read,
-       .write           = gsmld_write,
-       .ioctl           = gsmld_ioctl,
-       .poll            = gsmld_poll,
-       .receive_buf     = gsmld_receive_buf,
-       .write_wakeup    = gsmld_write_wakeup
-};
-
-/*
- *     Virtual tty side
- */
-
-#define TX_SIZE                512
-
-static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk)
-{
-       u8 modembits[5];
-       struct gsm_control *ctrl;
-       int len = 2;
-
-       if (brk)
-               len++;
-
-       modembits[0] = len << 1 | EA;           /* Data bytes */
-       modembits[1] = dlci->addr << 2 | 3;     /* DLCI, EA, 1 */
-       modembits[2] = gsm_encode_modem(dlci) << 1 | EA;
-       if (brk)
-               modembits[3] = brk << 4 | 2 | EA;       /* Valid, EA */
-       ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len + 1);
-       if (ctrl == NULL)
-               return -ENOMEM;
-       return gsm_control_wait(dlci->gsm, ctrl);
-}
-
-static int gsm_carrier_raised(struct tty_port *port)
-{
-       struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
-       /* Not yet open so no carrier info */
-       if (dlci->state != DLCI_OPEN)
-               return 0;
-       if (debug & 2)
-               return 1;
-       return dlci->modem_rx & TIOCM_CD;
-}
-
-static void gsm_dtr_rts(struct tty_port *port, int onoff)
-{
-       struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
-       unsigned int modem_tx = dlci->modem_tx;
-       if (onoff)
-               modem_tx |= TIOCM_DTR | TIOCM_RTS;
-       else
-               modem_tx &= ~(TIOCM_DTR | TIOCM_RTS);
-       if (modem_tx != dlci->modem_tx) {
-               dlci->modem_tx = modem_tx;
-               gsmtty_modem_update(dlci, 0);
-       }
-}
-
-static const struct tty_port_operations gsm_port_ops = {
-       .carrier_raised = gsm_carrier_raised,
-       .dtr_rts = gsm_dtr_rts,
-};
-
-
-static int gsmtty_open(struct tty_struct *tty, struct file *filp)
-{
-       struct gsm_mux *gsm;
-       struct gsm_dlci *dlci;
-       struct tty_port *port;
-       unsigned int line = tty->index;
-       unsigned int mux = line >> 6;
-
-       line = line & 0x3F;
-
-       if (mux >= MAX_MUX)
-               return -ENXIO;
-       /* FIXME: we need to lock gsm_mux for lifetimes of ttys eventually */
-       if (gsm_mux[mux] == NULL)
-               return -EUNATCH;
-       if (line == 0 || line > 61)     /* 62/63 reserved */
-               return -ECHRNG;
-       gsm = gsm_mux[mux];
-       if (gsm->dead)
-               return -EL2HLT;
-       dlci = gsm->dlci[line];
-       if (dlci == NULL)
-               dlci = gsm_dlci_alloc(gsm, line);
-       if (dlci == NULL)
-               return -ENOMEM;
-       port = &dlci->port;
-       port->count++;
-       tty->driver_data = dlci;
-       tty_port_tty_set(port, tty);
-
-       dlci->modem_rx = 0;
-       /* We could in theory open and close before we wait - eg if we get
-          a DM straight back. This is ok as that will have caused a hangup */
-       set_bit(ASYNCB_INITIALIZED, &port->flags);
-       /* Start sending off SABM messages */
-       gsm_dlci_begin_open(dlci);
-       /* And wait for virtual carrier */
-       return tty_port_block_til_ready(port, tty, filp);
-}
-
-static void gsmtty_close(struct tty_struct *tty, struct file *filp)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       if (dlci == NULL)
-               return;
-       if (tty_port_close_start(&dlci->port, tty, filp) == 0)
-               return;
-       gsm_dlci_begin_close(dlci);
-       tty_port_close_end(&dlci->port, tty);
-       tty_port_tty_set(&dlci->port, NULL);
-}
-
-static void gsmtty_hangup(struct tty_struct *tty)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       tty_port_hangup(&dlci->port);
-       gsm_dlci_begin_close(dlci);
-}
-
-static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf,
-                                                                   int len)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       /* Stuff the bytes into the fifo queue */
-       int sent = kfifo_in_locked(dlci->fifo, buf, len, &dlci->lock);
-       /* Need to kick the channel */
-       gsm_dlci_data_kick(dlci);
-       return sent;
-}
-
-static int gsmtty_write_room(struct tty_struct *tty)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       return TX_SIZE - kfifo_len(dlci->fifo);
-}
-
-static int gsmtty_chars_in_buffer(struct tty_struct *tty)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       return kfifo_len(dlci->fifo);
-}
-
-static void gsmtty_flush_buffer(struct tty_struct *tty)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       /* Caution needed: If we implement reliable transport classes
-          then the data being transmitted can't simply be junked once
-          it has first hit the stack. Until then we can just blow it
-          away */
-       kfifo_reset(dlci->fifo);
-       /* Need to unhook this DLCI from the transmit queue logic */
-}
-
-static void gsmtty_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-       /* The FIFO handles the queue so the kernel will do the right
-          thing waiting on chars_in_buffer before calling us. No work
-          to do here */
-}
-
-static int gsmtty_tiocmget(struct tty_struct *tty, struct file *filp)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       return dlci->modem_rx;
-}
-
-static int gsmtty_tiocmset(struct tty_struct *tty, struct file *filp,
-       unsigned int set, unsigned int clear)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       unsigned int modem_tx = dlci->modem_tx;
-
-       modem_tx &= clear;
-       modem_tx |= set;
-
-       if (modem_tx != dlci->modem_tx) {
-               dlci->modem_tx = modem_tx;
-               return gsmtty_modem_update(dlci, 0);
-       }
-       return 0;
-}
-
-
-static int gsmtty_ioctl(struct tty_struct *tty, struct file *filp,
-                       unsigned int cmd, unsigned long arg)
-{
-       return -ENOIOCTLCMD;
-}
-
-static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old)
-{
-       /* For the moment its fixed. In actual fact the speed information
-          for the virtual channel can be propogated in both directions by
-          the RPN control message. This however rapidly gets nasty as we
-          then have to remap modem signals each way according to whether
-          our virtual cable is null modem etc .. */
-       tty_termios_copy_hw(tty->termios, old);
-}
-
-static void gsmtty_throttle(struct tty_struct *tty)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       if (tty->termios->c_cflag & CRTSCTS)
-               dlci->modem_tx &= ~TIOCM_DTR;
-       dlci->throttled = 1;
-       /* Send an MSC with DTR cleared */
-       gsmtty_modem_update(dlci, 0);
-}
-
-static void gsmtty_unthrottle(struct tty_struct *tty)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       if (tty->termios->c_cflag & CRTSCTS)
-               dlci->modem_tx |= TIOCM_DTR;
-       dlci->throttled = 0;
-       /* Send an MSC with DTR set */
-       gsmtty_modem_update(dlci, 0);
-}
-
-static int gsmtty_break_ctl(struct tty_struct *tty, int state)
-{
-       struct gsm_dlci *dlci = tty->driver_data;
-       int encode = 0; /* Off */
-
-       if (state == -1)        /* "On indefinitely" - we can't encode this
-                                   properly */
-               encode = 0x0F;
-       else if (state > 0) {
-               encode = state / 200;   /* mS to encoding */
-               if (encode > 0x0F)
-                       encode = 0x0F;  /* Best effort */
-       }
-       return gsmtty_modem_update(dlci, encode);
-}
-
-static struct tty_driver *gsm_tty_driver;
-
-/* Virtual ttys for the demux */
-static const struct tty_operations gsmtty_ops = {
-       .open                   = gsmtty_open,
-       .close                  = gsmtty_close,
-       .write                  = gsmtty_write,
-       .write_room             = gsmtty_write_room,
-       .chars_in_buffer        = gsmtty_chars_in_buffer,
-       .flush_buffer           = gsmtty_flush_buffer,
-       .ioctl                  = gsmtty_ioctl,
-       .throttle               = gsmtty_throttle,
-       .unthrottle             = gsmtty_unthrottle,
-       .set_termios            = gsmtty_set_termios,
-       .hangup                 = gsmtty_hangup,
-       .wait_until_sent        = gsmtty_wait_until_sent,
-       .tiocmget               = gsmtty_tiocmget,
-       .tiocmset               = gsmtty_tiocmset,
-       .break_ctl              = gsmtty_break_ctl,
-};
-
-
-
-static int __init gsm_init(void)
-{
-       /* Fill in our line protocol discipline, and register it */
-       int status = tty_register_ldisc(N_GSM0710, &tty_ldisc_packet);
-       if (status != 0) {
-               printk(KERN_ERR "n_gsm: can't register line discipline (err = %d)\n", status);
-               return status;
-       }
-
-       gsm_tty_driver = alloc_tty_driver(256);
-       if (!gsm_tty_driver) {
-               tty_unregister_ldisc(N_GSM0710);
-               printk(KERN_ERR "gsm_init: tty allocation failed.\n");
-               return -EINVAL;
-       }
-       gsm_tty_driver->owner   = THIS_MODULE;
-       gsm_tty_driver->driver_name     = "gsmtty";
-       gsm_tty_driver->name            = "gsmtty";
-       gsm_tty_driver->major           = 0;    /* Dynamic */
-       gsm_tty_driver->minor_start     = 0;
-       gsm_tty_driver->type            = TTY_DRIVER_TYPE_SERIAL;
-       gsm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
-       gsm_tty_driver->flags   = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV
-                                                       | TTY_DRIVER_HARDWARE_BREAK;
-       gsm_tty_driver->init_termios    = tty_std_termios;
-       /* Fixme */
-       gsm_tty_driver->init_termios.c_lflag &= ~ECHO;
-       tty_set_operations(gsm_tty_driver, &gsmtty_ops);
-
-       spin_lock_init(&gsm_mux_lock);
-
-       if (tty_register_driver(gsm_tty_driver)) {
-               put_tty_driver(gsm_tty_driver);
-               tty_unregister_ldisc(N_GSM0710);
-               printk(KERN_ERR "gsm_init: tty registration failed.\n");
-               return -EBUSY;
-       }
-       printk(KERN_INFO "gsm_init: loaded as %d,%d.\n", gsm_tty_driver->major, gsm_tty_driver->minor_start);
-       return 0;
-}
-
-static void __exit gsm_exit(void)
-{
-       int status = tty_unregister_ldisc(N_GSM0710);
-       if (status != 0)
-               printk(KERN_ERR "n_gsm: can't unregister line discipline (err = %d)\n", status);
-       tty_unregister_driver(gsm_tty_driver);
-       put_tty_driver(gsm_tty_driver);
-       printk(KERN_INFO "gsm_init: unloaded.\n");
-}
-
-module_init(gsm_init);
-module_exit(gsm_exit);
-
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_LDISC(N_GSM0710);
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
deleted file mode 100644 (file)
index 47d3228..0000000
+++ /dev/null
@@ -1,1007 +0,0 @@
-/* generic HDLC line discipline for Linux
- *
- * Written by Paul Fulghum paulkf@microgate.com
- * for Microgate Corporation
- *
- * Microgate and SyncLink are registered trademarks of Microgate Corporation
- *
- * Adapted from ppp.c, written by Michael Callahan <callahan@maths.ox.ac.uk>,
- *     Al Longyear <longyear@netcom.com>,
- *     Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
- *
- * Original release 01/11/99
- *
- * This code is released under the GNU General Public License (GPL)
- *
- * This module implements the tty line discipline N_HDLC for use with
- * tty device drivers that support bit-synchronous HDLC communications.
- *
- * All HDLC data is frame oriented which means:
- *
- * 1. tty write calls represent one complete transmit frame of data
- *    The device driver should accept the complete frame or none of 
- *    the frame (busy) in the write method. Each write call should have
- *    a byte count in the range of 2-65535 bytes (2 is min HDLC frame
- *    with 1 addr byte and 1 ctrl byte). The max byte count of 65535
- *    should include any crc bytes required. For example, when using
- *    CCITT CRC32, 4 crc bytes are required, so the maximum size frame
- *    the application may transmit is limited to 65531 bytes. For CCITT
- *    CRC16, the maximum application frame size would be 65533.
- *
- *
- * 2. receive callbacks from the device driver represents
- *    one received frame. The device driver should bypass
- *    the tty flip buffer and call the line discipline receive
- *    callback directly to avoid fragmenting or concatenating
- *    multiple frames into a single receive callback.
- *
- *    The HDLC line discipline queues the receive frames in separate
- *    buffers so complete receive frames can be returned by the
- *    tty read calls.
- *
- * 3. tty read calls returns an entire frame of data or nothing.
- *    
- * 4. all send and receive data is considered raw. No processing
- *    or translation is performed by the line discipline, regardless
- *    of the tty flags
- *
- * 5. When line discipline is queried for the amount of receive
- *    data available (FIOC), 0 is returned if no data available,
- *    otherwise the count of the next available frame is returned.
- *    (instead of the sum of all received frame counts).
- *
- * These conventions allow the standard tty programming interface
- * to be used for synchronous HDLC applications when used with
- * this line discipline (or another line discipline that is frame
- * oriented such as N_PPP).
- *
- * The SyncLink driver (synclink.c) implements both asynchronous
- * (using standard line discipline N_TTY) and synchronous HDLC
- * (using N_HDLC) communications, with the latter using the above
- * conventions.
- *
- * This implementation is very basic and does not maintain
- * any statistics. The main point is to enforce the raw data
- * and frame orientation of HDLC communications.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define HDLC_MAGIC 0x239e
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-
-#undef VERSION
-#define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
-
-#include <linux/poll.h>
-#include <linux/in.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-#include <linux/tty.h>
-#include <linux/errno.h>
-#include <linux/smp_lock.h>
-#include <linux/string.h>      /* used in new tty drivers */
-#include <linux/signal.h>      /* used in new tty drivers */
-#include <linux/if.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/termios.h>
-#include <asm/uaccess.h>
-
-/*
- * Buffers for individual HDLC frames
- */
-#define MAX_HDLC_FRAME_SIZE 65535 
-#define DEFAULT_RX_BUF_COUNT 10
-#define MAX_RX_BUF_COUNT 60
-#define DEFAULT_TX_BUF_COUNT 3
-
-struct n_hdlc_buf {
-       struct n_hdlc_buf *link;
-       int               count;
-       char              buf[1];
-};
-
-#define        N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe)
-
-struct n_hdlc_buf_list {
-       struct n_hdlc_buf *head;
-       struct n_hdlc_buf *tail;
-       int               count;
-       spinlock_t        spinlock;
-};
-
-/**
- * struct n_hdlc - per device instance data structure
- * @magic - magic value for structure
- * @flags - miscellaneous control flags
- * @tty - ptr to TTY structure
- * @backup_tty - TTY to use if tty gets closed
- * @tbusy - reentrancy flag for tx wakeup code
- * @woke_up - FIXME: describe this field
- * @tbuf - currently transmitting tx buffer
- * @tx_buf_list - list of pending transmit frame buffers
- * @rx_buf_list - list of received frame buffers
- * @tx_free_buf_list - list unused transmit frame buffers
- * @rx_free_buf_list - list unused received frame buffers
- */
-struct n_hdlc {
-       int                     magic;
-       __u32                   flags;
-       struct tty_struct       *tty;
-       struct tty_struct       *backup_tty;
-       int                     tbusy;
-       int                     woke_up;
-       struct n_hdlc_buf       *tbuf;
-       struct n_hdlc_buf_list  tx_buf_list;
-       struct n_hdlc_buf_list  rx_buf_list;
-       struct n_hdlc_buf_list  tx_free_buf_list;
-       struct n_hdlc_buf_list  rx_free_buf_list;
-};
-
-/*
- * HDLC buffer list manipulation functions
- */
-static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list);
-static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
-                          struct n_hdlc_buf *buf);
-static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list);
-
-/* Local functions */
-
-static struct n_hdlc *n_hdlc_alloc (void);
-
-/* debug level can be set by insmod for debugging purposes */
-#define DEBUG_LEVEL_INFO       1
-static int debuglevel;
-
-/* max frame size for memory allocations */
-static int maxframe = 4096;
-
-/* TTY callbacks */
-
-static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
-                          __u8 __user *buf, size_t nr);
-static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
-                           const unsigned char *buf, size_t nr);
-static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
-                           unsigned int cmd, unsigned long arg);
-static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
-                                   poll_table *wait);
-static int n_hdlc_tty_open(struct tty_struct *tty);
-static void n_hdlc_tty_close(struct tty_struct *tty);
-static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
-                              char *fp, int count);
-static void n_hdlc_tty_wakeup(struct tty_struct *tty);
-
-#define bset(p,b)      ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
-
-#define tty2n_hdlc(tty)        ((struct n_hdlc *) ((tty)->disc_data))
-#define n_hdlc2tty(n_hdlc)     ((n_hdlc)->tty)
-
-static void flush_rx_queue(struct tty_struct *tty)
-{
-       struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
-       struct n_hdlc_buf *buf;
-
-       while ((buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list)))
-               n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, buf);
-}
-
-static void flush_tx_queue(struct tty_struct *tty)
-{
-       struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
-       struct n_hdlc_buf *buf;
-       unsigned long flags;
-
-       while ((buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list)))
-               n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, buf);
-       spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
-       if (n_hdlc->tbuf) {
-               n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, n_hdlc->tbuf);
-               n_hdlc->tbuf = NULL;
-       }
-       spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
-}
-
-static struct tty_ldisc_ops n_hdlc_ldisc = {
-       .owner          = THIS_MODULE,
-       .magic          = TTY_LDISC_MAGIC,
-       .name           = "hdlc",
-       .open           = n_hdlc_tty_open,
-       .close          = n_hdlc_tty_close,
-       .read           = n_hdlc_tty_read,
-       .write          = n_hdlc_tty_write,
-       .ioctl          = n_hdlc_tty_ioctl,
-       .poll           = n_hdlc_tty_poll,
-       .receive_buf    = n_hdlc_tty_receive,
-       .write_wakeup   = n_hdlc_tty_wakeup,
-       .flush_buffer   = flush_rx_queue,
-};
-
-/**
- * n_hdlc_release - release an n_hdlc per device line discipline info structure
- * @n_hdlc - per device line discipline info structure
- */
-static void n_hdlc_release(struct n_hdlc *n_hdlc)
-{
-       struct tty_struct *tty = n_hdlc2tty (n_hdlc);
-       struct n_hdlc_buf *buf;
-       
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_release() called\n",__FILE__,__LINE__);
-               
-       /* Ensure that the n_hdlcd process is not hanging on select()/poll() */
-       wake_up_interruptible (&tty->read_wait);
-       wake_up_interruptible (&tty->write_wait);
-
-       if (tty->disc_data == n_hdlc)
-               tty->disc_data = NULL;  /* Break the tty->n_hdlc link */
-
-       /* Release transmit and receive buffers */
-       for(;;) {
-               buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
-               if (buf) {
-                       kfree(buf);
-               } else
-                       break;
-       }
-       for(;;) {
-               buf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
-               if (buf) {
-                       kfree(buf);
-               } else
-                       break;
-       }
-       for(;;) {
-               buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
-               if (buf) {
-                       kfree(buf);
-               } else
-                       break;
-       }
-       for(;;) {
-               buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
-               if (buf) {
-                       kfree(buf);
-               } else
-                       break;
-       }
-       kfree(n_hdlc->tbuf);
-       kfree(n_hdlc);
-       
-}      /* end of n_hdlc_release() */
-
-/**
- * n_hdlc_tty_close - line discipline close
- * @tty - pointer to tty info structure
- *
- * Called when the line discipline is changed to something
- * else, the tty is closed, or the tty detects a hangup.
- */
-static void n_hdlc_tty_close(struct tty_struct *tty)
-{
-       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
-
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_close() called\n",__FILE__,__LINE__);
-               
-       if (n_hdlc != NULL) {
-               if (n_hdlc->magic != HDLC_MAGIC) {
-                       printk (KERN_WARNING"n_hdlc: trying to close unopened tty!\n");
-                       return;
-               }
-#if defined(TTY_NO_WRITE_SPLIT)
-               clear_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
-#endif
-               tty->disc_data = NULL;
-               if (tty == n_hdlc->backup_tty)
-                       n_hdlc->backup_tty = NULL;
-               if (tty != n_hdlc->tty)
-                       return;
-               if (n_hdlc->backup_tty) {
-                       n_hdlc->tty = n_hdlc->backup_tty;
-               } else {
-                       n_hdlc_release (n_hdlc);
-               }
-       }
-       
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_close() success\n",__FILE__,__LINE__);
-               
-}      /* end of n_hdlc_tty_close() */
-
-/**
- * n_hdlc_tty_open - called when line discipline changed to n_hdlc
- * @tty - pointer to tty info structure
- *
- * Returns 0 if success, otherwise error code
- */
-static int n_hdlc_tty_open (struct tty_struct *tty)
-{
-       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
-
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_open() called (device=%s)\n",
-               __FILE__,__LINE__,
-               tty->name);
-               
-       /* There should not be an existing table for this slot. */
-       if (n_hdlc) {
-               printk (KERN_ERR"n_hdlc_tty_open:tty already associated!\n" );
-               return -EEXIST;
-       }
-       
-       n_hdlc = n_hdlc_alloc();
-       if (!n_hdlc) {
-               printk (KERN_ERR "n_hdlc_alloc failed\n");
-               return -ENFILE;
-       }
-               
-       tty->disc_data = n_hdlc;
-       n_hdlc->tty    = tty;
-       tty->receive_room = 65536;
-       
-#if defined(TTY_NO_WRITE_SPLIT)
-       /* change tty_io write() to not split large writes into 8K chunks */
-       set_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
-#endif
-       
-       /* flush receive data from driver */
-       tty_driver_flush_buffer(tty);
-               
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__);
-               
-       return 0;
-       
-}      /* end of n_tty_hdlc_open() */
-
-/**
- * n_hdlc_send_frames - send frames on pending send buffer list
- * @n_hdlc - pointer to ldisc instance data
- * @tty - pointer to tty instance data
- *
- * Send frames on pending send buffer list until the driver does not accept a
- * frame (busy) this function is called after adding a frame to the send buffer
- * list and by the tty wakeup callback.
- */
-static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
-{
-       register int actual;
-       unsigned long flags;
-       struct n_hdlc_buf *tbuf;
-
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__,__LINE__);
- check_again:
-               
-       spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
-       if (n_hdlc->tbusy) {
-               n_hdlc->woke_up = 1;
-               spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
-               return;
-       }
-       n_hdlc->tbusy = 1;
-       n_hdlc->woke_up = 0;
-       spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
-
-       /* get current transmit buffer or get new transmit */
-       /* buffer from list of pending transmit buffers */
-               
-       tbuf = n_hdlc->tbuf;
-       if (!tbuf)
-               tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
-               
-       while (tbuf) {
-               if (debuglevel >= DEBUG_LEVEL_INFO)     
-                       printk("%s(%d)sending frame %p, count=%d\n",
-                               __FILE__,__LINE__,tbuf,tbuf->count);
-                       
-               /* Send the next block of data to device */
-               tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
-               actual = tty->ops->write(tty, tbuf->buf, tbuf->count);
-
-               /* rollback was possible and has been done */
-               if (actual == -ERESTARTSYS) {
-                       n_hdlc->tbuf = tbuf;
-                       break;
-               }
-               /* if transmit error, throw frame away by */
-               /* pretending it was accepted by driver */
-               if (actual < 0)
-                       actual = tbuf->count;
-               
-               if (actual == tbuf->count) {
-                       if (debuglevel >= DEBUG_LEVEL_INFO)     
-                               printk("%s(%d)frame %p completed\n",
-                                       __FILE__,__LINE__,tbuf);
-                                       
-                       /* free current transmit buffer */
-                       n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf);
-                       
-                       /* this tx buffer is done */
-                       n_hdlc->tbuf = NULL;
-                       
-                       /* wait up sleeping writers */
-                       wake_up_interruptible(&tty->write_wait);
-       
-                       /* get next pending transmit buffer */
-                       tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
-               } else {
-                       if (debuglevel >= DEBUG_LEVEL_INFO)     
-                               printk("%s(%d)frame %p pending\n",
-                                       __FILE__,__LINE__,tbuf);
-                                       
-                       /* buffer not accepted by driver */
-                       /* set this buffer as pending buffer */
-                       n_hdlc->tbuf = tbuf;
-                       break;
-               }
-       }
-       
-       if (!tbuf)
-               tty->flags  &= ~(1 << TTY_DO_WRITE_WAKEUP);
-       
-       /* Clear the re-entry flag */
-       spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
-       n_hdlc->tbusy = 0;
-       spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); 
-       
-        if (n_hdlc->woke_up)
-         goto check_again;
-
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_send_frames() exit\n",__FILE__,__LINE__);
-               
-}      /* end of n_hdlc_send_frames() */
-
-/**
- * n_hdlc_tty_wakeup - Callback for transmit wakeup
- * @tty        - pointer to associated tty instance data
- *
- * Called when low level device driver can accept more send data.
- */
-static void n_hdlc_tty_wakeup(struct tty_struct *tty)
-{
-       struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
-
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_wakeup() called\n",__FILE__,__LINE__);
-               
-       if (!n_hdlc)
-               return;
-
-       if (tty != n_hdlc->tty) {
-               tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
-               return;
-       }
-
-       n_hdlc_send_frames (n_hdlc, tty);
-               
-}      /* end of n_hdlc_tty_wakeup() */
-
-/**
- * n_hdlc_tty_receive - Called by tty driver when receive data is available
- * @tty        - pointer to tty instance data
- * @data - pointer to received data
- * @flags - pointer to flags for data
- * @count - count of received data in bytes
- *
- * Called by tty low level driver when receive data is available. Data is
- * interpreted as one HDLC frame.
- */
-static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
-                              char *flags, int count)
-{
-       register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
-       register struct n_hdlc_buf *buf;
-
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_receive() called count=%d\n",
-                       __FILE__,__LINE__, count);
-               
-       /* This can happen if stuff comes in on the backup tty */
-       if (!n_hdlc || tty != n_hdlc->tty)
-               return;
-               
-       /* verify line is using HDLC discipline */
-       if (n_hdlc->magic != HDLC_MAGIC) {
-               printk("%s(%d) line not using HDLC discipline\n",
-                       __FILE__,__LINE__);
-               return;
-       }
-       
-       if ( count>maxframe ) {
-               if (debuglevel >= DEBUG_LEVEL_INFO)     
-                       printk("%s(%d) rx count>maxframesize, data discarded\n",
-                              __FILE__,__LINE__);
-               return;
-       }
-
-       /* get a free HDLC buffer */    
-       buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
-       if (!buf) {
-               /* no buffers in free list, attempt to allocate another rx buffer */
-               /* unless the maximum count has been reached */
-               if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
-                       buf = kmalloc(N_HDLC_BUF_SIZE, GFP_ATOMIC);
-       }
-       
-       if (!buf) {
-               if (debuglevel >= DEBUG_LEVEL_INFO)     
-                       printk("%s(%d) no more rx buffers, data discarded\n",
-                              __FILE__,__LINE__);
-               return;
-       }
-               
-       /* copy received data to HDLC buffer */
-       memcpy(buf->buf,data,count);
-       buf->count=count;
-
-       /* add HDLC buffer to list of received frames */
-       n_hdlc_buf_put(&n_hdlc->rx_buf_list, buf);
-       
-       /* wake up any blocked reads and perform async signalling */
-       wake_up_interruptible (&tty->read_wait);
-       if (n_hdlc->tty->fasync != NULL)
-               kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
-
-}      /* end of n_hdlc_tty_receive() */
-
-/**
- * n_hdlc_tty_read - Called to retrieve one frame of data (if available)
- * @tty - pointer to tty instance data
- * @file - pointer to open file object
- * @buf - pointer to returned data buffer
- * @nr - size of returned data buffer
- *     
- * Returns the number of bytes returned or error code.
- */
-static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
-                          __u8 __user *buf, size_t nr)
-{
-       struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
-       int ret;
-       struct n_hdlc_buf *rbuf;
-
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__);
-               
-       /* Validate the pointers */
-       if (!n_hdlc)
-               return -EIO;
-
-       /* verify user access to buffer */
-       if (!access_ok(VERIFY_WRITE, buf, nr)) {
-               printk(KERN_WARNING "%s(%d) n_hdlc_tty_read() can't verify user "
-               "buffer\n", __FILE__, __LINE__);
-               return -EFAULT;
-       }
-
-       tty_lock();
-
-       for (;;) {
-               if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
-                       tty_unlock();
-                       return -EIO;
-               }
-
-               n_hdlc = tty2n_hdlc (tty);
-               if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
-                        tty != n_hdlc->tty) {
-                       tty_unlock();
-                       return 0;
-               }
-
-               rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
-               if (rbuf)
-                       break;
-                       
-               /* no data */
-               if (file->f_flags & O_NONBLOCK) {
-                       tty_unlock();
-                       return -EAGAIN;
-               }
-                       
-               interruptible_sleep_on (&tty->read_wait);
-               if (signal_pending(current)) {
-                       tty_unlock();
-                       return -EINTR;
-               }
-       }
-               
-       if (rbuf->count > nr)
-               /* frame too large for caller's buffer (discard frame) */
-               ret = -EOVERFLOW;
-       else {
-               /* Copy the data to the caller's buffer */
-               if (copy_to_user(buf, rbuf->buf, rbuf->count))
-                       ret = -EFAULT;
-               else
-                       ret = rbuf->count;
-       }
-       
-       /* return HDLC buffer to free list unless the free list */
-       /* count has exceeded the default value, in which case the */
-       /* buffer is freed back to the OS to conserve memory */
-       if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT)
-               kfree(rbuf);
-       else    
-               n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf);
-       tty_unlock();
-       return ret;
-       
-}      /* end of n_hdlc_tty_read() */
-
-/**
- * n_hdlc_tty_write - write a single frame of data to device
- * @tty        - pointer to associated tty device instance data
- * @file - pointer to file object data
- * @data - pointer to transmit data (one frame)
- * @count - size of transmit frame in bytes
- *             
- * Returns the number of bytes written (or error code).
- */
-static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
-                           const unsigned char *data, size_t count)
-{
-       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
-       int error = 0;
-       DECLARE_WAITQUEUE(wait, current);
-       struct n_hdlc_buf *tbuf;
-
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_write() called count=%Zd\n",
-                       __FILE__,__LINE__,count);
-               
-       /* Verify pointers */
-       if (!n_hdlc)
-               return -EIO;
-
-       if (n_hdlc->magic != HDLC_MAGIC)
-               return -EIO;
-
-       /* verify frame size */
-       if (count > maxframe ) {
-               if (debuglevel & DEBUG_LEVEL_INFO)
-                       printk (KERN_WARNING
-                               "n_hdlc_tty_write: truncating user packet "
-                               "from %lu to %d\n", (unsigned long) count,
-                               maxframe );
-               count = maxframe;
-       }
-       
-       tty_lock();
-
-       add_wait_queue(&tty->write_wait, &wait);
-       set_current_state(TASK_INTERRUPTIBLE);
-       
-       /* Allocate transmit buffer */
-       /* sleep until transmit buffer available */             
-       while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
-               if (file->f_flags & O_NONBLOCK) {
-                       error = -EAGAIN;
-                       break;
-               }
-               schedule();
-                       
-               n_hdlc = tty2n_hdlc (tty);
-               if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || 
-                   tty != n_hdlc->tty) {
-                       printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc);
-                       error = -EIO;
-                       break;
-               }
-                       
-               if (signal_pending(current)) {
-                       error = -EINTR;
-                       break;
-               }
-       }
-
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&tty->write_wait, &wait);
-
-       if (!error) {           
-               /* Retrieve the user's buffer */
-               memcpy(tbuf->buf, data, count);
-
-               /* Send the data */
-               tbuf->count = error = count;
-               n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
-               n_hdlc_send_frames(n_hdlc,tty);
-       }
-       tty_unlock();
-       return error;
-       
-}      /* end of n_hdlc_tty_write() */
-
-/**
- * n_hdlc_tty_ioctl - process IOCTL system call for the tty device.
- * @tty - pointer to tty instance data
- * @file - pointer to open file object for device
- * @cmd - IOCTL command code
- * @arg - argument for IOCTL call (cmd dependent)
- *
- * Returns command dependent result.
- */
-static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
-                           unsigned int cmd, unsigned long arg)
-{
-       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
-       int error = 0;
-       int count;
-       unsigned long flags;
-       
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
-                       __FILE__,__LINE__,cmd);
-               
-       /* Verify the status of the device */
-       if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC)
-               return -EBADF;
-
-       switch (cmd) {
-       case FIONREAD:
-               /* report count of read data available */
-               /* in next available frame (if any) */
-               spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
-               if (n_hdlc->rx_buf_list.head)
-                       count = n_hdlc->rx_buf_list.head->count;
-               else
-                       count = 0;
-               spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
-               error = put_user(count, (int __user *)arg);
-               break;
-
-       case TIOCOUTQ:
-               /* get the pending tx byte count in the driver */
-               count = tty_chars_in_buffer(tty);
-               /* add size of next output frame in queue */
-               spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
-               if (n_hdlc->tx_buf_list.head)
-                       count += n_hdlc->tx_buf_list.head->count;
-               spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
-               error = put_user(count, (int __user *)arg);
-               break;
-
-       case TCFLSH:
-               switch (arg) {
-               case TCIOFLUSH:
-               case TCOFLUSH:
-                       flush_tx_queue(tty);
-               }
-               /* fall through to default */
-
-       default:
-               error = n_tty_ioctl_helper(tty, file, cmd, arg);
-               break;
-       }
-       return error;
-       
-}      /* end of n_hdlc_tty_ioctl() */
-
-/**
- * n_hdlc_tty_poll - TTY callback for poll system call
- * @tty - pointer to tty instance data
- * @filp - pointer to open file object for device
- * @poll_table - wait queue for operations
- * 
- * Determine which operations (read/write) will not block and return info
- * to caller.
- * Returns a bit mask containing info on which ops will not block.
- */
-static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
-                                   poll_table *wait)
-{
-       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
-       unsigned int mask = 0;
-
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_poll() called\n",__FILE__,__LINE__);
-               
-       if (n_hdlc && n_hdlc->magic == HDLC_MAGIC && tty == n_hdlc->tty) {
-               /* queue current process into any wait queue that */
-               /* may awaken in the future (read and write) */
-
-               poll_wait(filp, &tty->read_wait, wait);
-               poll_wait(filp, &tty->write_wait, wait);
-
-               /* set bits for operations that won't block */
-               if (n_hdlc->rx_buf_list.head)
-                       mask |= POLLIN | POLLRDNORM;    /* readable */
-               if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
-                       mask |= POLLHUP;
-               if (tty_hung_up_p(filp))
-                       mask |= POLLHUP;
-               if (!tty_is_writelocked(tty) &&
-                               n_hdlc->tx_free_buf_list.head)
-                       mask |= POLLOUT | POLLWRNORM;   /* writable */
-       }
-       return mask;
-}      /* end of n_hdlc_tty_poll() */
-
-/**
- * n_hdlc_alloc - allocate an n_hdlc instance data structure
- *
- * Returns a pointer to newly created structure if success, otherwise %NULL
- */
-static struct n_hdlc *n_hdlc_alloc(void)
-{
-       struct n_hdlc_buf *buf;
-       int i;
-       struct n_hdlc *n_hdlc = kmalloc(sizeof(*n_hdlc), GFP_KERNEL);
-
-       if (!n_hdlc)
-               return NULL;
-
-       memset(n_hdlc, 0, sizeof(*n_hdlc));
-
-       n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list);
-       n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list);
-       n_hdlc_buf_list_init(&n_hdlc->rx_buf_list);
-       n_hdlc_buf_list_init(&n_hdlc->tx_buf_list);
-       
-       /* allocate free rx buffer list */
-       for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
-               buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
-               if (buf)
-                       n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
-               else if (debuglevel >= DEBUG_LEVEL_INFO)        
-                       printk("%s(%d)n_hdlc_alloc(), kalloc() failed for rx buffer %d\n",__FILE__,__LINE__, i);
-       }
-       
-       /* allocate free tx buffer list */
-       for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
-               buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
-               if (buf)
-                       n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
-               else if (debuglevel >= DEBUG_LEVEL_INFO)        
-                       printk("%s(%d)n_hdlc_alloc(), kalloc() failed for tx buffer %d\n",__FILE__,__LINE__, i);
-       }
-       
-       /* Initialize the control block */
-       n_hdlc->magic  = HDLC_MAGIC;
-       n_hdlc->flags  = 0;
-       
-       return n_hdlc;
-       
-}      /* end of n_hdlc_alloc() */
-
-/**
- * n_hdlc_buf_list_init - initialize specified HDLC buffer list
- * @list - pointer to buffer list
- */
-static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list)
-{
-       memset(list, 0, sizeof(*list));
-       spin_lock_init(&list->spinlock);
-}      /* end of n_hdlc_buf_list_init() */
-
-/**
- * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
- * @list - pointer to buffer list
- * @buf        - pointer to buffer
- */
-static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
-                          struct n_hdlc_buf *buf)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&list->spinlock,flags);
-       
-       buf->link=NULL;
-       if (list->tail)
-               list->tail->link = buf;
-       else
-               list->head = buf;
-       list->tail = buf;
-       (list->count)++;
-       
-       spin_unlock_irqrestore(&list->spinlock,flags);
-       
-}      /* end of n_hdlc_buf_put() */
-
-/**
- * n_hdlc_buf_get - remove and return an HDLC buffer from list
- * @list - pointer to HDLC buffer list
- * 
- * Remove and return an HDLC buffer from the head of the specified HDLC buffer
- * list.
- * Returns a pointer to HDLC buffer if available, otherwise %NULL.
- */
-static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list)
-{
-       unsigned long flags;
-       struct n_hdlc_buf *buf;
-       spin_lock_irqsave(&list->spinlock,flags);
-       
-       buf = list->head;
-       if (buf) {
-               list->head = buf->link;
-               (list->count)--;
-       }
-       if (!list->head)
-               list->tail = NULL;
-       
-       spin_unlock_irqrestore(&list->spinlock,flags);
-       return buf;
-       
-}      /* end of n_hdlc_buf_get() */
-
-static char hdlc_banner[] __initdata =
-       KERN_INFO "HDLC line discipline maxframe=%u\n";
-static char hdlc_register_ok[] __initdata =
-       KERN_INFO "N_HDLC line discipline registered.\n";
-static char hdlc_register_fail[] __initdata =
-       KERN_ERR "error registering line discipline: %d\n";
-static char hdlc_init_fail[] __initdata =
-       KERN_INFO "N_HDLC: init failure %d\n";
-
-static int __init n_hdlc_init(void)
-{
-       int status;
-
-       /* range check maxframe arg */
-       if (maxframe < 4096)
-               maxframe = 4096;
-       else if (maxframe > 65535)
-               maxframe = 65535;
-
-       printk(hdlc_banner, maxframe);
-
-       status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc);
-       if (!status)
-               printk(hdlc_register_ok);
-       else
-               printk(hdlc_register_fail, status);
-
-       if (status)
-               printk(hdlc_init_fail, status);
-       return status;
-       
-}      /* end of init_module() */
-
-static char hdlc_unregister_ok[] __exitdata =
-       KERN_INFO "N_HDLC: line discipline unregistered\n";
-static char hdlc_unregister_fail[] __exitdata =
-       KERN_ERR "N_HDLC: can't unregister line discipline (err = %d)\n";
-
-static void __exit n_hdlc_exit(void)
-{
-       /* Release tty registration of line discipline */
-       int status = tty_unregister_ldisc(N_HDLC);
-
-       if (status)
-               printk(hdlc_unregister_fail, status);
-       else
-               printk(hdlc_unregister_ok);
-}
-
-module_init(n_hdlc_init);
-module_exit(n_hdlc_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Paul Fulghum paulkf@microgate.com");
-module_param(debuglevel, int, 0);
-module_param(maxframe, int, 0);
-MODULE_ALIAS_LDISC(N_HDLC);
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
deleted file mode 100644 (file)
index 88dda0c..0000000
+++ /dev/null
@@ -1,1264 +0,0 @@
-/* r3964 linediscipline for linux
- *
- * -----------------------------------------------------------
- * Copyright by 
- * Philips Automation Projects
- * Kassel (Germany)
- * -----------------------------------------------------------
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- *
- * Author:
- * L. Haag
- *
- * $Log: n_r3964.c,v $
- * Revision 1.10  2001/03/18 13:02:24  dwmw2
- * Fix timer usage, use spinlocks properly.
- *
- * Revision 1.9  2001/03/18 12:52:14  dwmw2
- * Merge changes in 2.4.2
- *
- * Revision 1.8  2000/03/23 14:14:54  dwmw2
- * Fix race in sleeping in r3964_read()
- *
- * Revision 1.7  1999/28/08 11:41:50  dwmw2
- * Port to 2.3 kernel
- *
- * Revision 1.6  1998/09/30 00:40:40  dwmw2
- * Fixed compilation on 2.0.x kernels
- * Updated to newly registered tty-ldisc number 9
- *
- * Revision 1.5  1998/09/04 21:57:36  dwmw2
- * Signal handling bug fixes, port to 2.1.x.
- *
- * Revision 1.4  1998/04/02 20:26:59  lhaag
- * select, blocking, ...
- *
- * Revision 1.3  1998/02/12 18:58:43  root
- * fixed some memory leaks
- * calculation of checksum characters
- *
- * Revision 1.2  1998/02/07 13:03:34  root
- * ioctl read_telegram
- *
- * Revision 1.1  1998/02/06 19:21:03  root
- * Initial revision
- *
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/tty.h>
-#include <linux/errno.h>
-#include <linux/string.h>      /* used in new tty drivers */
-#include <linux/signal.h>      /* used in new tty drivers */
-#include <linux/ioctl.h>
-#include <linux/n_r3964.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-
-/*#define DEBUG_QUEUE*/
-
-/* Log successful handshake and protocol operations  */
-/*#define DEBUG_PROTO_S*/
-
-/* Log handshake and protocol errors: */
-/*#define DEBUG_PROTO_E*/
-
-/* Log Linediscipline operations (open, close, read, write...): */
-/*#define DEBUG_LDISC*/
-
-/* Log module and memory operations (init, cleanup; kmalloc, kfree): */
-/*#define DEBUG_MODUL*/
-
-/* Macro helpers for debug output: */
-#define TRACE(format, args...) printk("r3964: " format "\n" , ## args)
-
-#ifdef DEBUG_MODUL
-#define TRACE_M(format, args...) printk("r3964: " format "\n" , ## args)
-#else
-#define TRACE_M(fmt, arg...) do {} while (0)
-#endif
-#ifdef DEBUG_PROTO_S
-#define TRACE_PS(format, args...) printk("r3964: " format "\n" , ## args)
-#else
-#define TRACE_PS(fmt, arg...) do {} while (0)
-#endif
-#ifdef DEBUG_PROTO_E
-#define TRACE_PE(format, args...) printk("r3964: " format "\n" , ## args)
-#else
-#define TRACE_PE(fmt, arg...) do {} while (0)
-#endif
-#ifdef DEBUG_LDISC
-#define TRACE_L(format, args...) printk("r3964: " format "\n" , ## args)
-#else
-#define TRACE_L(fmt, arg...) do {} while (0)
-#endif
-#ifdef DEBUG_QUEUE
-#define TRACE_Q(format, args...) printk("r3964: " format "\n" , ## args)
-#else
-#define TRACE_Q(fmt, arg...) do {} while (0)
-#endif
-static void add_tx_queue(struct r3964_info *, struct r3964_block_header *);
-static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code);
-static void put_char(struct r3964_info *pInfo, unsigned char ch);
-static void trigger_transmit(struct r3964_info *pInfo);
-static void retry_transmit(struct r3964_info *pInfo);
-static void transmit_block(struct r3964_info *pInfo);
-static void receive_char(struct r3964_info *pInfo, const unsigned char c);
-static void receive_error(struct r3964_info *pInfo, const char flag);
-static void on_timeout(unsigned long priv);
-static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg);
-static int read_telegram(struct r3964_info *pInfo, struct pid *pid,
-               unsigned char __user * buf);
-static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
-               int error_code, struct r3964_block_header *pBlock);
-static struct r3964_message *remove_msg(struct r3964_info *pInfo,
-               struct r3964_client_info *pClient);
-static void remove_client_block(struct r3964_info *pInfo,
-               struct r3964_client_info *pClient);
-
-static int r3964_open(struct tty_struct *tty);
-static void r3964_close(struct tty_struct *tty);
-static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
-               unsigned char __user * buf, size_t nr);
-static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
-               const unsigned char *buf, size_t nr);
-static int r3964_ioctl(struct tty_struct *tty, struct file *file,
-               unsigned int cmd, unsigned long arg);
-static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old);
-static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
-               struct poll_table_struct *wait);
-static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
-               char *fp, int count);
-
-static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
-       .owner = THIS_MODULE,
-       .magic = TTY_LDISC_MAGIC,
-       .name = "R3964",
-       .open = r3964_open,
-       .close = r3964_close,
-       .read = r3964_read,
-       .write = r3964_write,
-       .ioctl = r3964_ioctl,
-       .set_termios = r3964_set_termios,
-       .poll = r3964_poll,
-       .receive_buf = r3964_receive_buf,
-};
-
-static void dump_block(const unsigned char *block, unsigned int length)
-{
-       unsigned int i, j;
-       char linebuf[16 * 3 + 1];
-
-       for (i = 0; i < length; i += 16) {
-               for (j = 0; (j < 16) && (j + i < length); j++) {
-                       sprintf(linebuf + 3 * j, "%02x ", block[i + j]);
-               }
-               linebuf[3 * j] = '\0';
-               TRACE_PS("%s", linebuf);
-       }
-}
-
-/*************************************************************
- * Driver initialisation
- *************************************************************/
-
-/*************************************************************
- * Module support routines
- *************************************************************/
-
-static void __exit r3964_exit(void)
-{
-       int status;
-
-       TRACE_M("cleanup_module()");
-
-       status = tty_unregister_ldisc(N_R3964);
-
-       if (status != 0) {
-               printk(KERN_ERR "r3964: error unregistering linediscipline: "
-                               "%d\n", status);
-       } else {
-               TRACE_L("linediscipline successfully unregistered");
-       }
-}
-
-static int __init r3964_init(void)
-{
-       int status;
-
-       printk("r3964: Philips r3964 Driver $Revision: 1.10 $\n");
-
-       /*
-        * Register the tty line discipline
-        */
-
-       status = tty_register_ldisc(N_R3964, &tty_ldisc_N_R3964);
-       if (status == 0) {
-               TRACE_L("line discipline %d registered", N_R3964);
-               TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags,
-                       tty_ldisc_N_R3964.num);
-               TRACE_L("open=%p", tty_ldisc_N_R3964.open);
-               TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964);
-       } else {
-               printk(KERN_ERR "r3964: error registering line discipline: "
-                               "%d\n", status);
-       }
-       return status;
-}
-
-module_init(r3964_init);
-module_exit(r3964_exit);
-
-/*************************************************************
- * Protocol implementation routines
- *************************************************************/
-
-static void add_tx_queue(struct r3964_info *pInfo,
-                        struct r3964_block_header *pHeader)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&pInfo->lock, flags);
-
-       pHeader->next = NULL;
-
-       if (pInfo->tx_last == NULL) {
-               pInfo->tx_first = pInfo->tx_last = pHeader;
-       } else {
-               pInfo->tx_last->next = pHeader;
-               pInfo->tx_last = pHeader;
-       }
-
-       spin_unlock_irqrestore(&pInfo->lock, flags);
-
-       TRACE_Q("add_tx_queue %p, length %d, tx_first = %p",
-               pHeader, pHeader->length, pInfo->tx_first);
-}
-
-static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
-{
-       struct r3964_block_header *pHeader;
-       unsigned long flags;
-#ifdef DEBUG_QUEUE
-       struct r3964_block_header *pDump;
-#endif
-
-       pHeader = pInfo->tx_first;
-
-       if (pHeader == NULL)
-               return;
-
-#ifdef DEBUG_QUEUE
-       printk("r3964: remove_from_tx_queue: %p, length %u - ",
-               pHeader, pHeader->length);
-       for (pDump = pHeader; pDump; pDump = pDump->next)
-               printk("%p ", pDump);
-       printk("\n");
-#endif
-
-       if (pHeader->owner) {
-               if (error_code) {
-                       add_msg(pHeader->owner, R3964_MSG_ACK, 0,
-                               error_code, NULL);
-               } else {
-                       add_msg(pHeader->owner, R3964_MSG_ACK, pHeader->length,
-                               error_code, NULL);
-               }
-               wake_up_interruptible(&pInfo->read_wait);
-       }
-
-       spin_lock_irqsave(&pInfo->lock, flags);
-
-       pInfo->tx_first = pHeader->next;
-       if (pInfo->tx_first == NULL) {
-               pInfo->tx_last = NULL;
-       }
-
-       spin_unlock_irqrestore(&pInfo->lock, flags);
-
-       kfree(pHeader);
-       TRACE_M("remove_from_tx_queue - kfree %p", pHeader);
-
-       TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p",
-               pInfo->tx_first, pInfo->tx_last);
-}
-
-static void add_rx_queue(struct r3964_info *pInfo,
-                        struct r3964_block_header *pHeader)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&pInfo->lock, flags);
-
-       pHeader->next = NULL;
-
-       if (pInfo->rx_last == NULL) {
-               pInfo->rx_first = pInfo->rx_last = pHeader;
-       } else {
-               pInfo->rx_last->next = pHeader;
-               pInfo->rx_last = pHeader;
-       }
-       pInfo->blocks_in_rx_queue++;
-
-       spin_unlock_irqrestore(&pInfo->lock, flags);
-
-       TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d",
-               pHeader, pHeader->length,
-               pInfo->rx_first, pInfo->blocks_in_rx_queue);
-}
-
-static void remove_from_rx_queue(struct r3964_info *pInfo,
-                                struct r3964_block_header *pHeader)
-{
-       unsigned long flags;
-       struct r3964_block_header *pFind;
-
-       if (pHeader == NULL)
-               return;
-
-       TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
-               pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue);
-       TRACE_Q("remove_from_rx_queue: %p, length %u",
-               pHeader, pHeader->length);
-
-       spin_lock_irqsave(&pInfo->lock, flags);
-
-       if (pInfo->rx_first == pHeader) {
-               /* Remove the first block in the linked list: */
-               pInfo->rx_first = pHeader->next;
-
-               if (pInfo->rx_first == NULL) {
-                       pInfo->rx_last = NULL;
-               }
-               pInfo->blocks_in_rx_queue--;
-       } else {
-               /* Find block to remove: */
-               for (pFind = pInfo->rx_first; pFind; pFind = pFind->next) {
-                       if (pFind->next == pHeader) {
-                               /* Got it. */
-                               pFind->next = pHeader->next;
-                               pInfo->blocks_in_rx_queue--;
-                               if (pFind->next == NULL) {
-                                       /* Oh, removed the last one! */
-                                       pInfo->rx_last = pFind;
-                               }
-                               break;
-                       }
-               }
-       }
-
-       spin_unlock_irqrestore(&pInfo->lock, flags);
-
-       kfree(pHeader);
-       TRACE_M("remove_from_rx_queue - kfree %p", pHeader);
-
-       TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
-               pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue);
-}
-
-static void put_char(struct r3964_info *pInfo, unsigned char ch)
-{
-       struct tty_struct *tty = pInfo->tty;
-       /* FIXME: put_char should not be called from an IRQ */
-       tty_put_char(tty, ch);
-       pInfo->bcc ^= ch;
-}
-
-static void flush(struct r3964_info *pInfo)
-{
-       struct tty_struct *tty = pInfo->tty;
-
-       if (tty == NULL || tty->ops->flush_chars == NULL)
-               return;
-       tty->ops->flush_chars(tty);
-}
-
-static void trigger_transmit(struct r3964_info *pInfo)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&pInfo->lock, flags);
-
-       if ((pInfo->state == R3964_IDLE) && (pInfo->tx_first != NULL)) {
-               pInfo->state = R3964_TX_REQUEST;
-               pInfo->nRetry = 0;
-               pInfo->flags &= ~R3964_ERROR;
-               mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
-
-               spin_unlock_irqrestore(&pInfo->lock, flags);
-
-               TRACE_PS("trigger_transmit - sent STX");
-
-               put_char(pInfo, STX);
-               flush(pInfo);
-
-               pInfo->bcc = 0;
-       } else {
-               spin_unlock_irqrestore(&pInfo->lock, flags);
-       }
-}
-
-static void retry_transmit(struct r3964_info *pInfo)
-{
-       if (pInfo->nRetry < R3964_MAX_RETRIES) {
-               TRACE_PE("transmission failed. Retry #%d", pInfo->nRetry);
-               pInfo->bcc = 0;
-               put_char(pInfo, STX);
-               flush(pInfo);
-               pInfo->state = R3964_TX_REQUEST;
-               pInfo->nRetry++;
-               mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
-       } else {
-               TRACE_PE("transmission failed after %d retries",
-                        R3964_MAX_RETRIES);
-
-               remove_from_tx_queue(pInfo, R3964_TX_FAIL);
-
-               put_char(pInfo, NAK);
-               flush(pInfo);
-               pInfo->state = R3964_IDLE;
-
-               trigger_transmit(pInfo);
-       }
-}
-
-static void transmit_block(struct r3964_info *pInfo)
-{
-       struct tty_struct *tty = pInfo->tty;
-       struct r3964_block_header *pBlock = pInfo->tx_first;
-       int room = 0;
-
-       if (tty == NULL || pBlock == NULL) {
-               return;
-       }
-
-       room = tty_write_room(tty);
-
-       TRACE_PS("transmit_block %p, room %d, length %d",
-                pBlock, room, pBlock->length);
-
-       while (pInfo->tx_position < pBlock->length) {
-               if (room < 2)
-                       break;
-
-               if (pBlock->data[pInfo->tx_position] == DLE) {
-                       /* send additional DLE char: */
-                       put_char(pInfo, DLE);
-               }
-               put_char(pInfo, pBlock->data[pInfo->tx_position++]);
-
-               room--;
-       }
-
-       if ((pInfo->tx_position == pBlock->length) && (room >= 3)) {
-               put_char(pInfo, DLE);
-               put_char(pInfo, ETX);
-               if (pInfo->flags & R3964_BCC) {
-                       put_char(pInfo, pInfo->bcc);
-               }
-               pInfo->state = R3964_WAIT_FOR_TX_ACK;
-               mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
-       }
-       flush(pInfo);
-}
-
-static void on_receive_block(struct r3964_info *pInfo)
-{
-       unsigned int length;
-       struct r3964_client_info *pClient;
-       struct r3964_block_header *pBlock;
-
-       length = pInfo->rx_position;
-
-       /* compare byte checksum characters: */
-       if (pInfo->flags & R3964_BCC) {
-               if (pInfo->bcc != pInfo->last_rx) {
-                       TRACE_PE("checksum error - got %x but expected %x",
-                                pInfo->last_rx, pInfo->bcc);
-                       pInfo->flags |= R3964_CHECKSUM;
-               }
-       }
-
-       /* check for errors (parity, overrun,...): */
-       if (pInfo->flags & R3964_ERROR) {
-               TRACE_PE("on_receive_block - transmission failed error %x",
-                        pInfo->flags & R3964_ERROR);
-
-               put_char(pInfo, NAK);
-               flush(pInfo);
-               if (pInfo->nRetry < R3964_MAX_RETRIES) {
-                       pInfo->state = R3964_WAIT_FOR_RX_REPEAT;
-                       pInfo->nRetry++;
-                       mod_timer(&pInfo->tmr, jiffies + R3964_TO_RX_PANIC);
-               } else {
-                       TRACE_PE("on_receive_block - failed after max retries");
-                       pInfo->state = R3964_IDLE;
-               }
-               return;
-       }
-
-       /* received block; submit DLE: */
-       put_char(pInfo, DLE);
-       flush(pInfo);
-       del_timer_sync(&pInfo->tmr);
-       TRACE_PS(" rx success: got %d chars", length);
-
-       /* prepare struct r3964_block_header: */
-       pBlock = kmalloc(length + sizeof(struct r3964_block_header),
-                       GFP_KERNEL);
-       TRACE_M("on_receive_block - kmalloc %p", pBlock);
-
-       if (pBlock == NULL)
-               return;
-
-       pBlock->length = length;
-       pBlock->data = ((unsigned char *)pBlock) +
-                       sizeof(struct r3964_block_header);
-       pBlock->locks = 0;
-       pBlock->next = NULL;
-       pBlock->owner = NULL;
-
-       memcpy(pBlock->data, pInfo->rx_buf, length);
-
-       /* queue block into rx_queue: */
-       add_rx_queue(pInfo, pBlock);
-
-       /* notify attached client processes: */
-       for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) {
-               if (pClient->sig_flags & R3964_SIG_DATA) {
-                       add_msg(pClient, R3964_MSG_DATA, length, R3964_OK,
-                               pBlock);
-               }
-       }
-       wake_up_interruptible(&pInfo->read_wait);
-
-       pInfo->state = R3964_IDLE;
-
-       trigger_transmit(pInfo);
-}
-
-static void receive_char(struct r3964_info *pInfo, const unsigned char c)
-{
-       switch (pInfo->state) {
-       case R3964_TX_REQUEST:
-               if (c == DLE) {
-                       TRACE_PS("TX_REQUEST - got DLE");
-
-                       pInfo->state = R3964_TRANSMITTING;
-                       pInfo->tx_position = 0;
-
-                       transmit_block(pInfo);
-               } else if (c == STX) {
-                       if (pInfo->nRetry == 0) {
-                               TRACE_PE("TX_REQUEST - init conflict");
-                               if (pInfo->priority == R3964_SLAVE) {
-                                       goto start_receiving;
-                               }
-                       } else {
-                               TRACE_PE("TX_REQUEST - secondary init "
-                                       "conflict!? Switching to SLAVE mode "
-                                       "for next rx.");
-                               goto start_receiving;
-                       }
-               } else {
-                       TRACE_PE("TX_REQUEST - char != DLE: %x", c);
-                       retry_transmit(pInfo);
-               }
-               break;
-       case R3964_TRANSMITTING:
-               if (c == NAK) {
-                       TRACE_PE("TRANSMITTING - got NAK");
-                       retry_transmit(pInfo);
-               } else {
-                       TRACE_PE("TRANSMITTING - got invalid char");
-
-                       pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY;
-                       mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
-               }
-               break;
-       case R3964_WAIT_FOR_TX_ACK:
-               if (c == DLE) {
-                       TRACE_PS("WAIT_FOR_TX_ACK - got DLE");
-                       remove_from_tx_queue(pInfo, R3964_OK);
-
-                       pInfo->state = R3964_IDLE;
-                       trigger_transmit(pInfo);
-               } else {
-                       retry_transmit(pInfo);
-               }
-               break;
-       case R3964_WAIT_FOR_RX_REPEAT:
-               /* FALLTHROUGH */
-       case R3964_IDLE:
-               if (c == STX) {
-                       /* Prevent rx_queue from overflow: */
-                       if (pInfo->blocks_in_rx_queue >=
-                           R3964_MAX_BLOCKS_IN_RX_QUEUE) {
-                               TRACE_PE("IDLE - got STX but no space in "
-                                               "rx_queue!");
-                               pInfo->state = R3964_WAIT_FOR_RX_BUF;
-                               mod_timer(&pInfo->tmr,
-                                         jiffies + R3964_TO_NO_BUF);
-                               break;
-                       }
-start_receiving:
-                       /* Ok, start receiving: */
-                       TRACE_PS("IDLE - got STX");
-                       pInfo->rx_position = 0;
-                       pInfo->last_rx = 0;
-                       pInfo->flags &= ~R3964_ERROR;
-                       pInfo->state = R3964_RECEIVING;
-                       mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
-                       pInfo->nRetry = 0;
-                       put_char(pInfo, DLE);
-                       flush(pInfo);
-                       pInfo->bcc = 0;
-               }
-               break;
-       case R3964_RECEIVING:
-               if (pInfo->rx_position < RX_BUF_SIZE) {
-                       pInfo->bcc ^= c;
-
-                       if (c == DLE) {
-                               if (pInfo->last_rx == DLE) {
-                                       pInfo->last_rx = 0;
-                                       goto char_to_buf;
-                               }
-                               pInfo->last_rx = DLE;
-                               break;
-                       } else if ((c == ETX) && (pInfo->last_rx == DLE)) {
-                               if (pInfo->flags & R3964_BCC) {
-                                       pInfo->state = R3964_WAIT_FOR_BCC;
-                                       mod_timer(&pInfo->tmr,
-                                                 jiffies + R3964_TO_ZVZ);
-                               } else {
-                                       on_receive_block(pInfo);
-                               }
-                       } else {
-                               pInfo->last_rx = c;
-char_to_buf:
-                               pInfo->rx_buf[pInfo->rx_position++] = c;
-                               mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
-                       }
-               }
-               /* else: overflow-msg? BUF_SIZE>MTU; should not happen? */
-               break;
-       case R3964_WAIT_FOR_BCC:
-               pInfo->last_rx = c;
-               on_receive_block(pInfo);
-               break;
-       }
-}
-
-static void receive_error(struct r3964_info *pInfo, const char flag)
-{
-       switch (flag) {
-       case TTY_NORMAL:
-               break;
-       case TTY_BREAK:
-               TRACE_PE("received break");
-               pInfo->flags |= R3964_BREAK;
-               break;
-       case TTY_PARITY:
-               TRACE_PE("parity error");
-               pInfo->flags |= R3964_PARITY;
-               break;
-       case TTY_FRAME:
-               TRACE_PE("frame error");
-               pInfo->flags |= R3964_FRAME;
-               break;
-       case TTY_OVERRUN:
-               TRACE_PE("frame overrun");
-               pInfo->flags |= R3964_OVERRUN;
-               break;
-       default:
-               TRACE_PE("receive_error - unknown flag %d", flag);
-               pInfo->flags |= R3964_UNKNOWN;
-               break;
-       }
-}
-
-static void on_timeout(unsigned long priv)
-{
-       struct r3964_info *pInfo = (void *)priv;
-
-       switch (pInfo->state) {
-       case R3964_TX_REQUEST:
-               TRACE_PE("TX_REQUEST - timeout");
-               retry_transmit(pInfo);
-               break;
-       case R3964_WAIT_ZVZ_BEFORE_TX_RETRY:
-               put_char(pInfo, NAK);
-               flush(pInfo);
-               retry_transmit(pInfo);
-               break;
-       case R3964_WAIT_FOR_TX_ACK:
-               TRACE_PE("WAIT_FOR_TX_ACK - timeout");
-               retry_transmit(pInfo);
-               break;
-       case R3964_WAIT_FOR_RX_BUF:
-               TRACE_PE("WAIT_FOR_RX_BUF - timeout");
-               put_char(pInfo, NAK);
-               flush(pInfo);
-               pInfo->state = R3964_IDLE;
-               break;
-       case R3964_RECEIVING:
-               TRACE_PE("RECEIVING - timeout after %d chars",
-                        pInfo->rx_position);
-               put_char(pInfo, NAK);
-               flush(pInfo);
-               pInfo->state = R3964_IDLE;
-               break;
-       case R3964_WAIT_FOR_RX_REPEAT:
-               TRACE_PE("WAIT_FOR_RX_REPEAT - timeout");
-               pInfo->state = R3964_IDLE;
-               break;
-       case R3964_WAIT_FOR_BCC:
-               TRACE_PE("WAIT_FOR_BCC - timeout");
-               put_char(pInfo, NAK);
-               flush(pInfo);
-               pInfo->state = R3964_IDLE;
-               break;
-       }
-}
-
-static struct r3964_client_info *findClient(struct r3964_info *pInfo,
-               struct pid *pid)
-{
-       struct r3964_client_info *pClient;
-
-       for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) {
-               if (pClient->pid == pid) {
-                       return pClient;
-               }
-       }
-       return NULL;
-}
-
-static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg)
-{
-       struct r3964_client_info *pClient;
-       struct r3964_client_info **ppClient;
-       struct r3964_message *pMsg;
-
-       if ((arg & R3964_SIG_ALL) == 0) {
-               /* Remove client from client list */
-               for (ppClient = &pInfo->firstClient; *ppClient;
-                    ppClient = &(*ppClient)->next) {
-                       pClient = *ppClient;
-
-                       if (pClient->pid == pid) {
-                               TRACE_PS("removing client %d from client list",
-                                        pid_nr(pid));
-                               *ppClient = pClient->next;
-                               while (pClient->msg_count) {
-                                       pMsg = remove_msg(pInfo, pClient);
-                                       if (pMsg) {
-                                               kfree(pMsg);
-                                               TRACE_M("enable_signals - msg "
-                                                       "kfree %p", pMsg);
-                                       }
-                               }
-                               put_pid(pClient->pid);
-                               kfree(pClient);
-                               TRACE_M("enable_signals - kfree %p", pClient);
-                               return 0;
-                       }
-               }
-               return -EINVAL;
-       } else {
-               pClient = findClient(pInfo, pid);
-               if (pClient) {
-                       /* update signal options */
-                       pClient->sig_flags = arg;
-               } else {
-                       /* add client to client list */
-                       pClient = kmalloc(sizeof(struct r3964_client_info),
-                                       GFP_KERNEL);
-                       TRACE_M("enable_signals - kmalloc %p", pClient);
-                       if (pClient == NULL)
-                               return -ENOMEM;
-
-                       TRACE_PS("add client %d to client list", pid_nr(pid));
-                       spin_lock_init(&pClient->lock);
-                       pClient->sig_flags = arg;
-                       pClient->pid = get_pid(pid);
-                       pClient->next = pInfo->firstClient;
-                       pClient->first_msg = NULL;
-                       pClient->last_msg = NULL;
-                       pClient->next_block_to_read = NULL;
-                       pClient->msg_count = 0;
-                       pInfo->firstClient = pClient;
-               }
-       }
-
-       return 0;
-}
-
-static int read_telegram(struct r3964_info *pInfo, struct pid *pid,
-                        unsigned char __user * buf)
-{
-       struct r3964_client_info *pClient;
-       struct r3964_block_header *block;
-
-       if (!buf) {
-               return -EINVAL;
-       }
-
-       pClient = findClient(pInfo, pid);
-       if (pClient == NULL) {
-               return -EINVAL;
-       }
-
-       block = pClient->next_block_to_read;
-       if (!block) {
-               return 0;
-       } else {
-               if (copy_to_user(buf, block->data, block->length))
-                       return -EFAULT;
-
-               remove_client_block(pInfo, pClient);
-               return block->length;
-       }
-
-       return -EINVAL;
-}
-
-static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
-               int error_code, struct r3964_block_header *pBlock)
-{
-       struct r3964_message *pMsg;
-       unsigned long flags;
-
-       if (pClient->msg_count < R3964_MAX_MSG_COUNT - 1) {
-queue_the_message:
-
-               pMsg = kmalloc(sizeof(struct r3964_message),
-                               error_code ? GFP_ATOMIC : GFP_KERNEL);
-               TRACE_M("add_msg - kmalloc %p", pMsg);
-               if (pMsg == NULL) {
-                       return;
-               }
-
-               spin_lock_irqsave(&pClient->lock, flags);
-
-               pMsg->msg_id = msg_id;
-               pMsg->arg = arg;
-               pMsg->error_code = error_code;
-               pMsg->block = pBlock;
-               pMsg->next = NULL;
-
-               if (pClient->last_msg == NULL) {
-                       pClient->first_msg = pClient->last_msg = pMsg;
-               } else {
-                       pClient->last_msg->next = pMsg;
-                       pClient->last_msg = pMsg;
-               }
-
-               pClient->msg_count++;
-
-               if (pBlock != NULL) {
-                       pBlock->locks++;
-               }
-               spin_unlock_irqrestore(&pClient->lock, flags);
-       } else {
-               if ((pClient->last_msg->msg_id == R3964_MSG_ACK)
-                   && (pClient->last_msg->error_code == R3964_OVERFLOW)) {
-                       pClient->last_msg->arg++;
-                       TRACE_PE("add_msg - inc prev OVERFLOW-msg");
-               } else {
-                       msg_id = R3964_MSG_ACK;
-                       arg = 0;
-                       error_code = R3964_OVERFLOW;
-                       pBlock = NULL;
-                       TRACE_PE("add_msg - queue OVERFLOW-msg");
-                       goto queue_the_message;
-               }
-       }
-       /* Send SIGIO signal to client process: */
-       if (pClient->sig_flags & R3964_USE_SIGIO) {
-               kill_pid(pClient->pid, SIGIO, 1);
-       }
-}
-
-static struct r3964_message *remove_msg(struct r3964_info *pInfo,
-                                       struct r3964_client_info *pClient)
-{
-       struct r3964_message *pMsg = NULL;
-       unsigned long flags;
-
-       if (pClient->first_msg) {
-               spin_lock_irqsave(&pClient->lock, flags);
-
-               pMsg = pClient->first_msg;
-               pClient->first_msg = pMsg->next;
-               if (pClient->first_msg == NULL) {
-                       pClient->last_msg = NULL;
-               }
-
-               pClient->msg_count--;
-               if (pMsg->block) {
-                       remove_client_block(pInfo, pClient);
-                       pClient->next_block_to_read = pMsg->block;
-               }
-               spin_unlock_irqrestore(&pClient->lock, flags);
-       }
-       return pMsg;
-}
-
-static void remove_client_block(struct r3964_info *pInfo,
-                               struct r3964_client_info *pClient)
-{
-       struct r3964_block_header *block;
-
-       TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid));
-
-       block = pClient->next_block_to_read;
-       if (block) {
-               block->locks--;
-               if (block->locks == 0) {
-                       remove_from_rx_queue(pInfo, block);
-               }
-       }
-       pClient->next_block_to_read = NULL;
-}
-
-/*************************************************************
- * Line discipline routines
- *************************************************************/
-
-static int r3964_open(struct tty_struct *tty)
-{
-       struct r3964_info *pInfo;
-
-       TRACE_L("open");
-       TRACE_L("tty=%p, PID=%d, disc_data=%p",
-               tty, current->pid, tty->disc_data);
-
-       pInfo = kmalloc(sizeof(struct r3964_info), GFP_KERNEL);
-       TRACE_M("r3964_open - info kmalloc %p", pInfo);
-
-       if (!pInfo) {
-               printk(KERN_ERR "r3964: failed to alloc info structure\n");
-               return -ENOMEM;
-       }
-
-       pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
-       TRACE_M("r3964_open - rx_buf kmalloc %p", pInfo->rx_buf);
-
-       if (!pInfo->rx_buf) {
-               printk(KERN_ERR "r3964: failed to alloc receive buffer\n");
-               kfree(pInfo);
-               TRACE_M("r3964_open - info kfree %p", pInfo);
-               return -ENOMEM;
-       }
-
-       pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL);
-       TRACE_M("r3964_open - tx_buf kmalloc %p", pInfo->tx_buf);
-
-       if (!pInfo->tx_buf) {
-               printk(KERN_ERR "r3964: failed to alloc transmit buffer\n");
-               kfree(pInfo->rx_buf);
-               TRACE_M("r3964_open - rx_buf kfree %p", pInfo->rx_buf);
-               kfree(pInfo);
-               TRACE_M("r3964_open - info kfree %p", pInfo);
-               return -ENOMEM;
-       }
-
-       spin_lock_init(&pInfo->lock);
-       pInfo->tty = tty;
-       init_waitqueue_head(&pInfo->read_wait);
-       pInfo->priority = R3964_MASTER;
-       pInfo->rx_first = pInfo->rx_last = NULL;
-       pInfo->tx_first = pInfo->tx_last = NULL;
-       pInfo->rx_position = 0;
-       pInfo->tx_position = 0;
-       pInfo->last_rx = 0;
-       pInfo->blocks_in_rx_queue = 0;
-       pInfo->firstClient = NULL;
-       pInfo->state = R3964_IDLE;
-       pInfo->flags = R3964_DEBUG;
-       pInfo->nRetry = 0;
-
-       tty->disc_data = pInfo;
-       tty->receive_room = 65536;
-
-       setup_timer(&pInfo->tmr, on_timeout, (unsigned long)pInfo);
-
-       return 0;
-}
-
-static void r3964_close(struct tty_struct *tty)
-{
-       struct r3964_info *pInfo = tty->disc_data;
-       struct r3964_client_info *pClient, *pNext;
-       struct r3964_message *pMsg;
-       struct r3964_block_header *pHeader, *pNextHeader;
-       unsigned long flags;
-
-       TRACE_L("close");
-
-       /*
-        * Make sure that our task queue isn't activated.  If it
-        * is, take it out of the linked list.
-        */
-       del_timer_sync(&pInfo->tmr);
-
-       /* Remove client-structs and message queues: */
-       pClient = pInfo->firstClient;
-       while (pClient) {
-               pNext = pClient->next;
-               while (pClient->msg_count) {
-                       pMsg = remove_msg(pInfo, pClient);
-                       if (pMsg) {
-                               kfree(pMsg);
-                               TRACE_M("r3964_close - msg kfree %p", pMsg);
-                       }
-               }
-               put_pid(pClient->pid);
-               kfree(pClient);
-               TRACE_M("r3964_close - client kfree %p", pClient);
-               pClient = pNext;
-       }
-       /* Remove jobs from tx_queue: */
-       spin_lock_irqsave(&pInfo->lock, flags);
-       pHeader = pInfo->tx_first;
-       pInfo->tx_first = pInfo->tx_last = NULL;
-       spin_unlock_irqrestore(&pInfo->lock, flags);
-
-       while (pHeader) {
-               pNextHeader = pHeader->next;
-               kfree(pHeader);
-               pHeader = pNextHeader;
-       }
-
-       /* Free buffers: */
-       wake_up_interruptible(&pInfo->read_wait);
-       kfree(pInfo->rx_buf);
-       TRACE_M("r3964_close - rx_buf kfree %p", pInfo->rx_buf);
-       kfree(pInfo->tx_buf);
-       TRACE_M("r3964_close - tx_buf kfree %p", pInfo->tx_buf);
-       kfree(pInfo);
-       TRACE_M("r3964_close - info kfree %p", pInfo);
-}
-
-static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
-                         unsigned char __user * buf, size_t nr)
-{
-       struct r3964_info *pInfo = tty->disc_data;
-       struct r3964_client_info *pClient;
-       struct r3964_message *pMsg;
-       struct r3964_client_message theMsg;
-       int ret;
-
-       TRACE_L("read()");
-
-       tty_lock();
-
-       pClient = findClient(pInfo, task_pid(current));
-       if (pClient) {
-               pMsg = remove_msg(pInfo, pClient);
-               if (pMsg == NULL) {
-                       /* no messages available. */
-                       if (file->f_flags & O_NONBLOCK) {
-                               ret = -EAGAIN;
-                               goto unlock;
-                       }
-                       /* block until there is a message: */
-                       wait_event_interruptible_tty(pInfo->read_wait,
-                                       (pMsg = remove_msg(pInfo, pClient)));
-               }
-
-               /* If we still haven't got a message, we must have been signalled */
-
-               if (!pMsg) {
-                       ret = -EINTR;
-                       goto unlock;
-               }
-
-               /* deliver msg to client process: */
-               theMsg.msg_id = pMsg->msg_id;
-               theMsg.arg = pMsg->arg;
-               theMsg.error_code = pMsg->error_code;
-               ret = sizeof(struct r3964_client_message);
-
-               kfree(pMsg);
-               TRACE_M("r3964_read - msg kfree %p", pMsg);
-
-               if (copy_to_user(buf, &theMsg, ret)) {
-                       ret = -EFAULT;
-                       goto unlock;
-               }
-
-               TRACE_PS("read - return %d", ret);
-               goto unlock;
-       }
-       ret = -EPERM;
-unlock:
-       tty_unlock();
-       return ret;
-}
-
-static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
-                          const unsigned char *data, size_t count)
-{
-       struct r3964_info *pInfo = tty->disc_data;
-       struct r3964_block_header *pHeader;
-       struct r3964_client_info *pClient;
-       unsigned char *new_data;
-
-       TRACE_L("write request, %d characters", count);
-/* 
- * Verify the pointers 
- */
-
-       if (!pInfo)
-               return -EIO;
-
-/*
- * Ensure that the caller does not wish to send too much.
- */
-       if (count > R3964_MTU) {
-               if (pInfo->flags & R3964_DEBUG) {
-                       TRACE_L(KERN_WARNING "r3964_write: truncating user "
-                               "packet from %u to mtu %d", count, R3964_MTU);
-               }
-               count = R3964_MTU;
-       }
-/*
- * Allocate a buffer for the data and copy it from the buffer with header prepended
- */
-       new_data = kmalloc(count + sizeof(struct r3964_block_header),
-                       GFP_KERNEL);
-       TRACE_M("r3964_write - kmalloc %p", new_data);
-       if (new_data == NULL) {
-               if (pInfo->flags & R3964_DEBUG) {
-                       printk(KERN_ERR "r3964_write: no memory\n");
-               }
-               return -ENOSPC;
-       }
-
-       pHeader = (struct r3964_block_header *)new_data;
-       pHeader->data = new_data + sizeof(struct r3964_block_header);
-       pHeader->length = count;
-       pHeader->locks = 0;
-       pHeader->owner = NULL;
-
-       tty_lock();
-
-       pClient = findClient(pInfo, task_pid(current));
-       if (pClient) {
-               pHeader->owner = pClient;
-       }
-
-       memcpy(pHeader->data, data, count);     /* We already verified this */
-
-       if (pInfo->flags & R3964_DEBUG) {
-               dump_block(pHeader->data, count);
-       }
-
-/*
- * Add buffer to transmit-queue:
- */
-       add_tx_queue(pInfo, pHeader);
-       trigger_transmit(pInfo);
-
-       tty_unlock();
-
-       return 0;
-}
-
-static int r3964_ioctl(struct tty_struct *tty, struct file *file,
-               unsigned int cmd, unsigned long arg)
-{
-       struct r3964_info *pInfo = tty->disc_data;
-       if (pInfo == NULL)
-               return -EINVAL;
-       switch (cmd) {
-       case R3964_ENABLE_SIGNALS:
-               return enable_signals(pInfo, task_pid(current), arg);
-       case R3964_SETPRIORITY:
-               if (arg < R3964_MASTER || arg > R3964_SLAVE)
-                       return -EINVAL;
-               pInfo->priority = arg & 0xff;
-               return 0;
-       case R3964_USE_BCC:
-               if (arg)
-                       pInfo->flags |= R3964_BCC;
-               else
-                       pInfo->flags &= ~R3964_BCC;
-               return 0;
-       case R3964_READ_TELEGRAM:
-               return read_telegram(pInfo, task_pid(current),
-                               (unsigned char __user *)arg);
-       default:
-               return -ENOIOCTLCMD;
-       }
-}
-
-static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old)
-{
-       TRACE_L("set_termios");
-}
-
-/* Called without the kernel lock held - fine */
-static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
-                       struct poll_table_struct *wait)
-{
-       struct r3964_info *pInfo = tty->disc_data;
-       struct r3964_client_info *pClient;
-       struct r3964_message *pMsg = NULL;
-       unsigned long flags;
-       int result = POLLOUT;
-
-       TRACE_L("POLL");
-
-       pClient = findClient(pInfo, task_pid(current));
-       if (pClient) {
-               poll_wait(file, &pInfo->read_wait, wait);
-               spin_lock_irqsave(&pInfo->lock, flags);
-               pMsg = pClient->first_msg;
-               spin_unlock_irqrestore(&pInfo->lock, flags);
-               if (pMsg)
-                       result |= POLLIN | POLLRDNORM;
-       } else {
-               result = -EINVAL;
-       }
-       return result;
-}
-
-static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
-                       char *fp, int count)
-{
-       struct r3964_info *pInfo = tty->disc_data;
-       const unsigned char *p;
-       char *f, flags = 0;
-       int i;
-
-       for (i = count, p = cp, f = fp; i; i--, p++) {
-               if (f)
-                       flags = *f++;
-               if (flags == TTY_NORMAL) {
-                       receive_char(pInfo, *p);
-               } else {
-                       receive_error(pInfo, flags);
-               }
-
-       }
-}
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_LDISC(N_R3964);
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
deleted file mode 100644 (file)
index 428f4fe..0000000
+++ /dev/null
@@ -1,2121 +0,0 @@
-/*
- * n_tty.c --- implements the N_TTY line discipline.
- *
- * This code used to be in tty_io.c, but things are getting hairy
- * enough that it made sense to split things off.  (The N_TTY
- * processing has changed so much that it's hardly recognizable,
- * anyway...)
- *
- * Note that the open routine for N_TTY is guaranteed never to return
- * an error.  This is because Linux will fall back to setting a line
- * to N_TTY if it can not switch to any other line discipline.
- *
- * Written by Theodore Ts'o, Copyright 1994.
- *
- * This file also contains code originally written by Linus Torvalds,
- * Copyright 1991, 1992, 1993, and by Julian Cowley, Copyright 1994.
- *
- * This file may be redistributed under the terms of the GNU General Public
- * License.
- *
- * Reduced memory usage for older ARM systems  - Russell King.
- *
- * 2000/01/20   Fixed SMP locking on put_tty_queue using bits of
- *             the patch by Andrew J. Kroll <ag784@freenet.buffalo.edu>
- *             who actually finally proved there really was a race.
- *
- * 2002/03/18   Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
- *             waiting writing processes-Sapan Bhatia <sapan@corewars.org>.
- *             Also fixed a bug in BLOCKING mode where n_tty_write returns
- *             EAGAIN
- */
-
-#include <linux/types.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/fcntl.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/timer.h>
-#include <linux/ctype.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/bitops.h>
-#include <linux/audit.h>
-#include <linux/file.h>
-#include <linux/uaccess.h>
-#include <linux/module.h>
-
-#include <asm/system.h>
-
-/* number of characters left in xmit buffer before select has we have room */
-#define WAKEUP_CHARS 256
-
-/*
- * This defines the low- and high-watermarks for throttling and
- * unthrottling the TTY driver.  These watermarks are used for
- * controlling the space in the read buffer.
- */
-#define TTY_THRESHOLD_THROTTLE         128 /* now based on remaining room */
-#define TTY_THRESHOLD_UNTHROTTLE       128
-
-/*
- * Special byte codes used in the echo buffer to represent operations
- * or special handling of characters.  Bytes in the echo buffer that
- * are not part of such special blocks are treated as normal character
- * codes.
- */
-#define ECHO_OP_START 0xff
-#define ECHO_OP_MOVE_BACK_COL 0x80
-#define ECHO_OP_SET_CANON_COL 0x81
-#define ECHO_OP_ERASE_TAB 0x82
-
-static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
-                              unsigned char __user *ptr)
-{
-       tty_audit_add_data(tty, &x, 1);
-       return put_user(x, ptr);
-}
-
-/**
- *     n_tty_set__room -       receive space
- *     @tty: terminal
- *
- *     Called by the driver to find out how much data it is
- *     permitted to feed to the line discipline without any being lost
- *     and thus to manage flow control. Not serialized. Answers for the
- *     "instant".
- */
-
-static void n_tty_set_room(struct tty_struct *tty)
-{
-       /* tty->read_cnt is not read locked ? */
-       int     left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
-
-       /*
-        * If we are doing input canonicalization, and there are no
-        * pending newlines, let characters through without limit, so
-        * that erase characters will be handled.  Other excess
-        * characters will be beeped.
-        */
-       if (left <= 0)
-               left = tty->icanon && !tty->canon_data;
-       tty->receive_room = left;
-}
-
-static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
-{
-       if (tty->read_cnt < N_TTY_BUF_SIZE) {
-               tty->read_buf[tty->read_head] = c;
-               tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1);
-               tty->read_cnt++;
-       }
-}
-
-/**
- *     put_tty_queue           -       add character to tty
- *     @c: character
- *     @tty: tty device
- *
- *     Add a character to the tty read_buf queue. This is done under the
- *     read_lock to serialize character addition and also to protect us
- *     against parallel reads or flushes
- */
-
-static void put_tty_queue(unsigned char c, struct tty_struct *tty)
-{
-       unsigned long flags;
-       /*
-        *      The problem of stomping on the buffers ends here.
-        *      Why didn't anyone see this one coming? --AJK
-       */
-       spin_lock_irqsave(&tty->read_lock, flags);
-       put_tty_queue_nolock(c, tty);
-       spin_unlock_irqrestore(&tty->read_lock, flags);
-}
-
-/**
- *     check_unthrottle        -       allow new receive data
- *     @tty; tty device
- *
- *     Check whether to call the driver unthrottle functions
- *
- *     Can sleep, may be called under the atomic_read_lock mutex but
- *     this is not guaranteed.
- */
-static void check_unthrottle(struct tty_struct *tty)
-{
-       if (tty->count)
-               tty_unthrottle(tty);
-}
-
-/**
- *     reset_buffer_flags      -       reset buffer state
- *     @tty: terminal to reset
- *
- *     Reset the read buffer counters, clear the flags,
- *     and make sure the driver is unthrottled. Called
- *     from n_tty_open() and n_tty_flush_buffer().
- *
- *     Locking: tty_read_lock for read fields.
- */
-
-static void reset_buffer_flags(struct tty_struct *tty)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&tty->read_lock, flags);
-       tty->read_head = tty->read_tail = tty->read_cnt = 0;
-       spin_unlock_irqrestore(&tty->read_lock, flags);
-
-       mutex_lock(&tty->echo_lock);
-       tty->echo_pos = tty->echo_cnt = tty->echo_overrun = 0;
-       mutex_unlock(&tty->echo_lock);
-
-       tty->canon_head = tty->canon_data = tty->erasing = 0;
-       memset(&tty->read_flags, 0, sizeof tty->read_flags);
-       n_tty_set_room(tty);
-       check_unthrottle(tty);
-}
-
-/**
- *     n_tty_flush_buffer      -       clean input queue
- *     @tty:   terminal device
- *
- *     Flush the input buffer. Called when the line discipline is
- *     being closed, when the tty layer wants the buffer flushed (eg
- *     at hangup) or when the N_TTY line discipline internally has to
- *     clean the pending queue (for example some signals).
- *
- *     Locking: ctrl_lock, read_lock.
- */
-
-static void n_tty_flush_buffer(struct tty_struct *tty)
-{
-       unsigned long flags;
-       /* clear everything and unthrottle the driver */
-       reset_buffer_flags(tty);
-
-       if (!tty->link)
-               return;
-
-       spin_lock_irqsave(&tty->ctrl_lock, flags);
-       if (tty->link->packet) {
-               tty->ctrl_status |= TIOCPKT_FLUSHREAD;
-               wake_up_interruptible(&tty->link->read_wait);
-       }
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-}
-
-/**
- *     n_tty_chars_in_buffer   -       report available bytes
- *     @tty: tty device
- *
- *     Report the number of characters buffered to be delivered to user
- *     at this instant in time.
- *
- *     Locking: read_lock
- */
-
-static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
-{
-       unsigned long flags;
-       ssize_t n = 0;
-
-       spin_lock_irqsave(&tty->read_lock, flags);
-       if (!tty->icanon) {
-               n = tty->read_cnt;
-       } else if (tty->canon_data) {
-               n = (tty->canon_head > tty->read_tail) ?
-                       tty->canon_head - tty->read_tail :
-                       tty->canon_head + (N_TTY_BUF_SIZE - tty->read_tail);
-       }
-       spin_unlock_irqrestore(&tty->read_lock, flags);
-       return n;
-}
-
-/**
- *     is_utf8_continuation    -       utf8 multibyte check
- *     @c: byte to check
- *
- *     Returns true if the utf8 character 'c' is a multibyte continuation
- *     character. We use this to correctly compute the on screen size
- *     of the character when printing
- */
-
-static inline int is_utf8_continuation(unsigned char c)
-{
-       return (c & 0xc0) == 0x80;
-}
-
-/**
- *     is_continuation         -       multibyte check
- *     @c: byte to check
- *
- *     Returns true if the utf8 character 'c' is a multibyte continuation
- *     character and the terminal is in unicode mode.
- */
-
-static inline int is_continuation(unsigned char c, struct tty_struct *tty)
-{
-       return I_IUTF8(tty) && is_utf8_continuation(c);
-}
-
-/**
- *     do_output_char                  -       output one character
- *     @c: character (or partial unicode symbol)
- *     @tty: terminal device
- *     @space: space available in tty driver write buffer
- *
- *     This is a helper function that handles one output character
- *     (including special characters like TAB, CR, LF, etc.),
- *     doing OPOST processing and putting the results in the
- *     tty driver's write buffer.
- *
- *     Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY
- *     and NLDLY.  They simply aren't relevant in the world today.
- *     If you ever need them, add them here.
- *
- *     Returns the number of bytes of buffer space used or -1 if
- *     no space left.
- *
- *     Locking: should be called under the output_lock to protect
- *              the column state and space left in the buffer
- */
-
-static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
-{
-       int     spaces;
-
-       if (!space)
-               return -1;
-
-       switch (c) {
-       case '\n':
-               if (O_ONLRET(tty))
-                       tty->column = 0;
-               if (O_ONLCR(tty)) {
-                       if (space < 2)
-                               return -1;
-                       tty->canon_column = tty->column = 0;
-                       tty->ops->write(tty, "\r\n", 2);
-                       return 2;
-               }
-               tty->canon_column = tty->column;
-               break;
-       case '\r':
-               if (O_ONOCR(tty) && tty->column == 0)
-                       return 0;
-               if (O_OCRNL(tty)) {
-                       c = '\n';
-                       if (O_ONLRET(tty))
-                               tty->canon_column = tty->column = 0;
-                       break;
-               }
-               tty->canon_column = tty->column = 0;
-               break;
-       case '\t':
-               spaces = 8 - (tty->column & 7);
-               if (O_TABDLY(tty) == XTABS) {
-                       if (space < spaces)
-                               return -1;
-                       tty->column += spaces;
-                       tty->ops->write(tty, "        ", spaces);
-                       return spaces;
-               }
-               tty->column += spaces;
-               break;
-       case '\b':
-               if (tty->column > 0)
-                       tty->column--;
-               break;
-       default:
-               if (!iscntrl(c)) {
-                       if (O_OLCUC(tty))
-                               c = toupper(c);
-                       if (!is_continuation(c, tty))
-                               tty->column++;
-               }
-               break;
-       }
-
-       tty_put_char(tty, c);
-       return 1;
-}
-
-/**
- *     process_output                  -       output post processor
- *     @c: character (or partial unicode symbol)
- *     @tty: terminal device
- *
- *     Output one character with OPOST processing.
- *     Returns -1 when the output device is full and the character
- *     must be retried.
- *
- *     Locking: output_lock to protect column state and space left
- *              (also, this is called from n_tty_write under the
- *               tty layer write lock)
- */
-
-static int process_output(unsigned char c, struct tty_struct *tty)
-{
-       int     space, retval;
-
-       mutex_lock(&tty->output_lock);
-
-       space = tty_write_room(tty);
-       retval = do_output_char(c, tty, space);
-
-       mutex_unlock(&tty->output_lock);
-       if (retval < 0)
-               return -1;
-       else
-               return 0;
-}
-
-/**
- *     process_output_block            -       block post processor
- *     @tty: terminal device
- *     @buf: character buffer
- *     @nr: number of bytes to output
- *
- *     Output a block of characters with OPOST processing.
- *     Returns the number of characters output.
- *
- *     This path is used to speed up block console writes, among other
- *     things when processing blocks of output data. It handles only
- *     the simple cases normally found and helps to generate blocks of
- *     symbols for the console driver and thus improve performance.
- *
- *     Locking: output_lock to protect column state and space left
- *              (also, this is called from n_tty_write under the
- *               tty layer write lock)
- */
-
-static ssize_t process_output_block(struct tty_struct *tty,
-                                   const unsigned char *buf, unsigned int nr)
-{
-       int     space;
-       int     i;
-       const unsigned char *cp;
-
-       mutex_lock(&tty->output_lock);
-
-       space = tty_write_room(tty);
-       if (!space) {
-               mutex_unlock(&tty->output_lock);
-               return 0;
-       }
-       if (nr > space)
-               nr = space;
-
-       for (i = 0, cp = buf; i < nr; i++, cp++) {
-               unsigned char c = *cp;
-
-               switch (c) {
-               case '\n':
-                       if (O_ONLRET(tty))
-                               tty->column = 0;
-                       if (O_ONLCR(tty))
-                               goto break_out;
-                       tty->canon_column = tty->column;
-                       break;
-               case '\r':
-                       if (O_ONOCR(tty) && tty->column == 0)
-                               goto break_out;
-                       if (O_OCRNL(tty))
-                               goto break_out;
-                       tty->canon_column = tty->column = 0;
-                       break;
-               case '\t':
-                       goto break_out;
-               case '\b':
-                       if (tty->column > 0)
-                               tty->column--;
-                       break;
-               default:
-                       if (!iscntrl(c)) {
-                               if (O_OLCUC(tty))
-                                       goto break_out;
-                               if (!is_continuation(c, tty))
-                                       tty->column++;
-                       }
-                       break;
-               }
-       }
-break_out:
-       i = tty->ops->write(tty, buf, i);
-
-       mutex_unlock(&tty->output_lock);
-       return i;
-}
-
-/**
- *     process_echoes  -       write pending echo characters
- *     @tty: terminal device
- *
- *     Write previously buffered echo (and other ldisc-generated)
- *     characters to the tty.
- *
- *     Characters generated by the ldisc (including echoes) need to
- *     be buffered because the driver's write buffer can fill during
- *     heavy program output.  Echoing straight to the driver will
- *     often fail under these conditions, causing lost characters and
- *     resulting mismatches of ldisc state information.
- *
- *     Since the ldisc state must represent the characters actually sent
- *     to the driver at the time of the write, operations like certain
- *     changes in column state are also saved in the buffer and executed
- *     here.
- *
- *     A circular fifo buffer is used so that the most recent characters
- *     are prioritized.  Also, when control characters are echoed with a
- *     prefixed "^", the pair is treated atomically and thus not separated.
- *
- *     Locking: output_lock to protect column state and space left,
- *              echo_lock to protect the echo buffer
- */
-
-static void process_echoes(struct tty_struct *tty)
-{
-       int     space, nr;
-       unsigned char c;
-       unsigned char *cp, *buf_end;
-
-       if (!tty->echo_cnt)
-               return;
-
-       mutex_lock(&tty->output_lock);
-       mutex_lock(&tty->echo_lock);
-
-       space = tty_write_room(tty);
-
-       buf_end = tty->echo_buf + N_TTY_BUF_SIZE;
-       cp = tty->echo_buf + tty->echo_pos;
-       nr = tty->echo_cnt;
-       while (nr > 0) {
-               c = *cp;
-               if (c == ECHO_OP_START) {
-                       unsigned char op;
-                       unsigned char *opp;
-                       int no_space_left = 0;
-
-                       /*
-                        * If the buffer byte is the start of a multi-byte
-                        * operation, get the next byte, which is either the
-                        * op code or a control character value.
-                        */
-                       opp = cp + 1;
-                       if (opp == buf_end)
-                               opp -= N_TTY_BUF_SIZE;
-                       op = *opp;
-
-                       switch (op) {
-                               unsigned int num_chars, num_bs;
-
-                       case ECHO_OP_ERASE_TAB:
-                               if (++opp == buf_end)
-                                       opp -= N_TTY_BUF_SIZE;
-                               num_chars = *opp;
-
-                               /*
-                                * Determine how many columns to go back
-                                * in order to erase the tab.
-                                * This depends on the number of columns
-                                * used by other characters within the tab
-                                * area.  If this (modulo 8) count is from
-                                * the start of input rather than from a
-                                * previous tab, we offset by canon column.
-                                * Otherwise, tab spacing is normal.
-                                */
-                               if (!(num_chars & 0x80))
-                                       num_chars += tty->canon_column;
-                               num_bs = 8 - (num_chars & 7);
-
-                               if (num_bs > space) {
-                                       no_space_left = 1;
-                                       break;
-                               }
-                               space -= num_bs;
-                               while (num_bs--) {
-                                       tty_put_char(tty, '\b');
-                                       if (tty->column > 0)
-                                               tty->column--;
-                               }
-                               cp += 3;
-                               nr -= 3;
-                               break;
-
-                       case ECHO_OP_SET_CANON_COL:
-                               tty->canon_column = tty->column;
-                               cp += 2;
-                               nr -= 2;
-                               break;
-
-                       case ECHO_OP_MOVE_BACK_COL:
-                               if (tty->column > 0)
-                                       tty->column--;
-                               cp += 2;
-                               nr -= 2;
-                               break;
-
-                       case ECHO_OP_START:
-                               /* This is an escaped echo op start code */
-                               if (!space) {
-                                       no_space_left = 1;
-                                       break;
-                               }
-                               tty_put_char(tty, ECHO_OP_START);
-                               tty->column++;
-                               space--;
-                               cp += 2;
-                               nr -= 2;
-                               break;
-
-                       default:
-                               /*
-                                * If the op is not a special byte code,
-                                * it is a ctrl char tagged to be echoed
-                                * as "^X" (where X is the letter
-                                * representing the control char).
-                                * Note that we must ensure there is
-                                * enough space for the whole ctrl pair.
-                                *
-                                */
-                               if (space < 2) {
-                                       no_space_left = 1;
-                                       break;
-                               }
-                               tty_put_char(tty, '^');
-                               tty_put_char(tty, op ^ 0100);
-                               tty->column += 2;
-                               space -= 2;
-                               cp += 2;
-                               nr -= 2;
-                       }
-
-                       if (no_space_left)
-                               break;
-               } else {
-                       if (O_OPOST(tty) &&
-                           !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
-                               int retval = do_output_char(c, tty, space);
-                               if (retval < 0)
-                                       break;
-                               space -= retval;
-                       } else {
-                               if (!space)
-                                       break;
-                               tty_put_char(tty, c);
-                               space -= 1;
-                       }
-                       cp += 1;
-                       nr -= 1;
-               }
-
-               /* When end of circular buffer reached, wrap around */
-               if (cp >= buf_end)
-                       cp -= N_TTY_BUF_SIZE;
-       }
-
-       if (nr == 0) {
-               tty->echo_pos = 0;
-               tty->echo_cnt = 0;
-               tty->echo_overrun = 0;
-       } else {
-               int num_processed = tty->echo_cnt - nr;
-               tty->echo_pos += num_processed;
-               tty->echo_pos &= N_TTY_BUF_SIZE - 1;
-               tty->echo_cnt = nr;
-               if (num_processed > 0)
-                       tty->echo_overrun = 0;
-       }
-
-       mutex_unlock(&tty->echo_lock);
-       mutex_unlock(&tty->output_lock);
-
-       if (tty->ops->flush_chars)
-               tty->ops->flush_chars(tty);
-}
-
-/**
- *     add_echo_byte   -       add a byte to the echo buffer
- *     @c: unicode byte to echo
- *     @tty: terminal device
- *
- *     Add a character or operation byte to the echo buffer.
- *
- *     Should be called under the echo lock to protect the echo buffer.
- */
-
-static void add_echo_byte(unsigned char c, struct tty_struct *tty)
-{
-       int     new_byte_pos;
-
-       if (tty->echo_cnt == N_TTY_BUF_SIZE) {
-               /* Circular buffer is already at capacity */
-               new_byte_pos = tty->echo_pos;
-
-               /*
-                * Since the buffer start position needs to be advanced,
-                * be sure to step by a whole operation byte group.
-                */
-               if (tty->echo_buf[tty->echo_pos] == ECHO_OP_START) {
-                       if (tty->echo_buf[(tty->echo_pos + 1) &
-                                         (N_TTY_BUF_SIZE - 1)] ==
-                                               ECHO_OP_ERASE_TAB) {
-                               tty->echo_pos += 3;
-                               tty->echo_cnt -= 2;
-                       } else {
-                               tty->echo_pos += 2;
-                               tty->echo_cnt -= 1;
-                       }
-               } else {
-                       tty->echo_pos++;
-               }
-               tty->echo_pos &= N_TTY_BUF_SIZE - 1;
-
-               tty->echo_overrun = 1;
-       } else {
-               new_byte_pos = tty->echo_pos + tty->echo_cnt;
-               new_byte_pos &= N_TTY_BUF_SIZE - 1;
-               tty->echo_cnt++;
-       }
-
-       tty->echo_buf[new_byte_pos] = c;
-}
-
-/**
- *     echo_move_back_col      -       add operation to move back a column
- *     @tty: terminal device
- *
- *     Add an operation to the echo buffer to move back one column.
- *
- *     Locking: echo_lock to protect the echo buffer
- */
-
-static void echo_move_back_col(struct tty_struct *tty)
-{
-       mutex_lock(&tty->echo_lock);
-
-       add_echo_byte(ECHO_OP_START, tty);
-       add_echo_byte(ECHO_OP_MOVE_BACK_COL, tty);
-
-       mutex_unlock(&tty->echo_lock);
-}
-
-/**
- *     echo_set_canon_col      -       add operation to set the canon column
- *     @tty: terminal device
- *
- *     Add an operation to the echo buffer to set the canon column
- *     to the current column.
- *
- *     Locking: echo_lock to protect the echo buffer
- */
-
-static void echo_set_canon_col(struct tty_struct *tty)
-{
-       mutex_lock(&tty->echo_lock);
-
-       add_echo_byte(ECHO_OP_START, tty);
-       add_echo_byte(ECHO_OP_SET_CANON_COL, tty);
-
-       mutex_unlock(&tty->echo_lock);
-}
-
-/**
- *     echo_erase_tab  -       add operation to erase a tab
- *     @num_chars: number of character columns already used
- *     @after_tab: true if num_chars starts after a previous tab
- *     @tty: terminal device
- *
- *     Add an operation to the echo buffer to erase a tab.
- *
- *     Called by the eraser function, which knows how many character
- *     columns have been used since either a previous tab or the start
- *     of input.  This information will be used later, along with
- *     canon column (if applicable), to go back the correct number
- *     of columns.
- *
- *     Locking: echo_lock to protect the echo buffer
- */
-
-static void echo_erase_tab(unsigned int num_chars, int after_tab,
-                          struct tty_struct *tty)
-{
-       mutex_lock(&tty->echo_lock);
-
-       add_echo_byte(ECHO_OP_START, tty);
-       add_echo_byte(ECHO_OP_ERASE_TAB, tty);
-
-       /* We only need to know this modulo 8 (tab spacing) */
-       num_chars &= 7;
-
-       /* Set the high bit as a flag if num_chars is after a previous tab */
-       if (after_tab)
-               num_chars |= 0x80;
-
-       add_echo_byte(num_chars, tty);
-
-       mutex_unlock(&tty->echo_lock);
-}
-
-/**
- *     echo_char_raw   -       echo a character raw
- *     @c: unicode byte to echo
- *     @tty: terminal device
- *
- *     Echo user input back onto the screen. This must be called only when
- *     L_ECHO(tty) is true. Called from the driver receive_buf path.
- *
- *     This variant does not treat control characters specially.
- *
- *     Locking: echo_lock to protect the echo buffer
- */
-
-static void echo_char_raw(unsigned char c, struct tty_struct *tty)
-{
-       mutex_lock(&tty->echo_lock);
-
-       if (c == ECHO_OP_START) {
-               add_echo_byte(ECHO_OP_START, tty);
-               add_echo_byte(ECHO_OP_START, tty);
-       } else {
-               add_echo_byte(c, tty);
-       }
-
-       mutex_unlock(&tty->echo_lock);
-}
-
-/**
- *     echo_char       -       echo a character
- *     @c: unicode byte to echo
- *     @tty: terminal device
- *
- *     Echo user input back onto the screen. This must be called only when
- *     L_ECHO(tty) is true. Called from the driver receive_buf path.
- *
- *     This variant tags control characters to be echoed as "^X"
- *     (where X is the letter representing the control char).
- *
- *     Locking: echo_lock to protect the echo buffer
- */
-
-static void echo_char(unsigned char c, struct tty_struct *tty)
-{
-       mutex_lock(&tty->echo_lock);
-
-       if (c == ECHO_OP_START) {
-               add_echo_byte(ECHO_OP_START, tty);
-               add_echo_byte(ECHO_OP_START, tty);
-       } else {
-               if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
-                       add_echo_byte(ECHO_OP_START, tty);
-               add_echo_byte(c, tty);
-       }
-
-       mutex_unlock(&tty->echo_lock);
-}
-
-/**
- *     finish_erasing          -       complete erase
- *     @tty: tty doing the erase
- */
-
-static inline void finish_erasing(struct tty_struct *tty)
-{
-       if (tty->erasing) {
-               echo_char_raw('/', tty);
-               tty->erasing = 0;
-       }
-}
-
-/**
- *     eraser          -       handle erase function
- *     @c: character input
- *     @tty: terminal device
- *
- *     Perform erase and necessary output when an erase character is
- *     present in the stream from the driver layer. Handles the complexities
- *     of UTF-8 multibyte symbols.
- *
- *     Locking: read_lock for tty buffers
- */
-
-static void eraser(unsigned char c, struct tty_struct *tty)
-{
-       enum { ERASE, WERASE, KILL } kill_type;
-       int head, seen_alnums, cnt;
-       unsigned long flags;
-
-       /* FIXME: locking needed ? */
-       if (tty->read_head == tty->canon_head) {
-               /* process_output('\a', tty); */ /* what do you think? */
-               return;
-       }
-       if (c == ERASE_CHAR(tty))
-               kill_type = ERASE;
-       else if (c == WERASE_CHAR(tty))
-               kill_type = WERASE;
-       else {
-               if (!L_ECHO(tty)) {
-                       spin_lock_irqsave(&tty->read_lock, flags);
-                       tty->read_cnt -= ((tty->read_head - tty->canon_head) &
-                                         (N_TTY_BUF_SIZE - 1));
-                       tty->read_head = tty->canon_head;
-                       spin_unlock_irqrestore(&tty->read_lock, flags);
-                       return;
-               }
-               if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
-                       spin_lock_irqsave(&tty->read_lock, flags);
-                       tty->read_cnt -= ((tty->read_head - tty->canon_head) &
-                                         (N_TTY_BUF_SIZE - 1));
-                       tty->read_head = tty->canon_head;
-                       spin_unlock_irqrestore(&tty->read_lock, flags);
-                       finish_erasing(tty);
-                       echo_char(KILL_CHAR(tty), tty);
-                       /* Add a newline if ECHOK is on and ECHOKE is off. */
-                       if (L_ECHOK(tty))
-                               echo_char_raw('\n', tty);
-                       return;
-               }
-               kill_type = KILL;
-       }
-
-       seen_alnums = 0;
-       /* FIXME: Locking ?? */
-       while (tty->read_head != tty->canon_head) {
-               head = tty->read_head;
-
-               /* erase a single possibly multibyte character */
-               do {
-                       head = (head - 1) & (N_TTY_BUF_SIZE-1);
-                       c = tty->read_buf[head];
-               } while (is_continuation(c, tty) && head != tty->canon_head);
-
-               /* do not partially erase */
-               if (is_continuation(c, tty))
-                       break;
-
-               if (kill_type == WERASE) {
-                       /* Equivalent to BSD's ALTWERASE. */
-                       if (isalnum(c) || c == '_')
-                               seen_alnums++;
-                       else if (seen_alnums)
-                               break;
-               }
-               cnt = (tty->read_head - head) & (N_TTY_BUF_SIZE-1);
-               spin_lock_irqsave(&tty->read_lock, flags);
-               tty->read_head = head;
-               tty->read_cnt -= cnt;
-               spin_unlock_irqrestore(&tty->read_lock, flags);
-               if (L_ECHO(tty)) {
-                       if (L_ECHOPRT(tty)) {
-                               if (!tty->erasing) {
-                                       echo_char_raw('\\', tty);
-                                       tty->erasing = 1;
-                               }
-                               /* if cnt > 1, output a multi-byte character */
-                               echo_char(c, tty);
-                               while (--cnt > 0) {
-                                       head = (head+1) & (N_TTY_BUF_SIZE-1);
-                                       echo_char_raw(tty->read_buf[head], tty);
-                                       echo_move_back_col(tty);
-                               }
-                       } else if (kill_type == ERASE && !L_ECHOE(tty)) {
-                               echo_char(ERASE_CHAR(tty), tty);
-                       } else if (c == '\t') {
-                               unsigned int num_chars = 0;
-                               int after_tab = 0;
-                               unsigned long tail = tty->read_head;
-
-                               /*
-                                * Count the columns used for characters
-                                * since the start of input or after a
-                                * previous tab.
-                                * This info is used to go back the correct
-                                * number of columns.
-                                */
-                               while (tail != tty->canon_head) {
-                                       tail = (tail-1) & (N_TTY_BUF_SIZE-1);
-                                       c = tty->read_buf[tail];
-                                       if (c == '\t') {
-                                               after_tab = 1;
-                                               break;
-                                       } else if (iscntrl(c)) {
-                                               if (L_ECHOCTL(tty))
-                                                       num_chars += 2;
-                                       } else if (!is_continuation(c, tty)) {
-                                               num_chars++;
-                                       }
-                               }
-                               echo_erase_tab(num_chars, after_tab, tty);
-                       } else {
-                               if (iscntrl(c) && L_ECHOCTL(tty)) {
-                                       echo_char_raw('\b', tty);
-                                       echo_char_raw(' ', tty);
-                                       echo_char_raw('\b', tty);
-                               }
-                               if (!iscntrl(c) || L_ECHOCTL(tty)) {
-                                       echo_char_raw('\b', tty);
-                                       echo_char_raw(' ', tty);
-                                       echo_char_raw('\b', tty);
-                               }
-                       }
-               }
-               if (kill_type == ERASE)
-                       break;
-       }
-       if (tty->read_head == tty->canon_head && L_ECHO(tty))
-               finish_erasing(tty);
-}
-
-/**
- *     isig            -       handle the ISIG optio
- *     @sig: signal
- *     @tty: terminal
- *     @flush: force flush
- *
- *     Called when a signal is being sent due to terminal input. This
- *     may caus terminal flushing to take place according to the termios
- *     settings and character used. Called from the driver receive_buf
- *     path so serialized.
- *
- *     Locking: ctrl_lock, read_lock (both via flush buffer)
- */
-
-static inline void isig(int sig, struct tty_struct *tty, int flush)
-{
-       if (tty->pgrp)
-               kill_pgrp(tty->pgrp, sig, 1);
-       if (flush || !L_NOFLSH(tty)) {
-               n_tty_flush_buffer(tty);
-               tty_driver_flush_buffer(tty);
-       }
-}
-
-/**
- *     n_tty_receive_break     -       handle break
- *     @tty: terminal
- *
- *     An RS232 break event has been hit in the incoming bitstream. This
- *     can cause a variety of events depending upon the termios settings.
- *
- *     Called from the receive_buf path so single threaded.
- */
-
-static inline void n_tty_receive_break(struct tty_struct *tty)
-{
-       if (I_IGNBRK(tty))
-               return;
-       if (I_BRKINT(tty)) {
-               isig(SIGINT, tty, 1);
-               return;
-       }
-       if (I_PARMRK(tty)) {
-               put_tty_queue('\377', tty);
-               put_tty_queue('\0', tty);
-       }
-       put_tty_queue('\0', tty);
-       wake_up_interruptible(&tty->read_wait);
-}
-
-/**
- *     n_tty_receive_overrun   -       handle overrun reporting
- *     @tty: terminal
- *
- *     Data arrived faster than we could process it. While the tty
- *     driver has flagged this the bits that were missed are gone
- *     forever.
- *
- *     Called from the receive_buf path so single threaded. Does not
- *     need locking as num_overrun and overrun_time are function
- *     private.
- */
-
-static inline void n_tty_receive_overrun(struct tty_struct *tty)
-{
-       char buf[64];
-
-       tty->num_overrun++;
-       if (time_before(tty->overrun_time, jiffies - HZ) ||
-                       time_after(tty->overrun_time, jiffies)) {
-               printk(KERN_WARNING "%s: %d input overrun(s)\n",
-                       tty_name(tty, buf),
-                       tty->num_overrun);
-               tty->overrun_time = jiffies;
-               tty->num_overrun = 0;
-       }
-}
-
-/**
- *     n_tty_receive_parity_error      -       error notifier
- *     @tty: terminal device
- *     @c: character
- *
- *     Process a parity error and queue the right data to indicate
- *     the error case if necessary. Locking as per n_tty_receive_buf.
- */
-static inline void n_tty_receive_parity_error(struct tty_struct *tty,
-                                             unsigned char c)
-{
-       if (I_IGNPAR(tty))
-               return;
-       if (I_PARMRK(tty)) {
-               put_tty_queue('\377', tty);
-               put_tty_queue('\0', tty);
-               put_tty_queue(c, tty);
-       } else  if (I_INPCK(tty))
-               put_tty_queue('\0', tty);
-       else
-               put_tty_queue(c, tty);
-       wake_up_interruptible(&tty->read_wait);
-}
-
-/**
- *     n_tty_receive_char      -       perform processing
- *     @tty: terminal device
- *     @c: character
- *
- *     Process an individual character of input received from the driver.
- *     This is serialized with respect to itself by the rules for the
- *     driver above.
- */
-
-static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
-{
-       unsigned long flags;
-       int parmrk;
-
-       if (tty->raw) {
-               put_tty_queue(c, tty);
-               return;
-       }
-
-       if (I_ISTRIP(tty))
-               c &= 0x7f;
-       if (I_IUCLC(tty) && L_IEXTEN(tty))
-               c = tolower(c);
-
-       if (L_EXTPROC(tty)) {
-               put_tty_queue(c, tty);
-               return;
-       }
-
-       if (tty->stopped && !tty->flow_stopped && I_IXON(tty) &&
-           I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) &&
-           c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) {
-               start_tty(tty);
-               process_echoes(tty);
-       }
-
-       if (tty->closing) {
-               if (I_IXON(tty)) {
-                       if (c == START_CHAR(tty)) {
-                               start_tty(tty);
-                               process_echoes(tty);
-                       } else if (c == STOP_CHAR(tty))
-                               stop_tty(tty);
-               }
-               return;
-       }
-
-       /*
-        * If the previous character was LNEXT, or we know that this
-        * character is not one of the characters that we'll have to
-        * handle specially, do shortcut processing to speed things
-        * up.
-        */
-       if (!test_bit(c, tty->process_char_map) || tty->lnext) {
-               tty->lnext = 0;
-               parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
-               if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
-                       /* beep if no space */
-                       if (L_ECHO(tty))
-                               process_output('\a', tty);
-                       return;
-               }
-               if (L_ECHO(tty)) {
-                       finish_erasing(tty);
-                       /* Record the column of first canon char. */
-                       if (tty->canon_head == tty->read_head)
-                               echo_set_canon_col(tty);
-                       echo_char(c, tty);
-                       process_echoes(tty);
-               }
-               if (parmrk)
-                       put_tty_queue(c, tty);
-               put_tty_queue(c, tty);
-               return;
-       }
-
-       if (I_IXON(tty)) {
-               if (c == START_CHAR(tty)) {
-                       start_tty(tty);
-                       process_echoes(tty);
-                       return;
-               }
-               if (c == STOP_CHAR(tty)) {
-                       stop_tty(tty);
-                       return;
-               }
-       }
-
-       if (L_ISIG(tty)) {
-               int signal;
-               signal = SIGINT;
-               if (c == INTR_CHAR(tty))
-                       goto send_signal;
-               signal = SIGQUIT;
-               if (c == QUIT_CHAR(tty))
-                       goto send_signal;
-               signal = SIGTSTP;
-               if (c == SUSP_CHAR(tty)) {
-send_signal:
-                       /*
-                        * Note that we do not use isig() here because we want
-                        * the order to be:
-                        * 1) flush, 2) echo, 3) signal
-                        */
-                       if (!L_NOFLSH(tty)) {
-                               n_tty_flush_buffer(tty);
-                               tty_driver_flush_buffer(tty);
-                       }
-                       if (I_IXON(tty))
-                               start_tty(tty);
-                       if (L_ECHO(tty)) {
-                               echo_char(c, tty);
-                               process_echoes(tty);
-                       }
-                       if (tty->pgrp)
-                               kill_pgrp(tty->pgrp, signal, 1);
-                       return;
-               }
-       }
-
-       if (c == '\r') {
-               if (I_IGNCR(tty))
-                       return;
-               if (I_ICRNL(tty))
-                       c = '\n';
-       } else if (c == '\n' && I_INLCR(tty))
-               c = '\r';
-
-       if (tty->icanon) {
-               if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
-                   (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
-                       eraser(c, tty);
-                       process_echoes(tty);
-                       return;
-               }
-               if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
-                       tty->lnext = 1;
-                       if (L_ECHO(tty)) {
-                               finish_erasing(tty);
-                               if (L_ECHOCTL(tty)) {
-                                       echo_char_raw('^', tty);
-                                       echo_char_raw('\b', tty);
-                                       process_echoes(tty);
-                               }
-                       }
-                       return;
-               }
-               if (c == REPRINT_CHAR(tty) && L_ECHO(tty) &&
-                   L_IEXTEN(tty)) {
-                       unsigned long tail = tty->canon_head;
-
-                       finish_erasing(tty);
-                       echo_char(c, tty);
-                       echo_char_raw('\n', tty);
-                       while (tail != tty->read_head) {
-                               echo_char(tty->read_buf[tail], tty);
-                               tail = (tail+1) & (N_TTY_BUF_SIZE-1);
-                       }
-                       process_echoes(tty);
-                       return;
-               }
-               if (c == '\n') {
-                       if (tty->read_cnt >= N_TTY_BUF_SIZE) {
-                               if (L_ECHO(tty))
-                                       process_output('\a', tty);
-                               return;
-                       }
-                       if (L_ECHO(tty) || L_ECHONL(tty)) {
-                               echo_char_raw('\n', tty);
-                               process_echoes(tty);
-                       }
-                       goto handle_newline;
-               }
-               if (c == EOF_CHAR(tty)) {
-                       if (tty->read_cnt >= N_TTY_BUF_SIZE)
-                               return;
-                       if (tty->canon_head != tty->read_head)
-                               set_bit(TTY_PUSH, &tty->flags);
-                       c = __DISABLED_CHAR;
-                       goto handle_newline;
-               }
-               if ((c == EOL_CHAR(tty)) ||
-                   (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
-                       parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty))
-                                ? 1 : 0;
-                       if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) {
-                               if (L_ECHO(tty))
-                                       process_output('\a', tty);
-                               return;
-                       }
-                       /*
-                        * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
-                        */
-                       if (L_ECHO(tty)) {
-                               /* Record the column of first canon char. */
-                               if (tty->canon_head == tty->read_head)
-                                       echo_set_canon_col(tty);
-                               echo_char(c, tty);
-                               process_echoes(tty);
-                       }
-                       /*
-                        * XXX does PARMRK doubling happen for
-                        * EOL_CHAR and EOL2_CHAR?
-                        */
-                       if (parmrk)
-                               put_tty_queue(c, tty);
-
-handle_newline:
-                       spin_lock_irqsave(&tty->read_lock, flags);
-                       set_bit(tty->read_head, tty->read_flags);
-                       put_tty_queue_nolock(c, tty);
-                       tty->canon_head = tty->read_head;
-                       tty->canon_data++;
-                       spin_unlock_irqrestore(&tty->read_lock, flags);
-                       kill_fasync(&tty->fasync, SIGIO, POLL_IN);
-                       if (waitqueue_active(&tty->read_wait))
-                               wake_up_interruptible(&tty->read_wait);
-                       return;
-               }
-       }
-
-       parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
-       if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
-               /* beep if no space */
-               if (L_ECHO(tty))
-                       process_output('\a', tty);
-               return;
-       }
-       if (L_ECHO(tty)) {
-               finish_erasing(tty);
-               if (c == '\n')
-                       echo_char_raw('\n', tty);
-               else {
-                       /* Record the column of first canon char. */
-                       if (tty->canon_head == tty->read_head)
-                               echo_set_canon_col(tty);
-                       echo_char(c, tty);
-               }
-               process_echoes(tty);
-       }
-
-       if (parmrk)
-               put_tty_queue(c, tty);
-
-       put_tty_queue(c, tty);
-}
-
-
-/**
- *     n_tty_write_wakeup      -       asynchronous I/O notifier
- *     @tty: tty device
- *
- *     Required for the ptys, serial driver etc. since processes
- *     that attach themselves to the master and rely on ASYNC
- *     IO must be woken up
- */
-
-static void n_tty_write_wakeup(struct tty_struct *tty)
-{
-       if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags))
-               kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
-}
-
-/**
- *     n_tty_receive_buf       -       data receive
- *     @tty: terminal device
- *     @cp: buffer
- *     @fp: flag buffer
- *     @count: characters
- *
- *     Called by the terminal driver when a block of characters has
- *     been received. This function must be called from soft contexts
- *     not from interrupt context. The driver is responsible for making
- *     calls one at a time and in order (or using flush_to_ldisc)
- */
-
-static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
-                             char *fp, int count)
-{
-       const unsigned char *p;
-       char *f, flags = TTY_NORMAL;
-       int     i;
-       char    buf[64];
-       unsigned long cpuflags;
-
-       if (!tty->read_buf)
-               return;
-
-       if (tty->real_raw) {
-               spin_lock_irqsave(&tty->read_lock, cpuflags);
-               i = min(N_TTY_BUF_SIZE - tty->read_cnt,
-                       N_TTY_BUF_SIZE - tty->read_head);
-               i = min(count, i);
-               memcpy(tty->read_buf + tty->read_head, cp, i);
-               tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
-               tty->read_cnt += i;
-               cp += i;
-               count -= i;
-
-               i = min(N_TTY_BUF_SIZE - tty->read_cnt,
-                       N_TTY_BUF_SIZE - tty->read_head);
-               i = min(count, i);
-               memcpy(tty->read_buf + tty->read_head, cp, i);
-               tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
-               tty->read_cnt += i;
-               spin_unlock_irqrestore(&tty->read_lock, cpuflags);
-       } else {
-               for (i = count, p = cp, f = fp; i; i--, p++) {
-                       if (f)
-                               flags = *f++;
-                       switch (flags) {
-                       case TTY_NORMAL:
-                               n_tty_receive_char(tty, *p);
-                               break;
-                       case TTY_BREAK:
-                               n_tty_receive_break(tty);
-                               break;
-                       case TTY_PARITY:
-                       case TTY_FRAME:
-                               n_tty_receive_parity_error(tty, *p);
-                               break;
-                       case TTY_OVERRUN:
-                               n_tty_receive_overrun(tty);
-                               break;
-                       default:
-                               printk(KERN_ERR "%s: unknown flag %d\n",
-                                      tty_name(tty, buf), flags);
-                               break;
-                       }
-               }
-               if (tty->ops->flush_chars)
-                       tty->ops->flush_chars(tty);
-       }
-
-       n_tty_set_room(tty);
-
-       if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
-               L_EXTPROC(tty)) {
-               kill_fasync(&tty->fasync, SIGIO, POLL_IN);
-               if (waitqueue_active(&tty->read_wait))
-                       wake_up_interruptible(&tty->read_wait);
-       }
-
-       /*
-        * Check the remaining room for the input canonicalization
-        * mode.  We don't want to throttle the driver if we're in
-        * canonical mode and don't have a newline yet!
-        */
-       if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
-               tty_throttle(tty);
-}
-
-int is_ignored(int sig)
-{
-       return (sigismember(&current->blocked, sig) ||
-               current->sighand->action[sig-1].sa.sa_handler == SIG_IGN);
-}
-
-/**
- *     n_tty_set_termios       -       termios data changed
- *     @tty: terminal
- *     @old: previous data
- *
- *     Called by the tty layer when the user changes termios flags so
- *     that the line discipline can plan ahead. This function cannot sleep
- *     and is protected from re-entry by the tty layer. The user is
- *     guaranteed that this function will not be re-entered or in progress
- *     when the ldisc is closed.
- *
- *     Locking: Caller holds tty->termios_mutex
- */
-
-static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
-{
-       int canon_change = 1;
-       BUG_ON(!tty);
-
-       if (old)
-               canon_change = (old->c_lflag ^ tty->termios->c_lflag) & ICANON;
-       if (canon_change) {
-               memset(&tty->read_flags, 0, sizeof tty->read_flags);
-               tty->canon_head = tty->read_tail;
-               tty->canon_data = 0;
-               tty->erasing = 0;
-       }
-
-       if (canon_change && !L_ICANON(tty) && tty->read_cnt)
-               wake_up_interruptible(&tty->read_wait);
-
-       tty->icanon = (L_ICANON(tty) != 0);
-       if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
-               tty->raw = 1;
-               tty->real_raw = 1;
-               n_tty_set_room(tty);
-               return;
-       }
-       if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
-           I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
-           I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
-           I_PARMRK(tty)) {
-               memset(tty->process_char_map, 0, 256/8);
-
-               if (I_IGNCR(tty) || I_ICRNL(tty))
-                       set_bit('\r', tty->process_char_map);
-               if (I_INLCR(tty))
-                       set_bit('\n', tty->process_char_map);
-
-               if (L_ICANON(tty)) {
-                       set_bit(ERASE_CHAR(tty), tty->process_char_map);
-                       set_bit(KILL_CHAR(tty), tty->process_char_map);
-                       set_bit(EOF_CHAR(tty), tty->process_char_map);
-                       set_bit('\n', tty->process_char_map);
-                       set_bit(EOL_CHAR(tty), tty->process_char_map);
-                       if (L_IEXTEN(tty)) {
-                               set_bit(WERASE_CHAR(tty),
-                                       tty->process_char_map);
-                               set_bit(LNEXT_CHAR(tty),
-                                       tty->process_char_map);
-                               set_bit(EOL2_CHAR(tty),
-                                       tty->process_char_map);
-                               if (L_ECHO(tty))
-                                       set_bit(REPRINT_CHAR(tty),
-                                               tty->process_char_map);
-                       }
-               }
-               if (I_IXON(tty)) {
-                       set_bit(START_CHAR(tty), tty->process_char_map);
-                       set_bit(STOP_CHAR(tty), tty->process_char_map);
-               }
-               if (L_ISIG(tty)) {
-                       set_bit(INTR_CHAR(tty), tty->process_char_map);
-                       set_bit(QUIT_CHAR(tty), tty->process_char_map);
-                       set_bit(SUSP_CHAR(tty), tty->process_char_map);
-               }
-               clear_bit(__DISABLED_CHAR, tty->process_char_map);
-               tty->raw = 0;
-               tty->real_raw = 0;
-       } else {
-               tty->raw = 1;
-               if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) &&
-                   (I_IGNPAR(tty) || !I_INPCK(tty)) &&
-                   (tty->driver->flags & TTY_DRIVER_REAL_RAW))
-                       tty->real_raw = 1;
-               else
-                       tty->real_raw = 0;
-       }
-       n_tty_set_room(tty);
-       /* The termios change make the tty ready for I/O */
-       wake_up_interruptible(&tty->write_wait);
-       wake_up_interruptible(&tty->read_wait);
-}
-
-/**
- *     n_tty_close             -       close the ldisc for this tty
- *     @tty: device
- *
- *     Called from the terminal layer when this line discipline is
- *     being shut down, either because of a close or becsuse of a
- *     discipline change. The function will not be called while other
- *     ldisc methods are in progress.
- */
-
-static void n_tty_close(struct tty_struct *tty)
-{
-       n_tty_flush_buffer(tty);
-       if (tty->read_buf) {
-               kfree(tty->read_buf);
-               tty->read_buf = NULL;
-       }
-       if (tty->echo_buf) {
-               kfree(tty->echo_buf);
-               tty->echo_buf = NULL;
-       }
-}
-
-/**
- *     n_tty_open              -       open an ldisc
- *     @tty: terminal to open
- *
- *     Called when this line discipline is being attached to the
- *     terminal device. Can sleep. Called serialized so that no
- *     other events will occur in parallel. No further open will occur
- *     until a close.
- */
-
-static int n_tty_open(struct tty_struct *tty)
-{
-       if (!tty)
-               return -EINVAL;
-
-       /* These are ugly. Currently a malloc failure here can panic */
-       if (!tty->read_buf) {
-               tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
-               if (!tty->read_buf)
-                       return -ENOMEM;
-       }
-       if (!tty->echo_buf) {
-               tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
-
-               if (!tty->echo_buf)
-                       return -ENOMEM;
-       }
-       reset_buffer_flags(tty);
-       tty->column = 0;
-       n_tty_set_termios(tty, NULL);
-       tty->minimum_to_wake = 1;
-       tty->closing = 0;
-       return 0;
-}
-
-static inline int input_available_p(struct tty_struct *tty, int amt)
-{
-       tty_flush_to_ldisc(tty);
-       if (tty->icanon && !L_EXTPROC(tty)) {
-               if (tty->canon_data)
-                       return 1;
-       } else if (tty->read_cnt >= (amt ? amt : 1))
-               return 1;
-
-       return 0;
-}
-
-/**
- *     copy_from_read_buf      -       copy read data directly
- *     @tty: terminal device
- *     @b: user data
- *     @nr: size of data
- *
- *     Helper function to speed up n_tty_read.  It is only called when
- *     ICANON is off; it copies characters straight from the tty queue to
- *     user space directly.  It can be profitably called twice; once to
- *     drain the space from the tail pointer to the (physical) end of the
- *     buffer, and once to drain the space from the (physical) beginning of
- *     the buffer to head pointer.
- *
- *     Called under the tty->atomic_read_lock sem
- *
- */
-
-static int copy_from_read_buf(struct tty_struct *tty,
-                                     unsigned char __user **b,
-                                     size_t *nr)
-
-{
-       int retval;
-       size_t n;
-       unsigned long flags;
-
-       retval = 0;
-       spin_lock_irqsave(&tty->read_lock, flags);
-       n = min(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail);
-       n = min(*nr, n);
-       spin_unlock_irqrestore(&tty->read_lock, flags);
-       if (n) {
-               retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
-               n -= retval;
-               tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n);
-               spin_lock_irqsave(&tty->read_lock, flags);
-               tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
-               tty->read_cnt -= n;
-               /* Turn single EOF into zero-length read */
-               if (L_EXTPROC(tty) && tty->icanon && n == 1) {
-                       if (!tty->read_cnt && (*b)[n-1] == EOF_CHAR(tty))
-                               n--;
-               }
-               spin_unlock_irqrestore(&tty->read_lock, flags);
-               *b += n;
-               *nr -= n;
-       }
-       return retval;
-}
-
-extern ssize_t redirected_tty_write(struct file *, const char __user *,
-                                                       size_t, loff_t *);
-
-/**
- *     job_control             -       check job control
- *     @tty: tty
- *     @file: file handle
- *
- *     Perform job control management checks on this file/tty descriptor
- *     and if appropriate send any needed signals and return a negative
- *     error code if action should be taken.
- *
- *     FIXME:
- *     Locking: None - redirected write test is safe, testing
- *     current->signal should possibly lock current->sighand
- *     pgrp locking ?
- */
-
-static int job_control(struct tty_struct *tty, struct file *file)
-{
-       /* Job control check -- must be done at start and after
-          every sleep (POSIX.1 7.1.1.4). */
-       /* NOTE: not yet done after every sleep pending a thorough
-          check of the logic of this change. -- jlc */
-       /* don't stop on /dev/console */
-       if (file->f_op->write != redirected_tty_write &&
-           current->signal->tty == tty) {
-               if (!tty->pgrp)
-                       printk(KERN_ERR "n_tty_read: no tty->pgrp!\n");
-               else if (task_pgrp(current) != tty->pgrp) {
-                       if (is_ignored(SIGTTIN) ||
-                           is_current_pgrp_orphaned())
-                               return -EIO;
-                       kill_pgrp(task_pgrp(current), SIGTTIN, 1);
-                       set_thread_flag(TIF_SIGPENDING);
-                       return -ERESTARTSYS;
-               }
-       }
-       return 0;
-}
-
-
-/**
- *     n_tty_read              -       read function for tty
- *     @tty: tty device
- *     @file: file object
- *     @buf: userspace buffer pointer
- *     @nr: size of I/O
- *
- *     Perform reads for the line discipline. We are guaranteed that the
- *     line discipline will not be closed under us but we may get multiple
- *     parallel readers and must handle this ourselves. We may also get
- *     a hangup. Always called in user context, may sleep.
- *
- *     This code must be sure never to sleep through a hangup.
- */
-
-static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
-                        unsigned char __user *buf, size_t nr)
-{
-       unsigned char __user *b = buf;
-       DECLARE_WAITQUEUE(wait, current);
-       int c;
-       int minimum, time;
-       ssize_t retval = 0;
-       ssize_t size;
-       long timeout;
-       unsigned long flags;
-       int packet;
-
-do_it_again:
-
-       BUG_ON(!tty->read_buf);
-
-       c = job_control(tty, file);
-       if (c < 0)
-               return c;
-
-       minimum = time = 0;
-       timeout = MAX_SCHEDULE_TIMEOUT;
-       if (!tty->icanon) {
-               time = (HZ / 10) * TIME_CHAR(tty);
-               minimum = MIN_CHAR(tty);
-               if (minimum) {
-                       if (time)
-                               tty->minimum_to_wake = 1;
-                       else if (!waitqueue_active(&tty->read_wait) ||
-                                (tty->minimum_to_wake > minimum))
-                               tty->minimum_to_wake = minimum;
-               } else {
-                       timeout = 0;
-                       if (time) {
-                               timeout = time;
-                               time = 0;
-                       }
-                       tty->minimum_to_wake = minimum = 1;
-               }
-       }
-
-       /*
-        *      Internal serialization of reads.
-        */
-       if (file->f_flags & O_NONBLOCK) {
-               if (!mutex_trylock(&tty->atomic_read_lock))
-                       return -EAGAIN;
-       } else {
-               if (mutex_lock_interruptible(&tty->atomic_read_lock))
-                       return -ERESTARTSYS;
-       }
-       packet = tty->packet;
-
-       add_wait_queue(&tty->read_wait, &wait);
-       while (nr) {
-               /* First test for status change. */
-               if (packet && tty->link->ctrl_status) {
-                       unsigned char cs;
-                       if (b != buf)
-                               break;
-                       spin_lock_irqsave(&tty->link->ctrl_lock, flags);
-                       cs = tty->link->ctrl_status;
-                       tty->link->ctrl_status = 0;
-                       spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
-                       if (tty_put_user(tty, cs, b++)) {
-                               retval = -EFAULT;
-                               b--;
-                               break;
-                       }
-                       nr--;
-                       break;
-               }
-               /* This statement must be first before checking for input
-                  so that any interrupt will set the state back to
-                  TASK_RUNNING. */
-               set_current_state(TASK_INTERRUPTIBLE);
-
-               if (((minimum - (b - buf)) < tty->minimum_to_wake) &&
-                   ((minimum - (b - buf)) >= 1))
-                       tty->minimum_to_wake = (minimum - (b - buf));
-
-               if (!input_available_p(tty, 0)) {
-                       if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
-                               retval = -EIO;
-                               break;
-                       }
-                       if (tty_hung_up_p(file))
-                               break;
-                       if (!timeout)
-                               break;
-                       if (file->f_flags & O_NONBLOCK) {
-                               retval = -EAGAIN;
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               retval = -ERESTARTSYS;
-                               break;
-                       }
-                       /* FIXME: does n_tty_set_room need locking ? */
-                       n_tty_set_room(tty);
-                       timeout = schedule_timeout(timeout);
-                       continue;
-               }
-               __set_current_state(TASK_RUNNING);
-
-               /* Deal with packet mode. */
-               if (packet && b == buf) {
-                       if (tty_put_user(tty, TIOCPKT_DATA, b++)) {
-                               retval = -EFAULT;
-                               b--;
-                               break;
-                       }
-                       nr--;
-               }
-
-               if (tty->icanon && !L_EXTPROC(tty)) {
-                       /* N.B. avoid overrun if nr == 0 */
-                       while (nr && tty->read_cnt) {
-                               int eol;
-
-                               eol = test_and_clear_bit(tty->read_tail,
-                                               tty->read_flags);
-                               c = tty->read_buf[tty->read_tail];
-                               spin_lock_irqsave(&tty->read_lock, flags);
-                               tty->read_tail = ((tty->read_tail+1) &
-                                                 (N_TTY_BUF_SIZE-1));
-                               tty->read_cnt--;
-                               if (eol) {
-                                       /* this test should be redundant:
-                                        * we shouldn't be reading data if
-                                        * canon_data is 0
-                                        */
-                                       if (--tty->canon_data < 0)
-                                               tty->canon_data = 0;
-                               }
-                               spin_unlock_irqrestore(&tty->read_lock, flags);
-
-                               if (!eol || (c != __DISABLED_CHAR)) {
-                                       if (tty_put_user(tty, c, b++)) {
-                                               retval = -EFAULT;
-                                               b--;
-                                               break;
-                                       }
-                                       nr--;
-                               }
-                               if (eol) {
-                                       tty_audit_push(tty);
-                                       break;
-                               }
-                       }
-                       if (retval)
-                               break;
-               } else {
-                       int uncopied;
-                       /* The copy function takes the read lock and handles
-                          locking internally for this case */
-                       uncopied = copy_from_read_buf(tty, &b, &nr);
-                       uncopied += copy_from_read_buf(tty, &b, &nr);
-                       if (uncopied) {
-                               retval = -EFAULT;
-                               break;
-                       }
-               }
-
-               /* If there is enough space in the read buffer now, let the
-                * low-level driver know. We use n_tty_chars_in_buffer() to
-                * check the buffer, as it now knows about canonical mode.
-                * Otherwise, if the driver is throttled and the line is
-                * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
-                * we won't get any more characters.
-                */
-               if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) {
-                       n_tty_set_room(tty);
-                       check_unthrottle(tty);
-               }
-
-               if (b - buf >= minimum)
-                       break;
-               if (time)
-                       timeout = time;
-       }
-       mutex_unlock(&tty->atomic_read_lock);
-       remove_wait_queue(&tty->read_wait, &wait);
-
-       if (!waitqueue_active(&tty->read_wait))
-               tty->minimum_to_wake = minimum;
-
-       __set_current_state(TASK_RUNNING);
-       size = b - buf;
-       if (size) {
-               retval = size;
-               if (nr)
-                       clear_bit(TTY_PUSH, &tty->flags);
-       } else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
-                goto do_it_again;
-
-       n_tty_set_room(tty);
-       return retval;
-}
-
-/**
- *     n_tty_write             -       write function for tty
- *     @tty: tty device
- *     @file: file object
- *     @buf: userspace buffer pointer
- *     @nr: size of I/O
- *
- *     Write function of the terminal device.  This is serialized with
- *     respect to other write callers but not to termios changes, reads
- *     and other such events.  Since the receive code will echo characters,
- *     thus calling driver write methods, the output_lock is used in
- *     the output processing functions called here as well as in the
- *     echo processing function to protect the column state and space
- *     left in the buffer.
- *
- *     This code must be sure never to sleep through a hangup.
- *
- *     Locking: output_lock to protect column state and space left
- *              (note that the process_output*() functions take this
- *               lock themselves)
- */
-
-static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
-                          const unsigned char *buf, size_t nr)
-{
-       const unsigned char *b = buf;
-       DECLARE_WAITQUEUE(wait, current);
-       int c;
-       ssize_t retval = 0;
-
-       /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
-       if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) {
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-       }
-
-       /* Write out any echoed characters that are still pending */
-       process_echoes(tty);
-
-       add_wait_queue(&tty->write_wait, &wait);
-       while (1) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               if (signal_pending(current)) {
-                       retval = -ERESTARTSYS;
-                       break;
-               }
-               if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
-                       retval = -EIO;
-                       break;
-               }
-               if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
-                       while (nr > 0) {
-                               ssize_t num = process_output_block(tty, b, nr);
-                               if (num < 0) {
-                                       if (num == -EAGAIN)
-                                               break;
-                                       retval = num;
-                                       goto break_out;
-                               }
-                               b += num;
-                               nr -= num;
-                               if (nr == 0)
-                                       break;
-                               c = *b;
-                               if (process_output(c, tty) < 0)
-                                       break;
-                               b++; nr--;
-                       }
-                       if (tty->ops->flush_chars)
-                               tty->ops->flush_chars(tty);
-               } else {
-                       while (nr > 0) {
-                               c = tty->ops->write(tty, b, nr);
-                               if (c < 0) {
-                                       retval = c;
-                                       goto break_out;
-                               }
-                               if (!c)
-                                       break;
-                               b += c;
-                               nr -= c;
-                       }
-               }
-               if (!nr)
-                       break;
-               if (file->f_flags & O_NONBLOCK) {
-                       retval = -EAGAIN;
-                       break;
-               }
-               schedule();
-       }
-break_out:
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&tty->write_wait, &wait);
-       if (b - buf != nr && tty->fasync)
-               set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-       return (b - buf) ? b - buf : retval;
-}
-
-/**
- *     n_tty_poll              -       poll method for N_TTY
- *     @tty: terminal device
- *     @file: file accessing it
- *     @wait: poll table
- *
- *     Called when the line discipline is asked to poll() for data or
- *     for special events. This code is not serialized with respect to
- *     other events save open/close.
- *
- *     This code must be sure never to sleep through a hangup.
- *     Called without the kernel lock held - fine
- */
-
-static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
-                                                       poll_table *wait)
-{
-       unsigned int mask = 0;
-
-       poll_wait(file, &tty->read_wait, wait);
-       poll_wait(file, &tty->write_wait, wait);
-       if (input_available_p(tty, TIME_CHAR(tty) ? 0 : MIN_CHAR(tty)))
-               mask |= POLLIN | POLLRDNORM;
-       if (tty->packet && tty->link->ctrl_status)
-               mask |= POLLPRI | POLLIN | POLLRDNORM;
-       if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
-               mask |= POLLHUP;
-       if (tty_hung_up_p(file))
-               mask |= POLLHUP;
-       if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
-               if (MIN_CHAR(tty) && !TIME_CHAR(tty))
-                       tty->minimum_to_wake = MIN_CHAR(tty);
-               else
-                       tty->minimum_to_wake = 1;
-       }
-       if (tty->ops->write && !tty_is_writelocked(tty) &&
-                       tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
-                       tty_write_room(tty) > 0)
-               mask |= POLLOUT | POLLWRNORM;
-       return mask;
-}
-
-static unsigned long inq_canon(struct tty_struct *tty)
-{
-       int nr, head, tail;
-
-       if (!tty->canon_data)
-               return 0;
-       head = tty->canon_head;
-       tail = tty->read_tail;
-       nr = (head - tail) & (N_TTY_BUF_SIZE-1);
-       /* Skip EOF-chars.. */
-       while (head != tail) {
-               if (test_bit(tail, tty->read_flags) &&
-                   tty->read_buf[tail] == __DISABLED_CHAR)
-                       nr--;
-               tail = (tail+1) & (N_TTY_BUF_SIZE-1);
-       }
-       return nr;
-}
-
-static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
-                      unsigned int cmd, unsigned long arg)
-{
-       int retval;
-
-       switch (cmd) {
-       case TIOCOUTQ:
-               return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
-       case TIOCINQ:
-               /* FIXME: Locking */
-               retval = tty->read_cnt;
-               if (L_ICANON(tty))
-                       retval = inq_canon(tty);
-               return put_user(retval, (unsigned int __user *) arg);
-       default:
-               return n_tty_ioctl_helper(tty, file, cmd, arg);
-       }
-}
-
-struct tty_ldisc_ops tty_ldisc_N_TTY = {
-       .magic           = TTY_LDISC_MAGIC,
-       .name            = "n_tty",
-       .open            = n_tty_open,
-       .close           = n_tty_close,
-       .flush_buffer    = n_tty_flush_buffer,
-       .chars_in_buffer = n_tty_chars_in_buffer,
-       .read            = n_tty_read,
-       .write           = n_tty_write,
-       .ioctl           = n_tty_ioctl,
-       .set_termios     = n_tty_set_termios,
-       .poll            = n_tty_poll,
-       .receive_buf     = n_tty_receive_buf,
-       .write_wakeup    = n_tty_write_wakeup
-};
-
-/**
- *     n_tty_inherit_ops       -       inherit N_TTY methods
- *     @ops: struct tty_ldisc_ops where to save N_TTY methods
- *
- *     Used by a generic struct tty_ldisc_ops to easily inherit N_TTY
- *     methods.
- */
-
-void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
-{
-       *ops = tty_ldisc_N_TTY;
-       ops->owner = NULL;
-       ops->refcount = ops->flags = 0;
-}
-EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
index dd3f9b1f11b4f59685853873977b3913daf3b0a2..294d03e8c61a6a249b6008878efd08386c86d0a9 100644 (file)
@@ -1828,7 +1828,6 @@ static int ntty_ioctl(struct tty_struct *tty, struct file *file,
                      unsigned int cmd, unsigned long arg)
 {
        struct port *port = tty->driver_data;
-       void __user *argp = (void __user *)arg;
        int rval = -ENOIOCTLCMD;
 
        DBG1("******** IOCTL, cmd: %d", cmd);
index d962f25dcc2a730b912c139f7b7ae5f7c408ce8d..777181a2e603592361b32bfea492429b506b64e6 100644 (file)
@@ -979,8 +979,9 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
                if (dev->flags0 & 1) {
                        set_bit(IS_CMM_ABSENT, &dev->flags);
                        rc = -ENODEV;
+               } else {
+                       rc = -EIO;
                }
-               rc = -EIO;
                goto release_io;
        }
 
index bfc10f89d9511d8f26367329c5b7658e8a6b526c..eaa41992fbe234a17bd1d102e05fd39229e0ac5d 100644 (file)
@@ -2796,6 +2796,7 @@ static const struct tty_operations mgslpc_ops = {
        .hangup = mgslpc_hangup,
        .tiocmget = tiocmget,
        .tiocmset = tiocmset,
+       .get_icount = mgslpc_get_icount,
        .proc_fops = &mgslpc_proc_fops,
 };
 
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
deleted file mode 100644 (file)
index 923a485..0000000
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- *  linux/drivers/char/pty.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *
- *  Added support for a Unix98-style ptmx device.
- *    -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
- *
- *  When reading this code see also fs/devpts. In particular note that the
- *  driver_data field is used by the devpts side as a binding to the devpts
- *  inode.
- */
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/fcntl.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/major.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/sysctl.h>
-#include <linux/device.h>
-#include <linux/uaccess.h>
-#include <linux/bitops.h>
-#include <linux/devpts_fs.h>
-#include <linux/slab.h>
-
-#include <asm/system.h>
-
-#ifdef CONFIG_UNIX98_PTYS
-static struct tty_driver *ptm_driver;
-static struct tty_driver *pts_driver;
-#endif
-
-static void pty_close(struct tty_struct *tty, struct file *filp)
-{
-       BUG_ON(!tty);
-       if (tty->driver->subtype == PTY_TYPE_MASTER)
-               WARN_ON(tty->count > 1);
-       else {
-               if (tty->count > 2)
-                       return;
-       }
-       wake_up_interruptible(&tty->read_wait);
-       wake_up_interruptible(&tty->write_wait);
-       tty->packet = 0;
-       if (!tty->link)
-               return;
-       tty->link->packet = 0;
-       set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
-       wake_up_interruptible(&tty->link->read_wait);
-       wake_up_interruptible(&tty->link->write_wait);
-       if (tty->driver->subtype == PTY_TYPE_MASTER) {
-               set_bit(TTY_OTHER_CLOSED, &tty->flags);
-#ifdef CONFIG_UNIX98_PTYS
-               if (tty->driver == ptm_driver)
-                       devpts_pty_kill(tty->link);
-#endif
-               tty_unlock();
-               tty_vhangup(tty->link);
-               tty_lock();
-       }
-}
-
-/*
- * The unthrottle routine is called by the line discipline to signal
- * that it can receive more characters.  For PTY's, the TTY_THROTTLED
- * flag is always set, to force the line discipline to always call the
- * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE
- * characters in the queue.  This is necessary since each time this
- * happens, we need to wake up any sleeping processes that could be
- * (1) trying to send data to the pty, or (2) waiting in wait_until_sent()
- * for the pty buffer to be drained.
- */
-static void pty_unthrottle(struct tty_struct *tty)
-{
-       tty_wakeup(tty->link);
-       set_bit(TTY_THROTTLED, &tty->flags);
-}
-
-/**
- *     pty_space       -       report space left for writing
- *     @to: tty we are writing into
- *
- *     The tty buffers allow 64K but we sneak a peak and clip at 8K this
- *     allows a lot of overspill room for echo and other fun messes to
- *     be handled properly
- */
-
-static int pty_space(struct tty_struct *to)
-{
-       int n = 8192 - to->buf.memory_used;
-       if (n < 0)
-               return 0;
-       return n;
-}
-
-/**
- *     pty_write               -       write to a pty
- *     @tty: the tty we write from
- *     @buf: kernel buffer of data
- *     @count: bytes to write
- *
- *     Our "hardware" write method. Data is coming from the ldisc which
- *     may be in a non sleeping state. We simply throw this at the other
- *     end of the link as if we were an IRQ handler receiving stuff for
- *     the other side of the pty/tty pair.
- */
-
-static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
-{
-       struct tty_struct *to = tty->link;
-
-       if (tty->stopped)
-               return 0;
-
-       if (c > 0) {
-               /* Stuff the data into the input queue of the other end */
-               c = tty_insert_flip_string(to, buf, c);
-               /* And shovel */
-               if (c) {
-                       tty_flip_buffer_push(to);
-                       tty_wakeup(tty);
-               }
-       }
-       return c;
-}
-
-/**
- *     pty_write_room  -       write space
- *     @tty: tty we are writing from
- *
- *     Report how many bytes the ldisc can send into the queue for
- *     the other device.
- */
-
-static int pty_write_room(struct tty_struct *tty)
-{
-       if (tty->stopped)
-               return 0;
-       return pty_space(tty->link);
-}
-
-/**
- *     pty_chars_in_buffer     -       characters currently in our tx queue
- *     @tty: our tty
- *
- *     Report how much we have in the transmit queue. As everything is
- *     instantly at the other end this is easy to implement.
- */
-
-static int pty_chars_in_buffer(struct tty_struct *tty)
-{
-       return 0;
-}
-
-/* Set the lock flag on a pty */
-static int pty_set_lock(struct tty_struct *tty, int __user *arg)
-{
-       int val;
-       if (get_user(val, arg))
-               return -EFAULT;
-       if (val)
-               set_bit(TTY_PTY_LOCK, &tty->flags);
-       else
-               clear_bit(TTY_PTY_LOCK, &tty->flags);
-       return 0;
-}
-
-/* Send a signal to the slave */
-static int pty_signal(struct tty_struct *tty, int sig)
-{
-       unsigned long flags;
-       struct pid *pgrp;
-
-       if (tty->link) {
-               spin_lock_irqsave(&tty->link->ctrl_lock, flags);
-               pgrp = get_pid(tty->link->pgrp);
-               spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
-
-               kill_pgrp(pgrp, sig, 1);
-               put_pid(pgrp);
-       }
-       return 0;
-}
-
-static void pty_flush_buffer(struct tty_struct *tty)
-{
-       struct tty_struct *to = tty->link;
-       unsigned long flags;
-
-       if (!to)
-               return;
-       /* tty_buffer_flush(to); FIXME */
-       if (to->packet) {
-               spin_lock_irqsave(&tty->ctrl_lock, flags);
-               tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
-               wake_up_interruptible(&to->read_wait);
-               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-       }
-}
-
-static int pty_open(struct tty_struct *tty, struct file *filp)
-{
-       int     retval = -ENODEV;
-
-       if (!tty || !tty->link)
-               goto out;
-
-       retval = -EIO;
-       if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
-               goto out;
-       if (test_bit(TTY_PTY_LOCK, &tty->link->flags))
-               goto out;
-       if (tty->link->count != 1)
-               goto out;
-
-       clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
-       set_bit(TTY_THROTTLED, &tty->flags);
-       retval = 0;
-out:
-       return retval;
-}
-
-static void pty_set_termios(struct tty_struct *tty,
-                                       struct ktermios *old_termios)
-{
-       tty->termios->c_cflag &= ~(CSIZE | PARENB);
-       tty->termios->c_cflag |= (CS8 | CREAD);
-}
-
-/**
- *     pty_do_resize           -       resize event
- *     @tty: tty being resized
- *     @ws: window size being set.
- *
- *     Update the termios variables and send the necessary signals to
- *     peform a terminal resize correctly
- */
-
-int pty_resize(struct tty_struct *tty,  struct winsize *ws)
-{
-       struct pid *pgrp, *rpgrp;
-       unsigned long flags;
-       struct tty_struct *pty = tty->link;
-
-       /* For a PTY we need to lock the tty side */
-       mutex_lock(&tty->termios_mutex);
-       if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
-               goto done;
-
-       /* Get the PID values and reference them so we can
-          avoid holding the tty ctrl lock while sending signals.
-          We need to lock these individually however. */
-
-       spin_lock_irqsave(&tty->ctrl_lock, flags);
-       pgrp = get_pid(tty->pgrp);
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-
-       spin_lock_irqsave(&pty->ctrl_lock, flags);
-       rpgrp = get_pid(pty->pgrp);
-       spin_unlock_irqrestore(&pty->ctrl_lock, flags);
-
-       if (pgrp)
-               kill_pgrp(pgrp, SIGWINCH, 1);
-       if (rpgrp != pgrp && rpgrp)
-               kill_pgrp(rpgrp, SIGWINCH, 1);
-
-       put_pid(pgrp);
-       put_pid(rpgrp);
-
-       tty->winsize = *ws;
-       pty->winsize = *ws;     /* Never used so will go away soon */
-done:
-       mutex_unlock(&tty->termios_mutex);
-       return 0;
-}
-
-/* Traditional BSD devices */
-#ifdef CONFIG_LEGACY_PTYS
-
-static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
-{
-       struct tty_struct *o_tty;
-       int idx = tty->index;
-       int retval;
-
-       o_tty = alloc_tty_struct();
-       if (!o_tty)
-               return -ENOMEM;
-       if (!try_module_get(driver->other->owner)) {
-               /* This cannot in fact currently happen */
-               free_tty_struct(o_tty);
-               return -ENOMEM;
-       }
-       initialize_tty_struct(o_tty, driver->other, idx);
-
-       /* We always use new tty termios data so we can do this
-          the easy way .. */
-       retval = tty_init_termios(tty);
-       if (retval)
-               goto free_mem_out;
-
-       retval = tty_init_termios(o_tty);
-       if (retval) {
-               tty_free_termios(tty);
-               goto free_mem_out;
-       }
-
-       /*
-        * Everything allocated ... set up the o_tty structure.
-        */
-       driver->other->ttys[idx] = o_tty;
-       tty_driver_kref_get(driver->other);
-       if (driver->subtype == PTY_TYPE_MASTER)
-               o_tty->count++;
-       /* Establish the links in both directions */
-       tty->link   = o_tty;
-       o_tty->link = tty;
-
-       tty_driver_kref_get(driver);
-       tty->count++;
-       driver->ttys[idx] = tty;
-       return 0;
-free_mem_out:
-       module_put(o_tty->driver->owner);
-       free_tty_struct(o_tty);
-       return -ENOMEM;
-}
-
-static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file,
-                        unsigned int cmd, unsigned long arg)
-{
-       switch (cmd) {
-       case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
-               return pty_set_lock(tty, (int __user *) arg);
-       case TIOCSIG:    /* Send signal to other side of pty */
-               return pty_signal(tty, (int) arg);
-       }
-       return -ENOIOCTLCMD;
-}
-
-static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
-module_param(legacy_count, int, 0);
-
-/*
- * The master side of a pty can do TIOCSPTLCK and thus
- * has pty_bsd_ioctl.
- */
-static const struct tty_operations master_pty_ops_bsd = {
-       .install = pty_install,
-       .open = pty_open,
-       .close = pty_close,
-       .write = pty_write,
-       .write_room = pty_write_room,
-       .flush_buffer = pty_flush_buffer,
-       .chars_in_buffer = pty_chars_in_buffer,
-       .unthrottle = pty_unthrottle,
-       .set_termios = pty_set_termios,
-       .ioctl = pty_bsd_ioctl,
-       .resize = pty_resize
-};
-
-static const struct tty_operations slave_pty_ops_bsd = {
-       .install = pty_install,
-       .open = pty_open,
-       .close = pty_close,
-       .write = pty_write,
-       .write_room = pty_write_room,
-       .flush_buffer = pty_flush_buffer,
-       .chars_in_buffer = pty_chars_in_buffer,
-       .unthrottle = pty_unthrottle,
-       .set_termios = pty_set_termios,
-       .resize = pty_resize
-};
-
-static void __init legacy_pty_init(void)
-{
-       struct tty_driver *pty_driver, *pty_slave_driver;
-
-       if (legacy_count <= 0)
-               return;
-
-       pty_driver = alloc_tty_driver(legacy_count);
-       if (!pty_driver)
-               panic("Couldn't allocate pty driver");
-
-       pty_slave_driver = alloc_tty_driver(legacy_count);
-       if (!pty_slave_driver)
-               panic("Couldn't allocate pty slave driver");
-
-       pty_driver->owner = THIS_MODULE;
-       pty_driver->driver_name = "pty_master";
-       pty_driver->name = "pty";
-       pty_driver->major = PTY_MASTER_MAJOR;
-       pty_driver->minor_start = 0;
-       pty_driver->type = TTY_DRIVER_TYPE_PTY;
-       pty_driver->subtype = PTY_TYPE_MASTER;
-       pty_driver->init_termios = tty_std_termios;
-       pty_driver->init_termios.c_iflag = 0;
-       pty_driver->init_termios.c_oflag = 0;
-       pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
-       pty_driver->init_termios.c_lflag = 0;
-       pty_driver->init_termios.c_ispeed = 38400;
-       pty_driver->init_termios.c_ospeed = 38400;
-       pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW;
-       pty_driver->other = pty_slave_driver;
-       tty_set_operations(pty_driver, &master_pty_ops_bsd);
-
-       pty_slave_driver->owner = THIS_MODULE;
-       pty_slave_driver->driver_name = "pty_slave";
-       pty_slave_driver->name = "ttyp";
-       pty_slave_driver->major = PTY_SLAVE_MAJOR;
-       pty_slave_driver->minor_start = 0;
-       pty_slave_driver->type = TTY_DRIVER_TYPE_PTY;
-       pty_slave_driver->subtype = PTY_TYPE_SLAVE;
-       pty_slave_driver->init_termios = tty_std_termios;
-       pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
-       pty_slave_driver->init_termios.c_ispeed = 38400;
-       pty_slave_driver->init_termios.c_ospeed = 38400;
-       pty_slave_driver->flags = TTY_DRIVER_RESET_TERMIOS |
-                                       TTY_DRIVER_REAL_RAW;
-       pty_slave_driver->other = pty_driver;
-       tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd);
-
-       if (tty_register_driver(pty_driver))
-               panic("Couldn't register pty driver");
-       if (tty_register_driver(pty_slave_driver))
-               panic("Couldn't register pty slave driver");
-}
-#else
-static inline void legacy_pty_init(void) { }
-#endif
-
-/* Unix98 devices */
-#ifdef CONFIG_UNIX98_PTYS
-/*
- * sysctl support for setting limits on the number of Unix98 ptys allocated.
- * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
- */
-int pty_limit = NR_UNIX98_PTY_DEFAULT;
-static int pty_limit_min;
-static int pty_limit_max = NR_UNIX98_PTY_MAX;
-static int pty_count;
-
-static struct cdev ptmx_cdev;
-
-static struct ctl_table pty_table[] = {
-       {
-               .procname       = "max",
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .data           = &pty_limit,
-               .proc_handler   = proc_dointvec_minmax,
-               .extra1         = &pty_limit_min,
-               .extra2         = &pty_limit_max,
-       }, {
-               .procname       = "nr",
-               .maxlen         = sizeof(int),
-               .mode           = 0444,
-               .data           = &pty_count,
-               .proc_handler   = proc_dointvec,
-       }, 
-       {}
-};
-
-static struct ctl_table pty_kern_table[] = {
-       {
-               .procname       = "pty",
-               .mode           = 0555,
-               .child          = pty_table,
-       },
-       {}
-};
-
-static struct ctl_table pty_root_table[] = {
-       {
-               .procname       = "kernel",
-               .mode           = 0555,
-               .child          = pty_kern_table,
-       },
-       {}
-};
-
-
-static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
-                           unsigned int cmd, unsigned long arg)
-{
-       switch (cmd) {
-       case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
-               return pty_set_lock(tty, (int __user *)arg);
-       case TIOCGPTN: /* Get PT Number */
-               return put_user(tty->index, (unsigned int __user *)arg);
-       case TIOCSIG:    /* Send signal to other side of pty */
-               return pty_signal(tty, (int) arg);
-       }
-
-       return -ENOIOCTLCMD;
-}
-
-/**
- *     ptm_unix98_lookup       -       find a pty master
- *     @driver: ptm driver
- *     @idx: tty index
- *
- *     Look up a pty master device. Called under the tty_mutex for now.
- *     This provides our locking.
- */
-
-static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver,
-               struct inode *ptm_inode, int idx)
-{
-       struct tty_struct *tty = devpts_get_tty(ptm_inode, idx);
-       if (tty)
-               tty = tty->link;
-       return tty;
-}
-
-/**
- *     pts_unix98_lookup       -       find a pty slave
- *     @driver: pts driver
- *     @idx: tty index
- *
- *     Look up a pty master device. Called under the tty_mutex for now.
- *     This provides our locking.
- */
-
-static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
-               struct inode *pts_inode, int idx)
-{
-       struct tty_struct *tty = devpts_get_tty(pts_inode, idx);
-       /* Master must be open before slave */
-       if (!tty)
-               return ERR_PTR(-EIO);
-       return tty;
-}
-
-static void pty_unix98_shutdown(struct tty_struct *tty)
-{
-       /* We have our own method as we don't use the tty index */
-       kfree(tty->termios);
-}
-
-/* We have no need to install and remove our tty objects as devpts does all
-   the work for us */
-
-static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
-{
-       struct tty_struct *o_tty;
-       int idx = tty->index;
-
-       o_tty = alloc_tty_struct();
-       if (!o_tty)
-               return -ENOMEM;
-       if (!try_module_get(driver->other->owner)) {
-               /* This cannot in fact currently happen */
-               free_tty_struct(o_tty);
-               return -ENOMEM;
-       }
-       initialize_tty_struct(o_tty, driver->other, idx);
-
-       tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
-       if (tty->termios == NULL)
-               goto free_mem_out;
-       *tty->termios = driver->init_termios;
-       tty->termios_locked = tty->termios + 1;
-
-       o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
-       if (o_tty->termios == NULL)
-               goto free_mem_out;
-       *o_tty->termios = driver->other->init_termios;
-       o_tty->termios_locked = o_tty->termios + 1;
-
-       tty_driver_kref_get(driver->other);
-       if (driver->subtype == PTY_TYPE_MASTER)
-               o_tty->count++;
-       /* Establish the links in both directions */
-       tty->link   = o_tty;
-       o_tty->link = tty;
-       /*
-        * All structures have been allocated, so now we install them.
-        * Failures after this point use release_tty to clean up, so
-        * there's no need to null out the local pointers.
-        */
-       tty_driver_kref_get(driver);
-       tty->count++;
-       pty_count++;
-       return 0;
-free_mem_out:
-       kfree(o_tty->termios);
-       module_put(o_tty->driver->owner);
-       free_tty_struct(o_tty);
-       kfree(tty->termios);
-       return -ENOMEM;
-}
-
-static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
-{
-       pty_count--;
-}
-
-static const struct tty_operations ptm_unix98_ops = {
-       .lookup = ptm_unix98_lookup,
-       .install = pty_unix98_install,
-       .remove = pty_unix98_remove,
-       .open = pty_open,
-       .close = pty_close,
-       .write = pty_write,
-       .write_room = pty_write_room,
-       .flush_buffer = pty_flush_buffer,
-       .chars_in_buffer = pty_chars_in_buffer,
-       .unthrottle = pty_unthrottle,
-       .set_termios = pty_set_termios,
-       .ioctl = pty_unix98_ioctl,
-       .shutdown = pty_unix98_shutdown,
-       .resize = pty_resize
-};
-
-static const struct tty_operations pty_unix98_ops = {
-       .lookup = pts_unix98_lookup,
-       .install = pty_unix98_install,
-       .remove = pty_unix98_remove,
-       .open = pty_open,
-       .close = pty_close,
-       .write = pty_write,
-       .write_room = pty_write_room,
-       .flush_buffer = pty_flush_buffer,
-       .chars_in_buffer = pty_chars_in_buffer,
-       .unthrottle = pty_unthrottle,
-       .set_termios = pty_set_termios,
-       .shutdown = pty_unix98_shutdown
-};
-
-/**
- *     ptmx_open               -       open a unix 98 pty master
- *     @inode: inode of device file
- *     @filp: file pointer to tty
- *
- *     Allocate a unix98 pty master device from the ptmx driver.
- *
- *     Locking: tty_mutex protects the init_dev work. tty->count should
- *             protect the rest.
- *             allocated_ptys_lock handles the list of free pty numbers
- */
-
-static int ptmx_open(struct inode *inode, struct file *filp)
-{
-       struct tty_struct *tty;
-       int retval;
-       int index;
-
-       nonseekable_open(inode, filp);
-
-       /* find a device that is not in use. */
-       tty_lock();
-       index = devpts_new_index(inode);
-       tty_unlock();
-       if (index < 0)
-               return index;
-
-       mutex_lock(&tty_mutex);
-       tty_lock();
-       tty = tty_init_dev(ptm_driver, index, 1);
-       mutex_unlock(&tty_mutex);
-
-       if (IS_ERR(tty)) {
-               retval = PTR_ERR(tty);
-               goto out;
-       }
-
-       set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
-
-       retval = tty_add_file(tty, filp);
-       if (retval)
-               goto out;
-
-       retval = devpts_pty_new(inode, tty->link);
-       if (retval)
-               goto out1;
-
-       retval = ptm_driver->ops->open(tty, filp);
-       if (retval)
-               goto out2;
-out1:
-       tty_unlock();
-       return retval;
-out2:
-       tty_unlock();
-       tty_release(inode, filp);
-       return retval;
-out:
-       devpts_kill_index(inode, index);
-       tty_unlock();
-       return retval;
-}
-
-static struct file_operations ptmx_fops;
-
-static void __init unix98_pty_init(void)
-{
-       ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
-       if (!ptm_driver)
-               panic("Couldn't allocate Unix98 ptm driver");
-       pts_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
-       if (!pts_driver)
-               panic("Couldn't allocate Unix98 pts driver");
-
-       ptm_driver->owner = THIS_MODULE;
-       ptm_driver->driver_name = "pty_master";
-       ptm_driver->name = "ptm";
-       ptm_driver->major = UNIX98_PTY_MASTER_MAJOR;
-       ptm_driver->minor_start = 0;
-       ptm_driver->type = TTY_DRIVER_TYPE_PTY;
-       ptm_driver->subtype = PTY_TYPE_MASTER;
-       ptm_driver->init_termios = tty_std_termios;
-       ptm_driver->init_termios.c_iflag = 0;
-       ptm_driver->init_termios.c_oflag = 0;
-       ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
-       ptm_driver->init_termios.c_lflag = 0;
-       ptm_driver->init_termios.c_ispeed = 38400;
-       ptm_driver->init_termios.c_ospeed = 38400;
-       ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
-               TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
-       ptm_driver->other = pts_driver;
-       tty_set_operations(ptm_driver, &ptm_unix98_ops);
-
-       pts_driver->owner = THIS_MODULE;
-       pts_driver->driver_name = "pty_slave";
-       pts_driver->name = "pts";
-       pts_driver->major = UNIX98_PTY_SLAVE_MAJOR;
-       pts_driver->minor_start = 0;
-       pts_driver->type = TTY_DRIVER_TYPE_PTY;
-       pts_driver->subtype = PTY_TYPE_SLAVE;
-       pts_driver->init_termios = tty_std_termios;
-       pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
-       pts_driver->init_termios.c_ispeed = 38400;
-       pts_driver->init_termios.c_ospeed = 38400;
-       pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
-               TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
-       pts_driver->other = ptm_driver;
-       tty_set_operations(pts_driver, &pty_unix98_ops);
-
-       if (tty_register_driver(ptm_driver))
-               panic("Couldn't register Unix98 ptm driver");
-       if (tty_register_driver(pts_driver))
-               panic("Couldn't register Unix98 pts driver");
-
-       register_sysctl_table(pty_root_table);
-
-       /* Now create the /dev/ptmx special device */
-       tty_default_fops(&ptmx_fops);
-       ptmx_fops.open = ptmx_open;
-
-       cdev_init(&ptmx_cdev, &ptmx_fops);
-       if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
-           register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
-               panic("Couldn't register /dev/ptmx driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
-}
-
-#else
-static inline void unix98_pty_init(void) { }
-#endif
-
-static int __init pty_init(void)
-{
-       legacy_pty_init();
-       unix98_pty_init();
-       return 0;
-}
-module_init(pty_init);
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
deleted file mode 100644 (file)
index ebae344..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * linux/drivers/char/selection.c
- *
- * This module exports the functions:
- *
- *     'int set_selection(struct tiocl_selection __user *, struct tty_struct *)'
- *     'void clear_selection(void)'
- *     'int paste_selection(struct tty_struct *)'
- *     'int sel_loadlut(char __user *)'
- *
- * Now that /dev/vcs exists, most of this can disappear again.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-
-#include <asm/uaccess.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/consolemap.h>
-#include <linux/selection.h>
-#include <linux/tiocl.h>
-#include <linux/console.h>
-#include <linux/smp_lock.h>
-
-/* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */
-#define isspace(c)     ((c) == ' ')
-
-extern void poke_blanked_console(void);
-
-/* Variables for selection control. */
-/* Use a dynamic buffer, instead of static (Dec 1994) */
-struct vc_data *sel_cons;              /* must not be deallocated */
-static int use_unicode;
-static volatile int sel_start = -1;    /* cleared by clear_selection */
-static int sel_end;
-static int sel_buffer_lth;
-static char *sel_buffer;
-
-/* clear_selection, highlight and highlight_pointer can be called
-   from interrupt (via scrollback/front) */
-
-/* set reverse video on characters s-e of console with selection. */
-static inline void highlight(const int s, const int e)
-{
-       invert_screen(sel_cons, s, e-s+2, 1);
-}
-
-/* use complementary color to show the pointer */
-static inline void highlight_pointer(const int where)
-{
-       complement_pos(sel_cons, where);
-}
-
-static u16
-sel_pos(int n)
-{
-       return inverse_translate(sel_cons, screen_glyph(sel_cons, n),
-                               use_unicode);
-}
-
-/* remove the current selection highlight, if any,
-   from the console holding the selection. */
-void
-clear_selection(void) {
-       highlight_pointer(-1); /* hide the pointer */
-       if (sel_start != -1) {
-               highlight(sel_start, sel_end);
-               sel_start = -1;
-       }
-}
-
-/*
- * User settable table: what characters are to be considered alphabetic?
- * 256 bits
- */
-static u32 inwordLut[8]={
-  0x00000000, /* control chars     */
-  0x03FF0000, /* digits            */
-  0x87FFFFFE, /* uppercase and '_' */
-  0x07FFFFFE, /* lowercase         */
-  0x00000000,
-  0x00000000,
-  0xFF7FFFFF, /* latin-1 accented letters, not multiplication sign */
-  0xFF7FFFFF  /* latin-1 accented letters, not division sign */
-};
-
-static inline int inword(const u16 c) {
-       return c > 0xff || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1);
-}
-
-/* set inwordLut contents. Invoked by ioctl(). */
-int sel_loadlut(char __user *p)
-{
-       return copy_from_user(inwordLut, (u32 __user *)(p+4), 32) ? -EFAULT : 0;
-}
-
-/* does screen address p correspond to character at LH/RH edge of screen? */
-static inline int atedge(const int p, int size_row)
-{
-       return (!(p % size_row) || !((p + 2) % size_row));
-}
-
-/* constrain v such that v <= u */
-static inline unsigned short limit(const unsigned short v, const unsigned short u)
-{
-       return (v > u) ? u : v;
-}
-
-/* stores the char in UTF8 and returns the number of bytes used (1-3) */
-static int store_utf8(u16 c, char *p)
-{
-       if (c < 0x80) {
-               /*  0******* */
-               p[0] = c;
-               return 1;
-       } else if (c < 0x800) {
-               /* 110***** 10****** */
-               p[0] = 0xc0 | (c >> 6);
-               p[1] = 0x80 | (c & 0x3f);
-               return 2;
-       } else {
-               /* 1110**** 10****** 10****** */
-               p[0] = 0xe0 | (c >> 12);
-               p[1] = 0x80 | ((c >> 6) & 0x3f);
-               p[2] = 0x80 | (c & 0x3f);
-               return 3;
-       }
-}
-
-/* set the current selection. Invoked by ioctl() or by kernel code. */
-int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
-{
-       struct vc_data *vc = vc_cons[fg_console].d;
-       int sel_mode, new_sel_start, new_sel_end, spc;
-       char *bp, *obp;
-       int i, ps, pe, multiplier;
-       u16 c;
-       struct kbd_struct *kbd = kbd_table + fg_console;
-
-       poke_blanked_console();
-
-       { unsigned short xs, ys, xe, ye;
-
-         if (!access_ok(VERIFY_READ, sel, sizeof(*sel)))
-               return -EFAULT;
-         __get_user(xs, &sel->xs);
-         __get_user(ys, &sel->ys);
-         __get_user(xe, &sel->xe);
-         __get_user(ye, &sel->ye);
-         __get_user(sel_mode, &sel->sel_mode);
-         xs--; ys--; xe--; ye--;
-         xs = limit(xs, vc->vc_cols - 1);
-         ys = limit(ys, vc->vc_rows - 1);
-         xe = limit(xe, vc->vc_cols - 1);
-         ye = limit(ye, vc->vc_rows - 1);
-         ps = ys * vc->vc_size_row + (xs << 1);
-         pe = ye * vc->vc_size_row + (xe << 1);
-
-         if (sel_mode == TIOCL_SELCLEAR) {
-             /* useful for screendump without selection highlights */
-             clear_selection();
-             return 0;
-         }
-
-         if (mouse_reporting() && (sel_mode & TIOCL_SELMOUSEREPORT)) {
-             mouse_report(tty, sel_mode & TIOCL_SELBUTTONMASK, xs, ys);
-             return 0;
-         }
-        }
-
-       if (ps > pe)    /* make sel_start <= sel_end */
-       {
-               int tmp = ps;
-               ps = pe;
-               pe = tmp;
-       }
-
-       if (sel_cons != vc_cons[fg_console].d) {
-               clear_selection();
-               sel_cons = vc_cons[fg_console].d;
-       }
-       use_unicode = kbd && kbd->kbdmode == VC_UNICODE;
-
-       switch (sel_mode)
-       {
-               case TIOCL_SELCHAR:     /* character-by-character selection */
-                       new_sel_start = ps;
-                       new_sel_end = pe;
-                       break;
-               case TIOCL_SELWORD:     /* word-by-word selection */
-                       spc = isspace(sel_pos(ps));
-                       for (new_sel_start = ps; ; ps -= 2)
-                       {
-                               if ((spc && !isspace(sel_pos(ps))) ||
-                                   (!spc && !inword(sel_pos(ps))))
-                                       break;
-                               new_sel_start = ps;
-                               if (!(ps % vc->vc_size_row))
-                                       break;
-                       }
-                       spc = isspace(sel_pos(pe));
-                       for (new_sel_end = pe; ; pe += 2)
-                       {
-                               if ((spc && !isspace(sel_pos(pe))) ||
-                                   (!spc && !inword(sel_pos(pe))))
-                                       break;
-                               new_sel_end = pe;
-                               if (!((pe + 2) % vc->vc_size_row))
-                                       break;
-                       }
-                       break;
-               case TIOCL_SELLINE:     /* line-by-line selection */
-                       new_sel_start = ps - ps % vc->vc_size_row;
-                       new_sel_end = pe + vc->vc_size_row
-                                   - pe % vc->vc_size_row - 2;
-                       break;
-               case TIOCL_SELPOINTER:
-                       highlight_pointer(pe);
-                       return 0;
-               default:
-                       return -EINVAL;
-       }
-
-       /* remove the pointer */
-       highlight_pointer(-1);
-
-       /* select to end of line if on trailing space */
-       if (new_sel_end > new_sel_start &&
-               !atedge(new_sel_end, vc->vc_size_row) &&
-               isspace(sel_pos(new_sel_end))) {
-               for (pe = new_sel_end + 2; ; pe += 2)
-                       if (!isspace(sel_pos(pe)) ||
-                           atedge(pe, vc->vc_size_row))
-                               break;
-               if (isspace(sel_pos(pe)))
-                       new_sel_end = pe;
-       }
-       if (sel_start == -1)    /* no current selection */
-               highlight(new_sel_start, new_sel_end);
-       else if (new_sel_start == sel_start)
-       {
-               if (new_sel_end == sel_end)     /* no action required */
-                       return 0;
-               else if (new_sel_end > sel_end) /* extend to right */
-                       highlight(sel_end + 2, new_sel_end);
-               else                            /* contract from right */
-                       highlight(new_sel_end + 2, sel_end);
-       }
-       else if (new_sel_end == sel_end)
-       {
-               if (new_sel_start < sel_start)  /* extend to left */
-                       highlight(new_sel_start, sel_start - 2);
-               else                            /* contract from left */
-                       highlight(sel_start, new_sel_start - 2);
-       }
-       else    /* some other case; start selection from scratch */
-       {
-               clear_selection();
-               highlight(new_sel_start, new_sel_end);
-       }
-       sel_start = new_sel_start;
-       sel_end = new_sel_end;
-
-       /* Allocate a new buffer before freeing the old one ... */
-       multiplier = use_unicode ? 3 : 1;  /* chars can take up to 3 bytes */
-       bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL);
-       if (!bp) {
-               printk(KERN_WARNING "selection: kmalloc() failed\n");
-               clear_selection();
-               return -ENOMEM;
-       }
-       kfree(sel_buffer);
-       sel_buffer = bp;
-
-       obp = bp;
-       for (i = sel_start; i <= sel_end; i += 2) {
-               c = sel_pos(i);
-               if (use_unicode)
-                       bp += store_utf8(c, bp);
-               else
-                       *bp++ = c;
-               if (!isspace(c))
-                       obp = bp;
-               if (! ((i + 2) % vc->vc_size_row)) {
-                       /* strip trailing blanks from line and add newline,
-                          unless non-space at end of line. */
-                       if (obp != bp) {
-                               bp = obp;
-                               *bp++ = '\r';
-                       }
-                       obp = bp;
-               }
-       }
-       sel_buffer_lth = bp - sel_buffer;
-       return 0;
-}
-
-/* Insert the contents of the selection buffer into the
- * queue of the tty associated with the current console.
- * Invoked by ioctl().
- */
-int paste_selection(struct tty_struct *tty)
-{
-       struct vc_data *vc = tty->driver_data;
-       int     pasted = 0;
-       unsigned int count;
-       struct  tty_ldisc *ld;
-       DECLARE_WAITQUEUE(wait, current);
-
-       /* always called with BTM from vt_ioctl */
-       WARN_ON(!tty_locked());
-
-       acquire_console_sem();
-       poke_blanked_console();
-       release_console_sem();
-
-       ld = tty_ldisc_ref(tty);
-       if (!ld) {
-               tty_unlock();
-               ld = tty_ldisc_ref_wait(tty);
-               tty_lock();
-       }
-
-       add_wait_queue(&vc->paste_wait, &wait);
-       while (sel_buffer && sel_buffer_lth > pasted) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               if (test_bit(TTY_THROTTLED, &tty->flags)) {
-                       schedule();
-                       continue;
-               }
-               count = sel_buffer_lth - pasted;
-               count = min(count, tty->receive_room);
-               tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
-                                                               NULL, count);
-               pasted += count;
-       }
-       remove_wait_queue(&vc->paste_wait, &wait);
-       __set_current_state(TASK_RUNNING);
-
-       tty_ldisc_deref(ld);
-       return 0;
-}
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
deleted file mode 100644 (file)
index eaa5d3e..0000000
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- *     Linux Magic System Request Key Hacks
- *
- *     (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- *     based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>
- *
- *     (c) 2000 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
- *     overhauled to use key registration
- *     based upon discusions in irc://irc.openprojects.net/#kernelnewbies
- *
- *     Copyright (c) 2010 Dmitry Torokhov
- *     Input handler conversion
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
-#include <linux/reboot.h>
-#include <linux/sysrq.h>
-#include <linux/kbd_kern.h>
-#include <linux/proc_fs.h>
-#include <linux/nmi.h>
-#include <linux/quotaops.h>
-#include <linux/perf_event.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/suspend.h>
-#include <linux/writeback.h>
-#include <linux/buffer_head.h>         /* for fsync_bdev() */
-#include <linux/swap.h>
-#include <linux/spinlock.h>
-#include <linux/vt_kern.h>
-#include <linux/workqueue.h>
-#include <linux/hrtimer.h>
-#include <linux/oom.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-
-#include <asm/ptrace.h>
-#include <asm/irq_regs.h>
-
-/* Whether we react on sysrq keys or just ignore them */
-static int __read_mostly sysrq_enabled = 1;
-static bool __read_mostly sysrq_always_enabled;
-
-static bool sysrq_on(void)
-{
-       return sysrq_enabled || sysrq_always_enabled;
-}
-
-/*
- * A value of 1 means 'all', other nonzero values are an op mask:
- */
-static bool sysrq_on_mask(int mask)
-{
-       return sysrq_always_enabled ||
-              sysrq_enabled == 1 ||
-              (sysrq_enabled & mask);
-}
-
-static int __init sysrq_always_enabled_setup(char *str)
-{
-       sysrq_always_enabled = true;
-       pr_info("sysrq always enabled.\n");
-
-       return 1;
-}
-
-__setup("sysrq_always_enabled", sysrq_always_enabled_setup);
-
-
-static void sysrq_handle_loglevel(int key)
-{
-       int i;
-
-       i = key - '0';
-       console_loglevel = 7;
-       printk("Loglevel set to %d\n", i);
-       console_loglevel = i;
-}
-static struct sysrq_key_op sysrq_loglevel_op = {
-       .handler        = sysrq_handle_loglevel,
-       .help_msg       = "loglevel(0-9)",
-       .action_msg     = "Changing Loglevel",
-       .enable_mask    = SYSRQ_ENABLE_LOG,
-};
-
-#ifdef CONFIG_VT
-static void sysrq_handle_SAK(int key)
-{
-       struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
-       schedule_work(SAK_work);
-}
-static struct sysrq_key_op sysrq_SAK_op = {
-       .handler        = sysrq_handle_SAK,
-       .help_msg       = "saK",
-       .action_msg     = "SAK",
-       .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
-};
-#else
-#define sysrq_SAK_op (*(struct sysrq_key_op *)NULL)
-#endif
-
-#ifdef CONFIG_VT
-static void sysrq_handle_unraw(int key)
-{
-       struct kbd_struct *kbd = &kbd_table[fg_console];
-
-       if (kbd)
-               kbd->kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
-}
-static struct sysrq_key_op sysrq_unraw_op = {
-       .handler        = sysrq_handle_unraw,
-       .help_msg       = "unRaw",
-       .action_msg     = "Keyboard mode set to system default",
-       .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
-};
-#else
-#define sysrq_unraw_op (*(struct sysrq_key_op *)NULL)
-#endif /* CONFIG_VT */
-
-static void sysrq_handle_crash(int key)
-{
-       char *killer = NULL;
-
-       panic_on_oops = 1;      /* force panic */
-       wmb();
-       *killer = 1;
-}
-static struct sysrq_key_op sysrq_crash_op = {
-       .handler        = sysrq_handle_crash,
-       .help_msg       = "Crash",
-       .action_msg     = "Trigger a crash",
-       .enable_mask    = SYSRQ_ENABLE_DUMP,
-};
-
-static void sysrq_handle_reboot(int key)
-{
-       lockdep_off();
-       local_irq_enable();
-       emergency_restart();
-}
-static struct sysrq_key_op sysrq_reboot_op = {
-       .handler        = sysrq_handle_reboot,
-       .help_msg       = "reBoot",
-       .action_msg     = "Resetting",
-       .enable_mask    = SYSRQ_ENABLE_BOOT,
-};
-
-static void sysrq_handle_sync(int key)
-{
-       emergency_sync();
-}
-static struct sysrq_key_op sysrq_sync_op = {
-       .handler        = sysrq_handle_sync,
-       .help_msg       = "Sync",
-       .action_msg     = "Emergency Sync",
-       .enable_mask    = SYSRQ_ENABLE_SYNC,
-};
-
-static void sysrq_handle_show_timers(int key)
-{
-       sysrq_timer_list_show();
-}
-
-static struct sysrq_key_op sysrq_show_timers_op = {
-       .handler        = sysrq_handle_show_timers,
-       .help_msg       = "show-all-timers(Q)",
-       .action_msg     = "Show clockevent devices & pending hrtimers (no others)",
-};
-
-static void sysrq_handle_mountro(int key)
-{
-       emergency_remount();
-}
-static struct sysrq_key_op sysrq_mountro_op = {
-       .handler        = sysrq_handle_mountro,
-       .help_msg       = "Unmount",
-       .action_msg     = "Emergency Remount R/O",
-       .enable_mask    = SYSRQ_ENABLE_REMOUNT,
-};
-
-#ifdef CONFIG_LOCKDEP
-static void sysrq_handle_showlocks(int key)
-{
-       debug_show_all_locks();
-}
-
-static struct sysrq_key_op sysrq_showlocks_op = {
-       .handler        = sysrq_handle_showlocks,
-       .help_msg       = "show-all-locks(D)",
-       .action_msg     = "Show Locks Held",
-};
-#else
-#define sysrq_showlocks_op (*(struct sysrq_key_op *)NULL)
-#endif
-
-#ifdef CONFIG_SMP
-static DEFINE_SPINLOCK(show_lock);
-
-static void showacpu(void *dummy)
-{
-       unsigned long flags;
-
-       /* Idle CPUs have no interesting backtrace. */
-       if (idle_cpu(smp_processor_id()))
-               return;
-
-       spin_lock_irqsave(&show_lock, flags);
-       printk(KERN_INFO "CPU%d:\n", smp_processor_id());
-       show_stack(NULL, NULL);
-       spin_unlock_irqrestore(&show_lock, flags);
-}
-
-static void sysrq_showregs_othercpus(struct work_struct *dummy)
-{
-       smp_call_function(showacpu, NULL, 0);
-}
-
-static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus);
-
-static void sysrq_handle_showallcpus(int key)
-{
-       /*
-        * Fall back to the workqueue based printing if the
-        * backtrace printing did not succeed or the
-        * architecture has no support for it:
-        */
-       if (!trigger_all_cpu_backtrace()) {
-               struct pt_regs *regs = get_irq_regs();
-
-               if (regs) {
-                       printk(KERN_INFO "CPU%d:\n", smp_processor_id());
-                       show_regs(regs);
-               }
-               schedule_work(&sysrq_showallcpus);
-       }
-}
-
-static struct sysrq_key_op sysrq_showallcpus_op = {
-       .handler        = sysrq_handle_showallcpus,
-       .help_msg       = "show-backtrace-all-active-cpus(L)",
-       .action_msg     = "Show backtrace of all active CPUs",
-       .enable_mask    = SYSRQ_ENABLE_DUMP,
-};
-#endif
-
-static void sysrq_handle_showregs(int key)
-{
-       struct pt_regs *regs = get_irq_regs();
-       if (regs)
-               show_regs(regs);
-       perf_event_print_debug();
-}
-static struct sysrq_key_op sysrq_showregs_op = {
-       .handler        = sysrq_handle_showregs,
-       .help_msg       = "show-registers(P)",
-       .action_msg     = "Show Regs",
-       .enable_mask    = SYSRQ_ENABLE_DUMP,
-};
-
-static void sysrq_handle_showstate(int key)
-{
-       show_state();
-}
-static struct sysrq_key_op sysrq_showstate_op = {
-       .handler        = sysrq_handle_showstate,
-       .help_msg       = "show-task-states(T)",
-       .action_msg     = "Show State",
-       .enable_mask    = SYSRQ_ENABLE_DUMP,
-};
-
-static void sysrq_handle_showstate_blocked(int key)
-{
-       show_state_filter(TASK_UNINTERRUPTIBLE);
-}
-static struct sysrq_key_op sysrq_showstate_blocked_op = {
-       .handler        = sysrq_handle_showstate_blocked,
-       .help_msg       = "show-blocked-tasks(W)",
-       .action_msg     = "Show Blocked State",
-       .enable_mask    = SYSRQ_ENABLE_DUMP,
-};
-
-#ifdef CONFIG_TRACING
-#include <linux/ftrace.h>
-
-static void sysrq_ftrace_dump(int key)
-{
-       ftrace_dump(DUMP_ALL);
-}
-static struct sysrq_key_op sysrq_ftrace_dump_op = {
-       .handler        = sysrq_ftrace_dump,
-       .help_msg       = "dump-ftrace-buffer(Z)",
-       .action_msg     = "Dump ftrace buffer",
-       .enable_mask    = SYSRQ_ENABLE_DUMP,
-};
-#else
-#define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL)
-#endif
-
-static void sysrq_handle_showmem(int key)
-{
-       show_mem();
-}
-static struct sysrq_key_op sysrq_showmem_op = {
-       .handler        = sysrq_handle_showmem,
-       .help_msg       = "show-memory-usage(M)",
-       .action_msg     = "Show Memory",
-       .enable_mask    = SYSRQ_ENABLE_DUMP,
-};
-
-/*
- * Signal sysrq helper function.  Sends a signal to all user processes.
- */
-static void send_sig_all(int sig)
-{
-       struct task_struct *p;
-
-       for_each_process(p) {
-               if (p->mm && !is_global_init(p))
-                       /* Not swapper, init nor kernel thread */
-                       force_sig(sig, p);
-       }
-}
-
-static void sysrq_handle_term(int key)
-{
-       send_sig_all(SIGTERM);
-       console_loglevel = 8;
-}
-static struct sysrq_key_op sysrq_term_op = {
-       .handler        = sysrq_handle_term,
-       .help_msg       = "terminate-all-tasks(E)",
-       .action_msg     = "Terminate All Tasks",
-       .enable_mask    = SYSRQ_ENABLE_SIGNAL,
-};
-
-static void moom_callback(struct work_struct *ignored)
-{
-       out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0, NULL);
-}
-
-static DECLARE_WORK(moom_work, moom_callback);
-
-static void sysrq_handle_moom(int key)
-{
-       schedule_work(&moom_work);
-}
-static struct sysrq_key_op sysrq_moom_op = {
-       .handler        = sysrq_handle_moom,
-       .help_msg       = "memory-full-oom-kill(F)",
-       .action_msg     = "Manual OOM execution",
-       .enable_mask    = SYSRQ_ENABLE_SIGNAL,
-};
-
-#ifdef CONFIG_BLOCK
-static void sysrq_handle_thaw(int key)
-{
-       emergency_thaw_all();
-}
-static struct sysrq_key_op sysrq_thaw_op = {
-       .handler        = sysrq_handle_thaw,
-       .help_msg       = "thaw-filesystems(J)",
-       .action_msg     = "Emergency Thaw of all frozen filesystems",
-       .enable_mask    = SYSRQ_ENABLE_SIGNAL,
-};
-#endif
-
-static void sysrq_handle_kill(int key)
-{
-       send_sig_all(SIGKILL);
-       console_loglevel = 8;
-}
-static struct sysrq_key_op sysrq_kill_op = {
-       .handler        = sysrq_handle_kill,
-       .help_msg       = "kill-all-tasks(I)",
-       .action_msg     = "Kill All Tasks",
-       .enable_mask    = SYSRQ_ENABLE_SIGNAL,
-};
-
-static void sysrq_handle_unrt(int key)
-{
-       normalize_rt_tasks();
-}
-static struct sysrq_key_op sysrq_unrt_op = {
-       .handler        = sysrq_handle_unrt,
-       .help_msg       = "nice-all-RT-tasks(N)",
-       .action_msg     = "Nice All RT Tasks",
-       .enable_mask    = SYSRQ_ENABLE_RTNICE,
-};
-
-/* Key Operations table and lock */
-static DEFINE_SPINLOCK(sysrq_key_table_lock);
-
-static struct sysrq_key_op *sysrq_key_table[36] = {
-       &sysrq_loglevel_op,             /* 0 */
-       &sysrq_loglevel_op,             /* 1 */
-       &sysrq_loglevel_op,             /* 2 */
-       &sysrq_loglevel_op,             /* 3 */
-       &sysrq_loglevel_op,             /* 4 */
-       &sysrq_loglevel_op,             /* 5 */
-       &sysrq_loglevel_op,             /* 6 */
-       &sysrq_loglevel_op,             /* 7 */
-       &sysrq_loglevel_op,             /* 8 */
-       &sysrq_loglevel_op,             /* 9 */
-
-       /*
-        * a: Don't use for system provided sysrqs, it is handled specially on
-        * sparc and will never arrive.
-        */
-       NULL,                           /* a */
-       &sysrq_reboot_op,               /* b */
-       &sysrq_crash_op,                /* c & ibm_emac driver debug */
-       &sysrq_showlocks_op,            /* d */
-       &sysrq_term_op,                 /* e */
-       &sysrq_moom_op,                 /* f */
-       /* g: May be registered for the kernel debugger */
-       NULL,                           /* g */
-       NULL,                           /* h - reserved for help */
-       &sysrq_kill_op,                 /* i */
-#ifdef CONFIG_BLOCK
-       &sysrq_thaw_op,                 /* j */
-#else
-       NULL,                           /* j */
-#endif
-       &sysrq_SAK_op,                  /* k */
-#ifdef CONFIG_SMP
-       &sysrq_showallcpus_op,          /* l */
-#else
-       NULL,                           /* l */
-#endif
-       &sysrq_showmem_op,              /* m */
-       &sysrq_unrt_op,                 /* n */
-       /* o: This will often be registered as 'Off' at init time */
-       NULL,                           /* o */
-       &sysrq_showregs_op,             /* p */
-       &sysrq_show_timers_op,          /* q */
-       &sysrq_unraw_op,                /* r */
-       &sysrq_sync_op,                 /* s */
-       &sysrq_showstate_op,            /* t */
-       &sysrq_mountro_op,              /* u */
-       /* v: May be registered for frame buffer console restore */
-       NULL,                           /* v */
-       &sysrq_showstate_blocked_op,    /* w */
-       /* x: May be registered on ppc/powerpc for xmon */
-       NULL,                           /* x */
-       /* y: May be registered on sparc64 for global register dump */
-       NULL,                           /* y */
-       &sysrq_ftrace_dump_op,          /* z */
-};
-
-/* key2index calculation, -1 on invalid index */
-static int sysrq_key_table_key2index(int key)
-{
-       int retval;
-
-       if ((key >= '0') && (key <= '9'))
-               retval = key - '0';
-       else if ((key >= 'a') && (key <= 'z'))
-               retval = key + 10 - 'a';
-       else
-               retval = -1;
-       return retval;
-}
-
-/*
- * get and put functions for the table, exposed to modules.
- */
-struct sysrq_key_op *__sysrq_get_key_op(int key)
-{
-        struct sysrq_key_op *op_p = NULL;
-        int i;
-
-       i = sysrq_key_table_key2index(key);
-       if (i != -1)
-               op_p = sysrq_key_table[i];
-
-        return op_p;
-}
-
-static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p)
-{
-        int i = sysrq_key_table_key2index(key);
-
-        if (i != -1)
-                sysrq_key_table[i] = op_p;
-}
-
-void __handle_sysrq(int key, bool check_mask)
-{
-       struct sysrq_key_op *op_p;
-       int orig_log_level;
-       int i;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sysrq_key_table_lock, flags);
-       /*
-        * Raise the apparent loglevel to maximum so that the sysrq header
-        * is shown to provide the user with positive feedback.  We do not
-        * simply emit this at KERN_EMERG as that would change message
-        * routing in the consumers of /proc/kmsg.
-        */
-       orig_log_level = console_loglevel;
-       console_loglevel = 7;
-       printk(KERN_INFO "SysRq : ");
-
-        op_p = __sysrq_get_key_op(key);
-        if (op_p) {
-               /*
-                * Should we check for enabled operations (/proc/sysrq-trigger
-                * should not) and is the invoked operation enabled?
-                */
-               if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
-                       printk("%s\n", op_p->action_msg);
-                       console_loglevel = orig_log_level;
-                       op_p->handler(key);
-               } else {
-                       printk("This sysrq operation is disabled.\n");
-               }
-       } else {
-               printk("HELP : ");
-               /* Only print the help msg once per handler */
-               for (i = 0; i < ARRAY_SIZE(sysrq_key_table); i++) {
-                       if (sysrq_key_table[i]) {
-                               int j;
-
-                               for (j = 0; sysrq_key_table[i] !=
-                                               sysrq_key_table[j]; j++)
-                                       ;
-                               if (j != i)
-                                       continue;
-                               printk("%s ", sysrq_key_table[i]->help_msg);
-                       }
-               }
-               printk("\n");
-               console_loglevel = orig_log_level;
-       }
-       spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
-}
-
-void handle_sysrq(int key)
-{
-       if (sysrq_on())
-               __handle_sysrq(key, true);
-}
-EXPORT_SYMBOL(handle_sysrq);
-
-#ifdef CONFIG_INPUT
-
-/* Simple translation table for the SysRq keys */
-static const unsigned char sysrq_xlate[KEY_MAX + 1] =
-        "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
-        "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
-        "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
-        "bnm,./\000*\000 \000\201\202\203\204\205"      /* 0x30 - 0x3f */
-        "\206\207\210\211\212\000\000789-456+1"         /* 0x40 - 0x4f */
-        "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-        "\r\000/";                                      /* 0x60 - 0x6f */
-
-static bool sysrq_down;
-static int sysrq_alt_use;
-static int sysrq_alt;
-static DEFINE_SPINLOCK(sysrq_event_lock);
-
-static bool sysrq_filter(struct input_handle *handle, unsigned int type,
-                        unsigned int code, int value)
-{
-       bool suppress;
-
-       /* We are called with interrupts disabled, just take the lock */
-       spin_lock(&sysrq_event_lock);
-
-       if (type != EV_KEY)
-               goto out;
-
-       switch (code) {
-
-       case KEY_LEFTALT:
-       case KEY_RIGHTALT:
-               if (value)
-                       sysrq_alt = code;
-               else {
-                       if (sysrq_down && code == sysrq_alt_use)
-                               sysrq_down = false;
-
-                       sysrq_alt = 0;
-               }
-               break;
-
-       case KEY_SYSRQ:
-               if (value == 1 && sysrq_alt) {
-                       sysrq_down = true;
-                       sysrq_alt_use = sysrq_alt;
-               }
-               break;
-
-       default:
-               if (sysrq_down && value && value != 2)
-                       __handle_sysrq(sysrq_xlate[code], true);
-               break;
-       }
-
-out:
-       suppress = sysrq_down;
-       spin_unlock(&sysrq_event_lock);
-
-       return suppress;
-}
-
-static int sysrq_connect(struct input_handler *handler,
-                        struct input_dev *dev,
-                        const struct input_device_id *id)
-{
-       struct input_handle *handle;
-       int error;
-
-       sysrq_down = false;
-       sysrq_alt = 0;
-
-       handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
-       if (!handle)
-               return -ENOMEM;
-
-       handle->dev = dev;
-       handle->handler = handler;
-       handle->name = "sysrq";
-
-       error = input_register_handle(handle);
-       if (error) {
-               pr_err("Failed to register input sysrq handler, error %d\n",
-                       error);
-               goto err_free;
-       }
-
-       error = input_open_device(handle);
-       if (error) {
-               pr_err("Failed to open input device, error %d\n", error);
-               goto err_unregister;
-       }
-
-       return 0;
-
- err_unregister:
-       input_unregister_handle(handle);
- err_free:
-       kfree(handle);
-       return error;
-}
-
-static void sysrq_disconnect(struct input_handle *handle)
-{
-       input_close_device(handle);
-       input_unregister_handle(handle);
-       kfree(handle);
-}
-
-/*
- * We are matching on KEY_LEFTALT instead of KEY_SYSRQ because not all
- * keyboards have SysRq key predefined and so user may add it to keymap
- * later, but we expect all such keyboards to have left alt.
- */
-static const struct input_device_id sysrq_ids[] = {
-       {
-               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
-                               INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT_MASK(EV_KEY) },
-               .keybit = { BIT_MASK(KEY_LEFTALT) },
-       },
-       { },
-};
-
-static struct input_handler sysrq_handler = {
-       .filter         = sysrq_filter,
-       .connect        = sysrq_connect,
-       .disconnect     = sysrq_disconnect,
-       .name           = "sysrq",
-       .id_table       = sysrq_ids,
-};
-
-static bool sysrq_handler_registered;
-
-static inline void sysrq_register_handler(void)
-{
-       int error;
-
-       error = input_register_handler(&sysrq_handler);
-       if (error)
-               pr_err("Failed to register input handler, error %d", error);
-       else
-               sysrq_handler_registered = true;
-}
-
-static inline void sysrq_unregister_handler(void)
-{
-       if (sysrq_handler_registered) {
-               input_unregister_handler(&sysrq_handler);
-               sysrq_handler_registered = false;
-       }
-}
-
-#else
-
-static inline void sysrq_register_handler(void)
-{
-}
-
-static inline void sysrq_unregister_handler(void)
-{
-}
-
-#endif /* CONFIG_INPUT */
-
-int sysrq_toggle_support(int enable_mask)
-{
-       bool was_enabled = sysrq_on();
-
-       sysrq_enabled = enable_mask;
-
-       if (was_enabled != sysrq_on()) {
-               if (sysrq_on())
-                       sysrq_register_handler();
-               else
-                       sysrq_unregister_handler();
-       }
-
-       return 0;
-}
-
-static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
-                                struct sysrq_key_op *remove_op_p)
-{
-       int retval;
-       unsigned long flags;
-
-       spin_lock_irqsave(&sysrq_key_table_lock, flags);
-       if (__sysrq_get_key_op(key) == remove_op_p) {
-               __sysrq_put_key_op(key, insert_op_p);
-               retval = 0;
-       } else {
-               retval = -1;
-       }
-       spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
-       return retval;
-}
-
-int register_sysrq_key(int key, struct sysrq_key_op *op_p)
-{
-       return __sysrq_swap_key_ops(key, op_p, NULL);
-}
-EXPORT_SYMBOL(register_sysrq_key);
-
-int unregister_sysrq_key(int key, struct sysrq_key_op *op_p)
-{
-       return __sysrq_swap_key_ops(key, NULL, op_p);
-}
-EXPORT_SYMBOL(unregister_sysrq_key);
-
-#ifdef CONFIG_PROC_FS
-/*
- * writing 'C' to /proc/sysrq-trigger is like sysrq-C
- */
-static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
-                                  size_t count, loff_t *ppos)
-{
-       if (count) {
-               char c;
-
-               if (get_user(c, buf))
-                       return -EFAULT;
-               __handle_sysrq(c, false);
-       }
-
-       return count;
-}
-
-static const struct file_operations proc_sysrq_trigger_operations = {
-       .write          = write_sysrq_trigger,
-       .llseek         = noop_llseek,
-};
-
-static void sysrq_init_procfs(void)
-{
-       if (!proc_create("sysrq-trigger", S_IWUSR, NULL,
-                        &proc_sysrq_trigger_operations))
-               pr_err("Failed to register proc interface\n");
-}
-
-#else
-
-static inline void sysrq_init_procfs(void)
-{
-}
-
-#endif /* CONFIG_PROC_FS */
-
-static int __init sysrq_init(void)
-{
-       sysrq_init_procfs();
-
-       if (sysrq_on())
-               sysrq_register_handler();
-
-       return 0;
-}
-module_init(sysrq_init);
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
deleted file mode 100644 (file)
index 1b8ee59..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Creating audit events from TTY input.
- *
- * Copyright (C) 2007 Red Hat, Inc.  All rights reserved.  This copyrighted
- * material is made available to anyone wishing to use, modify, copy, or
- * redistribute it subject to the terms and conditions of the GNU General
- * Public License v.2.
- *
- * Authors: Miloslav Trmac <mitr@redhat.com>
- */
-
-#include <linux/audit.h>
-#include <linux/slab.h>
-#include <linux/tty.h>
-
-struct tty_audit_buf {
-       atomic_t count;
-       struct mutex mutex;     /* Protects all data below */
-       int major, minor;       /* The TTY which the data is from */
-       unsigned icanon:1;
-       size_t valid;
-       unsigned char *data;    /* Allocated size N_TTY_BUF_SIZE */
-};
-
-static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor,
-                                                int icanon)
-{
-       struct tty_audit_buf *buf;
-
-       buf = kmalloc(sizeof(*buf), GFP_KERNEL);
-       if (!buf)
-               goto err;
-       buf->data = kmalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
-       if (!buf->data)
-               goto err_buf;
-       atomic_set(&buf->count, 1);
-       mutex_init(&buf->mutex);
-       buf->major = major;
-       buf->minor = minor;
-       buf->icanon = icanon;
-       buf->valid = 0;
-       return buf;
-
-err_buf:
-       kfree(buf);
-err:
-       return NULL;
-}
-
-static void tty_audit_buf_free(struct tty_audit_buf *buf)
-{
-       WARN_ON(buf->valid != 0);
-       kfree(buf->data);
-       kfree(buf);
-}
-
-static void tty_audit_buf_put(struct tty_audit_buf *buf)
-{
-       if (atomic_dec_and_test(&buf->count))
-               tty_audit_buf_free(buf);
-}
-
-static void tty_audit_log(const char *description, struct task_struct *tsk,
-                         uid_t loginuid, unsigned sessionid, int major,
-                         int minor, unsigned char *data, size_t size)
-{
-       struct audit_buffer *ab;
-
-       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY);
-       if (ab) {
-               char name[sizeof(tsk->comm)];
-               uid_t uid = task_uid(tsk);
-
-               audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u "
-                                "major=%d minor=%d comm=", description,
-                                tsk->pid, uid, loginuid, sessionid,
-                                major, minor);
-               get_task_comm(name, tsk);
-               audit_log_untrustedstring(ab, name);
-               audit_log_format(ab, " data=");
-               audit_log_n_hex(ab, data, size);
-               audit_log_end(ab);
-       }
-}
-
-/**
- *     tty_audit_buf_push      -       Push buffered data out
- *
- *     Generate an audit message from the contents of @buf, which is owned by
- *     @tsk with @loginuid.  @buf->mutex must be locked.
- */
-static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
-                              unsigned int sessionid,
-                              struct tty_audit_buf *buf)
-{
-       if (buf->valid == 0)
-               return;
-       if (audit_enabled == 0)
-               return;
-       tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor,
-                     buf->data, buf->valid);
-       buf->valid = 0;
-}
-
-/**
- *     tty_audit_buf_push_current      -       Push buffered data out
- *
- *     Generate an audit message from the contents of @buf, which is owned by
- *     the current task.  @buf->mutex must be locked.
- */
-static void tty_audit_buf_push_current(struct tty_audit_buf *buf)
-{
-       uid_t auid = audit_get_loginuid(current);
-       unsigned int sessionid = audit_get_sessionid(current);
-       tty_audit_buf_push(current, auid, sessionid, buf);
-}
-
-/**
- *     tty_audit_exit  -       Handle a task exit
- *
- *     Make sure all buffered data is written out and deallocate the buffer.
- *     Only needs to be called if current->signal->tty_audit_buf != %NULL.
- */
-void tty_audit_exit(void)
-{
-       struct tty_audit_buf *buf;
-
-       spin_lock_irq(&current->sighand->siglock);
-       buf = current->signal->tty_audit_buf;
-       current->signal->tty_audit_buf = NULL;
-       spin_unlock_irq(&current->sighand->siglock);
-       if (!buf)
-               return;
-
-       mutex_lock(&buf->mutex);
-       tty_audit_buf_push_current(buf);
-       mutex_unlock(&buf->mutex);
-
-       tty_audit_buf_put(buf);
-}
-
-/**
- *     tty_audit_fork  -       Copy TTY audit state for a new task
- *
- *     Set up TTY audit state in @sig from current.  @sig needs no locking.
- */
-void tty_audit_fork(struct signal_struct *sig)
-{
-       spin_lock_irq(&current->sighand->siglock);
-       sig->audit_tty = current->signal->audit_tty;
-       spin_unlock_irq(&current->sighand->siglock);
-}
-
-/**
- *     tty_audit_tiocsti       -       Log TIOCSTI
- */
-void tty_audit_tiocsti(struct tty_struct *tty, char ch)
-{
-       struct tty_audit_buf *buf;
-       int major, minor, should_audit;
-
-       spin_lock_irq(&current->sighand->siglock);
-       should_audit = current->signal->audit_tty;
-       buf = current->signal->tty_audit_buf;
-       if (buf)
-               atomic_inc(&buf->count);
-       spin_unlock_irq(&current->sighand->siglock);
-
-       major = tty->driver->major;
-       minor = tty->driver->minor_start + tty->index;
-       if (buf) {
-               mutex_lock(&buf->mutex);
-               if (buf->major == major && buf->minor == minor)
-                       tty_audit_buf_push_current(buf);
-               mutex_unlock(&buf->mutex);
-               tty_audit_buf_put(buf);
-       }
-
-       if (should_audit && audit_enabled) {
-               uid_t auid;
-               unsigned int sessionid;
-
-               auid = audit_get_loginuid(current);
-               sessionid = audit_get_sessionid(current);
-               tty_audit_log("ioctl=TIOCSTI", current, auid, sessionid, major,
-                             minor, &ch, 1);
-       }
-}
-
-/**
- *     tty_audit_push_task     -       Flush task's pending audit data
- */
-void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
-{
-       struct tty_audit_buf *buf;
-
-       spin_lock_irq(&tsk->sighand->siglock);
-       buf = tsk->signal->tty_audit_buf;
-       if (buf)
-               atomic_inc(&buf->count);
-       spin_unlock_irq(&tsk->sighand->siglock);
-       if (!buf)
-               return;
-
-       mutex_lock(&buf->mutex);
-       tty_audit_buf_push(tsk, loginuid, sessionid, buf);
-       mutex_unlock(&buf->mutex);
-
-       tty_audit_buf_put(buf);
-}
-
-/**
- *     tty_audit_buf_get       -       Get an audit buffer.
- *
- *     Get an audit buffer for @tty, allocate it if necessary.  Return %NULL
- *     if TTY auditing is disabled or out of memory.  Otherwise, return a new
- *     reference to the buffer.
- */
-static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty)
-{
-       struct tty_audit_buf *buf, *buf2;
-
-       buf = NULL;
-       buf2 = NULL;
-       spin_lock_irq(&current->sighand->siglock);
-       if (likely(!current->signal->audit_tty))
-               goto out;
-       buf = current->signal->tty_audit_buf;
-       if (buf) {
-               atomic_inc(&buf->count);
-               goto out;
-       }
-       spin_unlock_irq(&current->sighand->siglock);
-
-       buf2 = tty_audit_buf_alloc(tty->driver->major,
-                                  tty->driver->minor_start + tty->index,
-                                  tty->icanon);
-       if (buf2 == NULL) {
-               audit_log_lost("out of memory in TTY auditing");
-               return NULL;
-       }
-
-       spin_lock_irq(&current->sighand->siglock);
-       if (!current->signal->audit_tty)
-               goto out;
-       buf = current->signal->tty_audit_buf;
-       if (!buf) {
-               current->signal->tty_audit_buf = buf2;
-               buf = buf2;
-               buf2 = NULL;
-       }
-       atomic_inc(&buf->count);
-       /* Fall through */
- out:
-       spin_unlock_irq(&current->sighand->siglock);
-       if (buf2)
-               tty_audit_buf_free(buf2);
-       return buf;
-}
-
-/**
- *     tty_audit_add_data      -       Add data for TTY auditing.
- *
- *     Audit @data of @size from @tty, if necessary.
- */
-void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
-                       size_t size)
-{
-       struct tty_audit_buf *buf;
-       int major, minor;
-
-       if (unlikely(size == 0))
-               return;
-
-       if (tty->driver->type == TTY_DRIVER_TYPE_PTY
-           && tty->driver->subtype == PTY_TYPE_MASTER)
-               return;
-
-       buf = tty_audit_buf_get(tty);
-       if (!buf)
-               return;
-
-       mutex_lock(&buf->mutex);
-       major = tty->driver->major;
-       minor = tty->driver->minor_start + tty->index;
-       if (buf->major != major || buf->minor != minor
-           || buf->icanon != tty->icanon) {
-               tty_audit_buf_push_current(buf);
-               buf->major = major;
-               buf->minor = minor;
-               buf->icanon = tty->icanon;
-       }
-       do {
-               size_t run;
-
-               run = N_TTY_BUF_SIZE - buf->valid;
-               if (run > size)
-                       run = size;
-               memcpy(buf->data + buf->valid, data, run);
-               buf->valid += run;
-               data += run;
-               size -= run;
-               if (buf->valid == N_TTY_BUF_SIZE)
-                       tty_audit_buf_push_current(buf);
-       } while (size != 0);
-       mutex_unlock(&buf->mutex);
-       tty_audit_buf_put(buf);
-}
-
-/**
- *     tty_audit_push  -       Push buffered data out
- *
- *     Make sure no audit data is pending for @tty on the current process.
- */
-void tty_audit_push(struct tty_struct *tty)
-{
-       struct tty_audit_buf *buf;
-
-       spin_lock_irq(&current->sighand->siglock);
-       if (likely(!current->signal->audit_tty)) {
-               spin_unlock_irq(&current->sighand->siglock);
-               return;
-       }
-       buf = current->signal->tty_audit_buf;
-       if (buf)
-               atomic_inc(&buf->count);
-       spin_unlock_irq(&current->sighand->siglock);
-
-       if (buf) {
-               int major, minor;
-
-               major = tty->driver->major;
-               minor = tty->driver->minor_start + tty->index;
-               mutex_lock(&buf->mutex);
-               if (buf->major == major && buf->minor == minor)
-                       tty_audit_buf_push_current(buf);
-               mutex_unlock(&buf->mutex);
-               tty_audit_buf_put(buf);
-       }
-}
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
deleted file mode 100644 (file)
index cc1e985..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Tty buffer allocation management
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-
-/**
- *     tty_buffer_free_all             -       free buffers used by a tty
- *     @tty: tty to free from
- *
- *     Remove all the buffers pending on a tty whether queued with data
- *     or in the free ring. Must be called when the tty is no longer in use
- *
- *     Locking: none
- */
-
-void tty_buffer_free_all(struct tty_struct *tty)
-{
-       struct tty_buffer *thead;
-       while ((thead = tty->buf.head) != NULL) {
-               tty->buf.head = thead->next;
-               kfree(thead);
-       }
-       while ((thead = tty->buf.free) != NULL) {
-               tty->buf.free = thead->next;
-               kfree(thead);
-       }
-       tty->buf.tail = NULL;
-       tty->buf.memory_used = 0;
-}
-
-/**
- *     tty_buffer_alloc        -       allocate a tty buffer
- *     @tty: tty device
- *     @size: desired size (characters)
- *
- *     Allocate a new tty buffer to hold the desired number of characters.
- *     Return NULL if out of memory or the allocation would exceed the
- *     per device queue
- *
- *     Locking: Caller must hold tty->buf.lock
- */
-
-static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
-{
-       struct tty_buffer *p;
-
-       if (tty->buf.memory_used + size > 65536)
-               return NULL;
-       p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC);
-       if (p == NULL)
-               return NULL;
-       p->used = 0;
-       p->size = size;
-       p->next = NULL;
-       p->commit = 0;
-       p->read = 0;
-       p->char_buf_ptr = (char *)(p->data);
-       p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
-       tty->buf.memory_used += size;
-       return p;
-}
-
-/**
- *     tty_buffer_free         -       free a tty buffer
- *     @tty: tty owning the buffer
- *     @b: the buffer to free
- *
- *     Free a tty buffer, or add it to the free list according to our
- *     internal strategy
- *
- *     Locking: Caller must hold tty->buf.lock
- */
-
-static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
-{
-       /* Dumb strategy for now - should keep some stats */
-       tty->buf.memory_used -= b->size;
-       WARN_ON(tty->buf.memory_used < 0);
-
-       if (b->size >= 512)
-               kfree(b);
-       else {
-               b->next = tty->buf.free;
-               tty->buf.free = b;
-       }
-}
-
-/**
- *     __tty_buffer_flush              -       flush full tty buffers
- *     @tty: tty to flush
- *
- *     flush all the buffers containing receive data. Caller must
- *     hold the buffer lock and must have ensured no parallel flush to
- *     ldisc is running.
- *
- *     Locking: Caller must hold tty->buf.lock
- */
-
-static void __tty_buffer_flush(struct tty_struct *tty)
-{
-       struct tty_buffer *thead;
-
-       while ((thead = tty->buf.head) != NULL) {
-               tty->buf.head = thead->next;
-               tty_buffer_free(tty, thead);
-       }
-       tty->buf.tail = NULL;
-}
-
-/**
- *     tty_buffer_flush                -       flush full tty buffers
- *     @tty: tty to flush
- *
- *     flush all the buffers containing receive data. If the buffer is
- *     being processed by flush_to_ldisc then we defer the processing
- *     to that function
- *
- *     Locking: none
- */
-
-void tty_buffer_flush(struct tty_struct *tty)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&tty->buf.lock, flags);
-
-       /* If the data is being pushed to the tty layer then we can't
-          process it here. Instead set a flag and the flush_to_ldisc
-          path will process the flush request before it exits */
-       if (test_bit(TTY_FLUSHING, &tty->flags)) {
-               set_bit(TTY_FLUSHPENDING, &tty->flags);
-               spin_unlock_irqrestore(&tty->buf.lock, flags);
-               wait_event(tty->read_wait,
-                               test_bit(TTY_FLUSHPENDING, &tty->flags) == 0);
-               return;
-       } else
-               __tty_buffer_flush(tty);
-       spin_unlock_irqrestore(&tty->buf.lock, flags);
-}
-
-/**
- *     tty_buffer_find         -       find a free tty buffer
- *     @tty: tty owning the buffer
- *     @size: characters wanted
- *
- *     Locate an existing suitable tty buffer or if we are lacking one then
- *     allocate a new one. We round our buffers off in 256 character chunks
- *     to get better allocation behaviour.
- *
- *     Locking: Caller must hold tty->buf.lock
- */
-
-static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
-{
-       struct tty_buffer **tbh = &tty->buf.free;
-       while ((*tbh) != NULL) {
-               struct tty_buffer *t = *tbh;
-               if (t->size >= size) {
-                       *tbh = t->next;
-                       t->next = NULL;
-                       t->used = 0;
-                       t->commit = 0;
-                       t->read = 0;
-                       tty->buf.memory_used += t->size;
-                       return t;
-               }
-               tbh = &((*tbh)->next);
-       }
-       /* Round the buffer size out */
-       size = (size + 0xFF) & ~0xFF;
-       return tty_buffer_alloc(tty, size);
-       /* Should possibly check if this fails for the largest buffer we
-          have queued and recycle that ? */
-}
-
-/**
- *     tty_buffer_request_room         -       grow tty buffer if needed
- *     @tty: tty structure
- *     @size: size desired
- *
- *     Make at least size bytes of linear space available for the tty
- *     buffer. If we fail return the size we managed to find.
- *
- *     Locking: Takes tty->buf.lock
- */
-int tty_buffer_request_room(struct tty_struct *tty, size_t size)
-{
-       struct tty_buffer *b, *n;
-       int left;
-       unsigned long flags;
-
-       spin_lock_irqsave(&tty->buf.lock, flags);
-
-       /* OPTIMISATION: We could keep a per tty "zero" sized buffer to
-          remove this conditional if its worth it. This would be invisible
-          to the callers */
-       if ((b = tty->buf.tail) != NULL)
-               left = b->size - b->used;
-       else
-               left = 0;
-
-       if (left < size) {
-               /* This is the slow path - looking for new buffers to use */
-               if ((n = tty_buffer_find(tty, size)) != NULL) {
-                       if (b != NULL) {
-                               b->next = n;
-                               b->commit = b->used;
-                       } else
-                               tty->buf.head = n;
-                       tty->buf.tail = n;
-               } else
-                       size = left;
-       }
-
-       spin_unlock_irqrestore(&tty->buf.lock, flags);
-       return size;
-}
-EXPORT_SYMBOL_GPL(tty_buffer_request_room);
-
-/**
- *     tty_insert_flip_string_fixed_flag - Add characters to the tty buffer
- *     @tty: tty structure
- *     @chars: characters
- *     @flag: flag value for each character
- *     @size: size
- *
- *     Queue a series of bytes to the tty buffering. All the characters
- *     passed are marked with the supplied flag. Returns the number added.
- *
- *     Locking: Called functions may take tty->buf.lock
- */
-
-int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
-               const unsigned char *chars, char flag, size_t size)
-{
-       int copied = 0;
-       do {
-               int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
-               int space = tty_buffer_request_room(tty, goal);
-               struct tty_buffer *tb = tty->buf.tail;
-               /* If there is no space then tb may be NULL */
-               if (unlikely(space == 0))
-                       break;
-               memcpy(tb->char_buf_ptr + tb->used, chars, space);
-               memset(tb->flag_buf_ptr + tb->used, flag, space);
-               tb->used += space;
-               copied += space;
-               chars += space;
-               /* There is a small chance that we need to split the data over
-                  several buffers. If this is the case we must loop */
-       } while (unlikely(size > copied));
-       return copied;
-}
-EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag);
-
-/**
- *     tty_insert_flip_string_flags    -       Add characters to the tty buffer
- *     @tty: tty structure
- *     @chars: characters
- *     @flags: flag bytes
- *     @size: size
- *
- *     Queue a series of bytes to the tty buffering. For each character
- *     the flags array indicates the status of the character. Returns the
- *     number added.
- *
- *     Locking: Called functions may take tty->buf.lock
- */
-
-int tty_insert_flip_string_flags(struct tty_struct *tty,
-               const unsigned char *chars, const char *flags, size_t size)
-{
-       int copied = 0;
-       do {
-               int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
-               int space = tty_buffer_request_room(tty, goal);
-               struct tty_buffer *tb = tty->buf.tail;
-               /* If there is no space then tb may be NULL */
-               if (unlikely(space == 0))
-                       break;
-               memcpy(tb->char_buf_ptr + tb->used, chars, space);
-               memcpy(tb->flag_buf_ptr + tb->used, flags, space);
-               tb->used += space;
-               copied += space;
-               chars += space;
-               flags += space;
-               /* There is a small chance that we need to split the data over
-                  several buffers. If this is the case we must loop */
-       } while (unlikely(size > copied));
-       return copied;
-}
-EXPORT_SYMBOL(tty_insert_flip_string_flags);
-
-/**
- *     tty_schedule_flip       -       push characters to ldisc
- *     @tty: tty to push from
- *
- *     Takes any pending buffers and transfers their ownership to the
- *     ldisc side of the queue. It then schedules those characters for
- *     processing by the line discipline.
- *
- *     Locking: Takes tty->buf.lock
- */
-
-void tty_schedule_flip(struct tty_struct *tty)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&tty->buf.lock, flags);
-       if (tty->buf.tail != NULL)
-               tty->buf.tail->commit = tty->buf.tail->used;
-       spin_unlock_irqrestore(&tty->buf.lock, flags);
-       schedule_delayed_work(&tty->buf.work, 1);
-}
-EXPORT_SYMBOL(tty_schedule_flip);
-
-/**
- *     tty_prepare_flip_string         -       make room for characters
- *     @tty: tty
- *     @chars: return pointer for character write area
- *     @size: desired size
- *
- *     Prepare a block of space in the buffer for data. Returns the length
- *     available and buffer pointer to the space which is now allocated and
- *     accounted for as ready for normal characters. This is used for drivers
- *     that need their own block copy routines into the buffer. There is no
- *     guarantee the buffer is a DMA target!
- *
- *     Locking: May call functions taking tty->buf.lock
- */
-
-int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars,
-                                                               size_t size)
-{
-       int space = tty_buffer_request_room(tty, size);
-       if (likely(space)) {
-               struct tty_buffer *tb = tty->buf.tail;
-               *chars = tb->char_buf_ptr + tb->used;
-               memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
-               tb->used += space;
-       }
-       return space;
-}
-EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
-
-/**
- *     tty_prepare_flip_string_flags   -       make room for characters
- *     @tty: tty
- *     @chars: return pointer for character write area
- *     @flags: return pointer for status flag write area
- *     @size: desired size
- *
- *     Prepare a block of space in the buffer for data. Returns the length
- *     available and buffer pointer to the space which is now allocated and
- *     accounted for as ready for characters. This is used for drivers
- *     that need their own block copy routines into the buffer. There is no
- *     guarantee the buffer is a DMA target!
- *
- *     Locking: May call functions taking tty->buf.lock
- */
-
-int tty_prepare_flip_string_flags(struct tty_struct *tty,
-                       unsigned char **chars, char **flags, size_t size)
-{
-       int space = tty_buffer_request_room(tty, size);
-       if (likely(space)) {
-               struct tty_buffer *tb = tty->buf.tail;
-               *chars = tb->char_buf_ptr + tb->used;
-               *flags = tb->flag_buf_ptr + tb->used;
-               tb->used += space;
-       }
-       return space;
-}
-EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
-
-
-
-/**
- *     flush_to_ldisc
- *     @work: tty structure passed from work queue.
- *
- *     This routine is called out of the software interrupt to flush data
- *     from the buffer chain to the line discipline.
- *
- *     Locking: holds tty->buf.lock to guard buffer list. Drops the lock
- *     while invoking the line discipline receive_buf method. The
- *     receive_buf method is single threaded for each tty instance.
- */
-
-static void flush_to_ldisc(struct work_struct *work)
-{
-       struct tty_struct *tty =
-               container_of(work, struct tty_struct, buf.work.work);
-       unsigned long   flags;
-       struct tty_ldisc *disc;
-
-       disc = tty_ldisc_ref(tty);
-       if (disc == NULL)       /*  !TTY_LDISC */
-               return;
-
-       spin_lock_irqsave(&tty->buf.lock, flags);
-
-       if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
-               struct tty_buffer *head;
-               while ((head = tty->buf.head) != NULL) {
-                       int count;
-                       char *char_buf;
-                       unsigned char *flag_buf;
-
-                       count = head->commit - head->read;
-                       if (!count) {
-                               if (head->next == NULL)
-                                       break;
-                               tty->buf.head = head->next;
-                               tty_buffer_free(tty, head);
-                               continue;
-                       }
-                       /* Ldisc or user is trying to flush the buffers
-                          we are feeding to the ldisc, stop feeding the
-                          line discipline as we want to empty the queue */
-                       if (test_bit(TTY_FLUSHPENDING, &tty->flags))
-                               break;
-                       if (!tty->receive_room) {
-                               schedule_delayed_work(&tty->buf.work, 1);
-                               break;
-                       }
-                       if (count > tty->receive_room)
-                               count = tty->receive_room;
-                       char_buf = head->char_buf_ptr + head->read;
-                       flag_buf = head->flag_buf_ptr + head->read;
-                       head->read += count;
-                       spin_unlock_irqrestore(&tty->buf.lock, flags);
-                       disc->ops->receive_buf(tty, char_buf,
-                                                       flag_buf, count);
-                       spin_lock_irqsave(&tty->buf.lock, flags);
-               }
-               clear_bit(TTY_FLUSHING, &tty->flags);
-       }
-
-       /* We may have a deferred request to flush the input buffer,
-          if so pull the chain under the lock and empty the queue */
-       if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
-               __tty_buffer_flush(tty);
-               clear_bit(TTY_FLUSHPENDING, &tty->flags);
-               wake_up(&tty->read_wait);
-       }
-       spin_unlock_irqrestore(&tty->buf.lock, flags);
-
-       tty_ldisc_deref(disc);
-}
-
-/**
- *     tty_flush_to_ldisc
- *     @tty: tty to push
- *
- *     Push the terminal flip buffers to the line discipline.
- *
- *     Must not be called from IRQ context.
- */
-void tty_flush_to_ldisc(struct tty_struct *tty)
-{
-       flush_delayed_work(&tty->buf.work);
-}
-
-/**
- *     tty_flip_buffer_push    -       terminal
- *     @tty: tty to push
- *
- *     Queue a push of the terminal flip buffers to the line discipline. This
- *     function must not be called from IRQ context if tty->low_latency is set.
- *
- *     In the event of the queue being busy for flipping the work will be
- *     held off and retried later.
- *
- *     Locking: tty buffer lock. Driver locks in low latency mode.
- */
-
-void tty_flip_buffer_push(struct tty_struct *tty)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&tty->buf.lock, flags);
-       if (tty->buf.tail != NULL)
-               tty->buf.tail->commit = tty->buf.tail->used;
-       spin_unlock_irqrestore(&tty->buf.lock, flags);
-
-       if (tty->low_latency)
-               flush_to_ldisc(&tty->buf.work.work);
-       else
-               schedule_delayed_work(&tty->buf.work, 1);
-}
-EXPORT_SYMBOL(tty_flip_buffer_push);
-
-/**
- *     tty_buffer_init         -       prepare a tty buffer structure
- *     @tty: tty to initialise
- *
- *     Set up the initial state of the buffer management for a tty device.
- *     Must be called before the other tty buffer functions are used.
- *
- *     Locking: none
- */
-
-void tty_buffer_init(struct tty_struct *tty)
-{
-       spin_lock_init(&tty->buf.lock);
-       tty->buf.head = NULL;
-       tty->buf.tail = NULL;
-       tty->buf.free = NULL;
-       tty->buf.memory_used = 0;
-       INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc);
-}
-
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
deleted file mode 100644 (file)
index c05c5af..0000000
+++ /dev/null
@@ -1,3263 +0,0 @@
-/*
- *  linux/drivers/char/tty_io.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-/*
- * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
- * or rs-channels. It also implements echoing, cooked mode etc.
- *
- * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
- *
- * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the
- * tty_struct and tty_queue structures.  Previously there was an array
- * of 256 tty_struct's which was statically allocated, and the
- * tty_queue structures were allocated at boot time.  Both are now
- * dynamically allocated only when the tty is open.
- *
- * Also restructured routines so that there is more of a separation
- * between the high-level tty routines (tty_io.c and tty_ioctl.c) and
- * the low-level tty routines (serial.c, pty.c, console.c).  This
- * makes for cleaner and more compact code.  -TYT, 9/17/92
- *
- * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
- * which can be dynamically activated and de-activated by the line
- * discipline handling modules (like SLIP).
- *
- * NOTE: pay no attention to the line discipline code (yet); its
- * interface is still subject to change in this version...
- * -- TYT, 1/31/92
- *
- * Added functionality to the OPOST tty handling.  No delays, but all
- * other bits should be there.
- *     -- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993.
- *
- * Rewrote canonical mode and added more termios flags.
- *     -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94
- *
- * Reorganized FASYNC support so mouse code can share it.
- *     -- ctm@ardi.com, 9Sep95
- *
- * New TIOCLINUX variants added.
- *     -- mj@k332.feld.cvut.cz, 19-Nov-95
- *
- * Restrict vt switching via ioctl()
- *      -- grif@cs.ucr.edu, 5-Dec-95
- *
- * Move console and virtual terminal code to more appropriate files,
- * implement CONFIG_VT and generalize console device interface.
- *     -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97
- *
- * Rewrote tty_init_dev and tty_release_dev to eliminate races.
- *     -- Bill Hawes <whawes@star.net>, June 97
- *
- * Added devfs support.
- *      -- C. Scott Ananian <cananian@alumni.princeton.edu>, 13-Jan-1998
- *
- * Added support for a Unix98-style ptmx device.
- *      -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
- *
- * Reduced memory usage for older ARM systems
- *      -- Russell King <rmk@arm.linux.org.uk>
- *
- * Move do_SAK() into process context.  Less stack use in devfs functions.
- * alloc_tty_struct() always uses kmalloc()
- *                      -- Andrew Morton <andrewm@uow.edu.eu> 17Mar01
- */
-
-#include <linux/types.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/fcntl.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/devpts_fs.h>
-#include <linux/file.h>
-#include <linux/fdtable.h>
-#include <linux/console.h>
-#include <linux/timer.h>
-#include <linux/ctype.h>
-#include <linux/kd.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/smp_lock.h>
-#include <linux/device.h>
-#include <linux/wait.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/seq_file.h>
-#include <linux/serial.h>
-
-#include <linux/uaccess.h>
-#include <asm/system.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-
-#include <linux/kmod.h>
-#include <linux/nsproxy.h>
-
-#undef TTY_DEBUG_HANGUP
-
-#define TTY_PARANOIA_CHECK 1
-#define CHECK_TTY_COUNT 1
-
-struct ktermios tty_std_termios = {    /* for the benefit of tty drivers  */
-       .c_iflag = ICRNL | IXON,
-       .c_oflag = OPOST | ONLCR,
-       .c_cflag = B38400 | CS8 | CREAD | HUPCL,
-       .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
-                  ECHOCTL | ECHOKE | IEXTEN,
-       .c_cc = INIT_C_CC,
-       .c_ispeed = 38400,
-       .c_ospeed = 38400
-};
-
-EXPORT_SYMBOL(tty_std_termios);
-
-/* This list gets poked at by procfs and various bits of boot up code. This
-   could do with some rationalisation such as pulling the tty proc function
-   into this file */
-
-LIST_HEAD(tty_drivers);                        /* linked list of tty drivers */
-
-/* Mutex to protect creating and releasing a tty. This is shared with
-   vt.c for deeply disgusting hack reasons */
-DEFINE_MUTEX(tty_mutex);
-EXPORT_SYMBOL(tty_mutex);
-
-/* Spinlock to protect the tty->tty_files list */
-DEFINE_SPINLOCK(tty_files_lock);
-
-static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
-static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
-ssize_t redirected_tty_write(struct file *, const char __user *,
-                                                       size_t, loff_t *);
-static unsigned int tty_poll(struct file *, poll_table *);
-static int tty_open(struct inode *, struct file *);
-long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-#ifdef CONFIG_COMPAT
-static long tty_compat_ioctl(struct file *file, unsigned int cmd,
-                               unsigned long arg);
-#else
-#define tty_compat_ioctl NULL
-#endif
-static int __tty_fasync(int fd, struct file *filp, int on);
-static int tty_fasync(int fd, struct file *filp, int on);
-static void release_tty(struct tty_struct *tty, int idx);
-static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
-static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
-
-/**
- *     alloc_tty_struct        -       allocate a tty object
- *
- *     Return a new empty tty structure. The data fields have not
- *     been initialized in any way but has been zeroed
- *
- *     Locking: none
- */
-
-struct tty_struct *alloc_tty_struct(void)
-{
-       return kzalloc(sizeof(struct tty_struct), GFP_KERNEL);
-}
-
-/**
- *     free_tty_struct         -       free a disused tty
- *     @tty: tty struct to free
- *
- *     Free the write buffers, tty queue and tty memory itself.
- *
- *     Locking: none. Must be called after tty is definitely unused
- */
-
-void free_tty_struct(struct tty_struct *tty)
-{
-       if (tty->dev)
-               put_device(tty->dev);
-       kfree(tty->write_buf);
-       tty_buffer_free_all(tty);
-       kfree(tty);
-}
-
-static inline struct tty_struct *file_tty(struct file *file)
-{
-       return ((struct tty_file_private *)file->private_data)->tty;
-}
-
-/* Associate a new file with the tty structure */
-int tty_add_file(struct tty_struct *tty, struct file *file)
-{
-       struct tty_file_private *priv;
-
-       priv = kmalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       priv->tty = tty;
-       priv->file = file;
-       file->private_data = priv;
-
-       spin_lock(&tty_files_lock);
-       list_add(&priv->list, &tty->tty_files);
-       spin_unlock(&tty_files_lock);
-
-       return 0;
-}
-
-/* Delete file from its tty */
-void tty_del_file(struct file *file)
-{
-       struct tty_file_private *priv = file->private_data;
-
-       spin_lock(&tty_files_lock);
-       list_del(&priv->list);
-       spin_unlock(&tty_files_lock);
-       file->private_data = NULL;
-       kfree(priv);
-}
-
-
-#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)
-
-/**
- *     tty_name        -       return tty naming
- *     @tty: tty structure
- *     @buf: buffer for output
- *
- *     Convert a tty structure into a name. The name reflects the kernel
- *     naming policy and if udev is in use may not reflect user space
- *
- *     Locking: none
- */
-
-char *tty_name(struct tty_struct *tty, char *buf)
-{
-       if (!tty) /* Hmm.  NULL pointer.  That's fun. */
-               strcpy(buf, "NULL tty");
-       else
-               strcpy(buf, tty->name);
-       return buf;
-}
-
-EXPORT_SYMBOL(tty_name);
-
-int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
-                             const char *routine)
-{
-#ifdef TTY_PARANOIA_CHECK
-       if (!tty) {
-               printk(KERN_WARNING
-                       "null TTY for (%d:%d) in %s\n",
-                       imajor(inode), iminor(inode), routine);
-               return 1;
-       }
-       if (tty->magic != TTY_MAGIC) {
-               printk(KERN_WARNING
-                       "bad magic number for tty struct (%d:%d) in %s\n",
-                       imajor(inode), iminor(inode), routine);
-               return 1;
-       }
-#endif
-       return 0;
-}
-
-static int check_tty_count(struct tty_struct *tty, const char *routine)
-{
-#ifdef CHECK_TTY_COUNT
-       struct list_head *p;
-       int count = 0;
-
-       spin_lock(&tty_files_lock);
-       list_for_each(p, &tty->tty_files) {
-               count++;
-       }
-       spin_unlock(&tty_files_lock);
-       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
-           tty->driver->subtype == PTY_TYPE_SLAVE &&
-           tty->link && tty->link->count)
-               count++;
-       if (tty->count != count) {
-               printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) "
-                                   "!= #fd's(%d) in %s\n",
-                      tty->name, tty->count, count, routine);
-               return count;
-       }
-#endif
-       return 0;
-}
-
-/**
- *     get_tty_driver          -       find device of a tty
- *     @dev_t: device identifier
- *     @index: returns the index of the tty
- *
- *     This routine returns a tty driver structure, given a device number
- *     and also passes back the index number.
- *
- *     Locking: caller must hold tty_mutex
- */
-
-static struct tty_driver *get_tty_driver(dev_t device, int *index)
-{
-       struct tty_driver *p;
-
-       list_for_each_entry(p, &tty_drivers, tty_drivers) {
-               dev_t base = MKDEV(p->major, p->minor_start);
-               if (device < base || device >= base + p->num)
-                       continue;
-               *index = device - base;
-               return tty_driver_kref_get(p);
-       }
-       return NULL;
-}
-
-#ifdef CONFIG_CONSOLE_POLL
-
-/**
- *     tty_find_polling_driver -       find device of a polled tty
- *     @name: name string to match
- *     @line: pointer to resulting tty line nr
- *
- *     This routine returns a tty driver structure, given a name
- *     and the condition that the tty driver is capable of polled
- *     operation.
- */
-struct tty_driver *tty_find_polling_driver(char *name, int *line)
-{
-       struct tty_driver *p, *res = NULL;
-       int tty_line = 0;
-       int len;
-       char *str, *stp;
-
-       for (str = name; *str; str++)
-               if ((*str >= '0' && *str <= '9') || *str == ',')
-                       break;
-       if (!*str)
-               return NULL;
-
-       len = str - name;
-       tty_line = simple_strtoul(str, &str, 10);
-
-       mutex_lock(&tty_mutex);
-       /* Search through the tty devices to look for a match */
-       list_for_each_entry(p, &tty_drivers, tty_drivers) {
-               if (strncmp(name, p->name, len) != 0)
-                       continue;
-               stp = str;
-               if (*stp == ',')
-                       stp++;
-               if (*stp == '\0')
-                       stp = NULL;
-
-               if (tty_line >= 0 && tty_line < p->num && p->ops &&
-                   p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
-                       res = tty_driver_kref_get(p);
-                       *line = tty_line;
-                       break;
-               }
-       }
-       mutex_unlock(&tty_mutex);
-
-       return res;
-}
-EXPORT_SYMBOL_GPL(tty_find_polling_driver);
-#endif
-
-/**
- *     tty_check_change        -       check for POSIX terminal changes
- *     @tty: tty to check
- *
- *     If we try to write to, or set the state of, a terminal and we're
- *     not in the foreground, send a SIGTTOU.  If the signal is blocked or
- *     ignored, go ahead and perform the operation.  (POSIX 7.2)
- *
- *     Locking: ctrl_lock
- */
-
-int tty_check_change(struct tty_struct *tty)
-{
-       unsigned long flags;
-       int ret = 0;
-
-       if (current->signal->tty != tty)
-               return 0;
-
-       spin_lock_irqsave(&tty->ctrl_lock, flags);
-
-       if (!tty->pgrp) {
-               printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
-               goto out_unlock;
-       }
-       if (task_pgrp(current) == tty->pgrp)
-               goto out_unlock;
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-       if (is_ignored(SIGTTOU))
-               goto out;
-       if (is_current_pgrp_orphaned()) {
-               ret = -EIO;
-               goto out;
-       }
-       kill_pgrp(task_pgrp(current), SIGTTOU, 1);
-       set_thread_flag(TIF_SIGPENDING);
-       ret = -ERESTARTSYS;
-out:
-       return ret;
-out_unlock:
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-       return ret;
-}
-
-EXPORT_SYMBOL(tty_check_change);
-
-static ssize_t hung_up_tty_read(struct file *file, char __user *buf,
-                               size_t count, loff_t *ppos)
-{
-       return 0;
-}
-
-static ssize_t hung_up_tty_write(struct file *file, const char __user *buf,
-                                size_t count, loff_t *ppos)
-{
-       return -EIO;
-}
-
-/* No kernel lock held - none needed ;) */
-static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait)
-{
-       return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
-}
-
-static long hung_up_tty_ioctl(struct file *file, unsigned int cmd,
-               unsigned long arg)
-{
-       return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
-}
-
-static long hung_up_tty_compat_ioctl(struct file *file,
-                                    unsigned int cmd, unsigned long arg)
-{
-       return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
-}
-
-static const struct file_operations tty_fops = {
-       .llseek         = no_llseek,
-       .read           = tty_read,
-       .write          = tty_write,
-       .poll           = tty_poll,
-       .unlocked_ioctl = tty_ioctl,
-       .compat_ioctl   = tty_compat_ioctl,
-       .open           = tty_open,
-       .release        = tty_release,
-       .fasync         = tty_fasync,
-};
-
-static const struct file_operations console_fops = {
-       .llseek         = no_llseek,
-       .read           = tty_read,
-       .write          = redirected_tty_write,
-       .poll           = tty_poll,
-       .unlocked_ioctl = tty_ioctl,
-       .compat_ioctl   = tty_compat_ioctl,
-       .open           = tty_open,
-       .release        = tty_release,
-       .fasync         = tty_fasync,
-};
-
-static const struct file_operations hung_up_tty_fops = {
-       .llseek         = no_llseek,
-       .read           = hung_up_tty_read,
-       .write          = hung_up_tty_write,
-       .poll           = hung_up_tty_poll,
-       .unlocked_ioctl = hung_up_tty_ioctl,
-       .compat_ioctl   = hung_up_tty_compat_ioctl,
-       .release        = tty_release,
-};
-
-static DEFINE_SPINLOCK(redirect_lock);
-static struct file *redirect;
-
-/**
- *     tty_wakeup      -       request more data
- *     @tty: terminal
- *
- *     Internal and external helper for wakeups of tty. This function
- *     informs the line discipline if present that the driver is ready
- *     to receive more output data.
- */
-
-void tty_wakeup(struct tty_struct *tty)
-{
-       struct tty_ldisc *ld;
-
-       if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
-               ld = tty_ldisc_ref(tty);
-               if (ld) {
-                       if (ld->ops->write_wakeup)
-                               ld->ops->write_wakeup(tty);
-                       tty_ldisc_deref(ld);
-               }
-       }
-       wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
-}
-
-EXPORT_SYMBOL_GPL(tty_wakeup);
-
-/**
- *     __tty_hangup            -       actual handler for hangup events
- *     @work: tty device
- *
- *     This can be called by the "eventd" kernel thread.  That is process
- *     synchronous but doesn't hold any locks, so we need to make sure we
- *     have the appropriate locks for what we're doing.
- *
- *     The hangup event clears any pending redirections onto the hung up
- *     device. It ensures future writes will error and it does the needed
- *     line discipline hangup and signal delivery. The tty object itself
- *     remains intact.
- *
- *     Locking:
- *             BTM
- *               redirect lock for undoing redirection
- *               file list lock for manipulating list of ttys
- *               tty_ldisc_lock from called functions
- *               termios_mutex resetting termios data
- *               tasklist_lock to walk task list for hangup event
- *                 ->siglock to protect ->signal/->sighand
- */
-void __tty_hangup(struct tty_struct *tty)
-{
-       struct file *cons_filp = NULL;
-       struct file *filp, *f = NULL;
-       struct task_struct *p;
-       struct tty_file_private *priv;
-       int    closecount = 0, n;
-       unsigned long flags;
-       int refs = 0;
-
-       if (!tty)
-               return;
-
-
-       spin_lock(&redirect_lock);
-       if (redirect && file_tty(redirect) == tty) {
-               f = redirect;
-               redirect = NULL;
-       }
-       spin_unlock(&redirect_lock);
-
-       tty_lock();
-
-       /* inuse_filps is protected by the single tty lock,
-          this really needs to change if we want to flush the
-          workqueue with the lock held */
-       check_tty_count(tty, "tty_hangup");
-
-       spin_lock(&tty_files_lock);
-       /* This breaks for file handles being sent over AF_UNIX sockets ? */
-       list_for_each_entry(priv, &tty->tty_files, list) {
-               filp = priv->file;
-               if (filp->f_op->write == redirected_tty_write)
-                       cons_filp = filp;
-               if (filp->f_op->write != tty_write)
-                       continue;
-               closecount++;
-               __tty_fasync(-1, filp, 0);      /* can't block */
-               filp->f_op = &hung_up_tty_fops;
-       }
-       spin_unlock(&tty_files_lock);
-
-       tty_ldisc_hangup(tty);
-
-       read_lock(&tasklist_lock);
-       if (tty->session) {
-               do_each_pid_task(tty->session, PIDTYPE_SID, p) {
-                       spin_lock_irq(&p->sighand->siglock);
-                       if (p->signal->tty == tty) {
-                               p->signal->tty = NULL;
-                               /* We defer the dereferences outside fo
-                                  the tasklist lock */
-                               refs++;
-                       }
-                       if (!p->signal->leader) {
-                               spin_unlock_irq(&p->sighand->siglock);
-                               continue;
-                       }
-                       __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
-                       __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
-                       put_pid(p->signal->tty_old_pgrp);  /* A noop */
-                       spin_lock_irqsave(&tty->ctrl_lock, flags);
-                       if (tty->pgrp)
-                               p->signal->tty_old_pgrp = get_pid(tty->pgrp);
-                       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-                       spin_unlock_irq(&p->sighand->siglock);
-               } while_each_pid_task(tty->session, PIDTYPE_SID, p);
-       }
-       read_unlock(&tasklist_lock);
-
-       spin_lock_irqsave(&tty->ctrl_lock, flags);
-       clear_bit(TTY_THROTTLED, &tty->flags);
-       clear_bit(TTY_PUSH, &tty->flags);
-       clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-       put_pid(tty->session);
-       put_pid(tty->pgrp);
-       tty->session = NULL;
-       tty->pgrp = NULL;
-       tty->ctrl_status = 0;
-       set_bit(TTY_HUPPED, &tty->flags);
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-
-       /* Account for the p->signal references we killed */
-       while (refs--)
-               tty_kref_put(tty);
-
-       /*
-        * If one of the devices matches a console pointer, we
-        * cannot just call hangup() because that will cause
-        * tty->count and state->count to go out of sync.
-        * So we just call close() the right number of times.
-        */
-       if (cons_filp) {
-               if (tty->ops->close)
-                       for (n = 0; n < closecount; n++)
-                               tty->ops->close(tty, cons_filp);
-       } else if (tty->ops->hangup)
-               (tty->ops->hangup)(tty);
-       /*
-        * We don't want to have driver/ldisc interactions beyond
-        * the ones we did here. The driver layer expects no
-        * calls after ->hangup() from the ldisc side. However we
-        * can't yet guarantee all that.
-        */
-       set_bit(TTY_HUPPED, &tty->flags);
-       tty_ldisc_enable(tty);
-
-       tty_unlock();
-
-       if (f)
-               fput(f);
-}
-
-static void do_tty_hangup(struct work_struct *work)
-{
-       struct tty_struct *tty =
-               container_of(work, struct tty_struct, hangup_work);
-
-       __tty_hangup(tty);
-}
-
-/**
- *     tty_hangup              -       trigger a hangup event
- *     @tty: tty to hangup
- *
- *     A carrier loss (virtual or otherwise) has occurred on this like
- *     schedule a hangup sequence to run after this event.
- */
-
-void tty_hangup(struct tty_struct *tty)
-{
-#ifdef TTY_DEBUG_HANGUP
-       char    buf[64];
-       printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf));
-#endif
-       schedule_work(&tty->hangup_work);
-}
-
-EXPORT_SYMBOL(tty_hangup);
-
-/**
- *     tty_vhangup             -       process vhangup
- *     @tty: tty to hangup
- *
- *     The user has asked via system call for the terminal to be hung up.
- *     We do this synchronously so that when the syscall returns the process
- *     is complete. That guarantee is necessary for security reasons.
- */
-
-void tty_vhangup(struct tty_struct *tty)
-{
-#ifdef TTY_DEBUG_HANGUP
-       char    buf[64];
-
-       printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
-#endif
-       __tty_hangup(tty);
-}
-
-EXPORT_SYMBOL(tty_vhangup);
-
-
-/**
- *     tty_vhangup_self        -       process vhangup for own ctty
- *
- *     Perform a vhangup on the current controlling tty
- */
-
-void tty_vhangup_self(void)
-{
-       struct tty_struct *tty;
-
-       tty = get_current_tty();
-       if (tty) {
-               tty_vhangup(tty);
-               tty_kref_put(tty);
-       }
-}
-
-/**
- *     tty_hung_up_p           -       was tty hung up
- *     @filp: file pointer of tty
- *
- *     Return true if the tty has been subject to a vhangup or a carrier
- *     loss
- */
-
-int tty_hung_up_p(struct file *filp)
-{
-       return (filp->f_op == &hung_up_tty_fops);
-}
-
-EXPORT_SYMBOL(tty_hung_up_p);
-
-static void session_clear_tty(struct pid *session)
-{
-       struct task_struct *p;
-       do_each_pid_task(session, PIDTYPE_SID, p) {
-               proc_clear_tty(p);
-       } while_each_pid_task(session, PIDTYPE_SID, p);
-}
-
-/**
- *     disassociate_ctty       -       disconnect controlling tty
- *     @on_exit: true if exiting so need to "hang up" the session
- *
- *     This function is typically called only by the session leader, when
- *     it wants to disassociate itself from its controlling tty.
- *
- *     It performs the following functions:
- *     (1)  Sends a SIGHUP and SIGCONT to the foreground process group
- *     (2)  Clears the tty from being controlling the session
- *     (3)  Clears the controlling tty for all processes in the
- *             session group.
- *
- *     The argument on_exit is set to 1 if called when a process is
- *     exiting; it is 0 if called by the ioctl TIOCNOTTY.
- *
- *     Locking:
- *             BTM is taken for hysterical raisins, and held when
- *               called from no_tty().
- *               tty_mutex is taken to protect tty
- *               ->siglock is taken to protect ->signal/->sighand
- *               tasklist_lock is taken to walk process list for sessions
- *                 ->siglock is taken to protect ->signal/->sighand
- */
-
-void disassociate_ctty(int on_exit)
-{
-       struct tty_struct *tty;
-       struct pid *tty_pgrp = NULL;
-
-       if (!current->signal->leader)
-               return;
-
-       tty = get_current_tty();
-       if (tty) {
-               tty_pgrp = get_pid(tty->pgrp);
-               if (on_exit) {
-                       if (tty->driver->type != TTY_DRIVER_TYPE_PTY)
-                               tty_vhangup(tty);
-               }
-               tty_kref_put(tty);
-       } else if (on_exit) {
-               struct pid *old_pgrp;
-               spin_lock_irq(&current->sighand->siglock);
-               old_pgrp = current->signal->tty_old_pgrp;
-               current->signal->tty_old_pgrp = NULL;
-               spin_unlock_irq(&current->sighand->siglock);
-               if (old_pgrp) {
-                       kill_pgrp(old_pgrp, SIGHUP, on_exit);
-                       kill_pgrp(old_pgrp, SIGCONT, on_exit);
-                       put_pid(old_pgrp);
-               }
-               return;
-       }
-       if (tty_pgrp) {
-               kill_pgrp(tty_pgrp, SIGHUP, on_exit);
-               if (!on_exit)
-                       kill_pgrp(tty_pgrp, SIGCONT, on_exit);
-               put_pid(tty_pgrp);
-       }
-
-       spin_lock_irq(&current->sighand->siglock);
-       put_pid(current->signal->tty_old_pgrp);
-       current->signal->tty_old_pgrp = NULL;
-       spin_unlock_irq(&current->sighand->siglock);
-
-       tty = get_current_tty();
-       if (tty) {
-               unsigned long flags;
-               spin_lock_irqsave(&tty->ctrl_lock, flags);
-               put_pid(tty->session);
-               put_pid(tty->pgrp);
-               tty->session = NULL;
-               tty->pgrp = NULL;
-               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-               tty_kref_put(tty);
-       } else {
-#ifdef TTY_DEBUG_HANGUP
-               printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
-                      " = NULL", tty);
-#endif
-       }
-
-       /* Now clear signal->tty under the lock */
-       read_lock(&tasklist_lock);
-       session_clear_tty(task_session(current));
-       read_unlock(&tasklist_lock);
-}
-
-/**
- *
- *     no_tty  - Ensure the current process does not have a controlling tty
- */
-void no_tty(void)
-{
-       struct task_struct *tsk = current;
-       tty_lock();
-       disassociate_ctty(0);
-       tty_unlock();
-       proc_clear_tty(tsk);
-}
-
-
-/**
- *     stop_tty        -       propagate flow control
- *     @tty: tty to stop
- *
- *     Perform flow control to the driver. For PTY/TTY pairs we
- *     must also propagate the TIOCKPKT status. May be called
- *     on an already stopped device and will not re-call the driver
- *     method.
- *
- *     This functionality is used by both the line disciplines for
- *     halting incoming flow and by the driver. It may therefore be
- *     called from any context, may be under the tty atomic_write_lock
- *     but not always.
- *
- *     Locking:
- *             Uses the tty control lock internally
- */
-
-void stop_tty(struct tty_struct *tty)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&tty->ctrl_lock, flags);
-       if (tty->stopped) {
-               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-               return;
-       }
-       tty->stopped = 1;
-       if (tty->link && tty->link->packet) {
-               tty->ctrl_status &= ~TIOCPKT_START;
-               tty->ctrl_status |= TIOCPKT_STOP;
-               wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
-       }
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-       if (tty->ops->stop)
-               (tty->ops->stop)(tty);
-}
-
-EXPORT_SYMBOL(stop_tty);
-
-/**
- *     start_tty       -       propagate flow control
- *     @tty: tty to start
- *
- *     Start a tty that has been stopped if at all possible. Perform
- *     any necessary wakeups and propagate the TIOCPKT status. If this
- *     is the tty was previous stopped and is being started then the
- *     driver start method is invoked and the line discipline woken.
- *
- *     Locking:
- *             ctrl_lock
- */
-
-void start_tty(struct tty_struct *tty)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&tty->ctrl_lock, flags);
-       if (!tty->stopped || tty->flow_stopped) {
-               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-               return;
-       }
-       tty->stopped = 0;
-       if (tty->link && tty->link->packet) {
-               tty->ctrl_status &= ~TIOCPKT_STOP;
-               tty->ctrl_status |= TIOCPKT_START;
-               wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
-       }
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-       if (tty->ops->start)
-               (tty->ops->start)(tty);
-       /* If we have a running line discipline it may need kicking */
-       tty_wakeup(tty);
-}
-
-EXPORT_SYMBOL(start_tty);
-
-/**
- *     tty_read        -       read method for tty device files
- *     @file: pointer to tty file
- *     @buf: user buffer
- *     @count: size of user buffer
- *     @ppos: unused
- *
- *     Perform the read system call function on this terminal device. Checks
- *     for hung up devices before calling the line discipline method.
- *
- *     Locking:
- *             Locks the line discipline internally while needed. Multiple
- *     read calls may be outstanding in parallel.
- */
-
-static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
-                       loff_t *ppos)
-{
-       int i;
-       struct inode *inode = file->f_path.dentry->d_inode;
-       struct tty_struct *tty = file_tty(file);
-       struct tty_ldisc *ld;
-
-       if (tty_paranoia_check(tty, inode, "tty_read"))
-               return -EIO;
-       if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
-               return -EIO;
-
-       /* We want to wait for the line discipline to sort out in this
-          situation */
-       ld = tty_ldisc_ref_wait(tty);
-       if (ld->ops->read)
-               i = (ld->ops->read)(tty, file, buf, count);
-       else
-               i = -EIO;
-       tty_ldisc_deref(ld);
-       if (i > 0)
-               inode->i_atime = current_fs_time(inode->i_sb);
-       return i;
-}
-
-void tty_write_unlock(struct tty_struct *tty)
-{
-       mutex_unlock(&tty->atomic_write_lock);
-       wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
-}
-
-int tty_write_lock(struct tty_struct *tty, int ndelay)
-{
-       if (!mutex_trylock(&tty->atomic_write_lock)) {
-               if (ndelay)
-                       return -EAGAIN;
-               if (mutex_lock_interruptible(&tty->atomic_write_lock))
-                       return -ERESTARTSYS;
-       }
-       return 0;
-}
-
-/*
- * Split writes up in sane blocksizes to avoid
- * denial-of-service type attacks
- */
-static inline ssize_t do_tty_write(
-       ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),
-       struct tty_struct *tty,
-       struct file *file,
-       const char __user *buf,
-       size_t count)
-{
-       ssize_t ret, written = 0;
-       unsigned int chunk;
-
-       ret = tty_write_lock(tty, file->f_flags & O_NDELAY);
-       if (ret < 0)
-               return ret;
-
-       /*
-        * We chunk up writes into a temporary buffer. This
-        * simplifies low-level drivers immensely, since they
-        * don't have locking issues and user mode accesses.
-        *
-        * But if TTY_NO_WRITE_SPLIT is set, we should use a
-        * big chunk-size..
-        *
-        * The default chunk-size is 2kB, because the NTTY
-        * layer has problems with bigger chunks. It will
-        * claim to be able to handle more characters than
-        * it actually does.
-        *
-        * FIXME: This can probably go away now except that 64K chunks
-        * are too likely to fail unless switched to vmalloc...
-        */
-       chunk = 2048;
-       if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags))
-               chunk = 65536;
-       if (count < chunk)
-               chunk = count;
-
-       /* write_buf/write_cnt is protected by the atomic_write_lock mutex */
-       if (tty->write_cnt < chunk) {
-               unsigned char *buf_chunk;
-
-               if (chunk < 1024)
-                       chunk = 1024;
-
-               buf_chunk = kmalloc(chunk, GFP_KERNEL);
-               if (!buf_chunk) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               kfree(tty->write_buf);
-               tty->write_cnt = chunk;
-               tty->write_buf = buf_chunk;
-       }
-
-       /* Do the write .. */
-       for (;;) {
-               size_t size = count;
-               if (size > chunk)
-                       size = chunk;
-               ret = -EFAULT;
-               if (copy_from_user(tty->write_buf, buf, size))
-                       break;
-               ret = write(tty, file, tty->write_buf, size);
-               if (ret <= 0)
-                       break;
-               written += ret;
-               buf += ret;
-               count -= ret;
-               if (!count)
-                       break;
-               ret = -ERESTARTSYS;
-               if (signal_pending(current))
-                       break;
-               cond_resched();
-       }
-       if (written) {
-               struct inode *inode = file->f_path.dentry->d_inode;
-               inode->i_mtime = current_fs_time(inode->i_sb);
-               ret = written;
-       }
-out:
-       tty_write_unlock(tty);
-       return ret;
-}
-
-/**
- * tty_write_message - write a message to a certain tty, not just the console.
- * @tty: the destination tty_struct
- * @msg: the message to write
- *
- * This is used for messages that need to be redirected to a specific tty.
- * We don't put it into the syslog queue right now maybe in the future if
- * really needed.
- *
- * We must still hold the BTM and test the CLOSING flag for the moment.
- */
-
-void tty_write_message(struct tty_struct *tty, char *msg)
-{
-       if (tty) {
-               mutex_lock(&tty->atomic_write_lock);
-               tty_lock();
-               if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
-                       tty_unlock();
-                       tty->ops->write(tty, msg, strlen(msg));
-               } else
-                       tty_unlock();
-               tty_write_unlock(tty);
-       }
-       return;
-}
-
-
-/**
- *     tty_write               -       write method for tty device file
- *     @file: tty file pointer
- *     @buf: user data to write
- *     @count: bytes to write
- *     @ppos: unused
- *
- *     Write data to a tty device via the line discipline.
- *
- *     Locking:
- *             Locks the line discipline as required
- *             Writes to the tty driver are serialized by the atomic_write_lock
- *     and are then processed in chunks to the device. The line discipline
- *     write method will not be invoked in parallel for each device.
- */
-
-static ssize_t tty_write(struct file *file, const char __user *buf,
-                                               size_t count, loff_t *ppos)
-{
-       struct inode *inode = file->f_path.dentry->d_inode;
-       struct tty_struct *tty = file_tty(file);
-       struct tty_ldisc *ld;
-       ssize_t ret;
-
-       if (tty_paranoia_check(tty, inode, "tty_write"))
-               return -EIO;
-       if (!tty || !tty->ops->write ||
-               (test_bit(TTY_IO_ERROR, &tty->flags)))
-                       return -EIO;
-       /* Short term debug to catch buggy drivers */
-       if (tty->ops->write_room == NULL)
-               printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
-                       tty->driver->name);
-       ld = tty_ldisc_ref_wait(tty);
-       if (!ld->ops->write)
-               ret = -EIO;
-       else
-               ret = do_tty_write(ld->ops->write, tty, file, buf, count);
-       tty_ldisc_deref(ld);
-       return ret;
-}
-
-ssize_t redirected_tty_write(struct file *file, const char __user *buf,
-                                               size_t count, loff_t *ppos)
-{
-       struct file *p = NULL;
-
-       spin_lock(&redirect_lock);
-       if (redirect) {
-               get_file(redirect);
-               p = redirect;
-       }
-       spin_unlock(&redirect_lock);
-
-       if (p) {
-               ssize_t res;
-               res = vfs_write(p, buf, count, &p->f_pos);
-               fput(p);
-               return res;
-       }
-       return tty_write(file, buf, count, ppos);
-}
-
-static char ptychar[] = "pqrstuvwxyzabcde";
-
-/**
- *     pty_line_name   -       generate name for a pty
- *     @driver: the tty driver in use
- *     @index: the minor number
- *     @p: output buffer of at least 6 bytes
- *
- *     Generate a name from a driver reference and write it to the output
- *     buffer.
- *
- *     Locking: None
- */
-static void pty_line_name(struct tty_driver *driver, int index, char *p)
-{
-       int i = index + driver->name_base;
-       /* ->name is initialized to "ttyp", but "tty" is expected */
-       sprintf(p, "%s%c%x",
-               driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name,
-               ptychar[i >> 4 & 0xf], i & 0xf);
-}
-
-/**
- *     tty_line_name   -       generate name for a tty
- *     @driver: the tty driver in use
- *     @index: the minor number
- *     @p: output buffer of at least 7 bytes
- *
- *     Generate a name from a driver reference and write it to the output
- *     buffer.
- *
- *     Locking: None
- */
-static void tty_line_name(struct tty_driver *driver, int index, char *p)
-{
-       sprintf(p, "%s%d", driver->name, index + driver->name_base);
-}
-
-/**
- *     tty_driver_lookup_tty() - find an existing tty, if any
- *     @driver: the driver for the tty
- *     @idx:    the minor number
- *
- *     Return the tty, if found or ERR_PTR() otherwise.
- *
- *     Locking: tty_mutex must be held. If tty is found, the mutex must
- *     be held until the 'fast-open' is also done. Will change once we
- *     have refcounting in the driver and per driver locking
- */
-static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
-               struct inode *inode, int idx)
-{
-       struct tty_struct *tty;
-
-       if (driver->ops->lookup)
-               return driver->ops->lookup(driver, inode, idx);
-
-       tty = driver->ttys[idx];
-       return tty;
-}
-
-/**
- *     tty_init_termios        -  helper for termios setup
- *     @tty: the tty to set up
- *
- *     Initialise the termios structures for this tty. Thus runs under
- *     the tty_mutex currently so we can be relaxed about ordering.
- */
-
-int tty_init_termios(struct tty_struct *tty)
-{
-       struct ktermios *tp;
-       int idx = tty->index;
-
-       tp = tty->driver->termios[idx];
-       if (tp == NULL) {
-               tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
-               if (tp == NULL)
-                       return -ENOMEM;
-               memcpy(tp, &tty->driver->init_termios,
-                                               sizeof(struct ktermios));
-               tty->driver->termios[idx] = tp;
-       }
-       tty->termios = tp;
-       tty->termios_locked = tp + 1;
-
-       /* Compatibility until drivers always set this */
-       tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
-       tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(tty_init_termios);
-
-/**
- *     tty_driver_install_tty() - install a tty entry in the driver
- *     @driver: the driver for the tty
- *     @tty: the tty
- *
- *     Install a tty object into the driver tables. The tty->index field
- *     will be set by the time this is called. This method is responsible
- *     for ensuring any need additional structures are allocated and
- *     configured.
- *
- *     Locking: tty_mutex for now
- */
-static int tty_driver_install_tty(struct tty_driver *driver,
-                                               struct tty_struct *tty)
-{
-       int idx = tty->index;
-       int ret;
-
-       if (driver->ops->install) {
-               ret = driver->ops->install(driver, tty);
-               return ret;
-       }
-
-       if (tty_init_termios(tty) == 0) {
-               tty_driver_kref_get(driver);
-               tty->count++;
-               driver->ttys[idx] = tty;
-               return 0;
-       }
-       return -ENOMEM;
-}
-
-/**
- *     tty_driver_remove_tty() - remove a tty from the driver tables
- *     @driver: the driver for the tty
- *     @idx:    the minor number
- *
- *     Remvoe a tty object from the driver tables. The tty->index field
- *     will be set by the time this is called.
- *
- *     Locking: tty_mutex for now
- */
-static void tty_driver_remove_tty(struct tty_driver *driver,
-                                               struct tty_struct *tty)
-{
-       if (driver->ops->remove)
-               driver->ops->remove(driver, tty);
-       else
-               driver->ttys[tty->index] = NULL;
-}
-
-/*
- *     tty_reopen()    - fast re-open of an open tty
- *     @tty    - the tty to open
- *
- *     Return 0 on success, -errno on error.
- *
- *     Locking: tty_mutex must be held from the time the tty was found
- *              till this open completes.
- */
-static int tty_reopen(struct tty_struct *tty)
-{
-       struct tty_driver *driver = tty->driver;
-
-       if (test_bit(TTY_CLOSING, &tty->flags))
-               return -EIO;
-
-       if (driver->type == TTY_DRIVER_TYPE_PTY &&
-           driver->subtype == PTY_TYPE_MASTER) {
-               /*
-                * special case for PTY masters: only one open permitted,
-                * and the slave side open count is incremented as well.
-                */
-               if (tty->count)
-                       return -EIO;
-
-               tty->link->count++;
-       }
-       tty->count++;
-       tty->driver = driver; /* N.B. why do this every time?? */
-
-       mutex_lock(&tty->ldisc_mutex);
-       WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
-       mutex_unlock(&tty->ldisc_mutex);
-
-       return 0;
-}
-
-/**
- *     tty_init_dev            -       initialise a tty device
- *     @driver: tty driver we are opening a device on
- *     @idx: device index
- *     @ret_tty: returned tty structure
- *     @first_ok: ok to open a new device (used by ptmx)
- *
- *     Prepare a tty device. This may not be a "new" clean device but
- *     could also be an active device. The pty drivers require special
- *     handling because of this.
- *
- *     Locking:
- *             The function is called under the tty_mutex, which
- *     protects us from the tty struct or driver itself going away.
- *
- *     On exit the tty device has the line discipline attached and
- *     a reference count of 1. If a pair was created for pty/tty use
- *     and the other was a pty master then it too has a reference count of 1.
- *
- * WSH 06/09/97: Rewritten to remove races and properly clean up after a
- * failed open.  The new code protects the open with a mutex, so it's
- * really quite straightforward.  The mutex locking can probably be
- * relaxed for the (most common) case of reopening a tty.
- */
-
-struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
-                                                               int first_ok)
-{
-       struct tty_struct *tty;
-       int retval;
-
-       /* Check if pty master is being opened multiple times */
-       if (driver->subtype == PTY_TYPE_MASTER &&
-               (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
-               return ERR_PTR(-EIO);
-       }
-
-       /*
-        * First time open is complex, especially for PTY devices.
-        * This code guarantees that either everything succeeds and the
-        * TTY is ready for operation, or else the table slots are vacated
-        * and the allocated memory released.  (Except that the termios
-        * and locked termios may be retained.)
-        */
-
-       if (!try_module_get(driver->owner))
-               return ERR_PTR(-ENODEV);
-
-       tty = alloc_tty_struct();
-       if (!tty)
-               goto fail_no_mem;
-       initialize_tty_struct(tty, driver, idx);
-
-       retval = tty_driver_install_tty(driver, tty);
-       if (retval < 0) {
-               free_tty_struct(tty);
-               module_put(driver->owner);
-               return ERR_PTR(retval);
-       }
-
-       /*
-        * Structures all installed ... call the ldisc open routines.
-        * If we fail here just call release_tty to clean up.  No need
-        * to decrement the use counts, as release_tty doesn't care.
-        */
-       retval = tty_ldisc_setup(tty, tty->link);
-       if (retval)
-               goto release_mem_out;
-       return tty;
-
-fail_no_mem:
-       module_put(driver->owner);
-       return ERR_PTR(-ENOMEM);
-
-       /* call the tty release_tty routine to clean out this slot */
-release_mem_out:
-       if (printk_ratelimit())
-               printk(KERN_INFO "tty_init_dev: ldisc open failed, "
-                                "clearing slot %d\n", idx);
-       release_tty(tty, idx);
-       return ERR_PTR(retval);
-}
-
-void tty_free_termios(struct tty_struct *tty)
-{
-       struct ktermios *tp;
-       int idx = tty->index;
-       /* Kill this flag and push into drivers for locking etc */
-       if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
-               /* FIXME: Locking on ->termios array */
-               tp = tty->termios;
-               tty->driver->termios[idx] = NULL;
-               kfree(tp);
-       }
-}
-EXPORT_SYMBOL(tty_free_termios);
-
-void tty_shutdown(struct tty_struct *tty)
-{
-       tty_driver_remove_tty(tty->driver, tty);
-       tty_free_termios(tty);
-}
-EXPORT_SYMBOL(tty_shutdown);
-
-/**
- *     release_one_tty         -       release tty structure memory
- *     @kref: kref of tty we are obliterating
- *
- *     Releases memory associated with a tty structure, and clears out the
- *     driver table slots. This function is called when a device is no longer
- *     in use. It also gets called when setup of a device fails.
- *
- *     Locking:
- *             tty_mutex - sometimes only
- *             takes the file list lock internally when working on the list
- *     of ttys that the driver keeps.
- *
- *     This method gets called from a work queue so that the driver private
- *     cleanup ops can sleep (needed for USB at least)
- */
-static void release_one_tty(struct work_struct *work)
-{
-       struct tty_struct *tty =
-               container_of(work, struct tty_struct, hangup_work);
-       struct tty_driver *driver = tty->driver;
-
-       if (tty->ops->cleanup)
-               tty->ops->cleanup(tty);
-
-       tty->magic = 0;
-       tty_driver_kref_put(driver);
-       module_put(driver->owner);
-
-       spin_lock(&tty_files_lock);
-       list_del_init(&tty->tty_files);
-       spin_unlock(&tty_files_lock);
-
-       put_pid(tty->pgrp);
-       put_pid(tty->session);
-       free_tty_struct(tty);
-}
-
-static void queue_release_one_tty(struct kref *kref)
-{
-       struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
-
-       if (tty->ops->shutdown)
-               tty->ops->shutdown(tty);
-       else
-               tty_shutdown(tty);
-
-       /* The hangup queue is now free so we can reuse it rather than
-          waste a chunk of memory for each port */
-       INIT_WORK(&tty->hangup_work, release_one_tty);
-       schedule_work(&tty->hangup_work);
-}
-
-/**
- *     tty_kref_put            -       release a tty kref
- *     @tty: tty device
- *
- *     Release a reference to a tty device and if need be let the kref
- *     layer destruct the object for us
- */
-
-void tty_kref_put(struct tty_struct *tty)
-{
-       if (tty)
-               kref_put(&tty->kref, queue_release_one_tty);
-}
-EXPORT_SYMBOL(tty_kref_put);
-
-/**
- *     release_tty             -       release tty structure memory
- *
- *     Release both @tty and a possible linked partner (think pty pair),
- *     and decrement the refcount of the backing module.
- *
- *     Locking:
- *             tty_mutex - sometimes only
- *             takes the file list lock internally when working on the list
- *     of ttys that the driver keeps.
- *             FIXME: should we require tty_mutex is held here ??
- *
- */
-static void release_tty(struct tty_struct *tty, int idx)
-{
-       /* This should always be true but check for the moment */
-       WARN_ON(tty->index != idx);
-
-       if (tty->link)
-               tty_kref_put(tty->link);
-       tty_kref_put(tty);
-}
-
-/**
- *     tty_release             -       vfs callback for close
- *     @inode: inode of tty
- *     @filp: file pointer for handle to tty
- *
- *     Called the last time each file handle is closed that references
- *     this tty. There may however be several such references.
- *
- *     Locking:
- *             Takes bkl. See tty_release_dev
- *
- * Even releasing the tty structures is a tricky business.. We have
- * to be very careful that the structures are all released at the
- * same time, as interrupts might otherwise get the wrong pointers.
- *
- * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
- * lead to double frees or releasing memory still in use.
- */
-
-int tty_release(struct inode *inode, struct file *filp)
-{
-       struct tty_struct *tty = file_tty(filp);
-       struct tty_struct *o_tty;
-       int     pty_master, tty_closing, o_tty_closing, do_sleep;
-       int     devpts;
-       int     idx;
-       char    buf[64];
-
-       if (tty_paranoia_check(tty, inode, "tty_release_dev"))
-               return 0;
-
-       tty_lock();
-       check_tty_count(tty, "tty_release_dev");
-
-       __tty_fasync(-1, filp, 0);
-
-       idx = tty->index;
-       pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
-                     tty->driver->subtype == PTY_TYPE_MASTER);
-       devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
-       o_tty = tty->link;
-
-#ifdef TTY_PARANOIA_CHECK
-       if (idx < 0 || idx >= tty->driver->num) {
-               printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
-                                 "free (%s)\n", tty->name);
-               tty_unlock();
-               return 0;
-       }
-       if (!devpts) {
-               if (tty != tty->driver->ttys[idx]) {
-                       tty_unlock();
-                       printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
-                              "for (%s)\n", idx, tty->name);
-                       return 0;
-               }
-               if (tty->termios != tty->driver->termios[idx]) {
-                       tty_unlock();
-                       printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
-                              "for (%s)\n",
-                              idx, tty->name);
-                       return 0;
-               }
-       }
-#endif
-
-#ifdef TTY_DEBUG_HANGUP
-       printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...",
-              tty_name(tty, buf), tty->count);
-#endif
-
-#ifdef TTY_PARANOIA_CHECK
-       if (tty->driver->other &&
-            !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
-               if (o_tty != tty->driver->other->ttys[idx]) {
-                       tty_unlock();
-                       printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
-                                         "not o_tty for (%s)\n",
-                              idx, tty->name);
-                       return 0 ;
-               }
-               if (o_tty->termios != tty->driver->other->termios[idx]) {
-                       tty_unlock();
-                       printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
-                                         "not o_termios for (%s)\n",
-                              idx, tty->name);
-                       return 0;
-               }
-               if (o_tty->link != tty) {
-                       tty_unlock();
-                       printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
-                       return 0;
-               }
-       }
-#endif
-       if (tty->ops->close)
-               tty->ops->close(tty, filp);
-
-       tty_unlock();
-       /*
-        * Sanity check: if tty->count is going to zero, there shouldn't be
-        * any waiters on tty->read_wait or tty->write_wait.  We test the
-        * wait queues and kick everyone out _before_ actually starting to
-        * close.  This ensures that we won't block while releasing the tty
-        * structure.
-        *
-        * The test for the o_tty closing is necessary, since the master and
-        * slave sides may close in any order.  If the slave side closes out
-        * first, its count will be one, since the master side holds an open.
-        * Thus this test wouldn't be triggered at the time the slave closes,
-        * so we do it now.
-        *
-        * Note that it's possible for the tty to be opened again while we're
-        * flushing out waiters.  By recalculating the closing flags before
-        * each iteration we avoid any problems.
-        */
-       while (1) {
-               /* Guard against races with tty->count changes elsewhere and
-                  opens on /dev/tty */
-
-               mutex_lock(&tty_mutex);
-               tty_lock();
-               tty_closing = tty->count <= 1;
-               o_tty_closing = o_tty &&
-                       (o_tty->count <= (pty_master ? 1 : 0));
-               do_sleep = 0;
-
-               if (tty_closing) {
-                       if (waitqueue_active(&tty->read_wait)) {
-                               wake_up_poll(&tty->read_wait, POLLIN);
-                               do_sleep++;
-                       }
-                       if (waitqueue_active(&tty->write_wait)) {
-                               wake_up_poll(&tty->write_wait, POLLOUT);
-                               do_sleep++;
-                       }
-               }
-               if (o_tty_closing) {
-                       if (waitqueue_active(&o_tty->read_wait)) {
-                               wake_up_poll(&o_tty->read_wait, POLLIN);
-                               do_sleep++;
-                       }
-                       if (waitqueue_active(&o_tty->write_wait)) {
-                               wake_up_poll(&o_tty->write_wait, POLLOUT);
-                               do_sleep++;
-                       }
-               }
-               if (!do_sleep)
-                       break;
-
-               printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
-                                   "active!\n", tty_name(tty, buf));
-               tty_unlock();
-               mutex_unlock(&tty_mutex);
-               schedule();
-       }
-
-       /*
-        * The closing flags are now consistent with the open counts on
-        * both sides, and we've completed the last operation that could
-        * block, so it's safe to proceed with closing.
-        */
-       if (pty_master) {
-               if (--o_tty->count < 0) {
-                       printk(KERN_WARNING "tty_release_dev: bad pty slave count "
-                                           "(%d) for %s\n",
-                              o_tty->count, tty_name(o_tty, buf));
-                       o_tty->count = 0;
-               }
-       }
-       if (--tty->count < 0) {
-               printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n",
-                      tty->count, tty_name(tty, buf));
-               tty->count = 0;
-       }
-
-       /*
-        * We've decremented tty->count, so we need to remove this file
-        * descriptor off the tty->tty_files list; this serves two
-        * purposes:
-        *  - check_tty_count sees the correct number of file descriptors
-        *    associated with this tty.
-        *  - do_tty_hangup no longer sees this file descriptor as
-        *    something that needs to be handled for hangups.
-        */
-       tty_del_file(filp);
-
-       /*
-        * Perform some housekeeping before deciding whether to return.
-        *
-        * Set the TTY_CLOSING flag if this was the last open.  In the
-        * case of a pty we may have to wait around for the other side
-        * to close, and TTY_CLOSING makes sure we can't be reopened.
-        */
-       if (tty_closing)
-               set_bit(TTY_CLOSING, &tty->flags);
-       if (o_tty_closing)
-               set_bit(TTY_CLOSING, &o_tty->flags);
-
-       /*
-        * If _either_ side is closing, make sure there aren't any
-        * processes that still think tty or o_tty is their controlling
-        * tty.
-        */
-       if (tty_closing || o_tty_closing) {
-               read_lock(&tasklist_lock);
-               session_clear_tty(tty->session);
-               if (o_tty)
-                       session_clear_tty(o_tty->session);
-               read_unlock(&tasklist_lock);
-       }
-
-       mutex_unlock(&tty_mutex);
-
-       /* check whether both sides are closing ... */
-       if (!tty_closing || (o_tty && !o_tty_closing)) {
-               tty_unlock();
-               return 0;
-       }
-
-#ifdef TTY_DEBUG_HANGUP
-       printk(KERN_DEBUG "freeing tty structure...");
-#endif
-       /*
-        * Ask the line discipline code to release its structures
-        */
-       tty_ldisc_release(tty, o_tty);
-       /*
-        * The release_tty function takes care of the details of clearing
-        * the slots and preserving the termios structure.
-        */
-       release_tty(tty, idx);
-
-       /* Make this pty number available for reallocation */
-       if (devpts)
-               devpts_kill_index(inode, idx);
-       tty_unlock();
-       return 0;
-}
-
-/**
- *     tty_open                -       open a tty device
- *     @inode: inode of device file
- *     @filp: file pointer to tty
- *
- *     tty_open and tty_release keep up the tty count that contains the
- *     number of opens done on a tty. We cannot use the inode-count, as
- *     different inodes might point to the same tty.
- *
- *     Open-counting is needed for pty masters, as well as for keeping
- *     track of serial lines: DTR is dropped when the last close happens.
- *     (This is not done solely through tty->count, now.  - Ted 1/27/92)
- *
- *     The termios state of a pty is reset on first open so that
- *     settings don't persist across reuse.
- *
- *     Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work.
- *              tty->count should protect the rest.
- *              ->siglock protects ->signal/->sighand
- */
-
-static int tty_open(struct inode *inode, struct file *filp)
-{
-       struct tty_struct *tty = NULL;
-       int noctty, retval;
-       struct tty_driver *driver;
-       int index;
-       dev_t device = inode->i_rdev;
-       unsigned saved_flags = filp->f_flags;
-
-       nonseekable_open(inode, filp);
-
-retry_open:
-       noctty = filp->f_flags & O_NOCTTY;
-       index  = -1;
-       retval = 0;
-
-       mutex_lock(&tty_mutex);
-       tty_lock();
-
-       if (device == MKDEV(TTYAUX_MAJOR, 0)) {
-               tty = get_current_tty();
-               if (!tty) {
-                       tty_unlock();
-                       mutex_unlock(&tty_mutex);
-                       return -ENXIO;
-               }
-               driver = tty_driver_kref_get(tty->driver);
-               index = tty->index;
-               filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
-               /* noctty = 1; */
-               /* FIXME: Should we take a driver reference ? */
-               tty_kref_put(tty);
-               goto got_driver;
-       }
-#ifdef CONFIG_VT
-       if (device == MKDEV(TTY_MAJOR, 0)) {
-               extern struct tty_driver *console_driver;
-               driver = tty_driver_kref_get(console_driver);
-               index = fg_console;
-               noctty = 1;
-               goto got_driver;
-       }
-#endif
-       if (device == MKDEV(TTYAUX_MAJOR, 1)) {
-               struct tty_driver *console_driver = console_device(&index);
-               if (console_driver) {
-                       driver = tty_driver_kref_get(console_driver);
-                       if (driver) {
-                               /* Don't let /dev/console block */
-                               filp->f_flags |= O_NONBLOCK;
-                               noctty = 1;
-                               goto got_driver;
-                       }
-               }
-               tty_unlock();
-               mutex_unlock(&tty_mutex);
-               return -ENODEV;
-       }
-
-       driver = get_tty_driver(device, &index);
-       if (!driver) {
-               tty_unlock();
-               mutex_unlock(&tty_mutex);
-               return -ENODEV;
-       }
-got_driver:
-       if (!tty) {
-               /* check whether we're reopening an existing tty */
-               tty = tty_driver_lookup_tty(driver, inode, index);
-
-               if (IS_ERR(tty)) {
-                       tty_unlock();
-                       mutex_unlock(&tty_mutex);
-                       return PTR_ERR(tty);
-               }
-       }
-
-       if (tty) {
-               retval = tty_reopen(tty);
-               if (retval)
-                       tty = ERR_PTR(retval);
-       } else
-               tty = tty_init_dev(driver, index, 0);
-
-       mutex_unlock(&tty_mutex);
-       tty_driver_kref_put(driver);
-       if (IS_ERR(tty)) {
-               tty_unlock();
-               return PTR_ERR(tty);
-       }
-
-       retval = tty_add_file(tty, filp);
-       if (retval) {
-               tty_unlock();
-               return retval;
-       }
-
-       check_tty_count(tty, "tty_open");
-       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
-           tty->driver->subtype == PTY_TYPE_MASTER)
-               noctty = 1;
-#ifdef TTY_DEBUG_HANGUP
-       printk(KERN_DEBUG "opening %s...", tty->name);
-#endif
-       if (!retval) {
-               if (tty->ops->open)
-                       retval = tty->ops->open(tty, filp);
-               else
-                       retval = -ENODEV;
-       }
-       filp->f_flags = saved_flags;
-
-       if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) &&
-                                               !capable(CAP_SYS_ADMIN))
-               retval = -EBUSY;
-
-       if (retval) {
-#ifdef TTY_DEBUG_HANGUP
-               printk(KERN_DEBUG "error %d in opening %s...", retval,
-                      tty->name);
-#endif
-               tty_unlock(); /* need to call tty_release without BTM */
-               tty_release(inode, filp);
-               if (retval != -ERESTARTSYS)
-                       return retval;
-
-               if (signal_pending(current))
-                       return retval;
-
-               schedule();
-               /*
-                * Need to reset f_op in case a hangup happened.
-                */
-               tty_lock();
-               if (filp->f_op == &hung_up_tty_fops)
-                       filp->f_op = &tty_fops;
-               tty_unlock();
-               goto retry_open;
-       }
-       tty_unlock();
-
-
-       mutex_lock(&tty_mutex);
-       tty_lock();
-       spin_lock_irq(&current->sighand->siglock);
-       if (!noctty &&
-           current->signal->leader &&
-           !current->signal->tty &&
-           tty->session == NULL)
-               __proc_set_tty(current, tty);
-       spin_unlock_irq(&current->sighand->siglock);
-       tty_unlock();
-       mutex_unlock(&tty_mutex);
-       return 0;
-}
-
-
-
-/**
- *     tty_poll        -       check tty status
- *     @filp: file being polled
- *     @wait: poll wait structures to update
- *
- *     Call the line discipline polling method to obtain the poll
- *     status of the device.
- *
- *     Locking: locks called line discipline but ldisc poll method
- *     may be re-entered freely by other callers.
- */
-
-static unsigned int tty_poll(struct file *filp, poll_table *wait)
-{
-       struct tty_struct *tty = file_tty(filp);
-       struct tty_ldisc *ld;
-       int ret = 0;
-
-       if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
-               return 0;
-
-       ld = tty_ldisc_ref_wait(tty);
-       if (ld->ops->poll)
-               ret = (ld->ops->poll)(tty, filp, wait);
-       tty_ldisc_deref(ld);
-       return ret;
-}
-
-static int __tty_fasync(int fd, struct file *filp, int on)
-{
-       struct tty_struct *tty = file_tty(filp);
-       unsigned long flags;
-       int retval = 0;
-
-       if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
-               goto out;
-
-       retval = fasync_helper(fd, filp, on, &tty->fasync);
-       if (retval <= 0)
-               goto out;
-
-       if (on) {
-               enum pid_type type;
-               struct pid *pid;
-               if (!waitqueue_active(&tty->read_wait))
-                       tty->minimum_to_wake = 1;
-               spin_lock_irqsave(&tty->ctrl_lock, flags);
-               if (tty->pgrp) {
-                       pid = tty->pgrp;
-                       type = PIDTYPE_PGID;
-               } else {
-                       pid = task_pid(current);
-                       type = PIDTYPE_PID;
-               }
-               get_pid(pid);
-               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-               retval = __f_setown(filp, pid, type, 0);
-               put_pid(pid);
-               if (retval)
-                       goto out;
-       } else {
-               if (!tty->fasync && !waitqueue_active(&tty->read_wait))
-                       tty->minimum_to_wake = N_TTY_BUF_SIZE;
-       }
-       retval = 0;
-out:
-       return retval;
-}
-
-static int tty_fasync(int fd, struct file *filp, int on)
-{
-       int retval;
-       tty_lock();
-       retval = __tty_fasync(fd, filp, on);
-       tty_unlock();
-       return retval;
-}
-
-/**
- *     tiocsti                 -       fake input character
- *     @tty: tty to fake input into
- *     @p: pointer to character
- *
- *     Fake input to a tty device. Does the necessary locking and
- *     input management.
- *
- *     FIXME: does not honour flow control ??
- *
- *     Locking:
- *             Called functions take tty_ldisc_lock
- *             current->signal->tty check is safe without locks
- *
- *     FIXME: may race normal receive processing
- */
-
-static int tiocsti(struct tty_struct *tty, char __user *p)
-{
-       char ch, mbz = 0;
-       struct tty_ldisc *ld;
-
-       if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       if (get_user(ch, p))
-               return -EFAULT;
-       tty_audit_tiocsti(tty, ch);
-       ld = tty_ldisc_ref_wait(tty);
-       ld->ops->receive_buf(tty, &ch, &mbz, 1);
-       tty_ldisc_deref(ld);
-       return 0;
-}
-
-/**
- *     tiocgwinsz              -       implement window query ioctl
- *     @tty; tty
- *     @arg: user buffer for result
- *
- *     Copies the kernel idea of the window size into the user buffer.
- *
- *     Locking: tty->termios_mutex is taken to ensure the winsize data
- *             is consistent.
- */
-
-static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
-{
-       int err;
-
-       mutex_lock(&tty->termios_mutex);
-       err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
-       mutex_unlock(&tty->termios_mutex);
-
-       return err ? -EFAULT: 0;
-}
-
-/**
- *     tty_do_resize           -       resize event
- *     @tty: tty being resized
- *     @rows: rows (character)
- *     @cols: cols (character)
- *
- *     Update the termios variables and send the necessary signals to
- *     peform a terminal resize correctly
- */
-
-int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
-{
-       struct pid *pgrp;
-       unsigned long flags;
-
-       /* Lock the tty */
-       mutex_lock(&tty->termios_mutex);
-       if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
-               goto done;
-       /* Get the PID values and reference them so we can
-          avoid holding the tty ctrl lock while sending signals */
-       spin_lock_irqsave(&tty->ctrl_lock, flags);
-       pgrp = get_pid(tty->pgrp);
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-
-       if (pgrp)
-               kill_pgrp(pgrp, SIGWINCH, 1);
-       put_pid(pgrp);
-
-       tty->winsize = *ws;
-done:
-       mutex_unlock(&tty->termios_mutex);
-       return 0;
-}
-
-/**
- *     tiocswinsz              -       implement window size set ioctl
- *     @tty; tty side of tty
- *     @arg: user buffer for result
- *
- *     Copies the user idea of the window size to the kernel. Traditionally
- *     this is just advisory information but for the Linux console it
- *     actually has driver level meaning and triggers a VC resize.
- *
- *     Locking:
- *             Driver dependant. The default do_resize method takes the
- *     tty termios mutex and ctrl_lock. The console takes its own lock
- *     then calls into the default method.
- */
-
-static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg)
-{
-       struct winsize tmp_ws;
-       if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
-               return -EFAULT;
-
-       if (tty->ops->resize)
-               return tty->ops->resize(tty, &tmp_ws);
-       else
-               return tty_do_resize(tty, &tmp_ws);
-}
-
-/**
- *     tioccons        -       allow admin to move logical console
- *     @file: the file to become console
- *
- *     Allow the adminstrator to move the redirected console device
- *
- *     Locking: uses redirect_lock to guard the redirect information
- */
-
-static int tioccons(struct file *file)
-{
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       if (file->f_op->write == redirected_tty_write) {
-               struct file *f;
-               spin_lock(&redirect_lock);
-               f = redirect;
-               redirect = NULL;
-               spin_unlock(&redirect_lock);
-               if (f)
-                       fput(f);
-               return 0;
-       }
-       spin_lock(&redirect_lock);
-       if (redirect) {
-               spin_unlock(&redirect_lock);
-               return -EBUSY;
-       }
-       get_file(file);
-       redirect = file;
-       spin_unlock(&redirect_lock);
-       return 0;
-}
-
-/**
- *     fionbio         -       non blocking ioctl
- *     @file: file to set blocking value
- *     @p: user parameter
- *
- *     Historical tty interfaces had a blocking control ioctl before
- *     the generic functionality existed. This piece of history is preserved
- *     in the expected tty API of posix OS's.
- *
- *     Locking: none, the open file handle ensures it won't go away.
- */
-
-static int fionbio(struct file *file, int __user *p)
-{
-       int nonblock;
-
-       if (get_user(nonblock, p))
-               return -EFAULT;
-
-       spin_lock(&file->f_lock);
-       if (nonblock)
-               file->f_flags |= O_NONBLOCK;
-       else
-               file->f_flags &= ~O_NONBLOCK;
-       spin_unlock(&file->f_lock);
-       return 0;
-}
-
-/**
- *     tiocsctty       -       set controlling tty
- *     @tty: tty structure
- *     @arg: user argument
- *
- *     This ioctl is used to manage job control. It permits a session
- *     leader to set this tty as the controlling tty for the session.
- *
- *     Locking:
- *             Takes tty_mutex() to protect tty instance
- *             Takes tasklist_lock internally to walk sessions
- *             Takes ->siglock() when updating signal->tty
- */
-
-static int tiocsctty(struct tty_struct *tty, int arg)
-{
-       int ret = 0;
-       if (current->signal->leader && (task_session(current) == tty->session))
-               return ret;
-
-       mutex_lock(&tty_mutex);
-       /*
-        * The process must be a session leader and
-        * not have a controlling tty already.
-        */
-       if (!current->signal->leader || current->signal->tty) {
-               ret = -EPERM;
-               goto unlock;
-       }
-
-       if (tty->session) {
-               /*
-                * This tty is already the controlling
-                * tty for another session group!
-                */
-               if (arg == 1 && capable(CAP_SYS_ADMIN)) {
-                       /*
-                        * Steal it away
-                        */
-                       read_lock(&tasklist_lock);
-                       session_clear_tty(tty->session);
-                       read_unlock(&tasklist_lock);
-               } else {
-                       ret = -EPERM;
-                       goto unlock;
-               }
-       }
-       proc_set_tty(current, tty);
-unlock:
-       mutex_unlock(&tty_mutex);
-       return ret;
-}
-
-/**
- *     tty_get_pgrp    -       return a ref counted pgrp pid
- *     @tty: tty to read
- *
- *     Returns a refcounted instance of the pid struct for the process
- *     group controlling the tty.
- */
-
-struct pid *tty_get_pgrp(struct tty_struct *tty)
-{
-       unsigned long flags;
-       struct pid *pgrp;
-
-       spin_lock_irqsave(&tty->ctrl_lock, flags);
-       pgrp = get_pid(tty->pgrp);
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-
-       return pgrp;
-}
-EXPORT_SYMBOL_GPL(tty_get_pgrp);
-
-/**
- *     tiocgpgrp               -       get process group
- *     @tty: tty passed by user
- *     @real_tty: tty side of the tty pased by the user if a pty else the tty
- *     @p: returned pid
- *
- *     Obtain the process group of the tty. If there is no process group
- *     return an error.
- *
- *     Locking: none. Reference to current->signal->tty is safe.
- */
-
-static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
-{
-       struct pid *pid;
-       int ret;
-       /*
-        * (tty == real_tty) is a cheap way of
-        * testing if the tty is NOT a master pty.
-        */
-       if (tty == real_tty && current->signal->tty != real_tty)
-               return -ENOTTY;
-       pid = tty_get_pgrp(real_tty);
-       ret =  put_user(pid_vnr(pid), p);
-       put_pid(pid);
-       return ret;
-}
-
-/**
- *     tiocspgrp               -       attempt to set process group
- *     @tty: tty passed by user
- *     @real_tty: tty side device matching tty passed by user
- *     @p: pid pointer
- *
- *     Set the process group of the tty to the session passed. Only
- *     permitted where the tty session is our session.
- *
- *     Locking: RCU, ctrl lock
- */
-
-static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
-{
-       struct pid *pgrp;
-       pid_t pgrp_nr;
-       int retval = tty_check_change(real_tty);
-       unsigned long flags;
-
-       if (retval == -EIO)
-               return -ENOTTY;
-       if (retval)
-               return retval;
-       if (!current->signal->tty ||
-           (current->signal->tty != real_tty) ||
-           (real_tty->session != task_session(current)))
-               return -ENOTTY;
-       if (get_user(pgrp_nr, p))
-               return -EFAULT;
-       if (pgrp_nr < 0)
-               return -EINVAL;
-       rcu_read_lock();
-       pgrp = find_vpid(pgrp_nr);
-       retval = -ESRCH;
-       if (!pgrp)
-               goto out_unlock;
-       retval = -EPERM;
-       if (session_of_pgrp(pgrp) != task_session(current))
-               goto out_unlock;
-       retval = 0;
-       spin_lock_irqsave(&tty->ctrl_lock, flags);
-       put_pid(real_tty->pgrp);
-       real_tty->pgrp = get_pid(pgrp);
-       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-out_unlock:
-       rcu_read_unlock();
-       return retval;
-}
-
-/**
- *     tiocgsid                -       get session id
- *     @tty: tty passed by user
- *     @real_tty: tty side of the tty pased by the user if a pty else the tty
- *     @p: pointer to returned session id
- *
- *     Obtain the session id of the tty. If there is no session
- *     return an error.
- *
- *     Locking: none. Reference to current->signal->tty is safe.
- */
-
-static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
-{
-       /*
-        * (tty == real_tty) is a cheap way of
-        * testing if the tty is NOT a master pty.
-       */
-       if (tty == real_tty && current->signal->tty != real_tty)
-               return -ENOTTY;
-       if (!real_tty->session)
-               return -ENOTTY;
-       return put_user(pid_vnr(real_tty->session), p);
-}
-
-/**
- *     tiocsetd        -       set line discipline
- *     @tty: tty device
- *     @p: pointer to user data
- *
- *     Set the line discipline according to user request.
- *
- *     Locking: see tty_set_ldisc, this function is just a helper
- */
-
-static int tiocsetd(struct tty_struct *tty, int __user *p)
-{
-       int ldisc;
-       int ret;
-
-       if (get_user(ldisc, p))
-               return -EFAULT;
-
-       ret = tty_set_ldisc(tty, ldisc);
-
-       return ret;
-}
-
-/**
- *     send_break      -       performed time break
- *     @tty: device to break on
- *     @duration: timeout in mS
- *
- *     Perform a timed break on hardware that lacks its own driver level
- *     timed break functionality.
- *
- *     Locking:
- *             atomic_write_lock serializes
- *
- */
-
-static int send_break(struct tty_struct *tty, unsigned int duration)
-{
-       int retval;
-
-       if (tty->ops->break_ctl == NULL)
-               return 0;
-
-       if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
-               retval = tty->ops->break_ctl(tty, duration);
-       else {
-               /* Do the work ourselves */
-               if (tty_write_lock(tty, 0) < 0)
-                       return -EINTR;
-               retval = tty->ops->break_ctl(tty, -1);
-               if (retval)
-                       goto out;
-               if (!signal_pending(current))
-                       msleep_interruptible(duration);
-               retval = tty->ops->break_ctl(tty, 0);
-out:
-               tty_write_unlock(tty);
-               if (signal_pending(current))
-                       retval = -EINTR;
-       }
-       return retval;
-}
-
-/**
- *     tty_tiocmget            -       get modem status
- *     @tty: tty device
- *     @file: user file pointer
- *     @p: pointer to result
- *
- *     Obtain the modem status bits from the tty driver if the feature
- *     is supported. Return -EINVAL if it is not available.
- *
- *     Locking: none (up to the driver)
- */
-
-static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p)
-{
-       int retval = -EINVAL;
-
-       if (tty->ops->tiocmget) {
-               retval = tty->ops->tiocmget(tty, file);
-
-               if (retval >= 0)
-                       retval = put_user(retval, p);
-       }
-       return retval;
-}
-
-/**
- *     tty_tiocmset            -       set modem status
- *     @tty: tty device
- *     @file: user file pointer
- *     @cmd: command - clear bits, set bits or set all
- *     @p: pointer to desired bits
- *
- *     Set the modem status bits from the tty driver if the feature
- *     is supported. Return -EINVAL if it is not available.
- *
- *     Locking: none (up to the driver)
- */
-
-static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd,
-            unsigned __user *p)
-{
-       int retval;
-       unsigned int set, clear, val;
-
-       if (tty->ops->tiocmset == NULL)
-               return -EINVAL;
-
-       retval = get_user(val, p);
-       if (retval)
-               return retval;
-       set = clear = 0;
-       switch (cmd) {
-       case TIOCMBIS:
-               set = val;
-               break;
-       case TIOCMBIC:
-               clear = val;
-               break;
-       case TIOCMSET:
-               set = val;
-               clear = ~val;
-               break;
-       }
-       set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
-       clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
-       return tty->ops->tiocmset(tty, file, set, clear);
-}
-
-static int tty_tiocgicount(struct tty_struct *tty, void __user *arg)
-{
-       int retval = -EINVAL;
-       struct serial_icounter_struct icount;
-       memset(&icount, 0, sizeof(icount));
-       if (tty->ops->get_icount)
-               retval = tty->ops->get_icount(tty, &icount);
-       if (retval != 0)
-               return retval;
-       if (copy_to_user(arg, &icount, sizeof(icount)))
-               return -EFAULT;
-       return 0;
-}
-
-struct tty_struct *tty_pair_get_tty(struct tty_struct *tty)
-{
-       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
-           tty->driver->subtype == PTY_TYPE_MASTER)
-               tty = tty->link;
-       return tty;
-}
-EXPORT_SYMBOL(tty_pair_get_tty);
-
-struct tty_struct *tty_pair_get_pty(struct tty_struct *tty)
-{
-       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
-           tty->driver->subtype == PTY_TYPE_MASTER)
-           return tty;
-       return tty->link;
-}
-EXPORT_SYMBOL(tty_pair_get_pty);
-
-/*
- * Split this up, as gcc can choke on it otherwise..
- */
-long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct tty_struct *tty = file_tty(file);
-       struct tty_struct *real_tty;
-       void __user *p = (void __user *)arg;
-       int retval;
-       struct tty_ldisc *ld;
-       struct inode *inode = file->f_dentry->d_inode;
-
-       if (tty_paranoia_check(tty, inode, "tty_ioctl"))
-               return -EINVAL;
-
-       real_tty = tty_pair_get_tty(tty);
-
-       /*
-        * Factor out some common prep work
-        */
-       switch (cmd) {
-       case TIOCSETD:
-       case TIOCSBRK:
-       case TIOCCBRK:
-       case TCSBRK:
-       case TCSBRKP:
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               if (cmd != TIOCCBRK) {
-                       tty_wait_until_sent(tty, 0);
-                       if (signal_pending(current))
-                               return -EINTR;
-               }
-               break;
-       }
-
-       /*
-        *      Now do the stuff.
-        */
-       switch (cmd) {
-       case TIOCSTI:
-               return tiocsti(tty, p);
-       case TIOCGWINSZ:
-               return tiocgwinsz(real_tty, p);
-       case TIOCSWINSZ:
-               return tiocswinsz(real_tty, p);
-       case TIOCCONS:
-               return real_tty != tty ? -EINVAL : tioccons(file);
-       case FIONBIO:
-               return fionbio(file, p);
-       case TIOCEXCL:
-               set_bit(TTY_EXCLUSIVE, &tty->flags);
-               return 0;
-       case TIOCNXCL:
-               clear_bit(TTY_EXCLUSIVE, &tty->flags);
-               return 0;
-       case TIOCNOTTY:
-               if (current->signal->tty != tty)
-                       return -ENOTTY;
-               no_tty();
-               return 0;
-       case TIOCSCTTY:
-               return tiocsctty(tty, arg);
-       case TIOCGPGRP:
-               return tiocgpgrp(tty, real_tty, p);
-       case TIOCSPGRP:
-               return tiocspgrp(tty, real_tty, p);
-       case TIOCGSID:
-               return tiocgsid(tty, real_tty, p);
-       case TIOCGETD:
-               return put_user(tty->ldisc->ops->num, (int __user *)p);
-       case TIOCSETD:
-               return tiocsetd(tty, p);
-       /*
-        * Break handling
-        */
-       case TIOCSBRK:  /* Turn break on, unconditionally */
-               if (tty->ops->break_ctl)
-                       return tty->ops->break_ctl(tty, -1);
-               return 0;
-       case TIOCCBRK:  /* Turn break off, unconditionally */
-               if (tty->ops->break_ctl)
-                       return tty->ops->break_ctl(tty, 0);
-               return 0;
-       case TCSBRK:   /* SVID version: non-zero arg --> no break */
-               /* non-zero arg means wait for all output data
-                * to be sent (performed above) but don't send break.
-                * This is used by the tcdrain() termios function.
-                */
-               if (!arg)
-                       return send_break(tty, 250);
-               return 0;
-       case TCSBRKP:   /* support for POSIX tcsendbreak() */
-               return send_break(tty, arg ? arg*100 : 250);
-
-       case TIOCMGET:
-               return tty_tiocmget(tty, file, p);
-       case TIOCMSET:
-       case TIOCMBIC:
-       case TIOCMBIS:
-               return tty_tiocmset(tty, file, cmd, p);
-       case TIOCGICOUNT:
-               retval = tty_tiocgicount(tty, p);
-               /* For the moment allow fall through to the old method */
-               if (retval != -EINVAL)
-                       return retval;
-               break;
-       case TCFLSH:
-               switch (arg) {
-               case TCIFLUSH:
-               case TCIOFLUSH:
-               /* flush tty buffer and allow ldisc to process ioctl */
-                       tty_buffer_flush(tty);
-                       break;
-               }
-               break;
-       }
-       if (tty->ops->ioctl) {
-               retval = (tty->ops->ioctl)(tty, file, cmd, arg);
-               if (retval != -ENOIOCTLCMD)
-                       return retval;
-       }
-       ld = tty_ldisc_ref_wait(tty);
-       retval = -EINVAL;
-       if (ld->ops->ioctl) {
-               retval = ld->ops->ioctl(tty, file, cmd, arg);
-               if (retval == -ENOIOCTLCMD)
-                       retval = -EINVAL;
-       }
-       tty_ldisc_deref(ld);
-       return retval;
-}
-
-#ifdef CONFIG_COMPAT
-static long tty_compat_ioctl(struct file *file, unsigned int cmd,
-                               unsigned long arg)
-{
-       struct inode *inode = file->f_dentry->d_inode;
-       struct tty_struct *tty = file_tty(file);
-       struct tty_ldisc *ld;
-       int retval = -ENOIOCTLCMD;
-
-       if (tty_paranoia_check(tty, inode, "tty_ioctl"))
-               return -EINVAL;
-
-       if (tty->ops->compat_ioctl) {
-               retval = (tty->ops->compat_ioctl)(tty, file, cmd, arg);
-               if (retval != -ENOIOCTLCMD)
-                       return retval;
-       }
-
-       ld = tty_ldisc_ref_wait(tty);
-       if (ld->ops->compat_ioctl)
-               retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
-       tty_ldisc_deref(ld);
-
-       return retval;
-}
-#endif
-
-/*
- * This implements the "Secure Attention Key" ---  the idea is to
- * prevent trojan horses by killing all processes associated with this
- * tty when the user hits the "Secure Attention Key".  Required for
- * super-paranoid applications --- see the Orange Book for more details.
- *
- * This code could be nicer; ideally it should send a HUP, wait a few
- * seconds, then send a INT, and then a KILL signal.  But you then
- * have to coordinate with the init process, since all processes associated
- * with the current tty must be dead before the new getty is allowed
- * to spawn.
- *
- * Now, if it would be correct ;-/ The current code has a nasty hole -
- * it doesn't catch files in flight. We may send the descriptor to ourselves
- * via AF_UNIX socket, close it and later fetch from socket. FIXME.
- *
- * Nasty bug: do_SAK is being called in interrupt context.  This can
- * deadlock.  We punt it up to process context.  AKPM - 16Mar2001
- */
-void __do_SAK(struct tty_struct *tty)
-{
-#ifdef TTY_SOFT_SAK
-       tty_hangup(tty);
-#else
-       struct task_struct *g, *p;
-       struct pid *session;
-       int             i;
-       struct file     *filp;
-       struct fdtable *fdt;
-
-       if (!tty)
-               return;
-       session = tty->session;
-
-       tty_ldisc_flush(tty);
-
-       tty_driver_flush_buffer(tty);
-
-       read_lock(&tasklist_lock);
-       /* Kill the entire session */
-       do_each_pid_task(session, PIDTYPE_SID, p) {
-               printk(KERN_NOTICE "SAK: killed process %d"
-                       " (%s): task_session(p)==tty->session\n",
-                       task_pid_nr(p), p->comm);
-               send_sig(SIGKILL, p, 1);
-       } while_each_pid_task(session, PIDTYPE_SID, p);
-       /* Now kill any processes that happen to have the
-        * tty open.
-        */
-       do_each_thread(g, p) {
-               if (p->signal->tty == tty) {
-                       printk(KERN_NOTICE "SAK: killed process %d"
-                           " (%s): task_session(p)==tty->session\n",
-                           task_pid_nr(p), p->comm);
-                       send_sig(SIGKILL, p, 1);
-                       continue;
-               }
-               task_lock(p);
-               if (p->files) {
-                       /*
-                        * We don't take a ref to the file, so we must
-                        * hold ->file_lock instead.
-                        */
-                       spin_lock(&p->files->file_lock);
-                       fdt = files_fdtable(p->files);
-                       for (i = 0; i < fdt->max_fds; i++) {
-                               filp = fcheck_files(p->files, i);
-                               if (!filp)
-                                       continue;
-                               if (filp->f_op->read == tty_read &&
-                                   file_tty(filp) == tty) {
-                                       printk(KERN_NOTICE "SAK: killed process %d"
-                                           " (%s): fd#%d opened to the tty\n",
-                                           task_pid_nr(p), p->comm, i);
-                                       force_sig(SIGKILL, p);
-                                       break;
-                               }
-                       }
-                       spin_unlock(&p->files->file_lock);
-               }
-               task_unlock(p);
-       } while_each_thread(g, p);
-       read_unlock(&tasklist_lock);
-#endif
-}
-
-static void do_SAK_work(struct work_struct *work)
-{
-       struct tty_struct *tty =
-               container_of(work, struct tty_struct, SAK_work);
-       __do_SAK(tty);
-}
-
-/*
- * The tq handling here is a little racy - tty->SAK_work may already be queued.
- * Fortunately we don't need to worry, because if ->SAK_work is already queued,
- * the values which we write to it will be identical to the values which it
- * already has. --akpm
- */
-void do_SAK(struct tty_struct *tty)
-{
-       if (!tty)
-               return;
-       schedule_work(&tty->SAK_work);
-}
-
-EXPORT_SYMBOL(do_SAK);
-
-static int dev_match_devt(struct device *dev, void *data)
-{
-       dev_t *devt = data;
-       return dev->devt == *devt;
-}
-
-/* Must put_device() after it's unused! */
-static struct device *tty_get_device(struct tty_struct *tty)
-{
-       dev_t devt = tty_devnum(tty);
-       return class_find_device(tty_class, NULL, &devt, dev_match_devt);
-}
-
-
-/**
- *     initialize_tty_struct
- *     @tty: tty to initialize
- *
- *     This subroutine initializes a tty structure that has been newly
- *     allocated.
- *
- *     Locking: none - tty in question must not be exposed at this point
- */
-
-void initialize_tty_struct(struct tty_struct *tty,
-               struct tty_driver *driver, int idx)
-{
-       memset(tty, 0, sizeof(struct tty_struct));
-       kref_init(&tty->kref);
-       tty->magic = TTY_MAGIC;
-       tty_ldisc_init(tty);
-       tty->session = NULL;
-       tty->pgrp = NULL;
-       tty->overrun_time = jiffies;
-       tty->buf.head = tty->buf.tail = NULL;
-       tty_buffer_init(tty);
-       mutex_init(&tty->termios_mutex);
-       mutex_init(&tty->ldisc_mutex);
-       init_waitqueue_head(&tty->write_wait);
-       init_waitqueue_head(&tty->read_wait);
-       INIT_WORK(&tty->hangup_work, do_tty_hangup);
-       mutex_init(&tty->atomic_read_lock);
-       mutex_init(&tty->atomic_write_lock);
-       mutex_init(&tty->output_lock);
-       mutex_init(&tty->echo_lock);
-       spin_lock_init(&tty->read_lock);
-       spin_lock_init(&tty->ctrl_lock);
-       INIT_LIST_HEAD(&tty->tty_files);
-       INIT_WORK(&tty->SAK_work, do_SAK_work);
-
-       tty->driver = driver;
-       tty->ops = driver->ops;
-       tty->index = idx;
-       tty_line_name(driver, idx, tty->name);
-       tty->dev = tty_get_device(tty);
-}
-
-/**
- *     tty_put_char    -       write one character to a tty
- *     @tty: tty
- *     @ch: character
- *
- *     Write one byte to the tty using the provided put_char method
- *     if present. Returns the number of characters successfully output.
- *
- *     Note: the specific put_char operation in the driver layer may go
- *     away soon. Don't call it directly, use this method
- */
-
-int tty_put_char(struct tty_struct *tty, unsigned char ch)
-{
-       if (tty->ops->put_char)
-               return tty->ops->put_char(tty, ch);
-       return tty->ops->write(tty, &ch, 1);
-}
-EXPORT_SYMBOL_GPL(tty_put_char);
-
-struct class *tty_class;
-
-/**
- *     tty_register_device - register a tty device
- *     @driver: the tty driver that describes the tty device
- *     @index: the index in the tty driver for this tty device
- *     @device: a struct device that is associated with this tty device.
- *             This field is optional, if there is no known struct device
- *             for this tty device it can be set to NULL safely.
- *
- *     Returns a pointer to the struct device for this tty device
- *     (or ERR_PTR(-EFOO) on error).
- *
- *     This call is required to be made to register an individual tty device
- *     if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set.  If
- *     that bit is not set, this function should not be called by a tty
- *     driver.
- *
- *     Locking: ??
- */
-
-struct device *tty_register_device(struct tty_driver *driver, unsigned index,
-                                  struct device *device)
-{
-       char name[64];
-       dev_t dev = MKDEV(driver->major, driver->minor_start) + index;
-
-       if (index >= driver->num) {
-               printk(KERN_ERR "Attempt to register invalid tty line number "
-                      " (%d).\n", index);
-               return ERR_PTR(-EINVAL);
-       }
-
-       if (driver->type == TTY_DRIVER_TYPE_PTY)
-               pty_line_name(driver, index, name);
-       else
-               tty_line_name(driver, index, name);
-
-       return device_create(tty_class, device, dev, NULL, name);
-}
-EXPORT_SYMBOL(tty_register_device);
-
-/**
- *     tty_unregister_device - unregister a tty device
- *     @driver: the tty driver that describes the tty device
- *     @index: the index in the tty driver for this tty device
- *
- *     If a tty device is registered with a call to tty_register_device() then
- *     this function must be called when the tty device is gone.
- *
- *     Locking: ??
- */
-
-void tty_unregister_device(struct tty_driver *driver, unsigned index)
-{
-       device_destroy(tty_class,
-               MKDEV(driver->major, driver->minor_start) + index);
-}
-EXPORT_SYMBOL(tty_unregister_device);
-
-struct tty_driver *alloc_tty_driver(int lines)
-{
-       struct tty_driver *driver;
-
-       driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
-       if (driver) {
-               kref_init(&driver->kref);
-               driver->magic = TTY_DRIVER_MAGIC;
-               driver->num = lines;
-               /* later we'll move allocation of tables here */
-       }
-       return driver;
-}
-EXPORT_SYMBOL(alloc_tty_driver);
-
-static void destruct_tty_driver(struct kref *kref)
-{
-       struct tty_driver *driver = container_of(kref, struct tty_driver, kref);
-       int i;
-       struct ktermios *tp;
-       void *p;
-
-       if (driver->flags & TTY_DRIVER_INSTALLED) {
-               /*
-                * Free the termios and termios_locked structures because
-                * we don't want to get memory leaks when modular tty
-                * drivers are removed from the kernel.
-                */
-               for (i = 0; i < driver->num; i++) {
-                       tp = driver->termios[i];
-                       if (tp) {
-                               driver->termios[i] = NULL;
-                               kfree(tp);
-                       }
-                       if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
-                               tty_unregister_device(driver, i);
-               }
-               p = driver->ttys;
-               proc_tty_unregister_driver(driver);
-               driver->ttys = NULL;
-               driver->termios = NULL;
-               kfree(p);
-               cdev_del(&driver->cdev);
-       }
-       kfree(driver);
-}
-
-void tty_driver_kref_put(struct tty_driver *driver)
-{
-       kref_put(&driver->kref, destruct_tty_driver);
-}
-EXPORT_SYMBOL(tty_driver_kref_put);
-
-void tty_set_operations(struct tty_driver *driver,
-                       const struct tty_operations *op)
-{
-       driver->ops = op;
-};
-EXPORT_SYMBOL(tty_set_operations);
-
-void put_tty_driver(struct tty_driver *d)
-{
-       tty_driver_kref_put(d);
-}
-EXPORT_SYMBOL(put_tty_driver);
-
-/*
- * Called by a tty driver to register itself.
- */
-int tty_register_driver(struct tty_driver *driver)
-{
-       int error;
-       int i;
-       dev_t dev;
-       void **p = NULL;
-       struct device *d;
-
-       if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
-               p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
-               if (!p)
-                       return -ENOMEM;
-       }
-
-       if (!driver->major) {
-               error = alloc_chrdev_region(&dev, driver->minor_start,
-                                               driver->num, driver->name);
-               if (!error) {
-                       driver->major = MAJOR(dev);
-                       driver->minor_start = MINOR(dev);
-               }
-       } else {
-               dev = MKDEV(driver->major, driver->minor_start);
-               error = register_chrdev_region(dev, driver->num, driver->name);
-       }
-       if (error < 0) {
-               kfree(p);
-               return error;
-       }
-
-       if (p) {
-               driver->ttys = (struct tty_struct **)p;
-               driver->termios = (struct ktermios **)(p + driver->num);
-       } else {
-               driver->ttys = NULL;
-               driver->termios = NULL;
-       }
-
-       cdev_init(&driver->cdev, &tty_fops);
-       driver->cdev.owner = driver->owner;
-       error = cdev_add(&driver->cdev, dev, driver->num);
-       if (error) {
-               unregister_chrdev_region(dev, driver->num);
-               driver->ttys = NULL;
-               driver->termios = NULL;
-               kfree(p);
-               return error;
-       }
-
-       mutex_lock(&tty_mutex);
-       list_add(&driver->tty_drivers, &tty_drivers);
-       mutex_unlock(&tty_mutex);
-
-       if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
-               for (i = 0; i < driver->num; i++) {
-                       d = tty_register_device(driver, i, NULL);
-                       if (IS_ERR(d)) {
-                               error = PTR_ERR(d);
-                               goto err;
-                       }
-               }
-       }
-       proc_tty_register_driver(driver);
-       driver->flags |= TTY_DRIVER_INSTALLED;
-       return 0;
-
-err:
-       for (i--; i >= 0; i--)
-               tty_unregister_device(driver, i);
-
-       mutex_lock(&tty_mutex);
-       list_del(&driver->tty_drivers);
-       mutex_unlock(&tty_mutex);
-
-       unregister_chrdev_region(dev, driver->num);
-       driver->ttys = NULL;
-       driver->termios = NULL;
-       kfree(p);
-       return error;
-}
-
-EXPORT_SYMBOL(tty_register_driver);
-
-/*
- * Called by a tty driver to unregister itself.
- */
-int tty_unregister_driver(struct tty_driver *driver)
-{
-#if 0
-       /* FIXME */
-       if (driver->refcount)
-               return -EBUSY;
-#endif
-       unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
-                               driver->num);
-       mutex_lock(&tty_mutex);
-       list_del(&driver->tty_drivers);
-       mutex_unlock(&tty_mutex);
-       return 0;
-}
-
-EXPORT_SYMBOL(tty_unregister_driver);
-
-dev_t tty_devnum(struct tty_struct *tty)
-{
-       return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
-}
-EXPORT_SYMBOL(tty_devnum);
-
-void proc_clear_tty(struct task_struct *p)
-{
-       unsigned long flags;
-       struct tty_struct *tty;
-       spin_lock_irqsave(&p->sighand->siglock, flags);
-       tty = p->signal->tty;
-       p->signal->tty = NULL;
-       spin_unlock_irqrestore(&p->sighand->siglock, flags);
-       tty_kref_put(tty);
-}
-
-/* Called under the sighand lock */
-
-static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
-{
-       if (tty) {
-               unsigned long flags;
-               /* We should not have a session or pgrp to put here but.... */
-               spin_lock_irqsave(&tty->ctrl_lock, flags);
-               put_pid(tty->session);
-               put_pid(tty->pgrp);
-               tty->pgrp = get_pid(task_pgrp(tsk));
-               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-               tty->session = get_pid(task_session(tsk));
-               if (tsk->signal->tty) {
-                       printk(KERN_DEBUG "tty not NULL!!\n");
-                       tty_kref_put(tsk->signal->tty);
-               }
-       }
-       put_pid(tsk->signal->tty_old_pgrp);
-       tsk->signal->tty = tty_kref_get(tty);
-       tsk->signal->tty_old_pgrp = NULL;
-}
-
-static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
-{
-       spin_lock_irq(&tsk->sighand->siglock);
-       __proc_set_tty(tsk, tty);
-       spin_unlock_irq(&tsk->sighand->siglock);
-}
-
-struct tty_struct *get_current_tty(void)
-{
-       struct tty_struct *tty;
-       unsigned long flags;
-
-       spin_lock_irqsave(&current->sighand->siglock, flags);
-       tty = tty_kref_get(current->signal->tty);
-       spin_unlock_irqrestore(&current->sighand->siglock, flags);
-       return tty;
-}
-EXPORT_SYMBOL_GPL(get_current_tty);
-
-void tty_default_fops(struct file_operations *fops)
-{
-       *fops = tty_fops;
-}
-
-/*
- * Initialize the console device. This is called *early*, so
- * we can't necessarily depend on lots of kernel help here.
- * Just do some early initializations, and do the complex setup
- * later.
- */
-void __init console_init(void)
-{
-       initcall_t *call;
-
-       /* Setup the default TTY line discipline. */
-       tty_ldisc_begin();
-
-       /*
-        * set up the console device so that later boot sequences can
-        * inform about problems etc..
-        */
-       call = __con_initcall_start;
-       while (call < __con_initcall_end) {
-               (*call)();
-               call++;
-       }
-}
-
-static char *tty_devnode(struct device *dev, mode_t *mode)
-{
-       if (!mode)
-               return NULL;
-       if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
-           dev->devt == MKDEV(TTYAUX_MAJOR, 2))
-               *mode = 0666;
-       return NULL;
-}
-
-static int __init tty_class_init(void)
-{
-       tty_class = class_create(THIS_MODULE, "tty");
-       if (IS_ERR(tty_class))
-               return PTR_ERR(tty_class);
-       tty_class->devnode = tty_devnode;
-       return 0;
-}
-
-postcore_initcall(tty_class_init);
-
-/* 3/2004 jmc: why do these devices exist? */
-
-static struct cdev tty_cdev, console_cdev;
-
-/*
- * Ok, now we can initialize the rest of the tty devices and can count
- * on memory allocations, interrupts etc..
- */
-int __init tty_init(void)
-{
-       cdev_init(&tty_cdev, &tty_fops);
-       if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
-           register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
-               panic("Couldn't register /dev/tty driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
-                             "tty");
-
-       cdev_init(&console_cdev, &console_fops);
-       if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
-           register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
-               panic("Couldn't register /dev/console driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
-                             "console");
-
-#ifdef CONFIG_VT
-       vty_init(&console_fops);
-#endif
-       return 0;
-}
-
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
deleted file mode 100644 (file)
index 0c18899..0000000
+++ /dev/null
@@ -1,1179 +0,0 @@
-/*
- *  linux/drivers/char/tty_ioctl.c
- *
- *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
- *
- * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
- * which can be dynamically activated and de-activated by the line
- * discipline handling modules (like SLIP).
- */
-
-#include <linux/types.h>
-#include <linux/termios.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/tty.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/bitops.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#undef TTY_DEBUG_WAIT_UNTIL_SENT
-
-#undef DEBUG
-
-/*
- * Internal flag options for termios setting behavior
- */
-#define TERMIOS_FLUSH  1
-#define TERMIOS_WAIT   2
-#define TERMIOS_TERMIO 4
-#define TERMIOS_OLD    8
-
-
-/**
- *     tty_chars_in_buffer     -       characters pending
- *     @tty: terminal
- *
- *     Return the number of bytes of data in the device private
- *     output queue. If no private method is supplied there is assumed
- *     to be no queue on the device.
- */
-
-int tty_chars_in_buffer(struct tty_struct *tty)
-{
-       if (tty->ops->chars_in_buffer)
-               return tty->ops->chars_in_buffer(tty);
-       else
-               return 0;
-}
-EXPORT_SYMBOL(tty_chars_in_buffer);
-
-/**
- *     tty_write_room          -       write queue space
- *     @tty: terminal
- *
- *     Return the number of bytes that can be queued to this device
- *     at the present time. The result should be treated as a guarantee
- *     and the driver cannot offer a value it later shrinks by more than
- *     the number of bytes written. If no method is provided 2K is always
- *     returned and data may be lost as there will be no flow control.
- */
-int tty_write_room(struct tty_struct *tty)
-{
-       if (tty->ops->write_room)
-               return tty->ops->write_room(tty);
-       return 2048;
-}
-EXPORT_SYMBOL(tty_write_room);
-
-/**
- *     tty_driver_flush_buffer -       discard internal buffer
- *     @tty: terminal
- *
- *     Discard the internal output buffer for this device. If no method
- *     is provided then either the buffer cannot be hardware flushed or
- *     there is no buffer driver side.
- */
-void tty_driver_flush_buffer(struct tty_struct *tty)
-{
-       if (tty->ops->flush_buffer)
-               tty->ops->flush_buffer(tty);
-}
-EXPORT_SYMBOL(tty_driver_flush_buffer);
-
-/**
- *     tty_throttle            -       flow control
- *     @tty: terminal
- *
- *     Indicate that a tty should stop transmitting data down the stack.
- *     Takes the termios mutex to protect against parallel throttle/unthrottle
- *     and also to ensure the driver can consistently reference its own
- *     termios data at this point when implementing software flow control.
- */
-
-void tty_throttle(struct tty_struct *tty)
-{
-       mutex_lock(&tty->termios_mutex);
-       /* check TTY_THROTTLED first so it indicates our state */
-       if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
-           tty->ops->throttle)
-               tty->ops->throttle(tty);
-       mutex_unlock(&tty->termios_mutex);
-}
-EXPORT_SYMBOL(tty_throttle);
-
-/**
- *     tty_unthrottle          -       flow control
- *     @tty: terminal
- *
- *     Indicate that a tty may continue transmitting data down the stack.
- *     Takes the termios mutex to protect against parallel throttle/unthrottle
- *     and also to ensure the driver can consistently reference its own
- *     termios data at this point when implementing software flow control.
- *
- *     Drivers should however remember that the stack can issue a throttle,
- *     then change flow control method, then unthrottle.
- */
-
-void tty_unthrottle(struct tty_struct *tty)
-{
-       mutex_lock(&tty->termios_mutex);
-       if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
-           tty->ops->unthrottle)
-               tty->ops->unthrottle(tty);
-       mutex_unlock(&tty->termios_mutex);
-}
-EXPORT_SYMBOL(tty_unthrottle);
-
-/**
- *     tty_wait_until_sent     -       wait for I/O to finish
- *     @tty: tty we are waiting for
- *     @timeout: how long we will wait
- *
- *     Wait for characters pending in a tty driver to hit the wire, or
- *     for a timeout to occur (eg due to flow control)
- *
- *     Locking: none
- */
-
-void tty_wait_until_sent(struct tty_struct *tty, long timeout)
-{
-#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
-       char buf[64];
-
-       printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
-#endif
-       if (!timeout)
-               timeout = MAX_SCHEDULE_TIMEOUT;
-       if (wait_event_interruptible_timeout(tty->write_wait,
-                       !tty_chars_in_buffer(tty), timeout) >= 0) {
-               if (tty->ops->wait_until_sent)
-                       tty->ops->wait_until_sent(tty, timeout);
-       }
-}
-EXPORT_SYMBOL(tty_wait_until_sent);
-
-
-/*
- *             Termios Helper Methods
- */
-
-static void unset_locked_termios(struct ktermios *termios,
-                                struct ktermios *old,
-                                struct ktermios *locked)
-{
-       int     i;
-
-#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
-
-       if (!locked) {
-               printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
-               return;
-       }
-
-       NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
-       NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
-       NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
-       NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
-       termios->c_line = locked->c_line ? old->c_line : termios->c_line;
-       for (i = 0; i < NCCS; i++)
-               termios->c_cc[i] = locked->c_cc[i] ?
-                       old->c_cc[i] : termios->c_cc[i];
-       /* FIXME: What should we do for i/ospeed */
-}
-
-/*
- * Routine which returns the baud rate of the tty
- *
- * Note that the baud_table needs to be kept in sync with the
- * include/asm/termbits.h file.
- */
-static const speed_t baud_table[] = {
-       0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-       9600, 19200, 38400, 57600, 115200, 230400, 460800,
-#ifdef __sparc__
-       76800, 153600, 307200, 614400, 921600
-#else
-       500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
-       2500000, 3000000, 3500000, 4000000
-#endif
-};
-
-#ifndef __sparc__
-static const tcflag_t baud_bits[] = {
-       B0, B50, B75, B110, B134, B150, B200, B300, B600,
-       B1200, B1800, B2400, B4800, B9600, B19200, B38400,
-       B57600, B115200, B230400, B460800, B500000, B576000,
-       B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
-       B3000000, B3500000, B4000000
-};
-#else
-static const tcflag_t baud_bits[] = {
-       B0, B50, B75, B110, B134, B150, B200, B300, B600,
-       B1200, B1800, B2400, B4800, B9600, B19200, B38400,
-       B57600, B115200, B230400, B460800, B76800, B153600,
-       B307200, B614400, B921600
-};
-#endif
-
-static int n_baud_table = ARRAY_SIZE(baud_table);
-
-/**
- *     tty_termios_baud_rate
- *     @termios: termios structure
- *
- *     Convert termios baud rate data into a speed. This should be called
- *     with the termios lock held if this termios is a terminal termios
- *     structure. May change the termios data. Device drivers can call this
- *     function but should use ->c_[io]speed directly as they are updated.
- *
- *     Locking: none
- */
-
-speed_t tty_termios_baud_rate(struct ktermios *termios)
-{
-       unsigned int cbaud;
-
-       cbaud = termios->c_cflag & CBAUD;
-
-#ifdef BOTHER
-       /* Magic token for arbitary speed via c_ispeed/c_ospeed */
-       if (cbaud == BOTHER)
-               return termios->c_ospeed;
-#endif
-       if (cbaud & CBAUDEX) {
-               cbaud &= ~CBAUDEX;
-
-               if (cbaud < 1 || cbaud + 15 > n_baud_table)
-                       termios->c_cflag &= ~CBAUDEX;
-               else
-                       cbaud += 15;
-       }
-       return baud_table[cbaud];
-}
-EXPORT_SYMBOL(tty_termios_baud_rate);
-
-/**
- *     tty_termios_input_baud_rate
- *     @termios: termios structure
- *
- *     Convert termios baud rate data into a speed. This should be called
- *     with the termios lock held if this termios is a terminal termios
- *     structure. May change the termios data. Device drivers can call this
- *     function but should use ->c_[io]speed directly as they are updated.
- *
- *     Locking: none
- */
-
-speed_t tty_termios_input_baud_rate(struct ktermios *termios)
-{
-#ifdef IBSHIFT
-       unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
-
-       if (cbaud == B0)
-               return tty_termios_baud_rate(termios);
-
-       /* Magic token for arbitary speed via c_ispeed*/
-       if (cbaud == BOTHER)
-               return termios->c_ispeed;
-
-       if (cbaud & CBAUDEX) {
-               cbaud &= ~CBAUDEX;
-
-               if (cbaud < 1 || cbaud + 15 > n_baud_table)
-                       termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
-               else
-                       cbaud += 15;
-       }
-       return baud_table[cbaud];
-#else
-       return tty_termios_baud_rate(termios);
-#endif
-}
-EXPORT_SYMBOL(tty_termios_input_baud_rate);
-
-/**
- *     tty_termios_encode_baud_rate
- *     @termios: ktermios structure holding user requested state
- *     @ispeed: input speed
- *     @ospeed: output speed
- *
- *     Encode the speeds set into the passed termios structure. This is
- *     used as a library helper for drivers os that they can report back
- *     the actual speed selected when it differs from the speed requested
- *
- *     For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
- *     we need to carefully set the bits when the user does not get the
- *     desired speed. We allow small margins and preserve as much of possible
- *     of the input intent to keep compatibility.
- *
- *     Locking: Caller should hold termios lock. This is already held
- *     when calling this function from the driver termios handler.
- *
- *     The ifdefs deal with platforms whose owners have yet to update them
- *     and will all go away once this is done.
- */
-
-void tty_termios_encode_baud_rate(struct ktermios *termios,
-                                 speed_t ibaud, speed_t obaud)
-{
-       int i = 0;
-       int ifound = -1, ofound = -1;
-       int iclose = ibaud/50, oclose = obaud/50;
-       int ibinput = 0;
-
-       if (obaud == 0)                 /* CD dropped             */
-               ibaud = 0;              /* Clear ibaud to be sure */
-
-       termios->c_ispeed = ibaud;
-       termios->c_ospeed = obaud;
-
-#ifdef BOTHER
-       /* If the user asked for a precise weird speed give a precise weird
-          answer. If they asked for a Bfoo speed they many have problems
-          digesting non-exact replies so fuzz a bit */
-
-       if ((termios->c_cflag & CBAUD) == BOTHER)
-               oclose = 0;
-       if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
-               iclose = 0;
-       if ((termios->c_cflag >> IBSHIFT) & CBAUD)
-               ibinput = 1;    /* An input speed was specified */
-#endif
-       termios->c_cflag &= ~CBAUD;
-
-       /*
-        *      Our goal is to find a close match to the standard baud rate
-        *      returned. Walk the baud rate table and if we get a very close
-        *      match then report back the speed as a POSIX Bxxxx value by
-        *      preference
-        */
-
-       do {
-               if (obaud - oclose <= baud_table[i] &&
-                   obaud + oclose >= baud_table[i]) {
-                       termios->c_cflag |= baud_bits[i];
-                       ofound = i;
-               }
-               if (ibaud - iclose <= baud_table[i] &&
-                   ibaud + iclose >= baud_table[i]) {
-                       /* For the case input == output don't set IBAUD bits
-                          if the user didn't do so */
-                       if (ofound == i && !ibinput)
-                               ifound  = i;
-#ifdef IBSHIFT
-                       else {
-                               ifound = i;
-                               termios->c_cflag |= (baud_bits[i] << IBSHIFT);
-                       }
-#endif
-               }
-       } while (++i < n_baud_table);
-
-       /*
-        *      If we found no match then use BOTHER if provided or warn
-        *      the user their platform maintainer needs to wake up if not.
-        */
-#ifdef BOTHER
-       if (ofound == -1)
-               termios->c_cflag |= BOTHER;
-       /* Set exact input bits only if the input and output differ or the
-          user already did */
-       if (ifound == -1 && (ibaud != obaud || ibinput))
-               termios->c_cflag |= (BOTHER << IBSHIFT);
-#else
-       if (ifound == -1 || ofound == -1) {
-               printk_once(KERN_WARNING "tty: Unable to return correct "
-                         "speed data as your architecture needs updating.\n");
-       }
-#endif
-}
-EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
-
-/**
- *     tty_encode_baud_rate            -       set baud rate of the tty
- *     @ibaud: input baud rate
- *     @obad: output baud rate
- *
- *     Update the current termios data for the tty with the new speed
- *     settings. The caller must hold the termios_mutex for the tty in
- *     question.
- */
-
-void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
-{
-       tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
-}
-EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
-
-/**
- *     tty_get_baud_rate       -       get tty bit rates
- *     @tty: tty to query
- *
- *     Returns the baud rate as an integer for this terminal. The
- *     termios lock must be held by the caller and the terminal bit
- *     flags may be updated.
- *
- *     Locking: none
- */
-
-speed_t tty_get_baud_rate(struct tty_struct *tty)
-{
-       speed_t baud = tty_termios_baud_rate(tty->termios);
-
-       if (baud == 38400 && tty->alt_speed) {
-               if (!tty->warned) {
-                       printk(KERN_WARNING "Use of setserial/setrocket to "
-                                           "set SPD_* flags is deprecated\n");
-                       tty->warned = 1;
-               }
-               baud = tty->alt_speed;
-       }
-
-       return baud;
-}
-EXPORT_SYMBOL(tty_get_baud_rate);
-
-/**
- *     tty_termios_copy_hw     -       copy hardware settings
- *     @new: New termios
- *     @old: Old termios
- *
- *     Propogate the hardware specific terminal setting bits from
- *     the old termios structure to the new one. This is used in cases
- *     where the hardware does not support reconfiguration or as a helper
- *     in some cases where only minimal reconfiguration is supported
- */
-
-void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
-{
-       /* The bits a dumb device handles in software. Smart devices need
-          to always provide a set_termios method */
-       new->c_cflag &= HUPCL | CREAD | CLOCAL;
-       new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
-       new->c_ispeed = old->c_ispeed;
-       new->c_ospeed = old->c_ospeed;
-}
-EXPORT_SYMBOL(tty_termios_copy_hw);
-
-/**
- *     tty_termios_hw_change   -       check for setting change
- *     @a: termios
- *     @b: termios to compare
- *
- *     Check if any of the bits that affect a dumb device have changed
- *     between the two termios structures, or a speed change is needed.
- */
-
-int tty_termios_hw_change(struct ktermios *a, struct ktermios *b)
-{
-       if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
-               return 1;
-       if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
-               return 1;
-       return 0;
-}
-EXPORT_SYMBOL(tty_termios_hw_change);
-
-/**
- *     change_termios          -       update termios values
- *     @tty: tty to update
- *     @new_termios: desired new value
- *
- *     Perform updates to the termios values set on this terminal. There
- *     is a bit of layering violation here with n_tty in terms of the
- *     internal knowledge of this function.
- *
- *     Locking: termios_mutex
- */
-
-static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
-{
-       struct ktermios old_termios;
-       struct tty_ldisc *ld;
-       unsigned long flags;
-
-       /*
-        *      Perform the actual termios internal changes under lock.
-        */
-
-
-       /* FIXME: we need to decide on some locking/ordering semantics
-          for the set_termios notification eventually */
-       mutex_lock(&tty->termios_mutex);
-       old_termios = *tty->termios;
-       *tty->termios = *new_termios;
-       unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
-
-       /* See if packet mode change of state. */
-       if (tty->link && tty->link->packet) {
-               int extproc = (old_termios.c_lflag & EXTPROC) |
-                               (tty->termios->c_lflag & EXTPROC);
-               int old_flow = ((old_termios.c_iflag & IXON) &&
-                               (old_termios.c_cc[VSTOP] == '\023') &&
-                               (old_termios.c_cc[VSTART] == '\021'));
-               int new_flow = (I_IXON(tty) &&
-                               STOP_CHAR(tty) == '\023' &&
-                               START_CHAR(tty) == '\021');
-               if ((old_flow != new_flow) || extproc) {
-                       spin_lock_irqsave(&tty->ctrl_lock, flags);
-                       if (old_flow != new_flow) {
-                               tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
-                               if (new_flow)
-                                       tty->ctrl_status |= TIOCPKT_DOSTOP;
-                               else
-                                       tty->ctrl_status |= TIOCPKT_NOSTOP;
-                       }
-                       if (extproc)
-                               tty->ctrl_status |= TIOCPKT_IOCTL;
-                       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-                       wake_up_interruptible(&tty->link->read_wait);
-               }
-       }
-
-       if (tty->ops->set_termios)
-               (*tty->ops->set_termios)(tty, &old_termios);
-       else
-               tty_termios_copy_hw(tty->termios, &old_termios);
-
-       ld = tty_ldisc_ref(tty);
-       if (ld != NULL) {
-               if (ld->ops->set_termios)
-                       (ld->ops->set_termios)(tty, &old_termios);
-               tty_ldisc_deref(ld);
-       }
-       mutex_unlock(&tty->termios_mutex);
-}
-
-/**
- *     set_termios             -       set termios values for a tty
- *     @tty: terminal device
- *     @arg: user data
- *     @opt: option information
- *
- *     Helper function to prepare termios data and run necessary other
- *     functions before using change_termios to do the actual changes.
- *
- *     Locking:
- *             Called functions take ldisc and termios_mutex locks
- */
-
-static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
-{
-       struct ktermios tmp_termios;
-       struct tty_ldisc *ld;
-       int retval = tty_check_change(tty);
-
-       if (retval)
-               return retval;
-
-       mutex_lock(&tty->termios_mutex);
-       memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
-       mutex_unlock(&tty->termios_mutex);
-
-       if (opt & TERMIOS_TERMIO) {
-               if (user_termio_to_kernel_termios(&tmp_termios,
-                                               (struct termio __user *)arg))
-                       return -EFAULT;
-#ifdef TCGETS2
-       } else if (opt & TERMIOS_OLD) {
-               if (user_termios_to_kernel_termios_1(&tmp_termios,
-                                               (struct termios __user *)arg))
-                       return -EFAULT;
-       } else {
-               if (user_termios_to_kernel_termios(&tmp_termios,
-                                               (struct termios2 __user *)arg))
-                       return -EFAULT;
-       }
-#else
-       } else if (user_termios_to_kernel_termios(&tmp_termios,
-                                       (struct termios __user *)arg))
-               return -EFAULT;
-#endif
-
-       /* If old style Bfoo values are used then load c_ispeed/c_ospeed
-        * with the real speed so its unconditionally usable */
-       tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
-       tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
-
-       ld = tty_ldisc_ref(tty);
-
-       if (ld != NULL) {
-               if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
-                       ld->ops->flush_buffer(tty);
-               tty_ldisc_deref(ld);
-       }
-
-       if (opt & TERMIOS_WAIT) {
-               tty_wait_until_sent(tty, 0);
-               if (signal_pending(current))
-                       return -EINTR;
-       }
-
-       change_termios(tty, &tmp_termios);
-
-       /* FIXME: Arguably if tmp_termios == tty->termios AND the
-          actual requested termios was not tmp_termios then we may
-          want to return an error as no user requested change has
-          succeeded */
-       return 0;
-}
-
-static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
-{
-       mutex_lock(&tty->termios_mutex);
-       memcpy(kterm, tty->termios, sizeof(struct ktermios));
-       mutex_unlock(&tty->termios_mutex);
-}
-
-static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
-{
-       mutex_lock(&tty->termios_mutex);
-       memcpy(kterm, tty->termios_locked, sizeof(struct ktermios));
-       mutex_unlock(&tty->termios_mutex);
-}
-
-static int get_termio(struct tty_struct *tty, struct termio __user *termio)
-{
-       struct ktermios kterm;
-       copy_termios(tty, &kterm);
-       if (kernel_termios_to_user_termio(termio, &kterm))
-               return -EFAULT;
-       return 0;
-}
-
-
-#ifdef TCGETX
-
-/**
- *     set_termiox     -       set termiox fields if possible
- *     @tty: terminal
- *     @arg: termiox structure from user
- *     @opt: option flags for ioctl type
- *
- *     Implement the device calling points for the SYS5 termiox ioctl
- *     interface in Linux
- */
-
-static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
-{
-       struct termiox tnew;
-       struct tty_ldisc *ld;
-
-       if (tty->termiox == NULL)
-               return -EINVAL;
-       if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
-               return -EFAULT;
-
-       ld = tty_ldisc_ref(tty);
-       if (ld != NULL) {
-               if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
-                       ld->ops->flush_buffer(tty);
-               tty_ldisc_deref(ld);
-       }
-       if (opt & TERMIOS_WAIT) {
-               tty_wait_until_sent(tty, 0);
-               if (signal_pending(current))
-                       return -EINTR;
-       }
-
-       mutex_lock(&tty->termios_mutex);
-       if (tty->ops->set_termiox)
-               tty->ops->set_termiox(tty, &tnew);
-       mutex_unlock(&tty->termios_mutex);
-       return 0;
-}
-
-#endif
-
-
-#ifdef TIOCGETP
-/*
- * These are deprecated, but there is limited support..
- *
- * The "sg_flags" translation is a joke..
- */
-static int get_sgflags(struct tty_struct *tty)
-{
-       int flags = 0;
-
-       if (!(tty->termios->c_lflag & ICANON)) {
-               if (tty->termios->c_lflag & ISIG)
-                       flags |= 0x02;          /* cbreak */
-               else
-                       flags |= 0x20;          /* raw */
-       }
-       if (tty->termios->c_lflag & ECHO)
-               flags |= 0x08;                  /* echo */
-       if (tty->termios->c_oflag & OPOST)
-               if (tty->termios->c_oflag & ONLCR)
-                       flags |= 0x10;          /* crmod */
-       return flags;
-}
-
-static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
-{
-       struct sgttyb tmp;
-
-       mutex_lock(&tty->termios_mutex);
-       tmp.sg_ispeed = tty->termios->c_ispeed;
-       tmp.sg_ospeed = tty->termios->c_ospeed;
-       tmp.sg_erase = tty->termios->c_cc[VERASE];
-       tmp.sg_kill = tty->termios->c_cc[VKILL];
-       tmp.sg_flags = get_sgflags(tty);
-       mutex_unlock(&tty->termios_mutex);
-
-       return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
-}
-
-static void set_sgflags(struct ktermios *termios, int flags)
-{
-       termios->c_iflag = ICRNL | IXON;
-       termios->c_oflag = 0;
-       termios->c_lflag = ISIG | ICANON;
-       if (flags & 0x02) {     /* cbreak */
-               termios->c_iflag = 0;
-               termios->c_lflag &= ~ICANON;
-       }
-       if (flags & 0x08) {             /* echo */
-               termios->c_lflag |= ECHO | ECHOE | ECHOK |
-                                   ECHOCTL | ECHOKE | IEXTEN;
-       }
-       if (flags & 0x10) {             /* crmod */
-               termios->c_oflag |= OPOST | ONLCR;
-       }
-       if (flags & 0x20) {     /* raw */
-               termios->c_iflag = 0;
-               termios->c_lflag &= ~(ISIG | ICANON);
-       }
-       if (!(termios->c_lflag & ICANON)) {
-               termios->c_cc[VMIN] = 1;
-               termios->c_cc[VTIME] = 0;
-       }
-}
-
-/**
- *     set_sgttyb              -       set legacy terminal values
- *     @tty: tty structure
- *     @sgttyb: pointer to old style terminal structure
- *
- *     Updates a terminal from the legacy BSD style terminal information
- *     structure.
- *
- *     Locking: termios_mutex
- */
-
-static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
-{
-       int retval;
-       struct sgttyb tmp;
-       struct ktermios termios;
-
-       retval = tty_check_change(tty);
-       if (retval)
-               return retval;
-
-       if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
-               return -EFAULT;
-
-       mutex_lock(&tty->termios_mutex);
-       termios = *tty->termios;
-       termios.c_cc[VERASE] = tmp.sg_erase;
-       termios.c_cc[VKILL] = tmp.sg_kill;
-       set_sgflags(&termios, tmp.sg_flags);
-       /* Try and encode into Bfoo format */
-#ifdef BOTHER
-       tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
-                                               termios.c_ospeed);
-#endif
-       mutex_unlock(&tty->termios_mutex);
-       change_termios(tty, &termios);
-       return 0;
-}
-#endif
-
-#ifdef TIOCGETC
-static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
-{
-       struct tchars tmp;
-
-       mutex_lock(&tty->termios_mutex);
-       tmp.t_intrc = tty->termios->c_cc[VINTR];
-       tmp.t_quitc = tty->termios->c_cc[VQUIT];
-       tmp.t_startc = tty->termios->c_cc[VSTART];
-       tmp.t_stopc = tty->termios->c_cc[VSTOP];
-       tmp.t_eofc = tty->termios->c_cc[VEOF];
-       tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
-       mutex_unlock(&tty->termios_mutex);
-       return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
-}
-
-static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
-{
-       struct tchars tmp;
-
-       if (copy_from_user(&tmp, tchars, sizeof(tmp)))
-               return -EFAULT;
-       mutex_lock(&tty->termios_mutex);
-       tty->termios->c_cc[VINTR] = tmp.t_intrc;
-       tty->termios->c_cc[VQUIT] = tmp.t_quitc;
-       tty->termios->c_cc[VSTART] = tmp.t_startc;
-       tty->termios->c_cc[VSTOP] = tmp.t_stopc;
-       tty->termios->c_cc[VEOF] = tmp.t_eofc;
-       tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
-       mutex_unlock(&tty->termios_mutex);
-       return 0;
-}
-#endif
-
-#ifdef TIOCGLTC
-static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
-{
-       struct ltchars tmp;
-
-       mutex_lock(&tty->termios_mutex);
-       tmp.t_suspc = tty->termios->c_cc[VSUSP];
-       /* what is dsuspc anyway? */
-       tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
-       tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
-       /* what is flushc anyway? */
-       tmp.t_flushc = tty->termios->c_cc[VEOL2];
-       tmp.t_werasc = tty->termios->c_cc[VWERASE];
-       tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
-       mutex_unlock(&tty->termios_mutex);
-       return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
-}
-
-static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
-{
-       struct ltchars tmp;
-
-       if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
-               return -EFAULT;
-
-       mutex_lock(&tty->termios_mutex);
-       tty->termios->c_cc[VSUSP] = tmp.t_suspc;
-       /* what is dsuspc anyway? */
-       tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
-       tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
-       /* what is flushc anyway? */
-       tty->termios->c_cc[VEOL2] = tmp.t_flushc;
-       tty->termios->c_cc[VWERASE] = tmp.t_werasc;
-       tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
-       mutex_unlock(&tty->termios_mutex);
-       return 0;
-}
-#endif
-
-/**
- *     send_prio_char          -       send priority character
- *
- *     Send a high priority character to the tty even if stopped
- *
- *     Locking: none for xchar method, write ordering for write method.
- */
-
-static int send_prio_char(struct tty_struct *tty, char ch)
-{
-       int     was_stopped = tty->stopped;
-
-       if (tty->ops->send_xchar) {
-               tty->ops->send_xchar(tty, ch);
-               return 0;
-       }
-
-       if (tty_write_lock(tty, 0) < 0)
-               return -ERESTARTSYS;
-
-       if (was_stopped)
-               start_tty(tty);
-       tty->ops->write(tty, &ch, 1);
-       if (was_stopped)
-               stop_tty(tty);
-       tty_write_unlock(tty);
-       return 0;
-}
-
-/**
- *     tty_change_softcar      -       carrier change ioctl helper
- *     @tty: tty to update
- *     @arg: enable/disable CLOCAL
- *
- *     Perform a change to the CLOCAL state and call into the driver
- *     layer to make it visible. All done with the termios mutex
- */
-
-static int tty_change_softcar(struct tty_struct *tty, int arg)
-{
-       int ret = 0;
-       int bit = arg ? CLOCAL : 0;
-       struct ktermios old;
-
-       mutex_lock(&tty->termios_mutex);
-       old = *tty->termios;
-       tty->termios->c_cflag &= ~CLOCAL;
-       tty->termios->c_cflag |= bit;
-       if (tty->ops->set_termios)
-               tty->ops->set_termios(tty, &old);
-       if ((tty->termios->c_cflag & CLOCAL) != bit)
-               ret = -EINVAL;
-       mutex_unlock(&tty->termios_mutex);
-       return ret;
-}
-
-/**
- *     tty_mode_ioctl          -       mode related ioctls
- *     @tty: tty for the ioctl
- *     @file: file pointer for the tty
- *     @cmd: command
- *     @arg: ioctl argument
- *
- *     Perform non line discipline specific mode control ioctls. This
- *     is designed to be called by line disciplines to ensure they provide
- *     consistent mode setting.
- */
-
-int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
-                       unsigned int cmd, unsigned long arg)
-{
-       struct tty_struct *real_tty;
-       void __user *p = (void __user *)arg;
-       int ret = 0;
-       struct ktermios kterm;
-
-       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
-           tty->driver->subtype == PTY_TYPE_MASTER)
-               real_tty = tty->link;
-       else
-               real_tty = tty;
-
-       switch (cmd) {
-#ifdef TIOCGETP
-       case TIOCGETP:
-               return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
-       case TIOCSETP:
-       case TIOCSETN:
-               return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
-#endif
-#ifdef TIOCGETC
-       case TIOCGETC:
-               return get_tchars(real_tty, p);
-       case TIOCSETC:
-               return set_tchars(real_tty, p);
-#endif
-#ifdef TIOCGLTC
-       case TIOCGLTC:
-               return get_ltchars(real_tty, p);
-       case TIOCSLTC:
-               return set_ltchars(real_tty, p);
-#endif
-       case TCSETSF:
-               return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
-       case TCSETSW:
-               return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
-       case TCSETS:
-               return set_termios(real_tty, p, TERMIOS_OLD);
-#ifndef TCGETS2
-       case TCGETS:
-               copy_termios(real_tty, &kterm);
-               if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
-                       ret = -EFAULT;
-               return ret;
-#else
-       case TCGETS:
-               copy_termios(real_tty, &kterm);
-               if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
-                       ret = -EFAULT;
-               return ret;
-       case TCGETS2:
-               copy_termios(real_tty, &kterm);
-               if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm))
-                       ret = -EFAULT;
-               return ret;
-       case TCSETSF2:
-               return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
-       case TCSETSW2:
-               return set_termios(real_tty, p, TERMIOS_WAIT);
-       case TCSETS2:
-               return set_termios(real_tty, p, 0);
-#endif
-       case TCGETA:
-               return get_termio(real_tty, p);
-       case TCSETAF:
-               return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
-       case TCSETAW:
-               return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
-       case TCSETA:
-               return set_termios(real_tty, p, TERMIOS_TERMIO);
-#ifndef TCGETS2
-       case TIOCGLCKTRMIOS:
-               copy_termios_locked(real_tty, &kterm);
-               if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
-                       ret = -EFAULT;
-               return ret;
-       case TIOCSLCKTRMIOS:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               copy_termios_locked(real_tty, &kterm);
-               if (user_termios_to_kernel_termios(&kterm,
-                                              (struct termios __user *) arg))
-                       return -EFAULT;
-               mutex_lock(&real_tty->termios_mutex);
-               memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
-               mutex_unlock(&real_tty->termios_mutex);
-               return 0;
-#else
-       case TIOCGLCKTRMIOS:
-               copy_termios_locked(real_tty, &kterm);
-               if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
-                       ret = -EFAULT;
-               return ret;
-       case TIOCSLCKTRMIOS:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               copy_termios_locked(real_tty, &kterm);
-               if (user_termios_to_kernel_termios_1(&kterm,
-                                              (struct termios __user *) arg))
-                       return -EFAULT;
-               mutex_lock(&real_tty->termios_mutex);
-               memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
-               mutex_unlock(&real_tty->termios_mutex);
-               return ret;
-#endif
-#ifdef TCGETX
-       case TCGETX: {
-               struct termiox ktermx;
-               if (real_tty->termiox == NULL)
-                       return -EINVAL;
-               mutex_lock(&real_tty->termios_mutex);
-               memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
-               mutex_unlock(&real_tty->termios_mutex);
-               if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
-                       ret = -EFAULT;
-               return ret;
-       }
-       case TCSETX:
-               return set_termiox(real_tty, p, 0);
-       case TCSETXW:
-               return set_termiox(real_tty, p, TERMIOS_WAIT);
-       case TCSETXF:
-               return set_termiox(real_tty, p, TERMIOS_FLUSH);
-#endif         
-       case TIOCGSOFTCAR:
-               copy_termios(real_tty, &kterm);
-               ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
-                                               (int __user *)arg);
-               return ret;
-       case TIOCSSOFTCAR:
-               if (get_user(arg, (unsigned int __user *) arg))
-                       return -EFAULT;
-               return tty_change_softcar(real_tty, arg);
-       default:
-               return -ENOIOCTLCMD;
-       }
-}
-EXPORT_SYMBOL_GPL(tty_mode_ioctl);
-
-int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
-{
-       struct tty_ldisc *ld;
-       int retval = tty_check_change(tty);
-       if (retval)
-               return retval;
-
-       ld = tty_ldisc_ref_wait(tty);
-       switch (arg) {
-       case TCIFLUSH:
-               if (ld && ld->ops->flush_buffer)
-                       ld->ops->flush_buffer(tty);
-               break;
-       case TCIOFLUSH:
-               if (ld && ld->ops->flush_buffer)
-                       ld->ops->flush_buffer(tty);
-               /* fall through */
-       case TCOFLUSH:
-               tty_driver_flush_buffer(tty);
-               break;
-       default:
-               tty_ldisc_deref(ld);
-               return -EINVAL;
-       }
-       tty_ldisc_deref(ld);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(tty_perform_flush);
-
-int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
-                      unsigned int cmd, unsigned long arg)
-{
-       unsigned long flags;
-       int retval;
-
-       switch (cmd) {
-       case TCXONC:
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               switch (arg) {
-               case TCOOFF:
-                       if (!tty->flow_stopped) {
-                               tty->flow_stopped = 1;
-                               stop_tty(tty);
-                       }
-                       break;
-               case TCOON:
-                       if (tty->flow_stopped) {
-                               tty->flow_stopped = 0;
-                               start_tty(tty);
-                       }
-                       break;
-               case TCIOFF:
-                       if (STOP_CHAR(tty) != __DISABLED_CHAR)
-                               return send_prio_char(tty, STOP_CHAR(tty));
-                       break;
-               case TCION:
-                       if (START_CHAR(tty) != __DISABLED_CHAR)
-                               return send_prio_char(tty, START_CHAR(tty));
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               return 0;
-       case TCFLSH:
-               return tty_perform_flush(tty, arg);
-       case TIOCPKT:
-       {
-               int pktmode;
-
-               if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
-                   tty->driver->subtype != PTY_TYPE_MASTER)
-                       return -ENOTTY;
-               if (get_user(pktmode, (int __user *) arg))
-                       return -EFAULT;
-               spin_lock_irqsave(&tty->ctrl_lock, flags);
-               if (pktmode) {
-                       if (!tty->packet) {
-                               tty->packet = 1;
-                               tty->link->ctrl_status = 0;
-                       }
-               } else
-                       tty->packet = 0;
-               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
-               return 0;
-       }
-       default:
-               /* Try the mode commands */
-               return tty_mode_ioctl(tty, file, cmd, arg);
-       }
-}
-EXPORT_SYMBOL(n_tty_ioctl_helper);
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
deleted file mode 100644 (file)
index 412f977..0000000
+++ /dev/null
@@ -1,915 +0,0 @@
-#include <linux/types.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/fcntl.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/devpts_fs.h>
-#include <linux/file.h>
-#include <linux/console.h>
-#include <linux/timer.h>
-#include <linux/ctype.h>
-#include <linux/kd.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/wait.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/seq_file.h>
-
-#include <linux/uaccess.h>
-#include <asm/system.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-
-#include <linux/smp_lock.h>    /* For the moment */
-
-#include <linux/kmod.h>
-#include <linux/nsproxy.h>
-
-/*
- *     This guards the refcounted line discipline lists. The lock
- *     must be taken with irqs off because there are hangup path
- *     callers who will do ldisc lookups and cannot sleep.
- */
-
-static DEFINE_SPINLOCK(tty_ldisc_lock);
-static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
-/* Line disc dispatch table */
-static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
-
-static inline struct tty_ldisc *get_ldisc(struct tty_ldisc *ld)
-{
-       if (ld)
-               atomic_inc(&ld->users);
-       return ld;
-}
-
-static void put_ldisc(struct tty_ldisc *ld)
-{
-       unsigned long flags;
-
-       if (WARN_ON_ONCE(!ld))
-               return;
-
-       /*
-        * If this is the last user, free the ldisc, and
-        * release the ldisc ops.
-        *
-        * We really want an "atomic_dec_and_lock_irqsave()",
-        * but we don't have it, so this does it by hand.
-        */
-       local_irq_save(flags);
-       if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) {
-               struct tty_ldisc_ops *ldo = ld->ops;
-
-               ldo->refcount--;
-               module_put(ldo->owner);
-               spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
-               kfree(ld);
-               return;
-       }
-       local_irq_restore(flags);
-}
-
-/**
- *     tty_register_ldisc      -       install a line discipline
- *     @disc: ldisc number
- *     @new_ldisc: pointer to the ldisc object
- *
- *     Installs a new line discipline into the kernel. The discipline
- *     is set up as unreferenced and then made available to the kernel
- *     from this point onwards.
- *
- *     Locking:
- *             takes tty_ldisc_lock to guard against ldisc races
- */
-
-int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
-{
-       unsigned long flags;
-       int ret = 0;
-
-       if (disc < N_TTY || disc >= NR_LDISCS)
-               return -EINVAL;
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       tty_ldiscs[disc] = new_ldisc;
-       new_ldisc->num = disc;
-       new_ldisc->refcount = 0;
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(tty_register_ldisc);
-
-/**
- *     tty_unregister_ldisc    -       unload a line discipline
- *     @disc: ldisc number
- *     @new_ldisc: pointer to the ldisc object
- *
- *     Remove a line discipline from the kernel providing it is not
- *     currently in use.
- *
- *     Locking:
- *             takes tty_ldisc_lock to guard against ldisc races
- */
-
-int tty_unregister_ldisc(int disc)
-{
-       unsigned long flags;
-       int ret = 0;
-
-       if (disc < N_TTY || disc >= NR_LDISCS)
-               return -EINVAL;
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       if (tty_ldiscs[disc]->refcount)
-               ret = -EBUSY;
-       else
-               tty_ldiscs[disc] = NULL;
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(tty_unregister_ldisc);
-
-static struct tty_ldisc_ops *get_ldops(int disc)
-{
-       unsigned long flags;
-       struct tty_ldisc_ops *ldops, *ret;
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       ret = ERR_PTR(-EINVAL);
-       ldops = tty_ldiscs[disc];
-       if (ldops) {
-               ret = ERR_PTR(-EAGAIN);
-               if (try_module_get(ldops->owner)) {
-                       ldops->refcount++;
-                       ret = ldops;
-               }
-       }
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-       return ret;
-}
-
-static void put_ldops(struct tty_ldisc_ops *ldops)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       ldops->refcount--;
-       module_put(ldops->owner);
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-}
-
-/**
- *     tty_ldisc_get           -       take a reference to an ldisc
- *     @disc: ldisc number
- *
- *     Takes a reference to a line discipline. Deals with refcounts and
- *     module locking counts. Returns NULL if the discipline is not available.
- *     Returns a pointer to the discipline and bumps the ref count if it is
- *     available
- *
- *     Locking:
- *             takes tty_ldisc_lock to guard against ldisc races
- */
-
-static struct tty_ldisc *tty_ldisc_get(int disc)
-{
-       struct tty_ldisc *ld;
-       struct tty_ldisc_ops *ldops;
-
-       if (disc < N_TTY || disc >= NR_LDISCS)
-               return ERR_PTR(-EINVAL);
-
-       /*
-        * Get the ldisc ops - we may need to request them to be loaded
-        * dynamically and try again.
-        */
-       ldops = get_ldops(disc);
-       if (IS_ERR(ldops)) {
-               request_module("tty-ldisc-%d", disc);
-               ldops = get_ldops(disc);
-               if (IS_ERR(ldops))
-                       return ERR_CAST(ldops);
-       }
-
-       ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
-       if (ld == NULL) {
-               put_ldops(ldops);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       ld->ops = ldops;
-       atomic_set(&ld->users, 1);
-       return ld;
-}
-
-static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
-{
-       return (*pos < NR_LDISCS) ? pos : NULL;
-}
-
-static void *tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
-{
-       (*pos)++;
-       return (*pos < NR_LDISCS) ? pos : NULL;
-}
-
-static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
-{
-}
-
-static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
-{
-       int i = *(loff_t *)v;
-       struct tty_ldisc_ops *ldops;
-
-       ldops = get_ldops(i);
-       if (IS_ERR(ldops))
-               return 0;
-       seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
-       put_ldops(ldops);
-       return 0;
-}
-
-static const struct seq_operations tty_ldiscs_seq_ops = {
-       .start  = tty_ldiscs_seq_start,
-       .next   = tty_ldiscs_seq_next,
-       .stop   = tty_ldiscs_seq_stop,
-       .show   = tty_ldiscs_seq_show,
-};
-
-static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &tty_ldiscs_seq_ops);
-}
-
-const struct file_operations tty_ldiscs_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = proc_tty_ldiscs_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-/**
- *     tty_ldisc_assign        -       set ldisc on a tty
- *     @tty: tty to assign
- *     @ld: line discipline
- *
- *     Install an instance of a line discipline into a tty structure. The
- *     ldisc must have a reference count above zero to ensure it remains.
- *     The tty instance refcount starts at zero.
- *
- *     Locking:
- *             Caller must hold references
- */
-
-static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
-{
-       tty->ldisc = ld;
-}
-
-/**
- *     tty_ldisc_try           -       internal helper
- *     @tty: the tty
- *
- *     Make a single attempt to grab and bump the refcount on
- *     the tty ldisc. Return 0 on failure or 1 on success. This is
- *     used to implement both the waiting and non waiting versions
- *     of tty_ldisc_ref
- *
- *     Locking: takes tty_ldisc_lock
- */
-
-static struct tty_ldisc *tty_ldisc_try(struct tty_struct *tty)
-{
-       unsigned long flags;
-       struct tty_ldisc *ld;
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       ld = NULL;
-       if (test_bit(TTY_LDISC, &tty->flags))
-               ld = get_ldisc(tty->ldisc);
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-       return ld;
-}
-
-/**
- *     tty_ldisc_ref_wait      -       wait for the tty ldisc
- *     @tty: tty device
- *
- *     Dereference the line discipline for the terminal and take a
- *     reference to it. If the line discipline is in flux then
- *     wait patiently until it changes.
- *
- *     Note: Must not be called from an IRQ/timer context. The caller
- *     must also be careful not to hold other locks that will deadlock
- *     against a discipline change, such as an existing ldisc reference
- *     (which we check for)
- *
- *     Locking: call functions take tty_ldisc_lock
- */
-
-struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
-{
-       struct tty_ldisc *ld;
-
-       /* wait_event is a macro */
-       wait_event(tty_ldisc_wait, (ld = tty_ldisc_try(tty)) != NULL);
-       return ld;
-}
-EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
-
-/**
- *     tty_ldisc_ref           -       get the tty ldisc
- *     @tty: tty device
- *
- *     Dereference the line discipline for the terminal and take a
- *     reference to it. If the line discipline is in flux then
- *     return NULL. Can be called from IRQ and timer functions.
- *
- *     Locking: called functions take tty_ldisc_lock
- */
-
-struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
-{
-       return tty_ldisc_try(tty);
-}
-EXPORT_SYMBOL_GPL(tty_ldisc_ref);
-
-/**
- *     tty_ldisc_deref         -       free a tty ldisc reference
- *     @ld: reference to free up
- *
- *     Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May
- *     be called in IRQ context.
- *
- *     Locking: takes tty_ldisc_lock
- */
-
-void tty_ldisc_deref(struct tty_ldisc *ld)
-{
-       put_ldisc(ld);
-}
-EXPORT_SYMBOL_GPL(tty_ldisc_deref);
-
-static inline void tty_ldisc_put(struct tty_ldisc *ld)
-{
-       put_ldisc(ld);
-}
-
-/**
- *     tty_ldisc_enable        -       allow ldisc use
- *     @tty: terminal to activate ldisc on
- *
- *     Set the TTY_LDISC flag when the line discipline can be called
- *     again. Do necessary wakeups for existing sleepers. Clear the LDISC
- *     changing flag to indicate any ldisc change is now over.
- *
- *     Note: nobody should set the TTY_LDISC bit except via this function.
- *     Clearing directly is allowed.
- */
-
-void tty_ldisc_enable(struct tty_struct *tty)
-{
-       set_bit(TTY_LDISC, &tty->flags);
-       clear_bit(TTY_LDISC_CHANGING, &tty->flags);
-       wake_up(&tty_ldisc_wait);
-}
-
-/**
- *     tty_ldisc_flush -       flush line discipline queue
- *     @tty: tty
- *
- *     Flush the line discipline queue (if any) for this tty. If there
- *     is no line discipline active this is a no-op.
- */
-
-void tty_ldisc_flush(struct tty_struct *tty)
-{
-       struct tty_ldisc *ld = tty_ldisc_ref(tty);
-       if (ld) {
-               if (ld->ops->flush_buffer)
-                       ld->ops->flush_buffer(tty);
-               tty_ldisc_deref(ld);
-       }
-       tty_buffer_flush(tty);
-}
-EXPORT_SYMBOL_GPL(tty_ldisc_flush);
-
-/**
- *     tty_set_termios_ldisc           -       set ldisc field
- *     @tty: tty structure
- *     @num: line discipline number
- *
- *     This is probably overkill for real world processors but
- *     they are not on hot paths so a little discipline won't do
- *     any harm.
- *
- *     Locking: takes termios_mutex
- */
-
-static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
-{
-       mutex_lock(&tty->termios_mutex);
-       tty->termios->c_line = num;
-       mutex_unlock(&tty->termios_mutex);
-}
-
-/**
- *     tty_ldisc_open          -       open a line discipline
- *     @tty: tty we are opening the ldisc on
- *     @ld: discipline to open
- *
- *     A helper opening method. Also a convenient debugging and check
- *     point.
- *
- *     Locking: always called with BTM already held.
- */
-
-static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
-{
-       WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
-       if (ld->ops->open) {
-               int ret;
-                /* BTM here locks versus a hangup event */
-               WARN_ON(!tty_locked());
-               ret = ld->ops->open(tty);
-               return ret;
-       }
-       return 0;
-}
-
-/**
- *     tty_ldisc_close         -       close a line discipline
- *     @tty: tty we are opening the ldisc on
- *     @ld: discipline to close
- *
- *     A helper close method. Also a convenient debugging and check
- *     point.
- */
-
-static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
-{
-       WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags));
-       clear_bit(TTY_LDISC_OPEN, &tty->flags);
-       if (ld->ops->close)
-               ld->ops->close(tty);
-}
-
-/**
- *     tty_ldisc_restore       -       helper for tty ldisc change
- *     @tty: tty to recover
- *     @old: previous ldisc
- *
- *     Restore the previous line discipline or N_TTY when a line discipline
- *     change fails due to an open error
- */
-
-static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
-{
-       char buf[64];
-       struct tty_ldisc *new_ldisc;
-       int r;
-
-       /* There is an outstanding reference here so this is safe */
-       old = tty_ldisc_get(old->ops->num);
-       WARN_ON(IS_ERR(old));
-       tty_ldisc_assign(tty, old);
-       tty_set_termios_ldisc(tty, old->ops->num);
-       if (tty_ldisc_open(tty, old) < 0) {
-               tty_ldisc_put(old);
-               /* This driver is always present */
-               new_ldisc = tty_ldisc_get(N_TTY);
-               if (IS_ERR(new_ldisc))
-                       panic("n_tty: get");
-               tty_ldisc_assign(tty, new_ldisc);
-               tty_set_termios_ldisc(tty, N_TTY);
-               r = tty_ldisc_open(tty, new_ldisc);
-               if (r < 0)
-                       panic("Couldn't open N_TTY ldisc for "
-                             "%s --- error %d.",
-                             tty_name(tty, buf), r);
-       }
-}
-
-/**
- *     tty_ldisc_halt          -       shut down the line discipline
- *     @tty: tty device
- *
- *     Shut down the line discipline and work queue for this tty device.
- *     The TTY_LDISC flag being cleared ensures no further references can
- *     be obtained while the delayed work queue halt ensures that no more
- *     data is fed to the ldisc.
- *
- *     You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex)
- *     in order to make sure any currently executing ldisc work is also
- *     flushed.
- */
-
-static int tty_ldisc_halt(struct tty_struct *tty)
-{
-       clear_bit(TTY_LDISC, &tty->flags);
-       return cancel_delayed_work_sync(&tty->buf.work);
-}
-
-/**
- *     tty_set_ldisc           -       set line discipline
- *     @tty: the terminal to set
- *     @ldisc: the line discipline
- *
- *     Set the discipline of a tty line. Must be called from a process
- *     context. The ldisc change logic has to protect itself against any
- *     overlapping ldisc change (including on the other end of pty pairs),
- *     the close of one side of a tty/pty pair, and eventually hangup.
- *
- *     Locking: takes tty_ldisc_lock, termios_mutex
- */
-
-int tty_set_ldisc(struct tty_struct *tty, int ldisc)
-{
-       int retval;
-       struct tty_ldisc *o_ldisc, *new_ldisc;
-       int work, o_work = 0;
-       struct tty_struct *o_tty;
-
-       new_ldisc = tty_ldisc_get(ldisc);
-       if (IS_ERR(new_ldisc))
-               return PTR_ERR(new_ldisc);
-
-       tty_lock();
-       /*
-        *      We need to look at the tty locking here for pty/tty pairs
-        *      when both sides try to change in parallel.
-        */
-
-       o_tty = tty->link;      /* o_tty is the pty side or NULL */
-
-
-       /*
-        *      Check the no-op case
-        */
-
-       if (tty->ldisc->ops->num == ldisc) {
-               tty_unlock();
-               tty_ldisc_put(new_ldisc);
-               return 0;
-       }
-
-       tty_unlock();
-       /*
-        *      Problem: What do we do if this blocks ?
-        *      We could deadlock here
-        */
-
-       tty_wait_until_sent(tty, 0);
-
-       tty_lock();
-       mutex_lock(&tty->ldisc_mutex);
-
-       /*
-        *      We could be midstream of another ldisc change which has
-        *      dropped the lock during processing. If so we need to wait.
-        */
-
-       while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) {
-               mutex_unlock(&tty->ldisc_mutex);
-               tty_unlock();
-               wait_event(tty_ldisc_wait,
-                       test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
-               tty_lock();
-               mutex_lock(&tty->ldisc_mutex);
-       }
-
-       set_bit(TTY_LDISC_CHANGING, &tty->flags);
-
-       /*
-        *      No more input please, we are switching. The new ldisc
-        *      will update this value in the ldisc open function
-        */
-
-       tty->receive_room = 0;
-
-       o_ldisc = tty->ldisc;
-
-       tty_unlock();
-       /*
-        *      Make sure we don't change while someone holds a
-        *      reference to the line discipline. The TTY_LDISC bit
-        *      prevents anyone taking a reference once it is clear.
-        *      We need the lock to avoid racing reference takers.
-        *
-        *      We must clear the TTY_LDISC bit here to avoid a livelock
-        *      with a userspace app continually trying to use the tty in
-        *      parallel to the change and re-referencing the tty.
-        */
-
-       work = tty_ldisc_halt(tty);
-       if (o_tty)
-               o_work = tty_ldisc_halt(o_tty);
-
-       /*
-        * Wait for ->hangup_work and ->buf.work handlers to terminate.
-        * We must drop the mutex here in case a hangup is also in process.
-        */
-
-       mutex_unlock(&tty->ldisc_mutex);
-
-       flush_scheduled_work();
-
-       tty_lock();
-       mutex_lock(&tty->ldisc_mutex);
-       if (test_bit(TTY_HUPPED, &tty->flags)) {
-               /* We were raced by the hangup method. It will have stomped
-                  the ldisc data and closed the ldisc down */
-               clear_bit(TTY_LDISC_CHANGING, &tty->flags);
-               mutex_unlock(&tty->ldisc_mutex);
-               tty_ldisc_put(new_ldisc);
-               tty_unlock();
-               return -EIO;
-       }
-
-       /* Shutdown the current discipline. */
-       tty_ldisc_close(tty, o_ldisc);
-
-       /* Now set up the new line discipline. */
-       tty_ldisc_assign(tty, new_ldisc);
-       tty_set_termios_ldisc(tty, ldisc);
-
-       retval = tty_ldisc_open(tty, new_ldisc);
-       if (retval < 0) {
-               /* Back to the old one or N_TTY if we can't */
-               tty_ldisc_put(new_ldisc);
-               tty_ldisc_restore(tty, o_ldisc);
-       }
-
-       /* At this point we hold a reference to the new ldisc and a
-          a reference to the old ldisc. If we ended up flipping back
-          to the existing ldisc we have two references to it */
-
-       if (tty->ldisc->ops->num != o_ldisc->ops->num && tty->ops->set_ldisc)
-               tty->ops->set_ldisc(tty);
-
-       tty_ldisc_put(o_ldisc);
-
-       /*
-        *      Allow ldisc referencing to occur again
-        */
-
-       tty_ldisc_enable(tty);
-       if (o_tty)
-               tty_ldisc_enable(o_tty);
-
-       /* Restart the work queue in case no characters kick it off. Safe if
-          already running */
-       if (work)
-               schedule_delayed_work(&tty->buf.work, 1);
-       if (o_work)
-               schedule_delayed_work(&o_tty->buf.work, 1);
-       mutex_unlock(&tty->ldisc_mutex);
-       tty_unlock();
-       return retval;
-}
-
-/**
- *     tty_reset_termios       -       reset terminal state
- *     @tty: tty to reset
- *
- *     Restore a terminal to the driver default state.
- */
-
-static void tty_reset_termios(struct tty_struct *tty)
-{
-       mutex_lock(&tty->termios_mutex);
-       *tty->termios = tty->driver->init_termios;
-       tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
-       tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
-       mutex_unlock(&tty->termios_mutex);
-}
-
-
-/**
- *     tty_ldisc_reinit        -       reinitialise the tty ldisc
- *     @tty: tty to reinit
- *     @ldisc: line discipline to reinitialize
- *
- *     Switch the tty to a line discipline and leave the ldisc
- *     state closed
- */
-
-static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
-{
-       struct tty_ldisc *ld;
-
-       tty_ldisc_close(tty, tty->ldisc);
-       tty_ldisc_put(tty->ldisc);
-       tty->ldisc = NULL;
-       /*
-        *      Switch the line discipline back
-        */
-       ld = tty_ldisc_get(ldisc);
-       BUG_ON(IS_ERR(ld));
-       tty_ldisc_assign(tty, ld);
-       tty_set_termios_ldisc(tty, ldisc);
-}
-
-/**
- *     tty_ldisc_hangup                -       hangup ldisc reset
- *     @tty: tty being hung up
- *
- *     Some tty devices reset their termios when they receive a hangup
- *     event. In that situation we must also switch back to N_TTY properly
- *     before we reset the termios data.
- *
- *     Locking: We can take the ldisc mutex as the rest of the code is
- *     careful to allow for this.
- *
- *     In the pty pair case this occurs in the close() path of the
- *     tty itself so we must be careful about locking rules.
- */
-
-void tty_ldisc_hangup(struct tty_struct *tty)
-{
-       struct tty_ldisc *ld;
-       int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS;
-       int err = 0;
-
-       /*
-        * FIXME! What are the locking issues here? This may me overdoing
-        * things... This question is especially important now that we've
-        * removed the irqlock.
-        */
-       ld = tty_ldisc_ref(tty);
-       if (ld != NULL) {
-               /* We may have no line discipline at this point */
-               if (ld->ops->flush_buffer)
-                       ld->ops->flush_buffer(tty);
-               tty_driver_flush_buffer(tty);
-               if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
-                   ld->ops->write_wakeup)
-                       ld->ops->write_wakeup(tty);
-               if (ld->ops->hangup)
-                       ld->ops->hangup(tty);
-               tty_ldisc_deref(ld);
-       }
-       /*
-        * FIXME: Once we trust the LDISC code better we can wait here for
-        * ldisc completion and fix the driver call race
-        */
-       wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
-       wake_up_interruptible_poll(&tty->read_wait, POLLIN);
-       /*
-        * Shutdown the current line discipline, and reset it to
-        * N_TTY if need be.
-        *
-        * Avoid racing set_ldisc or tty_ldisc_release
-        */
-       mutex_lock(&tty->ldisc_mutex);
-
-       /*
-        * this is like tty_ldisc_halt, but we need to give up
-        * the BTM before calling cancel_delayed_work_sync,
-        * which may need to wait for another function taking the BTM
-        */
-       clear_bit(TTY_LDISC, &tty->flags);
-       tty_unlock();
-       cancel_delayed_work_sync(&tty->buf.work);
-       mutex_unlock(&tty->ldisc_mutex);
-
-       tty_lock();
-       mutex_lock(&tty->ldisc_mutex);
-
-       /* At this point we have a closed ldisc and we want to
-          reopen it. We could defer this to the next open but
-          it means auditing a lot of other paths so this is
-          a FIXME */
-       if (tty->ldisc) {       /* Not yet closed */
-               if (reset == 0) {
-                       tty_ldisc_reinit(tty, tty->termios->c_line);
-                       err = tty_ldisc_open(tty, tty->ldisc);
-               }
-               /* If the re-open fails or we reset then go to N_TTY. The
-                  N_TTY open cannot fail */
-               if (reset || err) {
-                       tty_ldisc_reinit(tty, N_TTY);
-                       WARN_ON(tty_ldisc_open(tty, tty->ldisc));
-               }
-               tty_ldisc_enable(tty);
-       }
-       mutex_unlock(&tty->ldisc_mutex);
-       if (reset)
-               tty_reset_termios(tty);
-}
-
-/**
- *     tty_ldisc_setup                 -       open line discipline
- *     @tty: tty being shut down
- *     @o_tty: pair tty for pty/tty pairs
- *
- *     Called during the initial open of a tty/pty pair in order to set up the
- *     line disciplines and bind them to the tty. This has no locking issues
- *     as the device isn't yet active.
- */
-
-int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
-{
-       struct tty_ldisc *ld = tty->ldisc;
-       int retval;
-
-       retval = tty_ldisc_open(tty, ld);
-       if (retval)
-               return retval;
-
-       if (o_tty) {
-               retval = tty_ldisc_open(o_tty, o_tty->ldisc);
-               if (retval) {
-                       tty_ldisc_close(tty, ld);
-                       return retval;
-               }
-               tty_ldisc_enable(o_tty);
-       }
-       tty_ldisc_enable(tty);
-       return 0;
-}
-/**
- *     tty_ldisc_release               -       release line discipline
- *     @tty: tty being shut down
- *     @o_tty: pair tty for pty/tty pairs
- *
- *     Called during the final close of a tty/pty pair in order to shut down
- *     the line discpline layer. On exit the ldisc assigned is N_TTY and the
- *     ldisc has not been opened.
- */
-
-void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
-{
-       /*
-        * Prevent flush_to_ldisc() from rescheduling the work for later.  Then
-        * kill any delayed work. As this is the final close it does not
-        * race with the set_ldisc code path.
-        */
-
-       tty_unlock();
-       tty_ldisc_halt(tty);
-       flush_scheduled_work();
-       tty_lock();
-
-       mutex_lock(&tty->ldisc_mutex);
-       /*
-        * Now kill off the ldisc
-        */
-       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);
-       mutex_unlock(&tty->ldisc_mutex);
-
-       /* 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 */
-}
-
-/**
- *     tty_ldisc_init          -       ldisc setup for new tty
- *     @tty: tty being allocated
- *
- *     Set up the line discipline objects for a newly allocated tty. Note that
- *     the tty structure is not completely set up when this call is made.
- */
-
-void tty_ldisc_init(struct tty_struct *tty)
-{
-       struct tty_ldisc *ld = tty_ldisc_get(N_TTY);
-       if (IS_ERR(ld))
-               panic("n_tty: init_tty");
-       tty_ldisc_assign(tty, ld);
-}
-
-void tty_ldisc_begin(void)
-{
-       /* Setup the default TTY line discipline. */
-       (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
-}
diff --git a/drivers/char/tty_mutex.c b/drivers/char/tty_mutex.c
deleted file mode 100644 (file)
index 1336975..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * drivers/char/tty_lock.c
- */
-#include <linux/tty.h>
-#include <linux/module.h>
-#include <linux/kallsyms.h>
-#include <linux/semaphore.h>
-#include <linux/sched.h>
-
-/*
- * The 'big tty mutex'
- *
- * This mutex is taken and released by tty_lock() and tty_unlock(),
- * replacing the older big kernel lock.
- * It can no longer be taken recursively, and does not get
- * released implicitly while sleeping.
- *
- * Don't use in new code.
- */
-static DEFINE_MUTEX(big_tty_mutex);
-struct task_struct *__big_tty_mutex_owner;
-EXPORT_SYMBOL_GPL(__big_tty_mutex_owner);
-
-/*
- * Getting the big tty mutex.
- */
-void __lockfunc tty_lock(void)
-{
-       struct task_struct *task = current;
-
-       WARN_ON(__big_tty_mutex_owner == task);
-
-       mutex_lock(&big_tty_mutex);
-       __big_tty_mutex_owner = task;
-}
-EXPORT_SYMBOL(tty_lock);
-
-void __lockfunc tty_unlock(void)
-{
-       struct task_struct *task = current;
-
-       WARN_ON(__big_tty_mutex_owner != task);
-       __big_tty_mutex_owner = NULL;
-
-       mutex_unlock(&big_tty_mutex);
-}
-EXPORT_SYMBOL(tty_unlock);
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
deleted file mode 100644 (file)
index 33d37d2..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Tty port functions
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/wait.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-
-void tty_port_init(struct tty_port *port)
-{
-       memset(port, 0, sizeof(*port));
-       init_waitqueue_head(&port->open_wait);
-       init_waitqueue_head(&port->close_wait);
-       init_waitqueue_head(&port->delta_msr_wait);
-       mutex_init(&port->mutex);
-       mutex_init(&port->buf_mutex);
-       spin_lock_init(&port->lock);
-       port->close_delay = (50 * HZ) / 100;
-       port->closing_wait = (3000 * HZ) / 100;
-       kref_init(&port->kref);
-}
-EXPORT_SYMBOL(tty_port_init);
-
-int tty_port_alloc_xmit_buf(struct tty_port *port)
-{
-       /* We may sleep in get_zeroed_page() */
-       mutex_lock(&port->buf_mutex);
-       if (port->xmit_buf == NULL)
-               port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
-       mutex_unlock(&port->buf_mutex);
-       if (port->xmit_buf == NULL)
-               return -ENOMEM;
-       return 0;
-}
-EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
-
-void tty_port_free_xmit_buf(struct tty_port *port)
-{
-       mutex_lock(&port->buf_mutex);
-       if (port->xmit_buf != NULL) {
-               free_page((unsigned long)port->xmit_buf);
-               port->xmit_buf = NULL;
-       }
-       mutex_unlock(&port->buf_mutex);
-}
-EXPORT_SYMBOL(tty_port_free_xmit_buf);
-
-static void tty_port_destructor(struct kref *kref)
-{
-       struct tty_port *port = container_of(kref, struct tty_port, kref);
-       if (port->xmit_buf)
-               free_page((unsigned long)port->xmit_buf);
-       if (port->ops->destruct)
-               port->ops->destruct(port);
-       else
-               kfree(port);
-}
-
-void tty_port_put(struct tty_port *port)
-{
-       if (port)
-               kref_put(&port->kref, tty_port_destructor);
-}
-EXPORT_SYMBOL(tty_port_put);
-
-/**
- *     tty_port_tty_get        -       get a tty reference
- *     @port: tty port
- *
- *     Return a refcount protected tty instance or NULL if the port is not
- *     associated with a tty (eg due to close or hangup)
- */
-
-struct tty_struct *tty_port_tty_get(struct tty_port *port)
-{
-       unsigned long flags;
-       struct tty_struct *tty;
-
-       spin_lock_irqsave(&port->lock, flags);
-       tty = tty_kref_get(port->tty);
-       spin_unlock_irqrestore(&port->lock, flags);
-       return tty;
-}
-EXPORT_SYMBOL(tty_port_tty_get);
-
-/**
- *     tty_port_tty_set        -       set the tty of a port
- *     @port: tty port
- *     @tty: the tty
- *
- *     Associate the port and tty pair. Manages any internal refcounts.
- *     Pass NULL to deassociate a port
- */
-
-void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&port->lock, flags);
-       if (port->tty)
-               tty_kref_put(port->tty);
-       port->tty = tty_kref_get(tty);
-       spin_unlock_irqrestore(&port->lock, flags);
-}
-EXPORT_SYMBOL(tty_port_tty_set);
-
-static void tty_port_shutdown(struct tty_port *port)
-{
-       mutex_lock(&port->mutex);
-       if (port->ops->shutdown && !port->console &&
-               test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
-                       port->ops->shutdown(port);
-       mutex_unlock(&port->mutex);
-}
-
-/**
- *     tty_port_hangup         -       hangup helper
- *     @port: tty port
- *
- *     Perform port level tty hangup flag and count changes. Drop the tty
- *     reference.
- */
-
-void tty_port_hangup(struct tty_port *port)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&port->lock, flags);
-       port->count = 0;
-       port->flags &= ~ASYNC_NORMAL_ACTIVE;
-       if (port->tty) {
-               set_bit(TTY_IO_ERROR, &port->tty->flags);
-               tty_kref_put(port->tty);
-       }
-       port->tty = NULL;
-       spin_unlock_irqrestore(&port->lock, flags);
-       wake_up_interruptible(&port->open_wait);
-       wake_up_interruptible(&port->delta_msr_wait);
-       tty_port_shutdown(port);
-}
-EXPORT_SYMBOL(tty_port_hangup);
-
-/**
- *     tty_port_carrier_raised -       carrier raised check
- *     @port: tty port
- *
- *     Wrapper for the carrier detect logic. For the moment this is used
- *     to hide some internal details. This will eventually become entirely
- *     internal to the tty port.
- */
-
-int tty_port_carrier_raised(struct tty_port *port)
-{
-       if (port->ops->carrier_raised == NULL)
-               return 1;
-       return port->ops->carrier_raised(port);
-}
-EXPORT_SYMBOL(tty_port_carrier_raised);
-
-/**
- *     tty_port_raise_dtr_rts  -       Raise DTR/RTS
- *     @port: tty port
- *
- *     Wrapper for the DTR/RTS raise logic. For the moment this is used
- *     to hide some internal details. This will eventually become entirely
- *     internal to the tty port.
- */
-
-void tty_port_raise_dtr_rts(struct tty_port *port)
-{
-       if (port->ops->dtr_rts)
-               port->ops->dtr_rts(port, 1);
-}
-EXPORT_SYMBOL(tty_port_raise_dtr_rts);
-
-/**
- *     tty_port_lower_dtr_rts  -       Lower DTR/RTS
- *     @port: tty port
- *
- *     Wrapper for the DTR/RTS raise logic. For the moment this is used
- *     to hide some internal details. This will eventually become entirely
- *     internal to the tty port.
- */
-
-void tty_port_lower_dtr_rts(struct tty_port *port)
-{
-       if (port->ops->dtr_rts)
-               port->ops->dtr_rts(port, 0);
-}
-EXPORT_SYMBOL(tty_port_lower_dtr_rts);
-
-/**
- *     tty_port_block_til_ready        -       Waiting logic for tty open
- *     @port: the tty port being opened
- *     @tty: the tty device being bound
- *     @filp: the file pointer of the opener
- *
- *     Implement the core POSIX/SuS tty behaviour when opening a tty device.
- *     Handles:
- *             - hangup (both before and during)
- *             - non blocking open
- *             - rts/dtr/dcd
- *             - signals
- *             - port flags and counts
- *
- *     The passed tty_port must implement the carrier_raised method if it can
- *     do carrier detect and the dtr_rts method if it supports software
- *     management of these lines. Note that the dtr/rts raise is done each
- *     iteration as a hangup may have previously dropped them while we wait.
- */
-
-int tty_port_block_til_ready(struct tty_port *port,
-                               struct tty_struct *tty, struct file *filp)
-{
-       int do_clocal = 0, retval;
-       unsigned long flags;
-       DEFINE_WAIT(wait);
-       int cd;
-
-       /* block if port is in the process of being closed */
-       if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
-               wait_event_interruptible_tty(port->close_wait,
-                               !(port->flags & ASYNC_CLOSING));
-               if (port->flags & ASYNC_HUP_NOTIFY)
-                       return -EAGAIN;
-               else
-                       return -ERESTARTSYS;
-       }
-
-       /* if non-blocking mode is set we can pass directly to open unless
-          the port has just hung up or is in another error state */
-       if (tty->flags & (1 << TTY_IO_ERROR)) {
-               port->flags |= ASYNC_NORMAL_ACTIVE;
-               return 0;
-       }
-       if (filp->f_flags & O_NONBLOCK) {
-               /* Indicate we are open */
-               if (tty->termios->c_cflag & CBAUD)
-                       tty_port_raise_dtr_rts(port);
-               port->flags |= ASYNC_NORMAL_ACTIVE;
-               return 0;
-       }
-
-       if (C_CLOCAL(tty))
-               do_clocal = 1;
-
-       /* Block waiting until we can proceed. We may need to wait for the
-          carrier, but we must also wait for any close that is in progress
-          before the next open may complete */
-
-       retval = 0;
-
-       /* The port lock protects the port counts */
-       spin_lock_irqsave(&port->lock, flags);
-       if (!tty_hung_up_p(filp))
-               port->count--;
-       port->blocked_open++;
-       spin_unlock_irqrestore(&port->lock, flags);
-
-       while (1) {
-               /* Indicate we are open */
-               if (tty->termios->c_cflag & CBAUD)
-                       tty_port_raise_dtr_rts(port);
-
-               prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
-               /* Check for a hangup or uninitialised port.
-                                                       Return accordingly */
-               if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
-                       if (port->flags & ASYNC_HUP_NOTIFY)
-                               retval = -EAGAIN;
-                       else
-                               retval = -ERESTARTSYS;
-                       break;
-               }
-               /* Probe the carrier. For devices with no carrier detect this
-                  will always return true */
-               cd = tty_port_carrier_raised(port);
-               if (!(port->flags & ASYNC_CLOSING) &&
-                               (do_clocal || cd))
-                       break;
-               if (signal_pending(current)) {
-                       retval = -ERESTARTSYS;
-                       break;
-               }
-               tty_unlock();
-               schedule();
-               tty_lock();
-       }
-       finish_wait(&port->open_wait, &wait);
-
-       /* Update counts. A parallel hangup will have set count to zero and
-          we must not mess that up further */
-       spin_lock_irqsave(&port->lock, flags);
-       if (!tty_hung_up_p(filp))
-               port->count++;
-       port->blocked_open--;
-       if (retval == 0)
-               port->flags |= ASYNC_NORMAL_ACTIVE;
-       spin_unlock_irqrestore(&port->lock, flags);
-       return retval;
-}
-EXPORT_SYMBOL(tty_port_block_til_ready);
-
-int tty_port_close_start(struct tty_port *port,
-                               struct tty_struct *tty, struct file *filp)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&port->lock, flags);
-       if (tty_hung_up_p(filp)) {
-               spin_unlock_irqrestore(&port->lock, flags);
-               return 0;
-       }
-
-       if (tty->count == 1 && port->count != 1) {
-               printk(KERN_WARNING
-                   "tty_port_close_start: tty->count = 1 port count = %d.\n",
-                                                               port->count);
-               port->count = 1;
-       }
-       if (--port->count < 0) {
-               printk(KERN_WARNING "tty_port_close_start: count = %d\n",
-                                                               port->count);
-               port->count = 0;
-       }
-
-       if (port->count) {
-               spin_unlock_irqrestore(&port->lock, flags);
-               if (port->ops->drop)
-                       port->ops->drop(port);
-               return 0;
-       }
-       set_bit(ASYNCB_CLOSING, &port->flags);
-       tty->closing = 1;
-       spin_unlock_irqrestore(&port->lock, flags);
-       /* Don't block on a stalled port, just pull the chain */
-       if (tty->flow_stopped)
-               tty_driver_flush_buffer(tty);
-       if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
-                       port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-               tty_wait_until_sent(tty, port->closing_wait);
-       if (port->drain_delay) {
-               unsigned int bps = tty_get_baud_rate(tty);
-               long timeout;
-
-               if (bps > 1200)
-                       timeout = max_t(long,
-                               (HZ * 10 * port->drain_delay) / bps, HZ / 10);
-               else
-                       timeout = 2 * HZ;
-               schedule_timeout_interruptible(timeout);
-       }
-       /* Flush the ldisc buffering */
-       tty_ldisc_flush(tty);
-
-       /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
-          hang up the line */
-       if (tty->termios->c_cflag & HUPCL)
-               tty_port_lower_dtr_rts(port);
-
-       /* Don't call port->drop for the last reference. Callers will want
-          to drop the last active reference in ->shutdown() or the tty
-          shutdown path */
-       return 1;
-}
-EXPORT_SYMBOL(tty_port_close_start);
-
-void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&port->lock, flags);
-       tty->closing = 0;
-
-       if (port->blocked_open) {
-               spin_unlock_irqrestore(&port->lock, flags);
-               if (port->close_delay) {
-                       msleep_interruptible(
-                               jiffies_to_msecs(port->close_delay));
-               }
-               spin_lock_irqsave(&port->lock, flags);
-               wake_up_interruptible(&port->open_wait);
-       }
-       port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
-       wake_up_interruptible(&port->close_wait);
-       spin_unlock_irqrestore(&port->lock, flags);
-}
-EXPORT_SYMBOL(tty_port_close_end);
-
-void tty_port_close(struct tty_port *port, struct tty_struct *tty,
-                                                       struct file *filp)
-{
-       if (tty_port_close_start(port, tty, filp) == 0)
-               return;
-       tty_port_shutdown(port);
-       set_bit(TTY_IO_ERROR, &tty->flags);
-       tty_port_close_end(port, tty);
-       tty_port_tty_set(port, NULL);
-}
-EXPORT_SYMBOL(tty_port_close);
-
-int tty_port_open(struct tty_port *port, struct tty_struct *tty,
-                                                       struct file *filp)
-{
-       spin_lock_irq(&port->lock);
-       if (!tty_hung_up_p(filp))
-               ++port->count;
-       spin_unlock_irq(&port->lock);
-       tty_port_tty_set(port, tty);
-
-       /*
-        * Do the device-specific open only if the hardware isn't
-        * already initialized. Serialize open and shutdown using the
-        * port mutex.
-        */
-
-       mutex_lock(&port->mutex);
-
-       if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
-               clear_bit(TTY_IO_ERROR, &tty->flags);
-               if (port->ops->activate) {
-                       int retval = port->ops->activate(port, tty);
-                       if (retval) {
-                               mutex_unlock(&port->mutex);
-                               return retval;
-                       }
-               }
-               set_bit(ASYNCB_INITIALIZED, &port->flags);
-       }
-       mutex_unlock(&port->mutex);
-       return tty_port_block_til_ready(port, tty, filp);
-}
-
-EXPORT_SYMBOL(tty_port_open);
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
deleted file mode 100644 (file)
index 273ab44..0000000
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- * linux/drivers/char/vc_screen.c
- *
- * Provide access to virtual console memory.
- * /dev/vcs0: the screen as it is being viewed right now (possibly scrolled)
- * /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63)
- *            [minor: N]
- *
- * /dev/vcsaN: idem, but including attributes, and prefixed with
- *     the 4 bytes lines,columns,x,y (as screendump used to give).
- *     Attribute/character pair is in native endianity.
- *            [minor: N+128]
- *
- * This replaces screendump and part of selection, so that the system
- * administrator can control access using file system permissions.
- *
- * aeb@cwi.nl - efter Friedas begravelse - 950211
- *
- * machek@k332.feld.cvut.cz - modified not to send characters to wrong console
- *      - fixed some fatal off-by-one bugs (0-- no longer == -1 -> looping and looping and looping...)
- *      - making it shorter - scr_readw are macros which expand in PRETTY long code
- */
-
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/tty.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/kbd_kern.h>
-#include <linux/console.h>
-#include <linux/device.h>
-#include <linux/smp_lock.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/poll.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/notifier.h>
-
-#include <asm/uaccess.h>
-#include <asm/byteorder.h>
-#include <asm/unaligned.h>
-
-#undef attr
-#undef org
-#undef addr
-#define HEADER_SIZE    4
-
-struct vcs_poll_data {
-       struct notifier_block notifier;
-       unsigned int cons_num;
-       bool seen_last_update;
-       wait_queue_head_t waitq;
-       struct fasync_struct *fasync;
-};
-
-static int
-vcs_notifier(struct notifier_block *nb, unsigned long code, void *_param)
-{
-       struct vt_notifier_param *param = _param;
-       struct vc_data *vc = param->vc;
-       struct vcs_poll_data *poll =
-               container_of(nb, struct vcs_poll_data, notifier);
-       int currcons = poll->cons_num;
-
-       if (code != VT_UPDATE)
-               return NOTIFY_DONE;
-
-       if (currcons == 0)
-               currcons = fg_console;
-       else
-               currcons--;
-       if (currcons != vc->vc_num)
-               return NOTIFY_DONE;
-
-       poll->seen_last_update = false;
-       wake_up_interruptible(&poll->waitq);
-       kill_fasync(&poll->fasync, SIGIO, POLL_IN);
-       return NOTIFY_OK;
-}
-
-static void
-vcs_poll_data_free(struct vcs_poll_data *poll)
-{
-       unregister_vt_notifier(&poll->notifier);
-       kfree(poll);
-}
-
-static struct vcs_poll_data *
-vcs_poll_data_get(struct file *file)
-{
-       struct vcs_poll_data *poll = file->private_data;
-
-       if (poll)
-               return poll;
-
-       poll = kzalloc(sizeof(*poll), GFP_KERNEL);
-       if (!poll)
-               return NULL;
-       poll->cons_num = iminor(file->f_path.dentry->d_inode) & 127;
-       init_waitqueue_head(&poll->waitq);
-       poll->notifier.notifier_call = vcs_notifier;
-       if (register_vt_notifier(&poll->notifier) != 0) {
-               kfree(poll);
-               return NULL;
-       }
-
-       /*
-        * This code may be called either through ->poll() or ->fasync().
-        * If we have two threads using the same file descriptor, they could
-        * both enter this function, both notice that the structure hasn't
-        * been allocated yet and go ahead allocating it in parallel, but
-        * only one of them must survive and be shared otherwise we'd leak
-        * memory with a dangling notifier callback.
-        */
-       spin_lock(&file->f_lock);
-       if (!file->private_data) {
-               file->private_data = poll;
-       } else {
-               /* someone else raced ahead of us */
-               vcs_poll_data_free(poll);
-               poll = file->private_data;
-       }
-       spin_unlock(&file->f_lock);
-
-       return poll;
-}
-
-static int
-vcs_size(struct inode *inode)
-{
-       int size;
-       int minor = iminor(inode);
-       int currcons = minor & 127;
-       struct vc_data *vc;
-
-       if (currcons == 0)
-               currcons = fg_console;
-       else
-               currcons--;
-       if (!vc_cons_allocated(currcons))
-               return -ENXIO;
-       vc = vc_cons[currcons].d;
-
-       size = vc->vc_rows * vc->vc_cols;
-
-       if (minor & 128)
-               size = 2*size + HEADER_SIZE;
-       return size;
-}
-
-static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
-{
-       int size;
-
-       mutex_lock(&con_buf_mtx);
-       size = vcs_size(file->f_path.dentry->d_inode);
-       switch (orig) {
-               default:
-                       mutex_unlock(&con_buf_mtx);
-                       return -EINVAL;
-               case 2:
-                       offset += size;
-                       break;
-               case 1:
-                       offset += file->f_pos;
-               case 0:
-                       break;
-       }
-       if (offset < 0 || offset > size) {
-               mutex_unlock(&con_buf_mtx);
-               return -EINVAL;
-       }
-       file->f_pos = offset;
-       mutex_unlock(&con_buf_mtx);
-       return file->f_pos;
-}
-
-
-static ssize_t
-vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
-{
-       struct inode *inode = file->f_path.dentry->d_inode;
-       unsigned int currcons = iminor(inode);
-       struct vc_data *vc;
-       struct vcs_poll_data *poll;
-       long pos;
-       long viewed, attr, read;
-       int col, maxcol;
-       unsigned short *org = NULL;
-       ssize_t ret;
-
-       mutex_lock(&con_buf_mtx);
-
-       pos = *ppos;
-
-       /* Select the proper current console and verify
-        * sanity of the situation under the console lock.
-        */
-       acquire_console_sem();
-
-       attr = (currcons & 128);
-       currcons = (currcons & 127);
-       if (currcons == 0) {
-               currcons = fg_console;
-               viewed = 1;
-       } else {
-               currcons--;
-               viewed = 0;
-       }
-       ret = -ENXIO;
-       if (!vc_cons_allocated(currcons))
-               goto unlock_out;
-       vc = vc_cons[currcons].d;
-
-       ret = -EINVAL;
-       if (pos < 0)
-               goto unlock_out;
-       poll = file->private_data;
-       if (count && poll)
-               poll->seen_last_update = true;
-       read = 0;
-       ret = 0;
-       while (count) {
-               char *con_buf0, *con_buf_start;
-               long this_round, size;
-               ssize_t orig_count;
-               long p = pos;
-
-               /* Check whether we are above size each round,
-                * as copy_to_user at the end of this loop
-                * could sleep.
-                */
-               size = vcs_size(inode);
-               if (pos >= size)
-                       break;
-               if (count > size - pos)
-                       count = size - pos;
-
-               this_round = count;
-               if (this_round > CON_BUF_SIZE)
-                       this_round = CON_BUF_SIZE;
-
-               /* Perform the whole read into the local con_buf.
-                * Then we can drop the console spinlock and safely
-                * attempt to move it to userspace.
-                */
-
-               con_buf_start = con_buf0 = con_buf;
-               orig_count = this_round;
-               maxcol = vc->vc_cols;
-               if (!attr) {
-                       org = screen_pos(vc, p, viewed);
-                       col = p % maxcol;
-                       p += maxcol - col;
-                       while (this_round-- > 0) {
-                               *con_buf0++ = (vcs_scr_readw(vc, org++) & 0xff);
-                               if (++col == maxcol) {
-                                       org = screen_pos(vc, p, viewed);
-                                       col = 0;
-                                       p += maxcol;
-                               }
-                       }
-               } else {
-                       if (p < HEADER_SIZE) {
-                               size_t tmp_count;
-
-                               con_buf0[0] = (char)vc->vc_rows;
-                               con_buf0[1] = (char)vc->vc_cols;
-                               getconsxy(vc, con_buf0 + 2);
-
-                               con_buf_start += p;
-                               this_round += p;
-                               if (this_round > CON_BUF_SIZE) {
-                                       this_round = CON_BUF_SIZE;
-                                       orig_count = this_round - p;
-                               }
-
-                               tmp_count = HEADER_SIZE;
-                               if (tmp_count > this_round)
-                                       tmp_count = this_round;
-
-                               /* Advance state pointers and move on. */
-                               this_round -= tmp_count;
-                               p = HEADER_SIZE;
-                               con_buf0 = con_buf + HEADER_SIZE;
-                               /* If this_round >= 0, then p is even... */
-                       } else if (p & 1) {
-                               /* Skip first byte for output if start address is odd
-                                * Update region sizes up/down depending on free
-                                * space in buffer.
-                                */
-                               con_buf_start++;
-                               if (this_round < CON_BUF_SIZE)
-                                       this_round++;
-                               else
-                                       orig_count--;
-                       }
-                       if (this_round > 0) {
-                               unsigned short *tmp_buf = (unsigned short *)con_buf0;
-
-                               p -= HEADER_SIZE;
-                               p /= 2;
-                               col = p % maxcol;
-
-                               org = screen_pos(vc, p, viewed);
-                               p += maxcol - col;
-
-                               /* Buffer has even length, so we can always copy
-                                * character + attribute. We do not copy last byte
-                                * to userspace if this_round is odd.
-                                */
-                               this_round = (this_round + 1) >> 1;
-
-                               while (this_round) {
-                                       *tmp_buf++ = vcs_scr_readw(vc, org++);
-                                       this_round --;
-                                       if (++col == maxcol) {
-                                               org = screen_pos(vc, p, viewed);
-                                               col = 0;
-                                               p += maxcol;
-                                       }
-                               }
-                       }
-               }
-
-               /* Finally, release the console semaphore while we push
-                * all the data to userspace from our temporary buffer.
-                *
-                * AKPM: Even though it's a semaphore, we should drop it because
-                * the pagefault handling code may want to call printk().
-                */
-
-               release_console_sem();
-               ret = copy_to_user(buf, con_buf_start, orig_count);
-               acquire_console_sem();
-
-               if (ret) {
-                       read += (orig_count - ret);
-                       ret = -EFAULT;
-                       break;
-               }
-               buf += orig_count;
-               pos += orig_count;
-               read += orig_count;
-               count -= orig_count;
-       }
-       *ppos += read;
-       if (read)
-               ret = read;
-unlock_out:
-       release_console_sem();
-       mutex_unlock(&con_buf_mtx);
-       return ret;
-}
-
-static ssize_t
-vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
-{
-       struct inode *inode = file->f_path.dentry->d_inode;
-       unsigned int currcons = iminor(inode);
-       struct vc_data *vc;
-       long pos;
-       long viewed, attr, size, written;
-       char *con_buf0;
-       int col, maxcol;
-       u16 *org0 = NULL, *org = NULL;
-       size_t ret;
-
-       mutex_lock(&con_buf_mtx);
-
-       pos = *ppos;
-
-       /* Select the proper current console and verify
-        * sanity of the situation under the console lock.
-        */
-       acquire_console_sem();
-
-       attr = (currcons & 128);
-       currcons = (currcons & 127);
-
-       if (currcons == 0) {
-               currcons = fg_console;
-               viewed = 1;
-       } else {
-               currcons--;
-               viewed = 0;
-       }
-       ret = -ENXIO;
-       if (!vc_cons_allocated(currcons))
-               goto unlock_out;
-       vc = vc_cons[currcons].d;
-
-       size = vcs_size(inode);
-       ret = -EINVAL;
-       if (pos < 0 || pos > size)
-               goto unlock_out;
-       if (count > size - pos)
-               count = size - pos;
-       written = 0;
-       while (count) {
-               long this_round = count;
-               size_t orig_count;
-               long p;
-
-               if (this_round > CON_BUF_SIZE)
-                       this_round = CON_BUF_SIZE;
-
-               /* Temporarily drop the console lock so that we can read
-                * in the write data from userspace safely.
-                */
-               release_console_sem();
-               ret = copy_from_user(con_buf, buf, this_round);
-               acquire_console_sem();
-
-               if (ret) {
-                       this_round -= ret;
-                       if (!this_round) {
-                               /* Abort loop if no data were copied. Otherwise
-                                * fail with -EFAULT.
-                                */
-                               if (written)
-                                       break;
-                               ret = -EFAULT;
-                               goto unlock_out;
-                       }
-               }
-
-               /* The vcs_size might have changed while we slept to grab
-                * the user buffer, so recheck.
-                * Return data written up to now on failure.
-                */
-               size = vcs_size(inode);
-               if (pos >= size)
-                       break;
-               if (this_round > size - pos)
-                       this_round = size - pos;
-
-               /* OK, now actually push the write to the console
-                * under the lock using the local kernel buffer.
-                */
-
-               con_buf0 = con_buf;
-               orig_count = this_round;
-               maxcol = vc->vc_cols;
-               p = pos;
-               if (!attr) {
-                       org0 = org = screen_pos(vc, p, viewed);
-                       col = p % maxcol;
-                       p += maxcol - col;
-
-                       while (this_round > 0) {
-                               unsigned char c = *con_buf0++;
-
-                               this_round--;
-                               vcs_scr_writew(vc,
-                                              (vcs_scr_readw(vc, org) & 0xff00) | c, org);
-                               org++;
-                               if (++col == maxcol) {
-                                       org = screen_pos(vc, p, viewed);
-                                       col = 0;
-                                       p += maxcol;
-                               }
-                       }
-               } else {
-                       if (p < HEADER_SIZE) {
-                               char header[HEADER_SIZE];
-
-                               getconsxy(vc, header + 2);
-                               while (p < HEADER_SIZE && this_round > 0) {
-                                       this_round--;
-                                       header[p++] = *con_buf0++;
-                               }
-                               if (!viewed)
-                                       putconsxy(vc, header + 2);
-                       }
-                       p -= HEADER_SIZE;
-                       col = (p/2) % maxcol;
-                       if (this_round > 0) {
-                               org0 = org = screen_pos(vc, p/2, viewed);
-                               if ((p & 1) && this_round > 0) {
-                                       char c;
-
-                                       this_round--;
-                                       c = *con_buf0++;
-#ifdef __BIG_ENDIAN
-                                       vcs_scr_writew(vc, c |
-                                            (vcs_scr_readw(vc, org) & 0xff00), org);
-#else
-                                       vcs_scr_writew(vc, (c << 8) |
-                                            (vcs_scr_readw(vc, org) & 0xff), org);
-#endif
-                                       org++;
-                                       p++;
-                                       if (++col == maxcol) {
-                                               org = screen_pos(vc, p/2, viewed);
-                                               col = 0;
-                                       }
-                               }
-                               p /= 2;
-                               p += maxcol - col;
-                       }
-                       while (this_round > 1) {
-                               unsigned short w;
-
-                               w = get_unaligned(((unsigned short *)con_buf0));
-                               vcs_scr_writew(vc, w, org++);
-                               con_buf0 += 2;
-                               this_round -= 2;
-                               if (++col == maxcol) {
-                                       org = screen_pos(vc, p, viewed);
-                                       col = 0;
-                                       p += maxcol;
-                               }
-                       }
-                       if (this_round > 0) {
-                               unsigned char c;
-
-                               c = *con_buf0++;
-#ifdef __BIG_ENDIAN
-                               vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org);
-#else
-                               vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org);
-#endif
-                       }
-               }
-               count -= orig_count;
-               written += orig_count;
-               buf += orig_count;
-               pos += orig_count;
-               if (org0)
-                       update_region(vc, (unsigned long)(org0), org - org0);
-       }
-       *ppos += written;
-       ret = written;
-       if (written)
-               vcs_scr_updated(vc);
-
-unlock_out:
-       release_console_sem();
-
-       mutex_unlock(&con_buf_mtx);
-
-       return ret;
-}
-
-static unsigned int
-vcs_poll(struct file *file, poll_table *wait)
-{
-       struct vcs_poll_data *poll = vcs_poll_data_get(file);
-       int ret = 0;
-
-       if (poll) {
-               poll_wait(file, &poll->waitq, wait);
-               if (!poll->seen_last_update)
-                       ret = POLLIN | POLLRDNORM;
-       }
-       return ret;
-}
-
-static int
-vcs_fasync(int fd, struct file *file, int on)
-{
-       struct vcs_poll_data *poll = file->private_data;
-
-       if (!poll) {
-               /* don't allocate anything if all we want is disable fasync */
-               if (!on)
-                       return 0;
-               poll = vcs_poll_data_get(file);
-               if (!poll)
-                       return -ENOMEM;
-       }
-
-       return fasync_helper(fd, file, on, &poll->fasync);
-}
-
-static int
-vcs_open(struct inode *inode, struct file *filp)
-{
-       unsigned int currcons = iminor(inode) & 127;
-       int ret = 0;
-       
-       tty_lock();
-       if(currcons && !vc_cons_allocated(currcons-1))
-               ret = -ENXIO;
-       tty_unlock();
-       return ret;
-}
-
-static int vcs_release(struct inode *inode, struct file *file)
-{
-       struct vcs_poll_data *poll = file->private_data;
-
-       if (poll)
-               vcs_poll_data_free(poll);
-       return 0;
-}
-
-static const struct file_operations vcs_fops = {
-       .llseek         = vcs_lseek,
-       .read           = vcs_read,
-       .write          = vcs_write,
-       .poll           = vcs_poll,
-       .fasync         = vcs_fasync,
-       .open           = vcs_open,
-       .release        = vcs_release,
-};
-
-static struct class *vc_class;
-
-void vcs_make_sysfs(int index)
-{
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL,
-                     "vcs%u", index + 1);
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL,
-                     "vcsa%u", index + 1);
-}
-
-void vcs_remove_sysfs(int index)
-{
-       device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1));
-       device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129));
-}
-
-int __init vcs_init(void)
-{
-       unsigned int i;
-
-       if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
-               panic("unable to get major %d for vcs device", VCS_MAJOR);
-       vc_class = class_create(THIS_MODULE, "vc");
-
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
-       for (i = 0; i < MIN_NR_CONSOLES; i++)
-               vcs_make_sysfs(i);
-       return 0;
-}
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
deleted file mode 100644 (file)
index a8ec48e..0000000
+++ /dev/null
@@ -1,4209 +0,0 @@
-/*
- *  linux/drivers/char/vt.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-/*
- * Hopefully this will be a rather complete VT102 implementation.
- *
- * Beeping thanks to John T Kohl.
- *
- * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
- *   Chars, and VT100 enhancements by Peter MacDonald.
- *
- * Copy and paste function by Andrew Haylett,
- *   some enhancements by Alessandro Rubini.
- *
- * Code to check for different video-cards mostly by Galen Hunt,
- * <g-hunt@ee.utah.edu>
- *
- * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
- * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
- *
- * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
- * Resizing of consoles, aeb, 940926
- *
- * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
- * <poe@daimi.aau.dk>
- *
- * User-defined bell sound, new setterm control sequences and printk
- * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
- *
- * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp>
- *
- * Merge with the abstract console driver by Geert Uytterhoeven
- * <geert@linux-m68k.org>, Jan 1997.
- *
- *   Original m68k console driver modifications by
- *
- *     - Arno Griffioen <arno@usn.nl>
- *     - David Carter <carter@cs.bris.ac.uk>
- * 
- *   The abstract console driver provides a generic interface for a text
- *   console. It supports VGA text mode, frame buffer based graphical consoles
- *   and special graphics processors that are only accessible through some
- *   registers (e.g. a TMS340x0 GSP).
- *
- *   The interface to the hardware is specified using a special structure
- *   (struct consw) which contains function pointers to console operations
- *   (see <linux/console.h> for more information).
- *
- * Support for changeable cursor shape
- * by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>, August 1997
- *
- * Ported to i386 and con_scrolldelta fixed
- * by Emmanuel Marty <core@ggi-project.org>, April 1998
- *
- * Resurrected character buffers in videoram plus lots of other trickery
- * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998
- *
- * Removed old-style timers, introduced console_timer, made timer
- * deletion SMP-safe.  17Jun00, Andrew Morton
- *
- * Removed console_lock, enabled interrupts across all console operations
- * 13 March 2001, Andrew Morton
- *
- * Fixed UTF-8 mode so alternate charset modes always work according
- * to control sequences interpreted in do_con_trol function
- * preserving backward VT100 semigraphics compatibility,
- * malformed UTF sequences represented as sequences of replacement glyphs,
- * original codes or '?' as a last resort if replacement glyph is undefined
- * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/kd.h>
-#include <linux/slab.h>
-#include <linux/major.h>
-#include <linux/mm.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/smp_lock.h>
-#include <linux/tiocl.h>
-#include <linux/kbd_kern.h>
-#include <linux/consolemap.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/pm.h>
-#include <linux/font.h>
-#include <linux/bitops.h>
-#include <linux/notifier.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <asm/system.h>
-#include <linux/uaccess.h>
-#include <linux/kdb.h>
-#include <linux/ctype.h>
-
-#define MAX_NR_CON_DRIVER 16
-
-#define CON_DRIVER_FLAG_MODULE 1
-#define CON_DRIVER_FLAG_INIT   2
-#define CON_DRIVER_FLAG_ATTR   4
-
-struct con_driver {
-       const struct consw *con;
-       const char *desc;
-       struct device *dev;
-       int node;
-       int first;
-       int last;
-       int flag;
-};
-
-static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
-const struct consw *conswitchp;
-
-/* A bitmap for codes <32. A bit of 1 indicates that the code
- * corresponding to that bit number invokes some special action
- * (such as cursor movement) and should not be displayed as a
- * glyph unless the disp_ctrl mode is explicitly enabled.
- */
-#define CTRL_ACTION 0x0d00ff81
-#define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */
-
-/*
- * Here is the default bell parameters: 750HZ, 1/8th of a second
- */
-#define DEFAULT_BELL_PITCH     750
-#define DEFAULT_BELL_DURATION  (HZ/8)
-
-struct vc vc_cons [MAX_NR_CONSOLES];
-
-#ifndef VT_SINGLE_DRIVER
-static const struct consw *con_driver_map[MAX_NR_CONSOLES];
-#endif
-
-static int con_open(struct tty_struct *, struct file *);
-static void vc_init(struct vc_data *vc, unsigned int rows,
-                   unsigned int cols, int do_clear);
-static void gotoxy(struct vc_data *vc, int new_x, int new_y);
-static void save_cur(struct vc_data *vc);
-static void reset_terminal(struct vc_data *vc, int do_clear);
-static void con_flush_chars(struct tty_struct *tty);
-static int set_vesa_blanking(char __user *p);
-static void set_cursor(struct vc_data *vc);
-static void hide_cursor(struct vc_data *vc);
-static void console_callback(struct work_struct *ignored);
-static void blank_screen_t(unsigned long dummy);
-static void set_palette(struct vc_data *vc);
-
-static int printable;          /* Is console ready for printing? */
-int default_utf8 = true;
-module_param(default_utf8, int, S_IRUGO | S_IWUSR);
-int global_cursor_default = -1;
-module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
-
-static int cur_default = CUR_DEFAULT;
-module_param(cur_default, int, S_IRUGO | S_IWUSR);
-
-/*
- * ignore_poke: don't unblank the screen when things are typed.  This is
- * mainly for the privacy of braille terminal users.
- */
-static int ignore_poke;
-
-int do_poke_blanked_console;
-int console_blanked;
-
-static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
-static int vesa_off_interval;
-static int blankinterval = 10*60;
-core_param(consoleblank, blankinterval, int, 0444);
-
-static DECLARE_WORK(console_work, console_callback);
-
-/*
- * fg_console is the current virtual console,
- * last_console is the last used one,
- * want_console is the console we want to switch to,
- * saved_* variants are for save/restore around kernel debugger enter/leave
- */
-int fg_console;
-int last_console;
-int want_console = -1;
-static int saved_fg_console;
-static int saved_last_console;
-static int saved_want_console;
-static int saved_vc_mode;
-static int saved_console_blanked;
-
-/*
- * For each existing display, we have a pointer to console currently visible
- * on that display, allowing consoles other than fg_console to be refreshed
- * appropriately. Unless the low-level driver supplies its own display_fg
- * variable, we use this one for the "master display".
- */
-static struct vc_data *master_display_fg;
-
-/*
- * Unfortunately, we need to delay tty echo when we're currently writing to the
- * console since the code is (and always was) not re-entrant, so we schedule
- * all flip requests to process context with schedule-task() and run it from
- * console_callback().
- */
-
-/*
- * For the same reason, we defer scrollback to the console callback.
- */
-static int scrollback_delta;
-
-/*
- * Hook so that the power management routines can (un)blank
- * the console on our behalf.
- */
-int (*console_blank_hook)(int);
-
-static DEFINE_TIMER(console_timer, blank_screen_t, 0, 0);
-static int blank_state;
-static int blank_timer_expired;
-enum {
-       blank_off = 0,
-       blank_normal_wait,
-       blank_vesa_wait,
-};
-
-/*
- * Notifier list for console events.
- */
-static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
-
-int register_vt_notifier(struct notifier_block *nb)
-{
-       return atomic_notifier_chain_register(&vt_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(register_vt_notifier);
-
-int unregister_vt_notifier(struct notifier_block *nb)
-{
-       return atomic_notifier_chain_unregister(&vt_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_vt_notifier);
-
-static void notify_write(struct vc_data *vc, unsigned int unicode)
-{
-       struct vt_notifier_param param = { .vc = vc, unicode = unicode };
-       atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
-}
-
-static void notify_update(struct vc_data *vc)
-{
-       struct vt_notifier_param param = { .vc = vc };
-       atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
-}
-/*
- *     Low-Level Functions
- */
-
-#define IS_FG(vc)      ((vc)->vc_num == fg_console)
-
-#ifdef VT_BUF_VRAM_ONLY
-#define DO_UPDATE(vc)  0
-#else
-#define DO_UPDATE(vc)  (CON_IS_VISIBLE(vc) && !console_blanked)
-#endif
-
-static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
-{
-       unsigned short *p;
-       
-       if (!viewed)
-               p = (unsigned short *)(vc->vc_origin + offset);
-       else if (!vc->vc_sw->con_screen_pos)
-               p = (unsigned short *)(vc->vc_visible_origin + offset);
-       else
-               p = vc->vc_sw->con_screen_pos(vc, offset);
-       return p;
-}
-
-/* Called  from the keyboard irq path.. */
-static inline void scrolldelta(int lines)
-{
-       /* FIXME */
-       /* scrolldelta needs some kind of consistency lock, but the BKL was
-          and still is not protecting versus the scheduled back end */
-       scrollback_delta += lines;
-       schedule_console_callback();
-}
-
-void schedule_console_callback(void)
-{
-       schedule_work(&console_work);
-}
-
-static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
-{
-       unsigned short *d, *s;
-
-       if (t+nr >= b)
-               nr = b - t - 1;
-       if (b > vc->vc_rows || t >= b || nr < 1)
-               return;
-       if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr))
-               return;
-       d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
-       s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr));
-       scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);
-       scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char,
-                   vc->vc_size_row * nr);
-}
-
-static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
-{
-       unsigned short *s;
-       unsigned int step;
-
-       if (t+nr >= b)
-               nr = b - t - 1;
-       if (b > vc->vc_rows || t >= b || nr < 1)
-               return;
-       if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr))
-               return;
-       s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
-       step = vc->vc_cols * nr;
-       scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row);
-       scr_memsetw(s, vc->vc_video_erase_char, 2 * step);
-}
-
-static void do_update_region(struct vc_data *vc, unsigned long start, int count)
-{
-#ifndef VT_BUF_VRAM_ONLY
-       unsigned int xx, yy, offset;
-       u16 *p;
-
-       p = (u16 *) start;
-       if (!vc->vc_sw->con_getxy) {
-               offset = (start - vc->vc_origin) / 2;
-               xx = offset % vc->vc_cols;
-               yy = offset / vc->vc_cols;
-       } else {
-               int nxx, nyy;
-               start = vc->vc_sw->con_getxy(vc, start, &nxx, &nyy);
-               xx = nxx; yy = nyy;
-       }
-       for(;;) {
-               u16 attrib = scr_readw(p) & 0xff00;
-               int startx = xx;
-               u16 *q = p;
-               while (xx < vc->vc_cols && count) {
-                       if (attrib != (scr_readw(p) & 0xff00)) {
-                               if (p > q)
-                                       vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
-                               startx = xx;
-                               q = p;
-                               attrib = scr_readw(p) & 0xff00;
-                       }
-                       p++;
-                       xx++;
-                       count--;
-               }
-               if (p > q)
-                       vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
-               if (!count)
-                       break;
-               xx = 0;
-               yy++;
-               if (vc->vc_sw->con_getxy) {
-                       p = (u16 *)start;
-                       start = vc->vc_sw->con_getxy(vc, start, NULL, NULL);
-               }
-       }
-#endif
-}
-
-void update_region(struct vc_data *vc, unsigned long start, int count)
-{
-       WARN_CONSOLE_UNLOCKED();
-
-       if (DO_UPDATE(vc)) {
-               hide_cursor(vc);
-               do_update_region(vc, start, count);
-               set_cursor(vc);
-       }
-}
-
-/* Structure of attributes is hardware-dependent */
-
-static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
-    u8 _underline, u8 _reverse, u8 _italic)
-{
-       if (vc->vc_sw->con_build_attr)
-               return vc->vc_sw->con_build_attr(vc, _color, _intensity,
-                      _blink, _underline, _reverse, _italic);
-
-#ifndef VT_BUF_VRAM_ONLY
-/*
- * ++roman: I completely changed the attribute format for monochrome
- * mode (!can_do_color). The formerly used MDA (monochrome display
- * adapter) format didn't allow the combination of certain effects.
- * Now the attribute is just a bit vector:
- *  Bit 0..1: intensity (0..2)
- *  Bit 2   : underline
- *  Bit 3   : reverse
- *  Bit 7   : blink
- */
-       {
-       u8 a = _color;
-       if (!vc->vc_can_do_color)
-               return _intensity |
-                      (_italic ? 2 : 0) |
-                      (_underline ? 4 : 0) |
-                      (_reverse ? 8 : 0) |
-                      (_blink ? 0x80 : 0);
-       if (_italic)
-               a = (a & 0xF0) | vc->vc_itcolor;
-       else if (_underline)
-               a = (a & 0xf0) | vc->vc_ulcolor;
-       else if (_intensity == 0)
-               a = (a & 0xf0) | vc->vc_ulcolor;
-       if (_reverse)
-               a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77);
-       if (_blink)
-               a ^= 0x80;
-       if (_intensity == 2)
-               a ^= 0x08;
-       if (vc->vc_hi_font_mask == 0x100)
-               a <<= 1;
-       return a;
-       }
-#else
-       return 0;
-#endif
-}
-
-static void update_attr(struct vc_data *vc)
-{
-       vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
-                     vc->vc_blink, vc->vc_underline,
-                     vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
-       vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
-}
-
-/* Note: inverting the screen twice should revert to the original state */
-void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
-{
-       unsigned short *p;
-
-       WARN_CONSOLE_UNLOCKED();
-
-       count /= 2;
-       p = screenpos(vc, offset, viewed);
-       if (vc->vc_sw->con_invert_region)
-               vc->vc_sw->con_invert_region(vc, p, count);
-#ifndef VT_BUF_VRAM_ONLY
-       else {
-               u16 *q = p;
-               int cnt = count;
-               u16 a;
-
-               if (!vc->vc_can_do_color) {
-                       while (cnt--) {
-                           a = scr_readw(q);
-                           a ^= 0x0800;
-                           scr_writew(a, q);
-                           q++;
-                       }
-               } else if (vc->vc_hi_font_mask == 0x100) {
-                       while (cnt--) {
-                               a = scr_readw(q);
-                               a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
-                               scr_writew(a, q);
-                               q++;
-                       }
-               } else {
-                       while (cnt--) {
-                               a = scr_readw(q);
-                               a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
-                               scr_writew(a, q);
-                               q++;
-                       }
-               }
-       }
-#endif
-       if (DO_UPDATE(vc))
-               do_update_region(vc, (unsigned long) p, count);
-}
-
-/* used by selection: complement pointer position */
-void complement_pos(struct vc_data *vc, int offset)
-{
-       static int old_offset = -1;
-       static unsigned short old;
-       static unsigned short oldx, oldy;
-
-       WARN_CONSOLE_UNLOCKED();
-
-       if (old_offset != -1 && old_offset >= 0 &&
-           old_offset < vc->vc_screenbuf_size) {
-               scr_writew(old, screenpos(vc, old_offset, 1));
-               if (DO_UPDATE(vc))
-                       vc->vc_sw->con_putc(vc, old, oldy, oldx);
-       }
-
-       old_offset = offset;
-
-       if (offset != -1 && offset >= 0 &&
-           offset < vc->vc_screenbuf_size) {
-               unsigned short new;
-               unsigned short *p;
-               p = screenpos(vc, offset, 1);
-               old = scr_readw(p);
-               new = old ^ vc->vc_complement_mask;
-               scr_writew(new, p);
-               if (DO_UPDATE(vc)) {
-                       oldx = (offset >> 1) % vc->vc_cols;
-                       oldy = (offset >> 1) / vc->vc_cols;
-                       vc->vc_sw->con_putc(vc, new, oldy, oldx);
-               }
-       }
-
-}
-
-static void insert_char(struct vc_data *vc, unsigned int nr)
-{
-       unsigned short *p, *q = (unsigned short *)vc->vc_pos;
-
-       p = q + vc->vc_cols - nr - vc->vc_x;
-       while (--p >= q)
-               scr_writew(scr_readw(p), p + nr);
-       scr_memsetw(q, vc->vc_video_erase_char, nr * 2);
-       vc->vc_need_wrap = 0;
-       if (DO_UPDATE(vc)) {
-               unsigned short oldattr = vc->vc_attr;
-               vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1,
-                                    vc->vc_cols - vc->vc_x - nr);
-               vc->vc_attr = vc->vc_video_erase_char >> 8;
-               while (nr--)
-                       vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr);
-               vc->vc_attr = oldattr;
-       }
-}
-
-static void delete_char(struct vc_data *vc, unsigned int nr)
-{
-       unsigned int i = vc->vc_x;
-       unsigned short *p = (unsigned short *)vc->vc_pos;
-
-       while (++i <= vc->vc_cols - nr) {
-               scr_writew(scr_readw(p+nr), p);
-               p++;
-       }
-       scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
-       vc->vc_need_wrap = 0;
-       if (DO_UPDATE(vc)) {
-               unsigned short oldattr = vc->vc_attr;
-               vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1,
-                                    vc->vc_cols - vc->vc_x - nr);
-               vc->vc_attr = vc->vc_video_erase_char >> 8;
-               while (nr--)
-                       vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y,
-                                    vc->vc_cols - 1 - nr);
-               vc->vc_attr = oldattr;
-       }
-}
-
-static int softcursor_original;
-
-static void add_softcursor(struct vc_data *vc)
-{
-       int i = scr_readw((u16 *) vc->vc_pos);
-       u32 type = vc->vc_cursor_type;
-
-       if (! (type & 0x10)) return;
-       if (softcursor_original != -1) return;
-       softcursor_original = i;
-       i |= ((type >> 8) & 0xff00 );
-       i ^= ((type) & 0xff00 );
-       if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
-       if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
-       scr_writew(i, (u16 *) vc->vc_pos);
-       if (DO_UPDATE(vc))
-               vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
-}
-
-static void hide_softcursor(struct vc_data *vc)
-{
-       if (softcursor_original != -1) {
-               scr_writew(softcursor_original, (u16 *)vc->vc_pos);
-               if (DO_UPDATE(vc))
-                       vc->vc_sw->con_putc(vc, softcursor_original,
-                                       vc->vc_y, vc->vc_x);
-               softcursor_original = -1;
-       }
-}
-
-static void hide_cursor(struct vc_data *vc)
-{
-       if (vc == sel_cons)
-               clear_selection();
-       vc->vc_sw->con_cursor(vc, CM_ERASE);
-       hide_softcursor(vc);
-}
-
-static void set_cursor(struct vc_data *vc)
-{
-       if (!IS_FG(vc) || console_blanked ||
-           vc->vc_mode == KD_GRAPHICS)
-               return;
-       if (vc->vc_deccm) {
-               if (vc == sel_cons)
-                       clear_selection();
-               add_softcursor(vc);
-               if ((vc->vc_cursor_type & 0x0f) != 1)
-                       vc->vc_sw->con_cursor(vc, CM_DRAW);
-       } else
-               hide_cursor(vc);
-}
-
-static void set_origin(struct vc_data *vc)
-{
-       WARN_CONSOLE_UNLOCKED();
-
-       if (!CON_IS_VISIBLE(vc) ||
-           !vc->vc_sw->con_set_origin ||
-           !vc->vc_sw->con_set_origin(vc))
-               vc->vc_origin = (unsigned long)vc->vc_screenbuf;
-       vc->vc_visible_origin = vc->vc_origin;
-       vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
-       vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
-}
-
-static inline void save_screen(struct vc_data *vc)
-{
-       WARN_CONSOLE_UNLOCKED();
-
-       if (vc->vc_sw->con_save_screen)
-               vc->vc_sw->con_save_screen(vc);
-}
-
-/*
- *     Redrawing of screen
- */
-
-static void clear_buffer_attributes(struct vc_data *vc)
-{
-       unsigned short *p = (unsigned short *)vc->vc_origin;
-       int count = vc->vc_screenbuf_size / 2;
-       int mask = vc->vc_hi_font_mask | 0xff;
-
-       for (; count > 0; count--, p++) {
-               scr_writew((scr_readw(p)&mask) | (vc->vc_video_erase_char & ~mask), p);
-       }
-}
-
-void redraw_screen(struct vc_data *vc, int is_switch)
-{
-       int redraw = 0;
-
-       WARN_CONSOLE_UNLOCKED();
-
-       if (!vc) {
-               /* strange ... */
-               /* printk("redraw_screen: tty %d not allocated ??\n", new_console+1); */
-               return;
-       }
-
-       if (is_switch) {
-               struct vc_data *old_vc = vc_cons[fg_console].d;
-               if (old_vc == vc)
-                       return;
-               if (!CON_IS_VISIBLE(vc))
-                       redraw = 1;
-               *vc->vc_display_fg = vc;
-               fg_console = vc->vc_num;
-               hide_cursor(old_vc);
-               if (!CON_IS_VISIBLE(old_vc)) {
-                       save_screen(old_vc);
-                       set_origin(old_vc);
-               }
-       } else {
-               hide_cursor(vc);
-               redraw = 1;
-       }
-
-       if (redraw) {
-               int update;
-               int old_was_color = vc->vc_can_do_color;
-
-               set_origin(vc);
-               update = vc->vc_sw->con_switch(vc);
-               set_palette(vc);
-               /*
-                * If console changed from mono<->color, the best we can do
-                * is to clear the buffer attributes. As it currently stands,
-                * rebuilding new attributes from the old buffer is not doable
-                * without overly complex code.
-                */
-               if (old_was_color != vc->vc_can_do_color) {
-                       update_attr(vc);
-                       clear_buffer_attributes(vc);
-               }
-
-               /* Forcibly update if we're panicing */
-               if ((update && vc->vc_mode != KD_GRAPHICS) ||
-                   vt_force_oops_output(vc))
-                       do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
-       }
-       set_cursor(vc);
-       if (is_switch) {
-               set_leds();
-               compute_shiftstate();
-               notify_update(vc);
-       }
-}
-
-/*
- *     Allocation, freeing and resizing of VTs.
- */
-
-int vc_cons_allocated(unsigned int i)
-{
-       return (i < MAX_NR_CONSOLES && vc_cons[i].d);
-}
-
-static void visual_init(struct vc_data *vc, int num, int init)
-{
-       /* ++Geert: vc->vc_sw->con_init determines console size */
-       if (vc->vc_sw)
-               module_put(vc->vc_sw->owner);
-       vc->vc_sw = conswitchp;
-#ifndef VT_SINGLE_DRIVER
-       if (con_driver_map[num])
-               vc->vc_sw = con_driver_map[num];
-#endif
-       __module_get(vc->vc_sw->owner);
-       vc->vc_num = num;
-       vc->vc_display_fg = &master_display_fg;
-       vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;
-       vc->vc_uni_pagedir = 0;
-       vc->vc_hi_font_mask = 0;
-       vc->vc_complement_mask = 0;
-       vc->vc_can_do_color = 0;
-       vc->vc_panic_force_write = false;
-       vc->vc_sw->con_init(vc, init);
-       if (!vc->vc_complement_mask)
-               vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
-       vc->vc_s_complement_mask = vc->vc_complement_mask;
-       vc->vc_size_row = vc->vc_cols << 1;
-       vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
-}
-
-int vc_allocate(unsigned int currcons) /* return 0 on success */
-{
-       WARN_CONSOLE_UNLOCKED();
-
-       if (currcons >= MAX_NR_CONSOLES)
-               return -ENXIO;
-       if (!vc_cons[currcons].d) {
-           struct vc_data *vc;
-           struct vt_notifier_param param;
-
-           /* prevent users from taking too much memory */
-           if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
-             return -EPERM;
-
-           /* due to the granularity of kmalloc, we waste some memory here */
-           /* the alloc is done in two steps, to optimize the common situation
-              of a 25x80 console (structsize=216, screenbuf_size=4000) */
-           /* although the numbers above are not valid since long ago, the
-              point is still up-to-date and the comment still has its value
-              even if only as a historical artifact.  --mj, July 1998 */
-           param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
-           if (!vc)
-               return -ENOMEM;
-           vc_cons[currcons].d = vc;
-           tty_port_init(&vc->port);
-           INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
-           visual_init(vc, currcons, 1);
-           if (!*vc->vc_uni_pagedir_loc)
-               con_set_default_unimap(vc);
-           vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
-           if (!vc->vc_screenbuf) {
-               kfree(vc);
-               vc_cons[currcons].d = NULL;
-               return -ENOMEM;
-           }
-
-           /* If no drivers have overridden us and the user didn't pass a
-              boot option, default to displaying the cursor */
-           if (global_cursor_default == -1)
-                   global_cursor_default = 1;
-
-           vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
-           vcs_make_sysfs(currcons);
-           atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
-       }
-       return 0;
-}
-
-static inline int resize_screen(struct vc_data *vc, int width, int height,
-                               int user)
-{
-       /* Resizes the resolution of the display adapater */
-       int err = 0;
-
-       if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
-               err = vc->vc_sw->con_resize(vc, width, height, user);
-
-       return err;
-}
-
-/*
- * Change # of rows and columns (0 means unchanged/the size of fg_console)
- * [this is to be used together with some user program
- * like resize that changes the hardware videomode]
- */
-#define VC_RESIZE_MAXCOL (32767)
-#define VC_RESIZE_MAXROW (32767)
-
-/**
- *     vc_do_resize    -       resizing method for the tty
- *     @tty: tty being resized
- *     @real_tty: real tty (different to tty if a pty/tty pair)
- *     @vc: virtual console private data
- *     @cols: columns
- *     @lines: lines
- *
- *     Resize a virtual console, clipping according to the actual constraints.
- *     If the caller passes a tty structure then update the termios winsize
- *     information and perform any necessary signal handling.
- *
- *     Caller must hold the console semaphore. Takes the termios mutex and
- *     ctrl_lock of the tty IFF a tty is passed.
- */
-
-static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
-                               unsigned int cols, unsigned int lines)
-{
-       unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
-       unsigned long end;
-       unsigned int old_cols, old_rows, old_row_size, old_screen_size;
-       unsigned int new_cols, new_rows, new_row_size, new_screen_size;
-       unsigned int user;
-       unsigned short *newscreen;
-
-       WARN_CONSOLE_UNLOCKED();
-
-       if (!vc)
-               return -ENXIO;
-
-       user = vc->vc_resize_user;
-       vc->vc_resize_user = 0;
-
-       if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
-               return -EINVAL;
-
-       new_cols = (cols ? cols : vc->vc_cols);
-       new_rows = (lines ? lines : vc->vc_rows);
-       new_row_size = new_cols << 1;
-       new_screen_size = new_row_size * new_rows;
-
-       if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
-               return 0;
-
-       newscreen = kmalloc(new_screen_size, GFP_USER);
-       if (!newscreen)
-               return -ENOMEM;
-
-       old_rows = vc->vc_rows;
-       old_cols = vc->vc_cols;
-       old_row_size = vc->vc_size_row;
-       old_screen_size = vc->vc_screenbuf_size;
-
-       err = resize_screen(vc, new_cols, new_rows, user);
-       if (err) {
-               kfree(newscreen);
-               return err;
-       }
-
-       vc->vc_rows = new_rows;
-       vc->vc_cols = new_cols;
-       vc->vc_size_row = new_row_size;
-       vc->vc_screenbuf_size = new_screen_size;
-
-       rlth = min(old_row_size, new_row_size);
-       rrem = new_row_size - rlth;
-       old_origin = vc->vc_origin;
-       new_origin = (long) newscreen;
-       new_scr_end = new_origin + new_screen_size;
-
-       if (vc->vc_y > new_rows) {
-               if (old_rows - vc->vc_y < new_rows) {
-                       /*
-                        * Cursor near the bottom, copy contents from the
-                        * bottom of buffer
-                        */
-                       old_origin += (old_rows - new_rows) * old_row_size;
-               } else {
-                       /*
-                        * Cursor is in no man's land, copy 1/2 screenful
-                        * from the top and bottom of cursor position
-                        */
-                       old_origin += (vc->vc_y - new_rows/2) * old_row_size;
-               }
-       }
-
-       end = old_origin + old_row_size * min(old_rows, new_rows);
-
-       update_attr(vc);
-
-       while (old_origin < end) {
-               scr_memcpyw((unsigned short *) new_origin,
-                           (unsigned short *) old_origin, rlth);
-               if (rrem)
-                       scr_memsetw((void *)(new_origin + rlth),
-                                   vc->vc_video_erase_char, rrem);
-               old_origin += old_row_size;
-               new_origin += new_row_size;
-       }
-       if (new_scr_end > new_origin)
-               scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
-                           new_scr_end - new_origin);
-       kfree(vc->vc_screenbuf);
-       vc->vc_screenbuf = newscreen;
-       vc->vc_screenbuf_size = new_screen_size;
-       set_origin(vc);
-
-       /* do part of a reset_terminal() */
-       vc->vc_top = 0;
-       vc->vc_bottom = vc->vc_rows;
-       gotoxy(vc, vc->vc_x, vc->vc_y);
-       save_cur(vc);
-
-       if (tty) {
-               /* Rewrite the requested winsize data with the actual
-                  resulting sizes */
-               struct winsize ws;
-               memset(&ws, 0, sizeof(ws));
-               ws.ws_row = vc->vc_rows;
-               ws.ws_col = vc->vc_cols;
-               ws.ws_ypixel = vc->vc_scan_lines;
-               tty_do_resize(tty, &ws);
-       }
-
-       if (CON_IS_VISIBLE(vc))
-               update_screen(vc);
-       vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
-       return err;
-}
-
-/**
- *     vc_resize               -       resize a VT
- *     @vc: virtual console
- *     @cols: columns
- *     @rows: rows
- *
- *     Resize a virtual console as seen from the console end of things. We
- *     use the common vc_do_resize methods to update the structures. The
- *     caller must hold the console sem to protect console internals and
- *     vc->port.tty
- */
-
-int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
-{
-       return vc_do_resize(vc->port.tty, vc, cols, rows);
-}
-
-/**
- *     vt_resize               -       resize a VT
- *     @tty: tty to resize
- *     @ws: winsize attributes
- *
- *     Resize a virtual terminal. This is called by the tty layer as we
- *     register our own handler for resizing. The mutual helper does all
- *     the actual work.
- *
- *     Takes the console sem and the called methods then take the tty
- *     termios_mutex and the tty ctrl_lock in that order.
- */
-static int vt_resize(struct tty_struct *tty, struct winsize *ws)
-{
-       struct vc_data *vc = tty->driver_data;
-       int ret;
-
-       acquire_console_sem();
-       ret = vc_do_resize(tty, vc, ws->ws_col, ws->ws_row);
-       release_console_sem();
-       return ret;
-}
-
-void vc_deallocate(unsigned int currcons)
-{
-       WARN_CONSOLE_UNLOCKED();
-
-       if (vc_cons_allocated(currcons)) {
-               struct vc_data *vc = vc_cons[currcons].d;
-               struct vt_notifier_param param = { .vc = vc };
-
-               atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
-               vcs_remove_sysfs(currcons);
-               vc->vc_sw->con_deinit(vc);
-               put_pid(vc->vt_pid);
-               module_put(vc->vc_sw->owner);
-               kfree(vc->vc_screenbuf);
-               if (currcons >= MIN_NR_CONSOLES)
-                       kfree(vc);
-               vc_cons[currcons].d = NULL;
-       }
-}
-
-/*
- *     VT102 emulator
- */
-
-#define set_kbd(vc, x) set_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
-#define clr_kbd(vc, x) clr_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
-#define is_kbd(vc, x)  vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
-
-#define decarm         VC_REPEAT
-#define decckm         VC_CKMODE
-#define kbdapplic      VC_APPLIC
-#define lnm            VC_CRLF
-
-/*
- * this is what the terminal answers to a ESC-Z or csi0c query.
- */
-#define VT100ID "\033[?1;2c"
-#define VT102ID "\033[?6c"
-
-unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
-                                      8,12,10,14, 9,13,11,15 };
-
-/* the default colour table, for VGA+ colour systems */
-int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
-    0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
-int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
-    0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
-int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
-    0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
-
-module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR);
-module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR);
-module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR);
-
-/*
- * gotoxy() must verify all boundaries, because the arguments
- * might also be negative. If the given position is out of
- * bounds, the cursor is placed at the nearest margin.
- */
-static void gotoxy(struct vc_data *vc, int new_x, int new_y)
-{
-       int min_y, max_y;
-
-       if (new_x < 0)
-               vc->vc_x = 0;
-       else {
-               if (new_x >= vc->vc_cols)
-                       vc->vc_x = vc->vc_cols - 1;
-               else
-                       vc->vc_x = new_x;
-       }
-
-       if (vc->vc_decom) {
-               min_y = vc->vc_top;
-               max_y = vc->vc_bottom;
-       } else {
-               min_y = 0;
-               max_y = vc->vc_rows;
-       }
-       if (new_y < min_y)
-               vc->vc_y = min_y;
-       else if (new_y >= max_y)
-               vc->vc_y = max_y - 1;
-       else
-               vc->vc_y = new_y;
-       vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
-       vc->vc_need_wrap = 0;
-}
-
-/* for absolute user moves, when decom is set */
-static void gotoxay(struct vc_data *vc, int new_x, int new_y)
-{
-       gotoxy(vc, new_x, vc->vc_decom ? (vc->vc_top + new_y) : new_y);
-}
-
-void scrollback(struct vc_data *vc, int lines)
-{
-       if (!lines)
-               lines = vc->vc_rows / 2;
-       scrolldelta(-lines);
-}
-
-void scrollfront(struct vc_data *vc, int lines)
-{
-       if (!lines)
-               lines = vc->vc_rows / 2;
-       scrolldelta(lines);
-}
-
-static void lf(struct vc_data *vc)
-{
-       /* don't scroll if above bottom of scrolling region, or
-        * if below scrolling region
-        */
-       if (vc->vc_y + 1 == vc->vc_bottom)
-               scrup(vc, vc->vc_top, vc->vc_bottom, 1);
-       else if (vc->vc_y < vc->vc_rows - 1) {
-               vc->vc_y++;
-               vc->vc_pos += vc->vc_size_row;
-       }
-       vc->vc_need_wrap = 0;
-       notify_write(vc, '\n');
-}
-
-static void ri(struct vc_data *vc)
-{
-       /* don't scroll if below top of scrolling region, or
-        * if above scrolling region
-        */
-       if (vc->vc_y == vc->vc_top)
-               scrdown(vc, vc->vc_top, vc->vc_bottom, 1);
-       else if (vc->vc_y > 0) {
-               vc->vc_y--;
-               vc->vc_pos -= vc->vc_size_row;
-       }
-       vc->vc_need_wrap = 0;
-}
-
-static inline void cr(struct vc_data *vc)
-{
-       vc->vc_pos -= vc->vc_x << 1;
-       vc->vc_need_wrap = vc->vc_x = 0;
-       notify_write(vc, '\r');
-}
-
-static inline void bs(struct vc_data *vc)
-{
-       if (vc->vc_x) {
-               vc->vc_pos -= 2;
-               vc->vc_x--;
-               vc->vc_need_wrap = 0;
-               notify_write(vc, '\b');
-       }
-}
-
-static inline void del(struct vc_data *vc)
-{
-       /* ignored */
-}
-
-static void csi_J(struct vc_data *vc, int vpar)
-{
-       unsigned int count;
-       unsigned short * start;
-
-       switch (vpar) {
-               case 0: /* erase from cursor to end of display */
-                       count = (vc->vc_scr_end - vc->vc_pos) >> 1;
-                       start = (unsigned short *)vc->vc_pos;
-                       if (DO_UPDATE(vc)) {
-                               /* do in two stages */
-                               vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
-                                             vc->vc_cols - vc->vc_x);
-                               vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0,
-                                             vc->vc_rows - vc->vc_y - 1,
-                                             vc->vc_cols);
-                       }
-                       break;
-               case 1: /* erase from start to cursor */
-                       count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
-                       start = (unsigned short *)vc->vc_origin;
-                       if (DO_UPDATE(vc)) {
-                               /* do in two stages */
-                               vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y,
-                                             vc->vc_cols);
-                               vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
-                                             vc->vc_x + 1);
-                       }
-                       break;
-               case 2: /* erase whole display */
-                       count = vc->vc_cols * vc->vc_rows;
-                       start = (unsigned short *)vc->vc_origin;
-                       if (DO_UPDATE(vc))
-                               vc->vc_sw->con_clear(vc, 0, 0,
-                                             vc->vc_rows,
-                                             vc->vc_cols);
-                       break;
-               default:
-                       return;
-       }
-       scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
-       vc->vc_need_wrap = 0;
-}
-
-static void csi_K(struct vc_data *vc, int vpar)
-{
-       unsigned int count;
-       unsigned short * start;
-
-       switch (vpar) {
-               case 0: /* erase from cursor to end of line */
-                       count = vc->vc_cols - vc->vc_x;
-                       start = (unsigned short *)vc->vc_pos;
-                       if (DO_UPDATE(vc))
-                               vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
-                                                    vc->vc_cols - vc->vc_x);
-                       break;
-               case 1: /* erase from start of line to cursor */
-                       start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
-                       count = vc->vc_x + 1;
-                       if (DO_UPDATE(vc))
-                               vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
-                                                    vc->vc_x + 1);
-                       break;
-               case 2: /* erase whole line */
-                       start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
-                       count = vc->vc_cols;
-                       if (DO_UPDATE(vc))
-                               vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
-                                             vc->vc_cols);
-                       break;
-               default:
-                       return;
-       }
-       scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
-       vc->vc_need_wrap = 0;
-}
-
-static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
-{                                        /* not vt100? */
-       int count;
-
-       if (!vpar)
-               vpar++;
-       count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;
-
-       scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
-       if (DO_UPDATE(vc))
-               vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
-       vc->vc_need_wrap = 0;
-}
-
-static void default_attr(struct vc_data *vc)
-{
-       vc->vc_intensity = 1;
-       vc->vc_italic = 0;
-       vc->vc_underline = 0;
-       vc->vc_reverse = 0;
-       vc->vc_blink = 0;
-       vc->vc_color = vc->vc_def_color;
-}
-
-/* console_sem is held */
-static void csi_m(struct vc_data *vc)
-{
-       int i;
-
-       for (i = 0; i <= vc->vc_npar; i++)
-               switch (vc->vc_par[i]) {
-                       case 0: /* all attributes off */
-                               default_attr(vc);
-                               break;
-                       case 1:
-                               vc->vc_intensity = 2;
-                               break;
-                       case 2:
-                               vc->vc_intensity = 0;
-                               break;
-                       case 3:
-                               vc->vc_italic = 1;
-                               break;
-                       case 4:
-                               vc->vc_underline = 1;
-                               break;
-                       case 5:
-                               vc->vc_blink = 1;
-                               break;
-                       case 7:
-                               vc->vc_reverse = 1;
-                               break;
-                       case 10: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Select primary font, don't display
-                                 * control chars if defined, don't set
-                                 * bit 8 on output.
-                                 */
-                               vc->vc_translate = set_translate(vc->vc_charset == 0
-                                               ? vc->vc_G0_charset
-                                               : vc->vc_G1_charset, vc);
-                               vc->vc_disp_ctrl = 0;
-                               vc->vc_toggle_meta = 0;
-                               break;
-                       case 11: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Select first alternate font, lets
-                                 * chars < 32 be displayed as ROM chars.
-                                 */
-                               vc->vc_translate = set_translate(IBMPC_MAP, vc);
-                               vc->vc_disp_ctrl = 1;
-                               vc->vc_toggle_meta = 0;
-                               break;
-                       case 12: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Select second alternate font, toggle
-                                 * high bit before displaying as ROM char.
-                                 */
-                               vc->vc_translate = set_translate(IBMPC_MAP, vc);
-                               vc->vc_disp_ctrl = 1;
-                               vc->vc_toggle_meta = 1;
-                               break;
-                       case 21:
-                       case 22:
-                               vc->vc_intensity = 1;
-                               break;
-                       case 23:
-                               vc->vc_italic = 0;
-                               break;
-                       case 24:
-                               vc->vc_underline = 0;
-                               break;
-                       case 25:
-                               vc->vc_blink = 0;
-                               break;
-                       case 27:
-                               vc->vc_reverse = 0;
-                               break;
-                       case 38: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Enables underscore, white foreground
-                                 * with white underscore (Linux - use
-                                 * default foreground).
-                                 */
-                               vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
-                               vc->vc_underline = 1;
-                               break;
-                       case 39: /* ANSI X3.64-1979 (SCO-ish?)
-                                 * Disable underline option.
-                                 * Reset colour to default? It did this
-                                 * before...
-                                 */
-                               vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
-                               vc->vc_underline = 0;
-                               break;
-                       case 49:
-                               vc->vc_color = (vc->vc_def_color & 0xf0) | (vc->vc_color & 0x0f);
-                               break;
-                       default:
-                               if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
-                                       vc->vc_color = color_table[vc->vc_par[i] - 30]
-                                               | (vc->vc_color & 0xf0);
-                               else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
-                                       vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
-                                               | (vc->vc_color & 0x0f);
-                               break;
-               }
-       update_attr(vc);
-}
-
-static void respond_string(const char *p, struct tty_struct *tty)
-{
-       while (*p) {
-               tty_insert_flip_char(tty, *p, 0);
-               p++;
-       }
-       con_schedule_flip(tty);
-}
-
-static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
-{
-       char buf[40];
-
-       sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1);
-       respond_string(buf, tty);
-}
-
-static inline void status_report(struct tty_struct *tty)
-{
-       respond_string("\033[0n", tty); /* Terminal ok */
-}
-
-static inline void respond_ID(struct tty_struct * tty)
-{
-       respond_string(VT102ID, tty);
-}
-
-void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
-{
-       char buf[8];
-
-       sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
-               (char)('!' + mry));
-       respond_string(buf, tty);
-}
-
-/* invoked via ioctl(TIOCLINUX) and through set_selection */
-int mouse_reporting(void)
-{
-       return vc_cons[fg_console].d->vc_report_mouse;
-}
-
-/* console_sem is held */
-static void set_mode(struct vc_data *vc, int on_off)
-{
-       int i;
-
-       for (i = 0; i <= vc->vc_npar; i++)
-               if (vc->vc_ques) {
-                       switch(vc->vc_par[i]) { /* DEC private modes set/reset */
-                       case 1:                 /* Cursor keys send ^[Ox/^[[x */
-                               if (on_off)
-                                       set_kbd(vc, decckm);
-                               else
-                                       clr_kbd(vc, decckm);
-                               break;
-                       case 3: /* 80/132 mode switch unimplemented */
-                               vc->vc_deccolm = on_off;
-#if 0
-                               vc_resize(deccolm ? 132 : 80, vc->vc_rows);
-                               /* this alone does not suffice; some user mode
-                                  utility has to change the hardware regs */
-#endif
-                               break;
-                       case 5:                 /* Inverted screen on/off */
-                               if (vc->vc_decscnm != on_off) {
-                                       vc->vc_decscnm = on_off;
-                                       invert_screen(vc, 0, vc->vc_screenbuf_size, 0);
-                                       update_attr(vc);
-                               }
-                               break;
-                       case 6:                 /* Origin relative/absolute */
-                               vc->vc_decom = on_off;
-                               gotoxay(vc, 0, 0);
-                               break;
-                       case 7:                 /* Autowrap on/off */
-                               vc->vc_decawm = on_off;
-                               break;
-                       case 8:                 /* Autorepeat on/off */
-                               if (on_off)
-                                       set_kbd(vc, decarm);
-                               else
-                                       clr_kbd(vc, decarm);
-                               break;
-                       case 9:
-                               vc->vc_report_mouse = on_off ? 1 : 0;
-                               break;
-                       case 25:                /* Cursor on/off */
-                               vc->vc_deccm = on_off;
-                               break;
-                       case 1000:
-                               vc->vc_report_mouse = on_off ? 2 : 0;
-                               break;
-                       }
-               } else {
-                       switch(vc->vc_par[i]) { /* ANSI modes set/reset */
-                       case 3:                 /* Monitor (display ctrls) */
-                               vc->vc_disp_ctrl = on_off;
-                               break;
-                       case 4:                 /* Insert Mode on/off */
-                               vc->vc_decim = on_off;
-                               break;
-                       case 20:                /* Lf, Enter == CrLf/Lf */
-                               if (on_off)
-                                       set_kbd(vc, lnm);
-                               else
-                                       clr_kbd(vc, lnm);
-                               break;
-                       }
-               }
-}
-
-/* console_sem is held */
-static void setterm_command(struct vc_data *vc)
-{
-       switch(vc->vc_par[0]) {
-               case 1: /* set color for underline mode */
-                       if (vc->vc_can_do_color &&
-                                       vc->vc_par[1] < 16) {
-                               vc->vc_ulcolor = color_table[vc->vc_par[1]];
-                               if (vc->vc_underline)
-                                       update_attr(vc);
-                       }
-                       break;
-               case 2: /* set color for half intensity mode */
-                       if (vc->vc_can_do_color &&
-                                       vc->vc_par[1] < 16) {
-                               vc->vc_halfcolor = color_table[vc->vc_par[1]];
-                               if (vc->vc_intensity == 0)
-                                       update_attr(vc);
-                       }
-                       break;
-               case 8: /* store colors as defaults */
-                       vc->vc_def_color = vc->vc_attr;
-                       if (vc->vc_hi_font_mask == 0x100)
-                               vc->vc_def_color >>= 1;
-                       default_attr(vc);
-                       update_attr(vc);
-                       break;
-               case 9: /* set blanking interval */
-                       blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60;
-                       poke_blanked_console();
-                       break;
-               case 10: /* set bell frequency in Hz */
-                       if (vc->vc_npar >= 1)
-                               vc->vc_bell_pitch = vc->vc_par[1];
-                       else
-                               vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
-                       break;
-               case 11: /* set bell duration in msec */
-                       if (vc->vc_npar >= 1)
-                               vc->vc_bell_duration = (vc->vc_par[1] < 2000) ?
-                                       vc->vc_par[1] * HZ / 1000 : 0;
-                       else
-                               vc->vc_bell_duration = DEFAULT_BELL_DURATION;
-                       break;
-               case 12: /* bring specified console to the front */
-                       if (vc->vc_par[1] >= 1 && vc_cons_allocated(vc->vc_par[1] - 1))
-                               set_console(vc->vc_par[1] - 1);
-                       break;
-               case 13: /* unblank the screen */
-                       poke_blanked_console();
-                       break;
-               case 14: /* set vesa powerdown interval */
-                       vesa_off_interval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ;
-                       break;
-               case 15: /* activate the previous console */
-                       set_console(last_console);
-                       break;
-       }
-}
-
-/* console_sem is held */
-static void csi_at(struct vc_data *vc, unsigned int nr)
-{
-       if (nr > vc->vc_cols - vc->vc_x)
-               nr = vc->vc_cols - vc->vc_x;
-       else if (!nr)
-               nr = 1;
-       insert_char(vc, nr);
-}
-
-/* console_sem is held */
-static void csi_L(struct vc_data *vc, unsigned int nr)
-{
-       if (nr > vc->vc_rows - vc->vc_y)
-               nr = vc->vc_rows - vc->vc_y;
-       else if (!nr)
-               nr = 1;
-       scrdown(vc, vc->vc_y, vc->vc_bottom, nr);
-       vc->vc_need_wrap = 0;
-}
-
-/* console_sem is held */
-static void csi_P(struct vc_data *vc, unsigned int nr)
-{
-       if (nr > vc->vc_cols - vc->vc_x)
-               nr = vc->vc_cols - vc->vc_x;
-       else if (!nr)
-               nr = 1;
-       delete_char(vc, nr);
-}
-
-/* console_sem is held */
-static void csi_M(struct vc_data *vc, unsigned int nr)
-{
-       if (nr > vc->vc_rows - vc->vc_y)
-               nr = vc->vc_rows - vc->vc_y;
-       else if (!nr)
-               nr=1;
-       scrup(vc, vc->vc_y, vc->vc_bottom, nr);
-       vc->vc_need_wrap = 0;
-}
-
-/* console_sem is held (except via vc_init->reset_terminal */
-static void save_cur(struct vc_data *vc)
-{
-       vc->vc_saved_x          = vc->vc_x;
-       vc->vc_saved_y          = vc->vc_y;
-       vc->vc_s_intensity      = vc->vc_intensity;
-       vc->vc_s_italic         = vc->vc_italic;
-       vc->vc_s_underline      = vc->vc_underline;
-       vc->vc_s_blink          = vc->vc_blink;
-       vc->vc_s_reverse        = vc->vc_reverse;
-       vc->vc_s_charset        = vc->vc_charset;
-       vc->vc_s_color          = vc->vc_color;
-       vc->vc_saved_G0         = vc->vc_G0_charset;
-       vc->vc_saved_G1         = vc->vc_G1_charset;
-}
-
-/* console_sem is held */
-static void restore_cur(struct vc_data *vc)
-{
-       gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
-       vc->vc_intensity        = vc->vc_s_intensity;
-       vc->vc_italic           = vc->vc_s_italic;
-       vc->vc_underline        = vc->vc_s_underline;
-       vc->vc_blink            = vc->vc_s_blink;
-       vc->vc_reverse          = vc->vc_s_reverse;
-       vc->vc_charset          = vc->vc_s_charset;
-       vc->vc_color            = vc->vc_s_color;
-       vc->vc_G0_charset       = vc->vc_saved_G0;
-       vc->vc_G1_charset       = vc->vc_saved_G1;
-       vc->vc_translate        = set_translate(vc->vc_charset ? vc->vc_G1_charset : vc->vc_G0_charset, vc);
-       update_attr(vc);
-       vc->vc_need_wrap = 0;
-}
-
-enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
-       EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
-       ESpalette };
-
-/* console_sem is held (except via vc_init()) */
-static void reset_terminal(struct vc_data *vc, int do_clear)
-{
-       vc->vc_top              = 0;
-       vc->vc_bottom           = vc->vc_rows;
-       vc->vc_state            = ESnormal;
-       vc->vc_ques             = 0;
-       vc->vc_translate        = set_translate(LAT1_MAP, vc);
-       vc->vc_G0_charset       = LAT1_MAP;
-       vc->vc_G1_charset       = GRAF_MAP;
-       vc->vc_charset          = 0;
-       vc->vc_need_wrap        = 0;
-       vc->vc_report_mouse     = 0;
-       vc->vc_utf              = default_utf8;
-       vc->vc_utf_count        = 0;
-
-       vc->vc_disp_ctrl        = 0;
-       vc->vc_toggle_meta      = 0;
-
-       vc->vc_decscnm          = 0;
-       vc->vc_decom            = 0;
-       vc->vc_decawm           = 1;
-       vc->vc_deccm            = global_cursor_default;
-       vc->vc_decim            = 0;
-
-       set_kbd(vc, decarm);
-       clr_kbd(vc, decckm);
-       clr_kbd(vc, kbdapplic);
-       clr_kbd(vc, lnm);
-       kbd_table[vc->vc_num].lockstate = 0;
-       kbd_table[vc->vc_num].slockstate = 0;
-       kbd_table[vc->vc_num].ledmode = LED_SHOW_FLAGS;
-       kbd_table[vc->vc_num].ledflagstate = kbd_table[vc->vc_num].default_ledflagstate;
-       /* do not do set_leds here because this causes an endless tasklet loop
-          when the keyboard hasn't been initialized yet */
-
-       vc->vc_cursor_type = cur_default;
-       vc->vc_complement_mask = vc->vc_s_complement_mask;
-
-       default_attr(vc);
-       update_attr(vc);
-
-       vc->vc_tab_stop[0]      = 0x01010100;
-       vc->vc_tab_stop[1]      =
-       vc->vc_tab_stop[2]      =
-       vc->vc_tab_stop[3]      =
-       vc->vc_tab_stop[4]      =
-       vc->vc_tab_stop[5]      =
-       vc->vc_tab_stop[6]      =
-       vc->vc_tab_stop[7]      = 0x01010101;
-
-       vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
-       vc->vc_bell_duration = DEFAULT_BELL_DURATION;
-
-       gotoxy(vc, 0, 0);
-       save_cur(vc);
-       if (do_clear)
-           csi_J(vc, 2);
-}
-
-/* console_sem is held */
-static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
-{
-       /*
-        *  Control characters can be used in the _middle_
-        *  of an escape sequence.
-        */
-       switch (c) {
-       case 0:
-               return;
-       case 7:
-               if (vc->vc_bell_duration)
-                       kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
-               return;
-       case 8:
-               bs(vc);
-               return;
-       case 9:
-               vc->vc_pos -= (vc->vc_x << 1);
-               while (vc->vc_x < vc->vc_cols - 1) {
-                       vc->vc_x++;
-                       if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31)))
-                               break;
-               }
-               vc->vc_pos += (vc->vc_x << 1);
-               notify_write(vc, '\t');
-               return;
-       case 10: case 11: case 12:
-               lf(vc);
-               if (!is_kbd(vc, lnm))
-                       return;
-       case 13:
-               cr(vc);
-               return;
-       case 14:
-               vc->vc_charset = 1;
-               vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
-               vc->vc_disp_ctrl = 1;
-               return;
-       case 15:
-               vc->vc_charset = 0;
-               vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
-               vc->vc_disp_ctrl = 0;
-               return;
-       case 24: case 26:
-               vc->vc_state = ESnormal;
-               return;
-       case 27:
-               vc->vc_state = ESesc;
-               return;
-       case 127:
-               del(vc);
-               return;
-       case 128+27:
-               vc->vc_state = ESsquare;
-               return;
-       }
-       switch(vc->vc_state) {
-       case ESesc:
-               vc->vc_state = ESnormal;
-               switch (c) {
-               case '[':
-                       vc->vc_state = ESsquare;
-                       return;
-               case ']':
-                       vc->vc_state = ESnonstd;
-                       return;
-               case '%':
-                       vc->vc_state = ESpercent;
-                       return;
-               case 'E':
-                       cr(vc);
-                       lf(vc);
-                       return;
-               case 'M':
-                       ri(vc);
-                       return;
-               case 'D':
-                       lf(vc);
-                       return;
-               case 'H':
-                       vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31));
-                       return;
-               case 'Z':
-                       respond_ID(tty);
-                       return;
-               case '7':
-                       save_cur(vc);
-                       return;
-               case '8':
-                       restore_cur(vc);
-                       return;
-               case '(':
-                       vc->vc_state = ESsetG0;
-                       return;
-               case ')':
-                       vc->vc_state = ESsetG1;
-                       return;
-               case '#':
-                       vc->vc_state = EShash;
-                       return;
-               case 'c':
-                       reset_terminal(vc, 1);
-                       return;
-               case '>':  /* Numeric keypad */
-                       clr_kbd(vc, kbdapplic);
-                       return;
-               case '=':  /* Appl. keypad */
-                       set_kbd(vc, kbdapplic);
-                       return;
-               }
-               return;
-       case ESnonstd:
-               if (c=='P') {   /* palette escape sequence */
-                       for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
-                               vc->vc_par[vc->vc_npar] = 0;
-                       vc->vc_npar = 0;
-                       vc->vc_state = ESpalette;
-                       return;
-               } else if (c=='R') {   /* reset palette */
-                       reset_palette(vc);
-                       vc->vc_state = ESnormal;
-               } else
-                       vc->vc_state = ESnormal;
-               return;
-       case ESpalette:
-               if (isxdigit(c)) {
-                       vc->vc_par[vc->vc_npar++] = hex_to_bin(c);
-                       if (vc->vc_npar == 7) {
-                               int i = vc->vc_par[0] * 3, j = 1;
-                               vc->vc_palette[i] = 16 * vc->vc_par[j++];
-                               vc->vc_palette[i++] += vc->vc_par[j++];
-                               vc->vc_palette[i] = 16 * vc->vc_par[j++];
-                               vc->vc_palette[i++] += vc->vc_par[j++];
-                               vc->vc_palette[i] = 16 * vc->vc_par[j++];
-                               vc->vc_palette[i] += vc->vc_par[j];
-                               set_palette(vc);
-                               vc->vc_state = ESnormal;
-                       }
-               } else
-                       vc->vc_state = ESnormal;
-               return;
-       case ESsquare:
-               for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
-                       vc->vc_par[vc->vc_npar] = 0;
-               vc->vc_npar = 0;
-               vc->vc_state = ESgetpars;
-               if (c == '[') { /* Function key */
-                       vc->vc_state=ESfunckey;
-                       return;
-               }
-               vc->vc_ques = (c == '?');
-               if (vc->vc_ques)
-                       return;
-       case ESgetpars:
-               if (c == ';' && vc->vc_npar < NPAR - 1) {
-                       vc->vc_npar++;
-                       return;
-               } else if (c>='0' && c<='9') {
-                       vc->vc_par[vc->vc_npar] *= 10;
-                       vc->vc_par[vc->vc_npar] += c - '0';
-                       return;
-               } else
-                       vc->vc_state = ESgotpars;
-       case ESgotpars:
-               vc->vc_state = ESnormal;
-               switch(c) {
-               case 'h':
-                       set_mode(vc, 1);
-                       return;
-               case 'l':
-                       set_mode(vc, 0);
-                       return;
-               case 'c':
-                       if (vc->vc_ques) {
-                               if (vc->vc_par[0])
-                                       vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
-                               else
-                                       vc->vc_cursor_type = cur_default;
-                               return;
-                       }
-                       break;
-               case 'm':
-                       if (vc->vc_ques) {
-                               clear_selection();
-                               if (vc->vc_par[0])
-                                       vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
-                               else
-                                       vc->vc_complement_mask = vc->vc_s_complement_mask;
-                               return;
-                       }
-                       break;
-               case 'n':
-                       if (!vc->vc_ques) {
-                               if (vc->vc_par[0] == 5)
-                                       status_report(tty);
-                               else if (vc->vc_par[0] == 6)
-                                       cursor_report(vc, tty);
-                       }
-                       return;
-               }
-               if (vc->vc_ques) {
-                       vc->vc_ques = 0;
-                       return;
-               }
-               switch(c) {
-               case 'G': case '`':
-                       if (vc->vc_par[0])
-                               vc->vc_par[0]--;
-                       gotoxy(vc, vc->vc_par[0], vc->vc_y);
-                       return;
-               case 'A':
-                       if (!vc->vc_par[0])
-                               vc->vc_par[0]++;
-                       gotoxy(vc, vc->vc_x, vc->vc_y - vc->vc_par[0]);
-                       return;
-               case 'B': case 'e':
-                       if (!vc->vc_par[0])
-                               vc->vc_par[0]++;
-                       gotoxy(vc, vc->vc_x, vc->vc_y + vc->vc_par[0]);
-                       return;
-               case 'C': case 'a':
-                       if (!vc->vc_par[0])
-                               vc->vc_par[0]++;
-                       gotoxy(vc, vc->vc_x + vc->vc_par[0], vc->vc_y);
-                       return;
-               case 'D':
-                       if (!vc->vc_par[0])
-                               vc->vc_par[0]++;
-                       gotoxy(vc, vc->vc_x - vc->vc_par[0], vc->vc_y);
-                       return;
-               case 'E':
-                       if (!vc->vc_par[0])
-                               vc->vc_par[0]++;
-                       gotoxy(vc, 0, vc->vc_y + vc->vc_par[0]);
-                       return;
-               case 'F':
-                       if (!vc->vc_par[0])
-                               vc->vc_par[0]++;
-                       gotoxy(vc, 0, vc->vc_y - vc->vc_par[0]);
-                       return;
-               case 'd':
-                       if (vc->vc_par[0])
-                               vc->vc_par[0]--;
-                       gotoxay(vc, vc->vc_x ,vc->vc_par[0]);
-                       return;
-               case 'H': case 'f':
-                       if (vc->vc_par[0])
-                               vc->vc_par[0]--;
-                       if (vc->vc_par[1])
-                               vc->vc_par[1]--;
-                       gotoxay(vc, vc->vc_par[1], vc->vc_par[0]);
-                       return;
-               case 'J':
-                       csi_J(vc, vc->vc_par[0]);
-                       return;
-               case 'K':
-                       csi_K(vc, vc->vc_par[0]);
-                       return;
-               case 'L':
-                       csi_L(vc, vc->vc_par[0]);
-                       return;
-               case 'M':
-                       csi_M(vc, vc->vc_par[0]);
-                       return;
-               case 'P':
-                       csi_P(vc, vc->vc_par[0]);
-                       return;
-               case 'c':
-                       if (!vc->vc_par[0])
-                               respond_ID(tty);
-                       return;
-               case 'g':
-                       if (!vc->vc_par[0])
-                               vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31));
-                       else if (vc->vc_par[0] == 3) {
-                               vc->vc_tab_stop[0] =
-                                       vc->vc_tab_stop[1] =
-                                       vc->vc_tab_stop[2] =
-                                       vc->vc_tab_stop[3] =
-                                       vc->vc_tab_stop[4] =
-                                       vc->vc_tab_stop[5] =
-                                       vc->vc_tab_stop[6] =
-                                       vc->vc_tab_stop[7] = 0;
-                       }
-                       return;
-               case 'm':
-                       csi_m(vc);
-                       return;
-               case 'q': /* DECLL - but only 3 leds */
-                       /* map 0,1,2,3 to 0,1,2,4 */
-                       if (vc->vc_par[0] < 4)
-                               setledstate(kbd_table + vc->vc_num,
-                                           (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
-                       return;
-               case 'r':
-                       if (!vc->vc_par[0])
-                               vc->vc_par[0]++;
-                       if (!vc->vc_par[1])
-                               vc->vc_par[1] = vc->vc_rows;
-                       /* Minimum allowed region is 2 lines */
-                       if (vc->vc_par[0] < vc->vc_par[1] &&
-                           vc->vc_par[1] <= vc->vc_rows) {
-                               vc->vc_top = vc->vc_par[0] - 1;
-                               vc->vc_bottom = vc->vc_par[1];
-                               gotoxay(vc, 0, 0);
-                       }
-                       return;
-               case 's':
-                       save_cur(vc);
-                       return;
-               case 'u':
-                       restore_cur(vc);
-                       return;
-               case 'X':
-                       csi_X(vc, vc->vc_par[0]);
-                       return;
-               case '@':
-                       csi_at(vc, vc->vc_par[0]);
-                       return;
-               case ']': /* setterm functions */
-                       setterm_command(vc);
-                       return;
-               }
-               return;
-       case ESpercent:
-               vc->vc_state = ESnormal;
-               switch (c) {
-               case '@':  /* defined in ISO 2022 */
-                       vc->vc_utf = 0;
-                       return;
-               case 'G':  /* prelim official escape code */
-               case '8':  /* retained for compatibility */
-                       vc->vc_utf = 1;
-                       return;
-               }
-               return;
-       case ESfunckey:
-               vc->vc_state = ESnormal;
-               return;
-       case EShash:
-               vc->vc_state = ESnormal;
-               if (c == '8') {
-                       /* DEC screen alignment test. kludge :-) */
-                       vc->vc_video_erase_char =
-                               (vc->vc_video_erase_char & 0xff00) | 'E';
-                       csi_J(vc, 2);
-                       vc->vc_video_erase_char =
-                               (vc->vc_video_erase_char & 0xff00) | ' ';
-                       do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
-               }
-               return;
-       case ESsetG0:
-               if (c == '0')
-                       vc->vc_G0_charset = GRAF_MAP;
-               else if (c == 'B')
-                       vc->vc_G0_charset = LAT1_MAP;
-               else if (c == 'U')
-                       vc->vc_G0_charset = IBMPC_MAP;
-               else if (c == 'K')
-                       vc->vc_G0_charset = USER_MAP;
-               if (vc->vc_charset == 0)
-                       vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
-               vc->vc_state = ESnormal;
-               return;
-       case ESsetG1:
-               if (c == '0')
-                       vc->vc_G1_charset = GRAF_MAP;
-               else if (c == 'B')
-                       vc->vc_G1_charset = LAT1_MAP;
-               else if (c == 'U')
-                       vc->vc_G1_charset = IBMPC_MAP;
-               else if (c == 'K')
-                       vc->vc_G1_charset = USER_MAP;
-               if (vc->vc_charset == 1)
-                       vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
-               vc->vc_state = ESnormal;
-               return;
-       default:
-               vc->vc_state = ESnormal;
-       }
-}
-
-/* This is a temporary buffer used to prepare a tty console write
- * so that we can easily avoid touching user space while holding the
- * console spinlock.  It is allocated in con_init and is shared by
- * this code and the vc_screen read/write tty calls.
- *
- * We have to allocate this statically in the kernel data section
- * since console_init (and thus con_init) are called before any
- * kernel memory allocation is available.
- */
-char con_buf[CON_BUF_SIZE];
-DEFINE_MUTEX(con_buf_mtx);
-
-/* is_double_width() is based on the wcwidth() implementation by
- * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
- * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
- */
-struct interval {
-       uint32_t first;
-       uint32_t last;
-};
-
-static int bisearch(uint32_t ucs, const struct interval *table, int max)
-{
-       int min = 0;
-       int mid;
-
-       if (ucs < table[0].first || ucs > table[max].last)
-               return 0;
-       while (max >= min) {
-               mid = (min + max) / 2;
-               if (ucs > table[mid].last)
-                       min = mid + 1;
-               else if (ucs < table[mid].first)
-                       max = mid - 1;
-               else
-                       return 1;
-       }
-       return 0;
-}
-
-static int is_double_width(uint32_t ucs)
-{
-       static const struct interval double_width[] = {
-               { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E },
-               { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF },
-               { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 },
-               { 0xFFE0, 0xFFE6 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD }
-       };
-       return bisearch(ucs, double_width, ARRAY_SIZE(double_width) - 1);
-}
-
-/* acquires console_sem */
-static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
-{
-#ifdef VT_BUF_VRAM_ONLY
-#define FLUSH do { } while(0);
-#else
-#define FLUSH if (draw_x >= 0) { \
-       vc->vc_sw->con_putcs(vc, (u16 *)draw_from, (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, draw_x); \
-       draw_x = -1; \
-       }
-#endif
-
-       int c, tc, ok, n = 0, draw_x = -1;
-       unsigned int currcons;
-       unsigned long draw_from = 0, draw_to = 0;
-       struct vc_data *vc;
-       unsigned char vc_attr;
-       struct vt_notifier_param param;
-       uint8_t rescan;
-       uint8_t inverse;
-       uint8_t width;
-       u16 himask, charmask;
-
-       if (in_interrupt())
-               return count;
-
-       might_sleep();
-
-       acquire_console_sem();
-       vc = tty->driver_data;
-       if (vc == NULL) {
-               printk(KERN_ERR "vt: argh, driver_data is NULL !\n");
-               release_console_sem();
-               return 0;
-       }
-
-       currcons = vc->vc_num;
-       if (!vc_cons_allocated(currcons)) {
-           /* could this happen? */
-               printk_once("con_write: tty %d not allocated\n", currcons+1);
-           release_console_sem();
-           return 0;
-       }
-
-       himask = vc->vc_hi_font_mask;
-       charmask = himask ? 0x1ff : 0xff;
-
-       /* undraw cursor first */
-       if (IS_FG(vc))
-               hide_cursor(vc);
-
-       param.vc = vc;
-
-       while (!tty->stopped && count) {
-               int orig = *buf;
-               c = orig;
-               buf++;
-               n++;
-               count--;
-               rescan = 0;
-               inverse = 0;
-               width = 1;
-
-               /* Do no translation at all in control states */
-               if (vc->vc_state != ESnormal) {
-                       tc = c;
-               } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
-                   /* Combine UTF-8 into Unicode in vc_utf_char.
-                    * vc_utf_count is the number of continuation bytes still
-                    * expected to arrive.
-                    * vc_npar is the number of continuation bytes arrived so
-                    * far
-                    */
-rescan_last_byte:
-                   if ((c & 0xc0) == 0x80) {
-                       /* Continuation byte received */
-                       static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
-                       if (vc->vc_utf_count) {
-                           vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
-                           vc->vc_npar++;
-                           if (--vc->vc_utf_count) {
-                               /* Still need some bytes */
-                               continue;
-                           }
-                           /* Got a whole character */
-                           c = vc->vc_utf_char;
-                           /* Reject overlong sequences */
-                           if (c <= utf8_length_changes[vc->vc_npar - 1] ||
-                                       c > utf8_length_changes[vc->vc_npar])
-                               c = 0xfffd;
-                       } else {
-                           /* Unexpected continuation byte */
-                           vc->vc_utf_count = 0;
-                           c = 0xfffd;
-                       }
-                   } else {
-                       /* Single ASCII byte or first byte of a sequence received */
-                       if (vc->vc_utf_count) {
-                           /* Continuation byte expected */
-                           rescan = 1;
-                           vc->vc_utf_count = 0;
-                           c = 0xfffd;
-                       } else if (c > 0x7f) {
-                           /* First byte of a multibyte sequence received */
-                           vc->vc_npar = 0;
-                           if ((c & 0xe0) == 0xc0) {
-                               vc->vc_utf_count = 1;
-                               vc->vc_utf_char = (c & 0x1f);
-                           } else if ((c & 0xf0) == 0xe0) {
-                               vc->vc_utf_count = 2;
-                               vc->vc_utf_char = (c & 0x0f);
-                           } else if ((c & 0xf8) == 0xf0) {
-                               vc->vc_utf_count = 3;
-                               vc->vc_utf_char = (c & 0x07);
-                           } else if ((c & 0xfc) == 0xf8) {
-                               vc->vc_utf_count = 4;
-                               vc->vc_utf_char = (c & 0x03);
-                           } else if ((c & 0xfe) == 0xfc) {
-                               vc->vc_utf_count = 5;
-                               vc->vc_utf_char = (c & 0x01);
-                           } else {
-                               /* 254 and 255 are invalid */
-                               c = 0xfffd;
-                           }
-                           if (vc->vc_utf_count) {
-                               /* Still need some bytes */
-                               continue;
-                           }
-                       }
-                       /* Nothing to do if an ASCII byte was received */
-                   }
-                   /* End of UTF-8 decoding. */
-                   /* c is the received character, or U+FFFD for invalid sequences. */
-                   /* Replace invalid Unicode code points with U+FFFD too */
-                   if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
-                       c = 0xfffd;
-                   tc = c;
-               } else {        /* no utf or alternate charset mode */
-                   tc = vc_translate(vc, c);
-               }
-
-               param.c = tc;
-               if (atomic_notifier_call_chain(&vt_notifier_list, VT_PREWRITE,
-                                       &param) == NOTIFY_STOP)
-                       continue;
-
-                /* If the original code was a control character we
-                 * only allow a glyph to be displayed if the code is
-                 * not normally used (such as for cursor movement) or
-                 * if the disp_ctrl mode has been explicitly enabled.
-                 * Certain characters (as given by the CTRL_ALWAYS
-                 * bitmap) are always displayed as control characters,
-                 * as the console would be pretty useless without
-                 * them; to display an arbitrary font position use the
-                 * direct-to-font zone in UTF-8 mode.
-                 */
-                ok = tc && (c >= 32 ||
-                           !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
-                                 vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
-                       && (c != 127 || vc->vc_disp_ctrl)
-                       && (c != 128+27);
-
-               if (vc->vc_state == ESnormal && ok) {
-                       if (vc->vc_utf && !vc->vc_disp_ctrl) {
-                               if (is_double_width(c))
-                                       width = 2;
-                       }
-                       /* Now try to find out how to display it */
-                       tc = conv_uni_to_pc(vc, tc);
-                       if (tc & ~charmask) {
-                               if (tc == -1 || tc == -2) {
-                                   continue; /* nothing to display */
-                               }
-                               /* Glyph not found */
-                               if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
-                                   /* In legacy mode use the glyph we get by a 1:1 mapping.
-                                      This would make absolutely no sense with Unicode in mind,
-                                      but do this for ASCII characters since a font may lack
-                                      Unicode mapping info and we don't want to end up with
-                                      having question marks only. */
-                                   tc = c;
-                               } else {
-                                   /* Display U+FFFD. If it's not found, display an inverse question mark. */
-                                   tc = conv_uni_to_pc(vc, 0xfffd);
-                                   if (tc < 0) {
-                                       inverse = 1;
-                                       tc = conv_uni_to_pc(vc, '?');
-                                       if (tc < 0) tc = '?';
-                                   }
-                               }
-                       }
-
-                       if (!inverse) {
-                               vc_attr = vc->vc_attr;
-                       } else {
-                               /* invert vc_attr */
-                               if (!vc->vc_can_do_color) {
-                                       vc_attr = (vc->vc_attr) ^ 0x08;
-                               } else if (vc->vc_hi_font_mask == 0x100) {
-                                       vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
-                               } else {
-                                       vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
-                               }
-                               FLUSH
-                       }
-
-                       while (1) {
-                               if (vc->vc_need_wrap || vc->vc_decim)
-                                       FLUSH
-                               if (vc->vc_need_wrap) {
-                                       cr(vc);
-                                       lf(vc);
-                               }
-                               if (vc->vc_decim)
-                                       insert_char(vc, 1);
-                               scr_writew(himask ?
-                                            ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
-                                            (vc_attr << 8) + tc,
-                                          (u16 *) vc->vc_pos);
-                               if (DO_UPDATE(vc) && draw_x < 0) {
-                                       draw_x = vc->vc_x;
-                                       draw_from = vc->vc_pos;
-                               }
-                               if (vc->vc_x == vc->vc_cols - 1) {
-                                       vc->vc_need_wrap = vc->vc_decawm;
-                                       draw_to = vc->vc_pos + 2;
-                               } else {
-                                       vc->vc_x++;
-                                       draw_to = (vc->vc_pos += 2);
-                               }
-
-                               if (!--width) break;
-
-                               tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
-                               if (tc < 0) tc = ' ';
-                       }
-                       notify_write(vc, c);
-
-                       if (inverse) {
-                               FLUSH
-                       }
-
-                       if (rescan) {
-                               rescan = 0;
-                               inverse = 0;
-                               width = 1;
-                               c = orig;
-                               goto rescan_last_byte;
-                       }
-                       continue;
-               }
-               FLUSH
-               do_con_trol(tty, vc, orig);
-       }
-       FLUSH
-       console_conditional_schedule();
-       release_console_sem();
-       notify_update(vc);
-       return n;
-#undef FLUSH
-}
-
-/*
- * This is the console switching callback.
- *
- * Doing console switching in a process context allows
- * us to do the switches asynchronously (needed when we want
- * to switch due to a keyboard interrupt).  Synchronization
- * with other console code and prevention of re-entrancy is
- * ensured with console_sem.
- */
-static void console_callback(struct work_struct *ignored)
-{
-       acquire_console_sem();
-
-       if (want_console >= 0) {
-               if (want_console != fg_console &&
-                   vc_cons_allocated(want_console)) {
-                       hide_cursor(vc_cons[fg_console].d);
-                       change_console(vc_cons[want_console].d);
-                       /* we only changed when the console had already
-                          been allocated - a new console is not created
-                          in an interrupt routine */
-               }
-               want_console = -1;
-       }
-       if (do_poke_blanked_console) { /* do not unblank for a LED change */
-               do_poke_blanked_console = 0;
-               poke_blanked_console();
-       }
-       if (scrollback_delta) {
-               struct vc_data *vc = vc_cons[fg_console].d;
-               clear_selection();
-               if (vc->vc_mode == KD_TEXT)
-                       vc->vc_sw->con_scrolldelta(vc, scrollback_delta);
-               scrollback_delta = 0;
-       }
-       if (blank_timer_expired) {
-               do_blank_screen(0);
-               blank_timer_expired = 0;
-       }
-       notify_update(vc_cons[fg_console].d);
-
-       release_console_sem();
-}
-
-int set_console(int nr)
-{
-       struct vc_data *vc = vc_cons[fg_console].d;
-
-       if (!vc_cons_allocated(nr) || vt_dont_switch ||
-               (vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) {
-
-               /*
-                * Console switch will fail in console_callback() or
-                * change_console() so there is no point scheduling
-                * the callback
-                *
-                * Existing set_console() users don't check the return
-                * value so this shouldn't break anything
-                */
-               return -EINVAL;
-       }
-
-       want_console = nr;
-       schedule_console_callback();
-
-       return 0;
-}
-
-struct tty_driver *console_driver;
-
-#ifdef CONFIG_VT_CONSOLE
-
-/**
- * vt_kmsg_redirect() - Sets/gets the kernel message console
- * @new:       The new virtual terminal number or -1 if the console should stay
- *             unchanged
- *
- * By default, the kernel messages are always printed on the current virtual
- * console. However, the user may modify that default with the
- * TIOCL_SETKMSGREDIRECT ioctl call.
- *
- * This function sets the kernel message console to be @new. It returns the old
- * virtual console number. The virtual terminal number 0 (both as parameter and
- * return value) means no redirection (i.e. always printed on the currently
- * active console).
- *
- * The parameter -1 means that only the current console is returned, but the
- * value is not modified. You may use the macro vt_get_kmsg_redirect() in that
- * case to make the code more understandable.
- *
- * When the kernel is compiled without CONFIG_VT_CONSOLE, this function ignores
- * the parameter and always returns 0.
- */
-int vt_kmsg_redirect(int new)
-{
-       static int kmsg_con;
-
-       if (new != -1)
-               return xchg(&kmsg_con, new);
-       else
-               return kmsg_con;
-}
-
-/*
- *     Console on virtual terminal
- *
- * The console must be locked when we get here.
- */
-
-static void vt_console_print(struct console *co, const char *b, unsigned count)
-{
-       struct vc_data *vc = vc_cons[fg_console].d;
-       unsigned char c;
-       static DEFINE_SPINLOCK(printing_lock);
-       const ushort *start;
-       ushort cnt = 0;
-       ushort myx;
-       int kmsg_console;
-
-       /* console busy or not yet initialized */
-       if (!printable)
-               return;
-       if (!spin_trylock(&printing_lock))
-               return;
-
-       kmsg_console = vt_get_kmsg_redirect();
-       if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
-               vc = vc_cons[kmsg_console - 1].d;
-
-       /* read `x' only after setting currcons properly (otherwise
-          the `x' macro will read the x of the foreground console). */
-       myx = vc->vc_x;
-
-       if (!vc_cons_allocated(fg_console)) {
-               /* impossible */
-               /* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */
-               goto quit;
-       }
-
-       if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
-               goto quit;
-
-       /* undraw cursor first */
-       if (IS_FG(vc))
-               hide_cursor(vc);
-
-       start = (ushort *)vc->vc_pos;
-
-       /* Contrived structure to try to emulate original need_wrap behaviour
-        * Problems caused when we have need_wrap set on '\n' character */
-       while (count--) {
-               c = *b++;
-               if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
-                       if (cnt > 0) {
-                               if (CON_IS_VISIBLE(vc))
-                                       vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
-                               vc->vc_x += cnt;
-                               if (vc->vc_need_wrap)
-                                       vc->vc_x--;
-                               cnt = 0;
-                       }
-                       if (c == 8) {           /* backspace */
-                               bs(vc);
-                               start = (ushort *)vc->vc_pos;
-                               myx = vc->vc_x;
-                               continue;
-                       }
-                       if (c != 13)
-                               lf(vc);
-                       cr(vc);
-                       start = (ushort *)vc->vc_pos;
-                       myx = vc->vc_x;
-                       if (c == 10 || c == 13)
-                               continue;
-               }
-               scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
-               notify_write(vc, c);
-               cnt++;
-               if (myx == vc->vc_cols - 1) {
-                       vc->vc_need_wrap = 1;
-                       continue;
-               }
-               vc->vc_pos += 2;
-               myx++;
-       }
-       if (cnt > 0) {
-               if (CON_IS_VISIBLE(vc))
-                       vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
-               vc->vc_x += cnt;
-               if (vc->vc_x == vc->vc_cols) {
-                       vc->vc_x--;
-                       vc->vc_need_wrap = 1;
-               }
-       }
-       set_cursor(vc);
-       notify_update(vc);
-
-quit:
-       spin_unlock(&printing_lock);
-}
-
-static struct tty_driver *vt_console_device(struct console *c, int *index)
-{
-       *index = c->index ? c->index-1 : fg_console;
-       return console_driver;
-}
-
-static struct console vt_console_driver = {
-       .name           = "tty",
-       .write          = vt_console_print,
-       .device         = vt_console_device,
-       .unblank        = unblank_screen,
-       .flags          = CON_PRINTBUFFER,
-       .index          = -1,
-};
-#endif
-
-/*
- *     Handling of Linux-specific VC ioctls
- */
-
-/*
- * Generally a bit racy with respect to console_sem().
- *
- * There are some functions which don't need it.
- *
- * There are some functions which can sleep for arbitrary periods
- * (paste_selection) but we don't need the lock there anyway.
- *
- * set_selection has locking, and definitely needs it
- */
-
-int tioclinux(struct tty_struct *tty, unsigned long arg)
-{
-       char type, data;
-       char __user *p = (char __user *)arg;
-       int lines;
-       int ret;
-
-       if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       if (get_user(type, p))
-               return -EFAULT;
-       ret = 0;
-
-       switch (type)
-       {
-               case TIOCL_SETSEL:
-                       acquire_console_sem();
-                       ret = set_selection((struct tiocl_selection __user *)(p+1), tty);
-                       release_console_sem();
-                       break;
-               case TIOCL_PASTESEL:
-                       ret = paste_selection(tty);
-                       break;
-               case TIOCL_UNBLANKSCREEN:
-                       acquire_console_sem();
-                       unblank_screen();
-                       release_console_sem();
-                       break;
-               case TIOCL_SELLOADLUT:
-                       ret = sel_loadlut(p);
-                       break;
-               case TIOCL_GETSHIFTSTATE:
-
-       /*
-        * Make it possible to react to Shift+Mousebutton.
-        * Note that 'shift_state' is an undocumented
-        * kernel-internal variable; programs not closely
-        * related to the kernel should not use this.
-        */
-                       data = shift_state;
-                       ret = __put_user(data, p);
-                       break;
-               case TIOCL_GETMOUSEREPORTING:
-                       data = mouse_reporting();
-                       ret = __put_user(data, p);
-                       break;
-               case TIOCL_SETVESABLANK:
-                       ret = set_vesa_blanking(p);
-                       break;
-               case TIOCL_GETKMSGREDIRECT:
-                       data = vt_get_kmsg_redirect();
-                       ret = __put_user(data, p);
-                       break;
-               case TIOCL_SETKMSGREDIRECT:
-                       if (!capable(CAP_SYS_ADMIN)) {
-                               ret = -EPERM;
-                       } else {
-                               if (get_user(data, p+1))
-                                       ret = -EFAULT;
-                               else
-                                       vt_kmsg_redirect(data);
-                       }
-                       break;
-               case TIOCL_GETFGCONSOLE:
-                       ret = fg_console;
-                       break;
-               case TIOCL_SCROLLCONSOLE:
-                       if (get_user(lines, (s32 __user *)(p+4))) {
-                               ret = -EFAULT;
-                       } else {
-                               scrollfront(vc_cons[fg_console].d, lines);
-                               ret = 0;
-                       }
-                       break;
-               case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */
-                       acquire_console_sem();
-                       ignore_poke = 1;
-                       do_blank_screen(0);
-                       release_console_sem();
-                       break;
-               case TIOCL_BLANKEDSCREEN:
-                       ret = console_blanked;
-                       break;
-               default:
-                       ret = -EINVAL;
-                       break;
-       }
-       return ret;
-}
-
-/*
- * /dev/ttyN handling
- */
-
-static int con_write(struct tty_struct *tty, const unsigned char *buf, int count)
-{
-       int     retval;
-
-       retval = do_con_write(tty, buf, count);
-       con_flush_chars(tty);
-
-       return retval;
-}
-
-static int con_put_char(struct tty_struct *tty, unsigned char ch)
-{
-       if (in_interrupt())
-               return 0;       /* n_r3964 calls put_char() from interrupt context */
-       return do_con_write(tty, &ch, 1);
-}
-
-static int con_write_room(struct tty_struct *tty)
-{
-       if (tty->stopped)
-               return 0;
-       return 32768;           /* No limit, really; we're not buffering */
-}
-
-static int con_chars_in_buffer(struct tty_struct *tty)
-{
-       return 0;               /* we're not buffering */
-}
-
-/*
- * con_throttle and con_unthrottle are only used for
- * paste_selection(), which has to stuff in a large number of
- * characters...
- */
-static void con_throttle(struct tty_struct *tty)
-{
-}
-
-static void con_unthrottle(struct tty_struct *tty)
-{
-       struct vc_data *vc = tty->driver_data;
-
-       wake_up_interruptible(&vc->paste_wait);
-}
-
-/*
- * Turn the Scroll-Lock LED on when the tty is stopped
- */
-static void con_stop(struct tty_struct *tty)
-{
-       int console_num;
-       if (!tty)
-               return;
-       console_num = tty->index;
-       if (!vc_cons_allocated(console_num))
-               return;
-       set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
-       set_leds();
-}
-
-/*
- * Turn the Scroll-Lock LED off when the console is started
- */
-static void con_start(struct tty_struct *tty)
-{
-       int console_num;
-       if (!tty)
-               return;
-       console_num = tty->index;
-       if (!vc_cons_allocated(console_num))
-               return;
-       clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
-       set_leds();
-}
-
-static void con_flush_chars(struct tty_struct *tty)
-{
-       struct vc_data *vc;
-
-       if (in_interrupt())     /* from flush_to_ldisc */
-               return;
-
-       /* if we race with con_close(), vt may be null */
-       acquire_console_sem();
-       vc = tty->driver_data;
-       if (vc)
-               set_cursor(vc);
-       release_console_sem();
-}
-
-/*
- * Allocate the console screen memory.
- */
-static int con_open(struct tty_struct *tty, struct file *filp)
-{
-       unsigned int currcons = tty->index;
-       int ret = 0;
-
-       acquire_console_sem();
-       if (tty->driver_data == NULL) {
-               ret = vc_allocate(currcons);
-               if (ret == 0) {
-                       struct vc_data *vc = vc_cons[currcons].d;
-
-                       /* Still being freed */
-                       if (vc->port.tty) {
-                               release_console_sem();
-                               return -ERESTARTSYS;
-                       }
-                       tty->driver_data = vc;
-                       vc->port.tty = tty;
-
-                       if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
-                               tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
-                               tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
-                       }
-                       if (vc->vc_utf)
-                               tty->termios->c_iflag |= IUTF8;
-                       else
-                               tty->termios->c_iflag &= ~IUTF8;
-                       release_console_sem();
-                       return ret;
-               }
-       }
-       release_console_sem();
-       return ret;
-}
-
-static void con_close(struct tty_struct *tty, struct file *filp)
-{
-       /* Nothing to do - we defer to shutdown */
-}
-
-static void con_shutdown(struct tty_struct *tty)
-{
-       struct vc_data *vc = tty->driver_data;
-       BUG_ON(vc == NULL);
-       acquire_console_sem();
-       vc->port.tty = NULL;
-       release_console_sem();
-       tty_shutdown(tty);
-}
-
-static int default_italic_color    = 2; // green (ASCII)
-static int default_underline_color = 3; // cyan (ASCII)
-module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
-module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
-
-static void vc_init(struct vc_data *vc, unsigned int rows,
-                   unsigned int cols, int do_clear)
-{
-       int j, k ;
-
-       vc->vc_cols = cols;
-       vc->vc_rows = rows;
-       vc->vc_size_row = cols << 1;
-       vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
-
-       set_origin(vc);
-       vc->vc_pos = vc->vc_origin;
-       reset_vc(vc);
-       for (j=k=0; j<16; j++) {
-               vc->vc_palette[k++] = default_red[j] ;
-               vc->vc_palette[k++] = default_grn[j] ;
-               vc->vc_palette[k++] = default_blu[j] ;
-       }
-       vc->vc_def_color       = 0x07;   /* white */
-       vc->vc_ulcolor         = default_underline_color;
-       vc->vc_itcolor         = default_italic_color;
-       vc->vc_halfcolor       = 0x08;   /* grey */
-       init_waitqueue_head(&vc->paste_wait);
-       reset_terminal(vc, do_clear);
-}
-
-/*
- * This routine initializes console interrupts, and does nothing
- * else. If you want the screen to clear, call tty_write with
- * the appropriate escape-sequence.
- */
-
-static int __init con_init(void)
-{
-       const char *display_desc = NULL;
-       struct vc_data *vc;
-       unsigned int currcons = 0, i;
-
-       acquire_console_sem();
-
-       if (conswitchp)
-               display_desc = conswitchp->con_startup();
-       if (!display_desc) {
-               fg_console = 0;
-               release_console_sem();
-               return 0;
-       }
-
-       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
-               struct con_driver *con_driver = &registered_con_driver[i];
-
-               if (con_driver->con == NULL) {
-                       con_driver->con = conswitchp;
-                       con_driver->desc = display_desc;
-                       con_driver->flag = CON_DRIVER_FLAG_INIT;
-                       con_driver->first = 0;
-                       con_driver->last = MAX_NR_CONSOLES - 1;
-                       break;
-               }
-       }
-
-       for (i = 0; i < MAX_NR_CONSOLES; i++)
-               con_driver_map[i] = conswitchp;
-
-       if (blankinterval) {
-               blank_state = blank_normal_wait;
-               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
-       }
-
-       for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
-               vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
-               INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
-               tty_port_init(&vc->port);
-               visual_init(vc, currcons, 1);
-               vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
-               vc_init(vc, vc->vc_rows, vc->vc_cols,
-                       currcons || !vc->vc_sw->con_save_screen);
-       }
-       currcons = fg_console = 0;
-       master_display_fg = vc = vc_cons[currcons].d;
-       set_origin(vc);
-       save_screen(vc);
-       gotoxy(vc, vc->vc_x, vc->vc_y);
-       csi_J(vc, 0);
-       update_screen(vc);
-       printk("Console: %s %s %dx%d",
-               vc->vc_can_do_color ? "colour" : "mono",
-               display_desc, vc->vc_cols, vc->vc_rows);
-       printable = 1;
-       printk("\n");
-
-       release_console_sem();
-
-#ifdef CONFIG_VT_CONSOLE
-       register_console(&vt_console_driver);
-#endif
-       return 0;
-}
-console_initcall(con_init);
-
-static const struct tty_operations con_ops = {
-       .open = con_open,
-       .close = con_close,
-       .write = con_write,
-       .write_room = con_write_room,
-       .put_char = con_put_char,
-       .flush_chars = con_flush_chars,
-       .chars_in_buffer = con_chars_in_buffer,
-       .ioctl = vt_ioctl,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl = vt_compat_ioctl,
-#endif
-       .stop = con_stop,
-       .start = con_start,
-       .throttle = con_throttle,
-       .unthrottle = con_unthrottle,
-       .resize = vt_resize,
-       .shutdown = con_shutdown
-};
-
-static struct cdev vc0_cdev;
-
-int __init vty_init(const struct file_operations *console_fops)
-{
-       cdev_init(&vc0_cdev, console_fops);
-       if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
-           register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
-               panic("Couldn't register /dev/tty0 driver\n");
-       device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
-
-       vcs_init();
-
-       console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
-       if (!console_driver)
-               panic("Couldn't allocate console driver\n");
-       console_driver->owner = THIS_MODULE;
-       console_driver->name = "tty";
-       console_driver->name_base = 1;
-       console_driver->major = TTY_MAJOR;
-       console_driver->minor_start = 1;
-       console_driver->type = TTY_DRIVER_TYPE_CONSOLE;
-       console_driver->init_termios = tty_std_termios;
-       if (default_utf8)
-               console_driver->init_termios.c_iflag |= IUTF8;
-       console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
-       tty_set_operations(console_driver, &con_ops);
-       if (tty_register_driver(console_driver))
-               panic("Couldn't register console driver\n");
-       kbd_init();
-       console_map_init();
-#ifdef CONFIG_MDA_CONSOLE
-       mda_console_init();
-#endif
-       return 0;
-}
-
-#ifndef VT_SINGLE_DRIVER
-
-static struct class *vtconsole_class;
-
-static int bind_con_driver(const struct consw *csw, int first, int last,
-                          int deflt)
-{
-       struct module *owner = csw->owner;
-       const char *desc = NULL;
-       struct con_driver *con_driver;
-       int i, j = -1, k = -1, retval = -ENODEV;
-
-       if (!try_module_get(owner))
-               return -ENODEV;
-
-       acquire_console_sem();
-
-       /* check if driver is registered */
-       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
-               con_driver = &registered_con_driver[i];
-
-               if (con_driver->con == csw) {
-                       desc = con_driver->desc;
-                       retval = 0;
-                       break;
-               }
-       }
-
-       if (retval)
-               goto err;
-
-       if (!(con_driver->flag & CON_DRIVER_FLAG_INIT)) {
-               csw->con_startup();
-               con_driver->flag |= CON_DRIVER_FLAG_INIT;
-       }
-
-       if (deflt) {
-               if (conswitchp)
-                       module_put(conswitchp->owner);
-
-               __module_get(owner);
-               conswitchp = csw;
-       }
-
-       first = max(first, con_driver->first);
-       last = min(last, con_driver->last);
-
-       for (i = first; i <= last; i++) {
-               int old_was_color;
-               struct vc_data *vc = vc_cons[i].d;
-
-               if (con_driver_map[i])
-                       module_put(con_driver_map[i]->owner);
-               __module_get(owner);
-               con_driver_map[i] = csw;
-
-               if (!vc || !vc->vc_sw)
-                       continue;
-
-               j = i;
-
-               if (CON_IS_VISIBLE(vc)) {
-                       k = i;
-                       save_screen(vc);
-               }
-
-               old_was_color = vc->vc_can_do_color;
-               vc->vc_sw->con_deinit(vc);
-               vc->vc_origin = (unsigned long)vc->vc_screenbuf;
-               visual_init(vc, i, 0);
-               set_origin(vc);
-               update_attr(vc);
-
-               /* If the console changed between mono <-> color, then
-                * the attributes in the screenbuf will be wrong.  The
-                * following resets all attributes to something sane.
-                */
-               if (old_was_color != vc->vc_can_do_color)
-                       clear_buffer_attributes(vc);
-       }
-
-       printk("Console: switching ");
-       if (!deflt)
-               printk("consoles %d-%d ", first+1, last+1);
-       if (j >= 0) {
-               struct vc_data *vc = vc_cons[j].d;
-
-               printk("to %s %s %dx%d\n",
-                      vc->vc_can_do_color ? "colour" : "mono",
-                      desc, vc->vc_cols, vc->vc_rows);
-
-               if (k >= 0) {
-                       vc = vc_cons[k].d;
-                       update_screen(vc);
-               }
-       } else
-               printk("to %s\n", desc);
-
-       retval = 0;
-err:
-       release_console_sem();
-       module_put(owner);
-       return retval;
-};
-
-#ifdef CONFIG_VT_HW_CONSOLE_BINDING
-static int con_is_graphics(const struct consw *csw, int first, int last)
-{
-       int i, retval = 0;
-
-       for (i = first; i <= last; i++) {
-               struct vc_data *vc = vc_cons[i].d;
-
-               if (vc && vc->vc_mode == KD_GRAPHICS) {
-                       retval = 1;
-                       break;
-               }
-       }
-
-       return retval;
-}
-
-/**
- * unbind_con_driver - unbind a console driver
- * @csw: pointer to console driver to unregister
- * @first: first in range of consoles that @csw should be unbound from
- * @last: last in range of consoles that @csw should be unbound from
- * @deflt: should next bound console driver be default after @csw is unbound?
- *
- * To unbind a driver from all possible consoles, pass 0 as @first and
- * %MAX_NR_CONSOLES as @last.
- *
- * @deflt controls whether the console that ends up replacing @csw should be
- * the default console.
- *
- * RETURNS:
- * -ENODEV if @csw isn't a registered console driver or can't be unregistered
- * or 0 on success.
- */
-int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
-{
-       struct module *owner = csw->owner;
-       const struct consw *defcsw = NULL;
-       struct con_driver *con_driver = NULL, *con_back = NULL;
-       int i, retval = -ENODEV;
-
-       if (!try_module_get(owner))
-               return -ENODEV;
-
-       acquire_console_sem();
-
-       /* check if driver is registered and if it is unbindable */
-       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
-               con_driver = &registered_con_driver[i];
-
-               if (con_driver->con == csw &&
-                   con_driver->flag & CON_DRIVER_FLAG_MODULE) {
-                       retval = 0;
-                       break;
-               }
-       }
-
-       if (retval) {
-               release_console_sem();
-               goto err;
-       }
-
-       retval = -ENODEV;
-
-       /* check if backup driver exists */
-       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
-               con_back = &registered_con_driver[i];
-
-               if (con_back->con &&
-                   !(con_back->flag & CON_DRIVER_FLAG_MODULE)) {
-                       defcsw = con_back->con;
-                       retval = 0;
-                       break;
-               }
-       }
-
-       if (retval) {
-               release_console_sem();
-               goto err;
-       }
-
-       if (!con_is_bound(csw)) {
-               release_console_sem();
-               goto err;
-       }
-
-       first = max(first, con_driver->first);
-       last = min(last, con_driver->last);
-
-       for (i = first; i <= last; i++) {
-               if (con_driver_map[i] == csw) {
-                       module_put(csw->owner);
-                       con_driver_map[i] = NULL;
-               }
-       }
-
-       if (!con_is_bound(defcsw)) {
-               const struct consw *defconsw = conswitchp;
-
-               defcsw->con_startup();
-               con_back->flag |= CON_DRIVER_FLAG_INIT;
-               /*
-                * vgacon may change the default driver to point
-                * to dummycon, we restore it here...
-                */
-               conswitchp = defconsw;
-       }
-
-       if (!con_is_bound(csw))
-               con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
-
-       release_console_sem();
-       /* ignore return value, binding should not fail */
-       bind_con_driver(defcsw, first, last, deflt);
-err:
-       module_put(owner);
-       return retval;
-
-}
-EXPORT_SYMBOL(unbind_con_driver);
-
-static int vt_bind(struct con_driver *con)
-{
-       const struct consw *defcsw = NULL, *csw = NULL;
-       int i, more = 1, first = -1, last = -1, deflt = 0;
-
-       if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
-           con_is_graphics(con->con, con->first, con->last))
-               goto err;
-
-       csw = con->con;
-
-       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
-               struct con_driver *con = &registered_con_driver[i];
-
-               if (con->con && !(con->flag & CON_DRIVER_FLAG_MODULE)) {
-                       defcsw = con->con;
-                       break;
-               }
-       }
-
-       if (!defcsw)
-               goto err;
-
-       while (more) {
-               more = 0;
-
-               for (i = con->first; i <= con->last; i++) {
-                       if (con_driver_map[i] == defcsw) {
-                               if (first == -1)
-                                       first = i;
-                               last = i;
-                               more = 1;
-                       } else if (first != -1)
-                               break;
-               }
-
-               if (first == 0 && last == MAX_NR_CONSOLES -1)
-                       deflt = 1;
-
-               if (first != -1)
-                       bind_con_driver(csw, first, last, deflt);
-
-               first = -1;
-               last = -1;
-               deflt = 0;
-       }
-
-err:
-       return 0;
-}
-
-static int vt_unbind(struct con_driver *con)
-{
-       const struct consw *csw = NULL;
-       int i, more = 1, first = -1, last = -1, deflt = 0;
-
-       if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
-           con_is_graphics(con->con, con->first, con->last))
-               goto err;
-
-       csw = con->con;
-
-       while (more) {
-               more = 0;
-
-               for (i = con->first; i <= con->last; i++) {
-                       if (con_driver_map[i] == csw) {
-                               if (first == -1)
-                                       first = i;
-                               last = i;
-                               more = 1;
-                       } else if (first != -1)
-                               break;
-               }
-
-               if (first == 0 && last == MAX_NR_CONSOLES -1)
-                       deflt = 1;
-
-               if (first != -1)
-                       unbind_con_driver(csw, first, last, deflt);
-
-               first = -1;
-               last = -1;
-               deflt = 0;
-       }
-
-err:
-       return 0;
-}
-#else
-static inline int vt_bind(struct con_driver *con)
-{
-       return 0;
-}
-static inline int vt_unbind(struct con_driver *con)
-{
-       return 0;
-}
-#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
-
-static ssize_t store_bind(struct device *dev, struct device_attribute *attr,
-                         const char *buf, size_t count)
-{
-       struct con_driver *con = dev_get_drvdata(dev);
-       int bind = simple_strtoul(buf, NULL, 0);
-
-       if (bind)
-               vt_bind(con);
-       else
-               vt_unbind(con);
-
-       return count;
-}
-
-static ssize_t show_bind(struct device *dev, struct device_attribute *attr,
-                        char *buf)
-{
-       struct con_driver *con = dev_get_drvdata(dev);
-       int bind = con_is_bound(con->con);
-
-       return snprintf(buf, PAGE_SIZE, "%i\n", bind);
-}
-
-static ssize_t show_name(struct device *dev, struct device_attribute *attr,
-                        char *buf)
-{
-       struct con_driver *con = dev_get_drvdata(dev);
-
-       return snprintf(buf, PAGE_SIZE, "%s %s\n",
-                       (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)",
-                        con->desc);
-
-}
-
-static struct device_attribute device_attrs[] = {
-       __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind),
-       __ATTR(name, S_IRUGO, show_name, NULL),
-};
-
-static int vtconsole_init_device(struct con_driver *con)
-{
-       int i;
-       int error = 0;
-
-       con->flag |= CON_DRIVER_FLAG_ATTR;
-       dev_set_drvdata(con->dev, con);
-       for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
-               error = device_create_file(con->dev, &device_attrs[i]);
-               if (error)
-                       break;
-       }
-
-       if (error) {
-               while (--i >= 0)
-                       device_remove_file(con->dev, &device_attrs[i]);
-               con->flag &= ~CON_DRIVER_FLAG_ATTR;
-       }
-
-       return error;
-}
-
-static void vtconsole_deinit_device(struct con_driver *con)
-{
-       int i;
-
-       if (con->flag & CON_DRIVER_FLAG_ATTR) {
-               for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
-                       device_remove_file(con->dev, &device_attrs[i]);
-               con->flag &= ~CON_DRIVER_FLAG_ATTR;
-       }
-}
-
-/**
- * con_is_bound - checks if driver is bound to the console
- * @csw: console driver
- *
- * RETURNS: zero if unbound, nonzero if bound
- *
- * Drivers can call this and if zero, they should release
- * all resources allocated on con_startup()
- */
-int con_is_bound(const struct consw *csw)
-{
-       int i, bound = 0;
-
-       for (i = 0; i < MAX_NR_CONSOLES; i++) {
-               if (con_driver_map[i] == csw) {
-                       bound = 1;
-                       break;
-               }
-       }
-
-       return bound;
-}
-EXPORT_SYMBOL(con_is_bound);
-
-/**
- * con_debug_enter - prepare the console for the kernel debugger
- * @sw: console driver
- *
- * Called when the console is taken over by the kernel debugger, this
- * function needs to save the current console state, then put the console
- * into a state suitable for the kernel debugger.
- *
- * RETURNS:
- * Zero on success, nonzero if a failure occurred when trying to prepare
- * the console for the debugger.
- */
-int con_debug_enter(struct vc_data *vc)
-{
-       int ret = 0;
-
-       saved_fg_console = fg_console;
-       saved_last_console = last_console;
-       saved_want_console = want_console;
-       saved_vc_mode = vc->vc_mode;
-       saved_console_blanked = console_blanked;
-       vc->vc_mode = KD_TEXT;
-       console_blanked = 0;
-       if (vc->vc_sw->con_debug_enter)
-               ret = vc->vc_sw->con_debug_enter(vc);
-#ifdef CONFIG_KGDB_KDB
-       /* Set the initial LINES variable if it is not already set */
-       if (vc->vc_rows < 999) {
-               int linecount;
-               char lns[4];
-               const char *setargs[3] = {
-                       "set",
-                       "LINES",
-                       lns,
-               };
-               if (kdbgetintenv(setargs[0], &linecount)) {
-                       snprintf(lns, 4, "%i", vc->vc_rows);
-                       kdb_set(2, setargs);
-               }
-       }
-#endif /* CONFIG_KGDB_KDB */
-       return ret;
-}
-EXPORT_SYMBOL_GPL(con_debug_enter);
-
-/**
- * con_debug_leave - restore console state
- * @sw: console driver
- *
- * Restore the console state to what it was before the kernel debugger
- * was invoked.
- *
- * RETURNS:
- * Zero on success, nonzero if a failure occurred when trying to restore
- * the console.
- */
-int con_debug_leave(void)
-{
-       struct vc_data *vc;
-       int ret = 0;
-
-       fg_console = saved_fg_console;
-       last_console = saved_last_console;
-       want_console = saved_want_console;
-       console_blanked = saved_console_blanked;
-       vc_cons[fg_console].d->vc_mode = saved_vc_mode;
-
-       vc = vc_cons[fg_console].d;
-       if (vc->vc_sw->con_debug_leave)
-               ret = vc->vc_sw->con_debug_leave(vc);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(con_debug_leave);
-
-/**
- * register_con_driver - register console driver to console layer
- * @csw: console driver
- * @first: the first console to take over, minimum value is 0
- * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
- *
- * DESCRIPTION: This function registers a console driver which can later
- * bind to a range of consoles specified by @first and @last. It will
- * also initialize the console driver by calling con_startup().
- */
-int register_con_driver(const struct consw *csw, int first, int last)
-{
-       struct module *owner = csw->owner;
-       struct con_driver *con_driver;
-       const char *desc;
-       int i, retval = 0;
-
-       if (!try_module_get(owner))
-               return -ENODEV;
-
-       acquire_console_sem();
-
-       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
-               con_driver = &registered_con_driver[i];
-
-               /* already registered */
-               if (con_driver->con == csw)
-                       retval = -EINVAL;
-       }
-
-       if (retval)
-               goto err;
-
-       desc = csw->con_startup();
-
-       if (!desc)
-               goto err;
-
-       retval = -EINVAL;
-
-       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
-               con_driver = &registered_con_driver[i];
-
-               if (con_driver->con == NULL) {
-                       con_driver->con = csw;
-                       con_driver->desc = desc;
-                       con_driver->node = i;
-                       con_driver->flag = CON_DRIVER_FLAG_MODULE |
-                                          CON_DRIVER_FLAG_INIT;
-                       con_driver->first = first;
-                       con_driver->last = last;
-                       retval = 0;
-                       break;
-               }
-       }
-
-       if (retval)
-               goto err;
-
-       con_driver->dev = device_create(vtconsole_class, NULL,
-                                               MKDEV(0, con_driver->node),
-                                               NULL, "vtcon%i",
-                                               con_driver->node);
-
-       if (IS_ERR(con_driver->dev)) {
-               printk(KERN_WARNING "Unable to create device for %s; "
-                      "errno = %ld\n", con_driver->desc,
-                      PTR_ERR(con_driver->dev));
-               con_driver->dev = NULL;
-       } else {
-               vtconsole_init_device(con_driver);
-       }
-
-err:
-       release_console_sem();
-       module_put(owner);
-       return retval;
-}
-EXPORT_SYMBOL(register_con_driver);
-
-/**
- * unregister_con_driver - unregister console driver from console layer
- * @csw: console driver
- *
- * DESCRIPTION: All drivers that registers to the console layer must
- * call this function upon exit, or if the console driver is in a state
- * where it won't be able to handle console services, such as the
- * framebuffer console without loaded framebuffer drivers.
- *
- * The driver must unbind first prior to unregistration.
- */
-int unregister_con_driver(const struct consw *csw)
-{
-       int i, retval = -ENODEV;
-
-       acquire_console_sem();
-
-       /* cannot unregister a bound driver */
-       if (con_is_bound(csw))
-               goto err;
-
-       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
-               struct con_driver *con_driver = &registered_con_driver[i];
-
-               if (con_driver->con == csw &&
-                   con_driver->flag & CON_DRIVER_FLAG_MODULE) {
-                       vtconsole_deinit_device(con_driver);
-                       device_destroy(vtconsole_class,
-                                      MKDEV(0, con_driver->node));
-                       con_driver->con = NULL;
-                       con_driver->desc = NULL;
-                       con_driver->dev = NULL;
-                       con_driver->node = 0;
-                       con_driver->flag = 0;
-                       con_driver->first = 0;
-                       con_driver->last = 0;
-                       retval = 0;
-                       break;
-               }
-       }
-err:
-       release_console_sem();
-       return retval;
-}
-EXPORT_SYMBOL(unregister_con_driver);
-
-/*
- *     If we support more console drivers, this function is used
- *     when a driver wants to take over some existing consoles
- *     and become default driver for newly opened ones.
- *
- *      take_over_console is basically a register followed by unbind
- */
-int take_over_console(const struct consw *csw, int first, int last, int deflt)
-{
-       int err;
-
-       err = register_con_driver(csw, first, last);
-
-       if (!err)
-               bind_con_driver(csw, first, last, deflt);
-
-       return err;
-}
-
-/*
- * give_up_console is a wrapper to unregister_con_driver. It will only
- * work if driver is fully unbound.
- */
-void give_up_console(const struct consw *csw)
-{
-       unregister_con_driver(csw);
-}
-
-static int __init vtconsole_class_init(void)
-{
-       int i;
-
-       vtconsole_class = class_create(THIS_MODULE, "vtconsole");
-       if (IS_ERR(vtconsole_class)) {
-               printk(KERN_WARNING "Unable to create vt console class; "
-                      "errno = %ld\n", PTR_ERR(vtconsole_class));
-               vtconsole_class = NULL;
-       }
-
-       /* Add system drivers to sysfs */
-       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
-               struct con_driver *con = &registered_con_driver[i];
-
-               if (con->con && !con->dev) {
-                       con->dev = device_create(vtconsole_class, NULL,
-                                                        MKDEV(0, con->node),
-                                                        NULL, "vtcon%i",
-                                                        con->node);
-
-                       if (IS_ERR(con->dev)) {
-                               printk(KERN_WARNING "Unable to create "
-                                      "device for %s; errno = %ld\n",
-                                      con->desc, PTR_ERR(con->dev));
-                               con->dev = NULL;
-                       } else {
-                               vtconsole_init_device(con);
-                       }
-               }
-       }
-
-       return 0;
-}
-postcore_initcall(vtconsole_class_init);
-
-#endif
-
-/*
- *     Screen blanking
- */
-
-static int set_vesa_blanking(char __user *p)
-{
-       unsigned int mode;
-
-       if (get_user(mode, p + 1))
-               return -EFAULT;
-
-       vesa_blank_mode = (mode < 4) ? mode : 0;
-       return 0;
-}
-
-void do_blank_screen(int entering_gfx)
-{
-       struct vc_data *vc = vc_cons[fg_console].d;
-       int i;
-
-       WARN_CONSOLE_UNLOCKED();
-
-       if (console_blanked) {
-               if (blank_state == blank_vesa_wait) {
-                       blank_state = blank_off;
-                       vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
-               }
-               return;
-       }
-
-       /* entering graphics mode? */
-       if (entering_gfx) {
-               hide_cursor(vc);
-               save_screen(vc);
-               vc->vc_sw->con_blank(vc, -1, 1);
-               console_blanked = fg_console + 1;
-               blank_state = blank_off;
-               set_origin(vc);
-               return;
-       }
-
-       if (blank_state != blank_normal_wait)
-               return;
-       blank_state = blank_off;
-
-       /* don't blank graphics */
-       if (vc->vc_mode != KD_TEXT) {
-               console_blanked = fg_console + 1;
-               return;
-       }
-
-       hide_cursor(vc);
-       del_timer_sync(&console_timer);
-       blank_timer_expired = 0;
-
-       save_screen(vc);
-       /* In case we need to reset origin, blanking hook returns 1 */
-       i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
-       console_blanked = fg_console + 1;
-       if (i)
-               set_origin(vc);
-
-       if (console_blank_hook && console_blank_hook(1))
-               return;
-
-       if (vesa_off_interval && vesa_blank_mode) {
-               blank_state = blank_vesa_wait;
-               mod_timer(&console_timer, jiffies + vesa_off_interval);
-       }
-       vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
-}
-EXPORT_SYMBOL(do_blank_screen);
-
-/*
- * Called by timer as well as from vt_console_driver
- */
-void do_unblank_screen(int leaving_gfx)
-{
-       struct vc_data *vc;
-
-       /* This should now always be called from a "sane" (read: can schedule)
-        * context for the sake of the low level drivers, except in the special
-        * case of oops_in_progress
-        */
-       if (!oops_in_progress)
-               might_sleep();
-
-       WARN_CONSOLE_UNLOCKED();
-
-       ignore_poke = 0;
-       if (!console_blanked)
-               return;
-       if (!vc_cons_allocated(fg_console)) {
-               /* impossible */
-               printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
-               return;
-       }
-       vc = vc_cons[fg_console].d;
-       /* Try to unblank in oops case too */
-       if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
-               return; /* but leave console_blanked != 0 */
-
-       if (blankinterval) {
-               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
-               blank_state = blank_normal_wait;
-       }
-
-       console_blanked = 0;
-       if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
-               /* Low-level driver cannot restore -> do it ourselves */
-               update_screen(vc);
-       if (console_blank_hook)
-               console_blank_hook(0);
-       set_palette(vc);
-       set_cursor(vc);
-       vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
-}
-EXPORT_SYMBOL(do_unblank_screen);
-
-/*
- * This is called by the outside world to cause a forced unblank, mostly for
- * oopses. Currently, I just call do_unblank_screen(0), but we could eventually
- * call it with 1 as an argument and so force a mode restore... that may kill
- * X or at least garbage the screen but would also make the Oops visible...
- */
-void unblank_screen(void)
-{
-       do_unblank_screen(0);
-}
-
-/*
- * We defer the timer blanking to work queue so it can take the console mutex
- * (console operations can still happen at irq time, but only from printk which
- * has the console mutex. Not perfect yet, but better than no locking
- */
-static void blank_screen_t(unsigned long dummy)
-{
-       if (unlikely(!keventd_up())) {
-               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
-               return;
-       }
-       blank_timer_expired = 1;
-       schedule_work(&console_work);
-}
-
-void poke_blanked_console(void)
-{
-       WARN_CONSOLE_UNLOCKED();
-
-       /* Add this so we quickly catch whoever might call us in a non
-        * safe context. Nowadays, unblank_screen() isn't to be called in
-        * atomic contexts and is allowed to schedule (with the special case
-        * of oops_in_progress, but that isn't of any concern for this
-        * function. --BenH.
-        */
-       might_sleep();
-
-       /* This isn't perfectly race free, but a race here would be mostly harmless,
-        * at worse, we'll do a spurrious blank and it's unlikely
-        */
-       del_timer(&console_timer);
-       blank_timer_expired = 0;
-
-       if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode == KD_GRAPHICS)
-               return;
-       if (console_blanked)
-               unblank_screen();
-       else if (blankinterval) {
-               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
-               blank_state = blank_normal_wait;
-       }
-}
-
-/*
- *     Palettes
- */
-
-static void set_palette(struct vc_data *vc)
-{
-       WARN_CONSOLE_UNLOCKED();
-
-       if (vc->vc_mode != KD_GRAPHICS)
-               vc->vc_sw->con_set_palette(vc, color_table);
-}
-
-static int set_get_cmap(unsigned char __user *arg, int set)
-{
-    int i, j, k;
-
-    WARN_CONSOLE_UNLOCKED();
-
-    for (i = 0; i < 16; i++)
-       if (set) {
-           get_user(default_red[i], arg++);
-           get_user(default_grn[i], arg++);
-           get_user(default_blu[i], arg++);
-       } else {
-           put_user(default_red[i], arg++);
-           put_user(default_grn[i], arg++);
-           put_user(default_blu[i], arg++);
-       }
-    if (set) {
-       for (i = 0; i < MAX_NR_CONSOLES; i++)
-           if (vc_cons_allocated(i)) {
-               for (j = k = 0; j < 16; j++) {
-                   vc_cons[i].d->vc_palette[k++] = default_red[j];
-                   vc_cons[i].d->vc_palette[k++] = default_grn[j];
-                   vc_cons[i].d->vc_palette[k++] = default_blu[j];
-               }
-               set_palette(vc_cons[i].d);
-           }
-    }
-    return 0;
-}
-
-/*
- * Load palette into the DAC registers. arg points to a colour
- * map, 3 bytes per colour, 16 colours, range from 0 to 255.
- */
-
-int con_set_cmap(unsigned char __user *arg)
-{
-       int rc;
-
-       acquire_console_sem();
-       rc = set_get_cmap (arg,1);
-       release_console_sem();
-
-       return rc;
-}
-
-int con_get_cmap(unsigned char __user *arg)
-{
-       int rc;
-
-       acquire_console_sem();
-       rc = set_get_cmap (arg,0);
-       release_console_sem();
-
-       return rc;
-}
-
-void reset_palette(struct vc_data *vc)
-{
-       int j, k;
-       for (j=k=0; j<16; j++) {
-               vc->vc_palette[k++] = default_red[j];
-               vc->vc_palette[k++] = default_grn[j];
-               vc->vc_palette[k++] = default_blu[j];
-       }
-       set_palette(vc);
-}
-
-/*
- *  Font switching
- *
- *  Currently we only support fonts up to 32 pixels wide, at a maximum height
- *  of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints, 
- *  depending on width) reserved for each character which is kinda wasty, but 
- *  this is done in order to maintain compatibility with the EGA/VGA fonts. It 
- *  is upto the actual low-level console-driver convert data into its favorite
- *  format (maybe we should add a `fontoffset' field to the `display'
- *  structure so we won't have to convert the fontdata all the time.
- *  /Jes
- */
-
-#define max_font_size 65536
-
-static int con_font_get(struct vc_data *vc, struct console_font_op *op)
-{
-       struct console_font font;
-       int rc = -EINVAL;
-       int c;
-
-       if (vc->vc_mode != KD_TEXT)
-               return -EINVAL;
-
-       if (op->data) {
-               font.data = kmalloc(max_font_size, GFP_KERNEL);
-               if (!font.data)
-                       return -ENOMEM;
-       } else
-               font.data = NULL;
-
-       acquire_console_sem();
-       if (vc->vc_sw->con_font_get)
-               rc = vc->vc_sw->con_font_get(vc, &font);
-       else
-               rc = -ENOSYS;
-       release_console_sem();
-
-       if (rc)
-               goto out;
-
-       c = (font.width+7)/8 * 32 * font.charcount;
-
-       if (op->data && font.charcount > op->charcount)
-               rc = -ENOSPC;
-       if (!(op->flags & KD_FONT_FLAG_OLD)) {
-               if (font.width > op->width || font.height > op->height) 
-                       rc = -ENOSPC;
-       } else {
-               if (font.width != 8)
-                       rc = -EIO;
-               else if ((op->height && font.height > op->height) ||
-                        font.height > 32)
-                       rc = -ENOSPC;
-       }
-       if (rc)
-               goto out;
-
-       op->height = font.height;
-       op->width = font.width;
-       op->charcount = font.charcount;
-
-       if (op->data && copy_to_user(op->data, font.data, c))
-               rc = -EFAULT;
-
-out:
-       kfree(font.data);
-       return rc;
-}
-
-static int con_font_set(struct vc_data *vc, struct console_font_op *op)
-{
-       struct console_font font;
-       int rc = -EINVAL;
-       int size;
-
-       if (vc->vc_mode != KD_TEXT)
-               return -EINVAL;
-       if (!op->data)
-               return -EINVAL;
-       if (op->charcount > 512)
-               return -EINVAL;
-       if (!op->height) {              /* Need to guess font height [compat] */
-               int h, i;
-               u8 __user *charmap = op->data;
-               u8 tmp;
-               
-               /* If from KDFONTOP ioctl, don't allow things which can be done in userland,
-                  so that we can get rid of this soon */
-               if (!(op->flags & KD_FONT_FLAG_OLD))
-                       return -EINVAL;
-               for (h = 32; h > 0; h--)
-                       for (i = 0; i < op->charcount; i++) {
-                               if (get_user(tmp, &charmap[32*i+h-1]))
-                                       return -EFAULT;
-                               if (tmp)
-                                       goto nonzero;
-                       }
-               return -EINVAL;
-       nonzero:
-               op->height = h;
-       }
-       if (op->width <= 0 || op->width > 32 || op->height > 32)
-               return -EINVAL;
-       size = (op->width+7)/8 * 32 * op->charcount;
-       if (size > max_font_size)
-               return -ENOSPC;
-       font.charcount = op->charcount;
-       font.height = op->height;
-       font.width = op->width;
-       font.data = memdup_user(op->data, size);
-       if (IS_ERR(font.data))
-               return PTR_ERR(font.data);
-       acquire_console_sem();
-       if (vc->vc_sw->con_font_set)
-               rc = vc->vc_sw->con_font_set(vc, &font, op->flags);
-       else
-               rc = -ENOSYS;
-       release_console_sem();
-       kfree(font.data);
-       return rc;
-}
-
-static int con_font_default(struct vc_data *vc, struct console_font_op *op)
-{
-       struct console_font font = {.width = op->width, .height = op->height};
-       char name[MAX_FONT_NAME];
-       char *s = name;
-       int rc;
-
-       if (vc->vc_mode != KD_TEXT)
-               return -EINVAL;
-
-       if (!op->data)
-               s = NULL;
-       else if (strncpy_from_user(name, op->data, MAX_FONT_NAME - 1) < 0)
-               return -EFAULT;
-       else
-               name[MAX_FONT_NAME - 1] = 0;
-
-       acquire_console_sem();
-       if (vc->vc_sw->con_font_default)
-               rc = vc->vc_sw->con_font_default(vc, &font, s);
-       else
-               rc = -ENOSYS;
-       release_console_sem();
-       if (!rc) {
-               op->width = font.width;
-               op->height = font.height;
-       }
-       return rc;
-}
-
-static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
-{
-       int con = op->height;
-       int rc;
-
-       if (vc->vc_mode != KD_TEXT)
-               return -EINVAL;
-
-       acquire_console_sem();
-       if (!vc->vc_sw->con_font_copy)
-               rc = -ENOSYS;
-       else if (con < 0 || !vc_cons_allocated(con))
-               rc = -ENOTTY;
-       else if (con == vc->vc_num)     /* nothing to do */
-               rc = 0;
-       else
-               rc = vc->vc_sw->con_font_copy(vc, con);
-       release_console_sem();
-       return rc;
-}
-
-int con_font_op(struct vc_data *vc, struct console_font_op *op)
-{
-       switch (op->op) {
-       case KD_FONT_OP_SET:
-               return con_font_set(vc, op);
-       case KD_FONT_OP_GET:
-               return con_font_get(vc, op);
-       case KD_FONT_OP_SET_DEFAULT:
-               return con_font_default(vc, op);
-       case KD_FONT_OP_COPY:
-               return con_font_copy(vc, op);
-       }
-       return -ENOSYS;
-}
-
-/*
- *     Interface exported to selection and vcs.
- */
-
-/* used by selection */
-u16 screen_glyph(struct vc_data *vc, int offset)
-{
-       u16 w = scr_readw(screenpos(vc, offset, 1));
-       u16 c = w & 0xff;
-
-       if (w & vc->vc_hi_font_mask)
-               c |= 0x100;
-       return c;
-}
-EXPORT_SYMBOL_GPL(screen_glyph);
-
-/* used by vcs - note the word offset */
-unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
-{
-       return screenpos(vc, 2 * w_offset, viewed);
-}
-
-void getconsxy(struct vc_data *vc, unsigned char *p)
-{
-       p[0] = vc->vc_x;
-       p[1] = vc->vc_y;
-}
-
-void putconsxy(struct vc_data *vc, unsigned char *p)
-{
-       hide_cursor(vc);
-       gotoxy(vc, p[0], p[1]);
-       set_cursor(vc);
-}
-
-u16 vcs_scr_readw(struct vc_data *vc, const u16 *org)
-{
-       if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
-               return softcursor_original;
-       return scr_readw(org);
-}
-
-void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
-{
-       scr_writew(val, org);
-       if ((unsigned long)org == vc->vc_pos) {
-               softcursor_original = -1;
-               add_softcursor(vc);
-       }
-}
-
-void vcs_scr_updated(struct vc_data *vc)
-{
-       notify_update(vc);
-}
-
-/*
- *     Visible symbols for modules
- */
-
-EXPORT_SYMBOL(color_table);
-EXPORT_SYMBOL(default_red);
-EXPORT_SYMBOL(default_grn);
-EXPORT_SYMBOL(default_blu);
-EXPORT_SYMBOL(update_region);
-EXPORT_SYMBOL(redraw_screen);
-EXPORT_SYMBOL(vc_resize);
-EXPORT_SYMBOL(fg_console);
-EXPORT_SYMBOL(console_blank_hook);
-EXPORT_SYMBOL(console_blanked);
-EXPORT_SYMBOL(vc_cons);
-EXPORT_SYMBOL(global_cursor_default);
-#ifndef VT_SINGLE_DRIVER
-EXPORT_SYMBOL(take_over_console);
-EXPORT_SYMBOL(give_up_console);
-#endif
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
deleted file mode 100644 (file)
index 6b68a0f..0000000
+++ /dev/null
@@ -1,1788 +0,0 @@
-/*
- *  linux/drivers/char/vt_ioctl.c
- *
- *  Copyright (C) 1992 obz under the linux copyright
- *
- *  Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
- *  Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
- *  Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
- *  Some code moved for less code duplication - Andi Kleen - Mar 1997
- *  Check put/get_user, cleanups - acme@conectiva.com.br - Jun 2001
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-#include <linux/timer.h>
-#include <linux/kernel.h>
-#include <linux/compat.h>
-#include <linux/module.h>
-#include <linux/kd.h>
-#include <linux/vt.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-#include <linux/console.h>
-#include <linux/consolemap.h>
-#include <linux/signal.h>
-#include <linux/smp_lock.h>
-#include <linux/timex.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/kbd_diacr.h>
-#include <linux/selection.h>
-
-char vt_dont_switch;
-extern struct tty_driver *console_driver;
-
-#define VT_IS_IN_USE(i)        (console_driver->ttys[i] && console_driver->ttys[i]->count)
-#define VT_BUSY(i)     (VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
-
-/*
- * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
- * experimentation and study of X386 SYSV handling.
- *
- * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
- * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
- * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
- * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
- * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
- * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
- * to the current console is done by the main ioctl code.
- */
-
-#ifdef CONFIG_X86
-#include <linux/syscalls.h>
-#endif
-
-static void complete_change_console(struct vc_data *vc);
-
-/*
- *     User space VT_EVENT handlers
- */
-
-struct vt_event_wait {
-       struct list_head list;
-       struct vt_event event;
-       int done;
-};
-
-static LIST_HEAD(vt_events);
-static DEFINE_SPINLOCK(vt_event_lock);
-static DECLARE_WAIT_QUEUE_HEAD(vt_event_waitqueue);
-
-/**
- *     vt_event_post
- *     @event: the event that occurred
- *     @old: old console
- *     @new: new console
- *
- *     Post an VT event to interested VT handlers
- */
-
-void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
-{
-       struct list_head *pos, *head;
-       unsigned long flags;
-       int wake = 0;
-
-       spin_lock_irqsave(&vt_event_lock, flags);
-       head = &vt_events;
-
-       list_for_each(pos, head) {
-               struct vt_event_wait *ve = list_entry(pos,
-                                               struct vt_event_wait, list);
-               if (!(ve->event.event & event))
-                       continue;
-               ve->event.event = event;
-               /* kernel view is consoles 0..n-1, user space view is
-                  console 1..n with 0 meaning current, so we must bias */
-               ve->event.oldev = old + 1;
-               ve->event.newev = new + 1;
-               wake = 1;
-               ve->done = 1;
-       }
-       spin_unlock_irqrestore(&vt_event_lock, flags);
-       if (wake)
-               wake_up_interruptible(&vt_event_waitqueue);
-}
-
-/**
- *     vt_event_wait           -       wait for an event
- *     @vw: our event
- *
- *     Waits for an event to occur which completes our vt_event_wait
- *     structure. On return the structure has wv->done set to 1 for success
- *     or 0 if some event such as a signal ended the wait.
- */
-
-static void vt_event_wait(struct vt_event_wait *vw)
-{
-       unsigned long flags;
-       /* Prepare the event */
-       INIT_LIST_HEAD(&vw->list);
-       vw->done = 0;
-       /* Queue our event */
-       spin_lock_irqsave(&vt_event_lock, flags);
-       list_add(&vw->list, &vt_events);
-       spin_unlock_irqrestore(&vt_event_lock, flags);
-       /* Wait for it to pass */
-       wait_event_interruptible_tty(vt_event_waitqueue, vw->done);
-       /* Dequeue it */
-       spin_lock_irqsave(&vt_event_lock, flags);
-       list_del(&vw->list);
-       spin_unlock_irqrestore(&vt_event_lock, flags);
-}
-
-/**
- *     vt_event_wait_ioctl     -       event ioctl handler
- *     @arg: argument to ioctl
- *
- *     Implement the VT_WAITEVENT ioctl using the VT event interface
- */
-
-static int vt_event_wait_ioctl(struct vt_event __user *event)
-{
-       struct vt_event_wait vw;
-
-       if (copy_from_user(&vw.event, event, sizeof(struct vt_event)))
-               return -EFAULT;
-       /* Highest supported event for now */
-       if (vw.event.event & ~VT_MAX_EVENT)
-               return -EINVAL;
-
-       vt_event_wait(&vw);
-       /* If it occurred report it */
-       if (vw.done) {
-               if (copy_to_user(event, &vw.event, sizeof(struct vt_event)))
-                       return -EFAULT;
-               return 0;
-       }
-       return -EINTR;
-}
-
-/**
- *     vt_waitactive   -       active console wait
- *     @event: event code
- *     @n: new console
- *
- *     Helper for event waits. Used to implement the legacy
- *     event waiting ioctls in terms of events
- */
-
-int vt_waitactive(int n)
-{
-       struct vt_event_wait vw;
-       do {
-               if (n == fg_console + 1)
-                       break;
-               vw.event.event = VT_EVENT_SWITCH;
-               vt_event_wait(&vw);
-               if (vw.done == 0)
-                       return -EINTR;
-       } while (vw.event.newev != n);
-       return 0;
-}
-
-/*
- * these are the valid i/o ports we're allowed to change. they map all the
- * video ports
- */
-#define GPFIRST 0x3b4
-#define GPLAST 0x3df
-#define GPNUM (GPLAST - GPFIRST + 1)
-
-#define i (tmp.kb_index)
-#define s (tmp.kb_table)
-#define v (tmp.kb_value)
-static inline int
-do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_struct *kbd)
-{
-       struct kbentry tmp;
-       ushort *key_map, val, ov;
-
-       if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
-               return -EFAULT;
-
-       if (!capable(CAP_SYS_TTY_CONFIG))
-               perm = 0;
-
-       switch (cmd) {
-       case KDGKBENT:
-               key_map = key_maps[s];
-               if (key_map) {
-                   val = U(key_map[i]);
-                   if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
-                       val = K_HOLE;
-               } else
-                   val = (i ? K_HOLE : K_NOSUCHMAP);
-               return put_user(val, &user_kbe->kb_value);
-       case KDSKBENT:
-               if (!perm)
-                       return -EPERM;
-               if (!i && v == K_NOSUCHMAP) {
-                       /* deallocate map */
-                       key_map = key_maps[s];
-                       if (s && key_map) {
-                           key_maps[s] = NULL;
-                           if (key_map[0] == U(K_ALLOCATED)) {
-                                       kfree(key_map);
-                                       keymap_count--;
-                           }
-                       }
-                       break;
-               }
-
-               if (KTYP(v) < NR_TYPES) {
-                   if (KVAL(v) > max_vals[KTYP(v)])
-                               return -EINVAL;
-               } else
-                   if (kbd->kbdmode != VC_UNICODE)
-                               return -EINVAL;
-
-               /* ++Geert: non-PC keyboards may generate keycode zero */
-#if !defined(__mc68000__) && !defined(__powerpc__)
-               /* assignment to entry 0 only tests validity of args */
-               if (!i)
-                       break;
-#endif
-
-               if (!(key_map = key_maps[s])) {
-                       int j;
-
-                       if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
-                           !capable(CAP_SYS_RESOURCE))
-                               return -EPERM;
-
-                       key_map = kmalloc(sizeof(plain_map),
-                                                    GFP_KERNEL);
-                       if (!key_map)
-                               return -ENOMEM;
-                       key_maps[s] = key_map;
-                       key_map[0] = U(K_ALLOCATED);
-                       for (j = 1; j < NR_KEYS; j++)
-                               key_map[j] = U(K_HOLE);
-                       keymap_count++;
-               }
-               ov = U(key_map[i]);
-               if (v == ov)
-                       break;  /* nothing to do */
-               /*
-                * Attention Key.
-                */
-               if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               key_map[i] = U(v);
-               if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
-                       compute_shiftstate();
-               break;
-       }
-       return 0;
-}
-#undef i
-#undef s
-#undef v
-
-static inline int 
-do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, int perm)
-{
-       struct kbkeycode tmp;
-       int kc = 0;
-
-       if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
-               return -EFAULT;
-       switch (cmd) {
-       case KDGETKEYCODE:
-               kc = getkeycode(tmp.scancode);
-               if (kc >= 0)
-                       kc = put_user(kc, &user_kbkc->keycode);
-               break;
-       case KDSETKEYCODE:
-               if (!perm)
-                       return -EPERM;
-               kc = setkeycode(tmp.scancode, tmp.keycode);
-               break;
-       }
-       return kc;
-}
-
-static inline int
-do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
-{
-       struct kbsentry *kbs;
-       char *p;
-       u_char *q;
-       u_char __user *up;
-       int sz;
-       int delta;
-       char *first_free, *fj, *fnw;
-       int i, j, k;
-       int ret;
-
-       if (!capable(CAP_SYS_TTY_CONFIG))
-               perm = 0;
-
-       kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
-       if (!kbs) {
-               ret = -ENOMEM;
-               goto reterr;
-       }
-
-       /* we mostly copy too much here (512bytes), but who cares ;) */
-       if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
-               ret = -EFAULT;
-               goto reterr;
-       }
-       kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
-       i = kbs->kb_func;
-
-       switch (cmd) {
-       case KDGKBSENT:
-               sz = sizeof(kbs->kb_string) - 1; /* sz should have been
-                                                 a struct member */
-               up = user_kdgkb->kb_string;
-               p = func_table[i];
-               if(p)
-                       for ( ; *p && sz; p++, sz--)
-                               if (put_user(*p, up++)) {
-                                       ret = -EFAULT;
-                                       goto reterr;
-                               }
-               if (put_user('\0', up)) {
-                       ret = -EFAULT;
-                       goto reterr;
-               }
-               kfree(kbs);
-               return ((p && *p) ? -EOVERFLOW : 0);
-       case KDSKBSENT:
-               if (!perm) {
-                       ret = -EPERM;
-                       goto reterr;
-               }
-
-               q = func_table[i];
-               first_free = funcbufptr + (funcbufsize - funcbufleft);
-               for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
-                       ;
-               if (j < MAX_NR_FUNC)
-                       fj = func_table[j];
-               else
-                       fj = first_free;
-
-               delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
-               if (delta <= funcbufleft) {     /* it fits in current buf */
-                   if (j < MAX_NR_FUNC) {
-                       memmove(fj + delta, fj, first_free - fj);
-                       for (k = j; k < MAX_NR_FUNC; k++)
-                           if (func_table[k])
-                               func_table[k] += delta;
-                   }
-                   if (!q)
-                     func_table[i] = fj;
-                   funcbufleft -= delta;
-               } else {                        /* allocate a larger buffer */
-                   sz = 256;
-                   while (sz < funcbufsize - funcbufleft + delta)
-                     sz <<= 1;
-                   fnw = kmalloc(sz, GFP_KERNEL);
-                   if(!fnw) {
-                     ret = -ENOMEM;
-                     goto reterr;
-                   }
-
-                   if (!q)
-                     func_table[i] = fj;
-                   if (fj > funcbufptr)
-                       memmove(fnw, funcbufptr, fj - funcbufptr);
-                   for (k = 0; k < j; k++)
-                     if (func_table[k])
-                       func_table[k] = fnw + (func_table[k] - funcbufptr);
-
-                   if (first_free > fj) {
-                       memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
-                       for (k = j; k < MAX_NR_FUNC; k++)
-                         if (func_table[k])
-                           func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
-                   }
-                   if (funcbufptr != func_buf)
-                     kfree(funcbufptr);
-                   funcbufptr = fnw;
-                   funcbufleft = funcbufleft - delta + sz - funcbufsize;
-                   funcbufsize = sz;
-               }
-               strcpy(func_table[i], kbs->kb_string);
-               break;
-       }
-       ret = 0;
-reterr:
-       kfree(kbs);
-       return ret;
-}
-
-static inline int 
-do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
-{
-       struct consolefontdesc cfdarg;
-       int i;
-
-       if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) 
-               return -EFAULT;
-       
-       switch (cmd) {
-       case PIO_FONTX:
-               if (!perm)
-                       return -EPERM;
-               op->op = KD_FONT_OP_SET;
-               op->flags = KD_FONT_FLAG_OLD;
-               op->width = 8;
-               op->height = cfdarg.charheight;
-               op->charcount = cfdarg.charcount;
-               op->data = cfdarg.chardata;
-               return con_font_op(vc_cons[fg_console].d, op);
-       case GIO_FONTX: {
-               op->op = KD_FONT_OP_GET;
-               op->flags = KD_FONT_FLAG_OLD;
-               op->width = 8;
-               op->height = cfdarg.charheight;
-               op->charcount = cfdarg.charcount;
-               op->data = cfdarg.chardata;
-               i = con_font_op(vc_cons[fg_console].d, op);
-               if (i)
-                       return i;
-               cfdarg.charheight = op->height;
-               cfdarg.charcount = op->charcount;
-               if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
-                       return -EFAULT;
-               return 0;
-               }
-       }
-       return -EINVAL;
-}
-
-static inline int 
-do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc)
-{
-       struct unimapdesc tmp;
-
-       if (copy_from_user(&tmp, user_ud, sizeof tmp))
-               return -EFAULT;
-       if (tmp.entries)
-               if (!access_ok(VERIFY_WRITE, tmp.entries,
-                               tmp.entry_ct*sizeof(struct unipair)))
-                       return -EFAULT;
-       switch (cmd) {
-       case PIO_UNIMAP:
-               if (!perm)
-                       return -EPERM;
-               return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
-       case GIO_UNIMAP:
-               if (!perm && fg_console != vc->vc_num)
-                       return -EPERM;
-               return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
-       }
-       return 0;
-}
-
-
-
-/*
- * We handle the console-specific ioctl's here.  We allow the
- * capability to modify any console, not just the fg_console. 
- */
-int vt_ioctl(struct tty_struct *tty, struct file * file,
-            unsigned int cmd, unsigned long arg)
-{
-       struct vc_data *vc = tty->driver_data;
-       struct console_font_op op;      /* used in multiple places here */
-       struct kbd_struct * kbd;
-       unsigned int console;
-       unsigned char ucval;
-       unsigned int uival;
-       void __user *up = (void __user *)arg;
-       int i, perm;
-       int ret = 0;
-
-       console = vc->vc_num;
-
-       tty_lock();
-
-       if (!vc_cons_allocated(console)) {      /* impossible? */
-               ret = -ENOIOCTLCMD;
-               goto out;
-       }
-
-
-       /*
-        * To have permissions to do most of the vt ioctls, we either have
-        * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
-        */
-       perm = 0;
-       if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
-               perm = 1;
-       kbd = kbd_table + console;
-       switch (cmd) {
-       case TIOCLINUX:
-               ret = tioclinux(tty, arg);
-               break;
-       case KIOCSOUND:
-               if (!perm)
-                       goto eperm;
-               /*
-                * The use of PIT_TICK_RATE is historic, it used to be
-                * the platform-dependent CLOCK_TICK_RATE between 2.6.12
-                * and 2.6.36, which was a minor but unfortunate ABI
-                * change.
-                */
-               if (arg)
-                       arg = PIT_TICK_RATE / arg;
-               kd_mksound(arg, 0);
-               break;
-
-       case KDMKTONE:
-               if (!perm)
-                       goto eperm;
-       {
-               unsigned int ticks, count;
-               
-               /*
-                * Generate the tone for the appropriate number of ticks.
-                * If the time is zero, turn off sound ourselves.
-                */
-               ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
-               count = ticks ? (arg & 0xffff) : 0;
-               if (count)
-                       count = PIT_TICK_RATE / count;
-               kd_mksound(count, ticks);
-               break;
-       }
-
-       case KDGKBTYPE:
-               /*
-                * this is naive.
-                */
-               ucval = KB_101;
-               goto setchar;
-
-               /*
-                * These cannot be implemented on any machine that implements
-                * ioperm() in user level (such as Alpha PCs) or not at all.
-                *
-                * XXX: you should never use these, just call ioperm directly..
-                */
-#ifdef CONFIG_X86
-       case KDADDIO:
-       case KDDELIO:
-               /*
-                * KDADDIO and KDDELIO may be able to add ports beyond what
-                * we reject here, but to be safe...
-                */
-               if (arg < GPFIRST || arg > GPLAST) {
-                       ret = -EINVAL;
-                       break;
-               }
-               ret = sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
-               break;
-
-       case KDENABIO:
-       case KDDISABIO:
-               ret = sys_ioperm(GPFIRST, GPNUM,
-                                 (cmd == KDENABIO)) ? -ENXIO : 0;
-               break;
-#endif
-
-       /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */
-               
-       case KDKBDREP:
-       {
-               struct kbd_repeat kbrep;
-               
-               if (!capable(CAP_SYS_TTY_CONFIG))
-                       goto eperm;
-
-               if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
-                       ret =  -EFAULT;
-                       break;
-               }
-               ret = kbd_rate(&kbrep);
-               if (ret)
-                       break;
-               if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat)))
-                       ret = -EFAULT;
-               break;
-       }
-
-       case KDSETMODE:
-               /*
-                * currently, setting the mode from KD_TEXT to KD_GRAPHICS
-                * doesn't do a whole lot. i'm not sure if it should do any
-                * restoration of modes or what...
-                *
-                * XXX It should at least call into the driver, fbdev's definitely
-                * need to restore their engine state. --BenH
-                */
-               if (!perm)
-                       goto eperm;
-               switch (arg) {
-               case KD_GRAPHICS:
-                       break;
-               case KD_TEXT0:
-               case KD_TEXT1:
-                       arg = KD_TEXT;
-               case KD_TEXT:
-                       break;
-               default:
-                       ret = -EINVAL;
-                       goto out;
-               }
-               if (vc->vc_mode == (unsigned char) arg)
-                       break;
-               vc->vc_mode = (unsigned char) arg;
-               if (console != fg_console)
-                       break;
-               /*
-                * explicitly blank/unblank the screen if switching modes
-                */
-               acquire_console_sem();
-               if (arg == KD_TEXT)
-                       do_unblank_screen(1);
-               else
-                       do_blank_screen(1);
-               release_console_sem();
-               break;
-
-       case KDGETMODE:
-               uival = vc->vc_mode;
-               goto setint;
-
-       case KDMAPDISP:
-       case KDUNMAPDISP:
-               /*
-                * these work like a combination of mmap and KDENABIO.
-                * this could be easily finished.
-                */
-               ret = -EINVAL;
-               break;
-
-       case KDSKBMODE:
-               if (!perm)
-                       goto eperm;
-               switch(arg) {
-                 case K_RAW:
-                       kbd->kbdmode = VC_RAW;
-                       break;
-                 case K_MEDIUMRAW:
-                       kbd->kbdmode = VC_MEDIUMRAW;
-                       break;
-                 case K_XLATE:
-                       kbd->kbdmode = VC_XLATE;
-                       compute_shiftstate();
-                       break;
-                 case K_UNICODE:
-                       kbd->kbdmode = VC_UNICODE;
-                       compute_shiftstate();
-                       break;
-                 default:
-                       ret = -EINVAL;
-                       goto out;
-               }
-               tty_ldisc_flush(tty);
-               break;
-
-       case KDGKBMODE:
-               uival = ((kbd->kbdmode == VC_RAW) ? K_RAW :
-                                (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
-                                (kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
-                                K_XLATE);
-               goto setint;
-
-       /* this could be folded into KDSKBMODE, but for compatibility
-          reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
-       case KDSKBMETA:
-               switch(arg) {
-                 case K_METABIT:
-                       clr_vc_kbd_mode(kbd, VC_META);
-                       break;
-                 case K_ESCPREFIX:
-                       set_vc_kbd_mode(kbd, VC_META);
-                       break;
-                 default:
-                       ret = -EINVAL;
-               }
-               break;
-
-       case KDGKBMETA:
-               uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
-       setint:
-               ret = put_user(uival, (int __user *)arg);
-               break;
-
-       case KDGETKEYCODE:
-       case KDSETKEYCODE:
-               if(!capable(CAP_SYS_TTY_CONFIG))
-                       perm = 0;
-               ret = do_kbkeycode_ioctl(cmd, up, perm);
-               break;
-
-       case KDGKBENT:
-       case KDSKBENT:
-               ret = do_kdsk_ioctl(cmd, up, perm, kbd);
-               break;
-
-       case KDGKBSENT:
-       case KDSKBSENT:
-               ret = do_kdgkb_ioctl(cmd, up, perm);
-               break;
-
-       case KDGKBDIACR:
-       {
-               struct kbdiacrs __user *a = up;
-               struct kbdiacr diacr;
-               int i;
-
-               if (put_user(accent_table_size, &a->kb_cnt)) {
-                       ret = -EFAULT;
-                       break;
-               }
-               for (i = 0; i < accent_table_size; i++) {
-                       diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr);
-                       diacr.base = conv_uni_to_8bit(accent_table[i].base);
-                       diacr.result = conv_uni_to_8bit(accent_table[i].result);
-                       if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) {
-                               ret = -EFAULT;
-                               break;
-                       }
-               }
-               break;
-       }
-       case KDGKBDIACRUC:
-       {
-               struct kbdiacrsuc __user *a = up;
-
-               if (put_user(accent_table_size, &a->kb_cnt))
-                       ret = -EFAULT;
-               else if (copy_to_user(a->kbdiacruc, accent_table,
-                               accent_table_size*sizeof(struct kbdiacruc)))
-                       ret = -EFAULT;
-               break;
-       }
-
-       case KDSKBDIACR:
-       {
-               struct kbdiacrs __user *a = up;
-               struct kbdiacr diacr;
-               unsigned int ct;
-               int i;
-
-               if (!perm)
-                       goto eperm;
-               if (get_user(ct,&a->kb_cnt)) {
-                       ret = -EFAULT;
-                       break;
-               }
-               if (ct >= MAX_DIACR) {
-                       ret = -EINVAL;
-                       break;
-               }
-               accent_table_size = ct;
-               for (i = 0; i < ct; i++) {
-                       if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) {
-                               ret = -EFAULT;
-                               break;
-                       }
-                       accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr);
-                       accent_table[i].base = conv_8bit_to_uni(diacr.base);
-                       accent_table[i].result = conv_8bit_to_uni(diacr.result);
-               }
-               break;
-       }
-
-       case KDSKBDIACRUC:
-       {
-               struct kbdiacrsuc __user *a = up;
-               unsigned int ct;
-
-               if (!perm)
-                       goto eperm;
-               if (get_user(ct,&a->kb_cnt)) {
-                       ret = -EFAULT;
-                       break;
-               }
-               if (ct >= MAX_DIACR) {
-                       ret = -EINVAL;
-                       break;
-               }
-               accent_table_size = ct;
-               if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
-                       ret = -EFAULT;
-               break;
-       }
-
-       /* the ioctls below read/set the flags usually shown in the leds */
-       /* don't use them - they will go away without warning */
-       case KDGKBLED:
-               ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
-               goto setchar;
-
-       case KDSKBLED:
-               if (!perm)
-                       goto eperm;
-               if (arg & ~0x77) {
-                       ret = -EINVAL;
-                       break;
-               }
-               kbd->ledflagstate = (arg & 7);
-               kbd->default_ledflagstate = ((arg >> 4) & 7);
-               set_leds();
-               break;
-
-       /* the ioctls below only set the lights, not the functions */
-       /* for those, see KDGKBLED and KDSKBLED above */
-       case KDGETLED:
-               ucval = getledstate();
-       setchar:
-               ret = put_user(ucval, (char __user *)arg);
-               break;
-
-       case KDSETLED:
-               if (!perm)
-                       goto eperm;
-               setledstate(kbd, arg);
-               break;
-
-       /*
-        * A process can indicate its willingness to accept signals
-        * generated by pressing an appropriate key combination.
-        * Thus, one can have a daemon that e.g. spawns a new console
-        * upon a keypress and then changes to it.
-        * See also the kbrequest field of inittab(5).
-        */
-       case KDSIGACCEPT:
-       {
-               if (!perm || !capable(CAP_KILL))
-                       goto eperm;
-               if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
-                       ret = -EINVAL;
-               else {
-                       spin_lock_irq(&vt_spawn_con.lock);
-                       put_pid(vt_spawn_con.pid);
-                       vt_spawn_con.pid = get_pid(task_pid(current));
-                       vt_spawn_con.sig = arg;
-                       spin_unlock_irq(&vt_spawn_con.lock);
-               }
-               break;
-       }
-
-       case VT_SETMODE:
-       {
-               struct vt_mode tmp;
-
-               if (!perm)
-                       goto eperm;
-               if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
-                       ret = -EFAULT;
-                       goto out;
-               }
-               if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               acquire_console_sem();
-               vc->vt_mode = tmp;
-               /* the frsig is ignored, so we set it to 0 */
-               vc->vt_mode.frsig = 0;
-               put_pid(vc->vt_pid);
-               vc->vt_pid = get_pid(task_pid(current));
-               /* no switch is required -- saw@shade.msu.ru */
-               vc->vt_newvt = -1;
-               release_console_sem();
-               break;
-       }
-
-       case VT_GETMODE:
-       {
-               struct vt_mode tmp;
-               int rc;
-
-               acquire_console_sem();
-               memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
-               release_console_sem();
-
-               rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
-               if (rc)
-                       ret = -EFAULT;
-               break;
-       }
-
-       /*
-        * Returns global vt state. Note that VT 0 is always open, since
-        * it's an alias for the current VT, and people can't use it here.
-        * We cannot return state for more than 16 VTs, since v_state is short.
-        */
-       case VT_GETSTATE:
-       {
-               struct vt_stat __user *vtstat = up;
-               unsigned short state, mask;
-
-               if (put_user(fg_console + 1, &vtstat->v_active))
-                       ret = -EFAULT;
-               else {
-                       state = 1;      /* /dev/tty0 is always open */
-                       for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
-                                                       ++i, mask <<= 1)
-                               if (VT_IS_IN_USE(i))
-                                       state |= mask;
-                       ret = put_user(state, &vtstat->v_state);
-               }
-               break;
-       }
-
-       /*
-        * Returns the first available (non-opened) console.
-        */
-       case VT_OPENQRY:
-               for (i = 0; i < MAX_NR_CONSOLES; ++i)
-                       if (! VT_IS_IN_USE(i))
-                               break;
-               uival = i < MAX_NR_CONSOLES ? (i+1) : -1;
-               goto setint;             
-
-       /*
-        * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num,
-        * with num >= 1 (switches to vt 0, our console, are not allowed, just
-        * to preserve sanity).
-        */
-       case VT_ACTIVATE:
-               if (!perm)
-                       goto eperm;
-               if (arg == 0 || arg > MAX_NR_CONSOLES)
-                       ret =  -ENXIO;
-               else {
-                       arg--;
-                       acquire_console_sem();
-                       ret = vc_allocate(arg);
-                       release_console_sem();
-                       if (ret)
-                               break;
-                       set_console(arg);
-               }
-               break;
-
-       case VT_SETACTIVATE:
-       {
-               struct vt_setactivate vsa;
-
-               if (!perm)
-                       goto eperm;
-
-               if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
-                                       sizeof(struct vt_setactivate))) {
-                       ret = -EFAULT;
-                       goto out;
-               }
-               if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
-                       ret = -ENXIO;
-               else {
-                       vsa.console--;
-                       acquire_console_sem();
-                       ret = vc_allocate(vsa.console);
-                       if (ret == 0) {
-                               struct vc_data *nvc;
-                               /* This is safe providing we don't drop the
-                                  console sem between vc_allocate and
-                                  finishing referencing nvc */
-                               nvc = vc_cons[vsa.console].d;
-                               nvc->vt_mode = vsa.mode;
-                               nvc->vt_mode.frsig = 0;
-                               put_pid(nvc->vt_pid);
-                               nvc->vt_pid = get_pid(task_pid(current));
-                       }
-                       release_console_sem();
-                       if (ret)
-                               break;
-                       /* Commence switch and lock */
-                       set_console(arg);
-               }
-       }
-
-       /*
-        * wait until the specified VT has been activated
-        */
-       case VT_WAITACTIVE:
-               if (!perm)
-                       goto eperm;
-               if (arg == 0 || arg > MAX_NR_CONSOLES)
-                       ret = -ENXIO;
-               else
-                       ret = vt_waitactive(arg);
-               break;
-
-       /*
-        * If a vt is under process control, the kernel will not switch to it
-        * immediately, but postpone the operation until the process calls this
-        * ioctl, allowing the switch to complete.
-        *
-        * According to the X sources this is the behavior:
-        *      0:      pending switch-from not OK
-        *      1:      pending switch-from OK
-        *      2:      completed switch-to OK
-        */
-       case VT_RELDISP:
-               if (!perm)
-                       goto eperm;
-
-               if (vc->vt_mode.mode != VT_PROCESS) {
-                       ret = -EINVAL;
-                       break;
-               }
-               /*
-                * Switching-from response
-                */
-               acquire_console_sem();
-               if (vc->vt_newvt >= 0) {
-                       if (arg == 0)
-                               /*
-                                * Switch disallowed, so forget we were trying
-                                * to do it.
-                                */
-                               vc->vt_newvt = -1;
-
-                       else {
-                               /*
-                                * The current vt has been released, so
-                                * complete the switch.
-                                */
-                               int newvt;
-                               newvt = vc->vt_newvt;
-                               vc->vt_newvt = -1;
-                               ret = vc_allocate(newvt);
-                               if (ret) {
-                                       release_console_sem();
-                                       break;
-                               }
-                               /*
-                                * When we actually do the console switch,
-                                * make sure we are atomic with respect to
-                                * other console switches..
-                                */
-                               complete_change_console(vc_cons[newvt].d);
-                       }
-               } else {
-                       /*
-                        * Switched-to response
-                        */
-                       /*
-                        * If it's just an ACK, ignore it
-                        */
-                       if (arg != VT_ACKACQ)
-                               ret = -EINVAL;
-               }
-               release_console_sem();
-               break;
-
-        /*
-         * Disallocate memory associated to VT (but leave VT1)
-         */
-        case VT_DISALLOCATE:
-               if (arg > MAX_NR_CONSOLES) {
-                       ret = -ENXIO;
-                       break;
-               }
-               if (arg == 0) {
-                   /* deallocate all unused consoles, but leave 0 */
-                       acquire_console_sem();
-                       for (i=1; i<MAX_NR_CONSOLES; i++)
-                               if (! VT_BUSY(i))
-                                       vc_deallocate(i);
-                       release_console_sem();
-               } else {
-                       /* deallocate a single console, if possible */
-                       arg--;
-                       if (VT_BUSY(arg))
-                               ret = -EBUSY;
-                       else if (arg) {                       /* leave 0 */
-                               acquire_console_sem();
-                               vc_deallocate(arg);
-                               release_console_sem();
-                       }
-               }
-               break;
-
-       case VT_RESIZE:
-       {
-               struct vt_sizes __user *vtsizes = up;
-               struct vc_data *vc;
-
-               ushort ll,cc;
-               if (!perm)
-                       goto eperm;
-               if (get_user(ll, &vtsizes->v_rows) ||
-                   get_user(cc, &vtsizes->v_cols))
-                       ret = -EFAULT;
-               else {
-                       acquire_console_sem();
-                       for (i = 0; i < MAX_NR_CONSOLES; i++) {
-                               vc = vc_cons[i].d;
-
-                               if (vc) {
-                                       vc->vc_resize_user = 1;
-                                       vc_resize(vc_cons[i].d, cc, ll);
-                               }
-                       }
-                       release_console_sem();
-               }
-               break;
-       }
-
-       case VT_RESIZEX:
-       {
-               struct vt_consize __user *vtconsize = up;
-               ushort ll,cc,vlin,clin,vcol,ccol;
-               if (!perm)
-                       goto eperm;
-               if (!access_ok(VERIFY_READ, vtconsize,
-                               sizeof(struct vt_consize))) {
-                       ret = -EFAULT;
-                       break;
-               }
-               /* FIXME: Should check the copies properly */
-               __get_user(ll, &vtconsize->v_rows);
-               __get_user(cc, &vtconsize->v_cols);
-               __get_user(vlin, &vtconsize->v_vlin);
-               __get_user(clin, &vtconsize->v_clin);
-               __get_user(vcol, &vtconsize->v_vcol);
-               __get_user(ccol, &vtconsize->v_ccol);
-               vlin = vlin ? vlin : vc->vc_scan_lines;
-               if (clin) {
-                       if (ll) {
-                               if (ll != vlin/clin) {
-                                       /* Parameters don't add up */
-                                       ret = -EINVAL;
-                                       break;
-                               }
-                       } else 
-                               ll = vlin/clin;
-               }
-               if (vcol && ccol) {
-                       if (cc) {
-                               if (cc != vcol/ccol) {
-                                       ret = -EINVAL;
-                                       break;
-                               }
-                       } else
-                               cc = vcol/ccol;
-               }
-
-               if (clin > 32) {
-                       ret =  -EINVAL;
-                       break;
-               }
-                   
-               for (i = 0; i < MAX_NR_CONSOLES; i++) {
-                       if (!vc_cons[i].d)
-                               continue;
-                       acquire_console_sem();
-                       if (vlin)
-                               vc_cons[i].d->vc_scan_lines = vlin;
-                       if (clin)
-                               vc_cons[i].d->vc_font.height = clin;
-                       vc_cons[i].d->vc_resize_user = 1;
-                       vc_resize(vc_cons[i].d, cc, ll);
-                       release_console_sem();
-               }
-               break;
-       }
-
-       case PIO_FONT: {
-               if (!perm)
-                       goto eperm;
-               op.op = KD_FONT_OP_SET;
-               op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
-               op.width = 8;
-               op.height = 0;
-               op.charcount = 256;
-               op.data = up;
-               ret = con_font_op(vc_cons[fg_console].d, &op);
-               break;
-       }
-
-       case GIO_FONT: {
-               op.op = KD_FONT_OP_GET;
-               op.flags = KD_FONT_FLAG_OLD;
-               op.width = 8;
-               op.height = 32;
-               op.charcount = 256;
-               op.data = up;
-               ret = con_font_op(vc_cons[fg_console].d, &op);
-               break;
-       }
-
-       case PIO_CMAP:
-                if (!perm)
-                       ret = -EPERM;
-               else
-                       ret = con_set_cmap(up);
-               break;
-
-       case GIO_CMAP:
-                ret = con_get_cmap(up);
-               break;
-
-       case PIO_FONTX:
-       case GIO_FONTX:
-               ret = do_fontx_ioctl(cmd, up, perm, &op);
-               break;
-
-       case PIO_FONTRESET:
-       {
-               if (!perm)
-                       goto eperm;
-
-#ifdef BROKEN_GRAPHICS_PROGRAMS
-               /* With BROKEN_GRAPHICS_PROGRAMS defined, the default
-                  font is not saved. */
-               ret = -ENOSYS;
-               break;
-#else
-               {
-               op.op = KD_FONT_OP_SET_DEFAULT;
-               op.data = NULL;
-               ret = con_font_op(vc_cons[fg_console].d, &op);
-               if (ret)
-                       break;
-               con_set_default_unimap(vc_cons[fg_console].d);
-               break;
-               }
-#endif
-       }
-
-       case KDFONTOP: {
-               if (copy_from_user(&op, up, sizeof(op))) {
-                       ret = -EFAULT;
-                       break;
-               }
-               if (!perm && op.op != KD_FONT_OP_GET)
-                       goto eperm;
-               ret = con_font_op(vc, &op);
-               if (ret)
-                       break;
-               if (copy_to_user(up, &op, sizeof(op)))
-                       ret = -EFAULT;
-               break;
-       }
-
-       case PIO_SCRNMAP:
-               if (!perm)
-                       ret = -EPERM;
-               else
-                       ret = con_set_trans_old(up);
-               break;
-
-       case GIO_SCRNMAP:
-               ret = con_get_trans_old(up);
-               break;
-
-       case PIO_UNISCRNMAP:
-               if (!perm)
-                       ret = -EPERM;
-               else
-                       ret = con_set_trans_new(up);
-               break;
-
-       case GIO_UNISCRNMAP:
-               ret = con_get_trans_new(up);
-               break;
-
-       case PIO_UNIMAPCLR:
-             { struct unimapinit ui;
-               if (!perm)
-                       goto eperm;
-               ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
-               if (ret)
-                       ret = -EFAULT;
-               else
-                       con_clear_unimap(vc, &ui);
-               break;
-             }
-
-       case PIO_UNIMAP:
-       case GIO_UNIMAP:
-               ret = do_unimap_ioctl(cmd, up, perm, vc);
-               break;
-
-       case VT_LOCKSWITCH:
-               if (!capable(CAP_SYS_TTY_CONFIG))
-                       goto eperm;
-               vt_dont_switch = 1;
-               break;
-       case VT_UNLOCKSWITCH:
-               if (!capable(CAP_SYS_TTY_CONFIG))
-                       goto eperm;
-               vt_dont_switch = 0;
-               break;
-       case VT_GETHIFONTMASK:
-               ret = put_user(vc->vc_hi_font_mask,
-                                       (unsigned short __user *)arg);
-               break;
-       case VT_WAITEVENT:
-               ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
-               break;
-       default:
-               ret = -ENOIOCTLCMD;
-       }
-out:
-       tty_unlock();
-       return ret;
-eperm:
-       ret = -EPERM;
-       goto out;
-}
-
-void reset_vc(struct vc_data *vc)
-{
-       vc->vc_mode = KD_TEXT;
-       kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
-       vc->vt_mode.mode = VT_AUTO;
-       vc->vt_mode.waitv = 0;
-       vc->vt_mode.relsig = 0;
-       vc->vt_mode.acqsig = 0;
-       vc->vt_mode.frsig = 0;
-       put_pid(vc->vt_pid);
-       vc->vt_pid = NULL;
-       vc->vt_newvt = -1;
-       if (!in_interrupt())    /* Via keyboard.c:SAK() - akpm */
-               reset_palette(vc);
-}
-
-void vc_SAK(struct work_struct *work)
-{
-       struct vc *vc_con =
-               container_of(work, struct vc, SAK_work);
-       struct vc_data *vc;
-       struct tty_struct *tty;
-
-       acquire_console_sem();
-       vc = vc_con->d;
-       if (vc) {
-               tty = vc->port.tty;
-               /*
-                * SAK should also work in all raw modes and reset
-                * them properly.
-                */
-               if (tty)
-                       __do_SAK(tty);
-               reset_vc(vc);
-       }
-       release_console_sem();
-}
-
-#ifdef CONFIG_COMPAT
-
-struct compat_consolefontdesc {
-       unsigned short charcount;       /* characters in font (256 or 512) */
-       unsigned short charheight;      /* scan lines per character (1-32) */
-       compat_caddr_t chardata;        /* font data in expanded form */
-};
-
-static inline int
-compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
-                        int perm, struct console_font_op *op)
-{
-       struct compat_consolefontdesc cfdarg;
-       int i;
-
-       if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc)))
-               return -EFAULT;
-
-       switch (cmd) {
-       case PIO_FONTX:
-               if (!perm)
-                       return -EPERM;
-               op->op = KD_FONT_OP_SET;
-               op->flags = KD_FONT_FLAG_OLD;
-               op->width = 8;
-               op->height = cfdarg.charheight;
-               op->charcount = cfdarg.charcount;
-               op->data = compat_ptr(cfdarg.chardata);
-               return con_font_op(vc_cons[fg_console].d, op);
-       case GIO_FONTX:
-               op->op = KD_FONT_OP_GET;
-               op->flags = KD_FONT_FLAG_OLD;
-               op->width = 8;
-               op->height = cfdarg.charheight;
-               op->charcount = cfdarg.charcount;
-               op->data = compat_ptr(cfdarg.chardata);
-               i = con_font_op(vc_cons[fg_console].d, op);
-               if (i)
-                       return i;
-               cfdarg.charheight = op->height;
-               cfdarg.charcount = op->charcount;
-               if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc)))
-                       return -EFAULT;
-               return 0;
-       }
-       return -EINVAL;
-}
-
-struct compat_console_font_op {
-       compat_uint_t op;        /* operation code KD_FONT_OP_* */
-       compat_uint_t flags;     /* KD_FONT_FLAG_* */
-       compat_uint_t width, height;     /* font size */
-       compat_uint_t charcount;
-       compat_caddr_t data;    /* font data with height fixed to 32 */
-};
-
-static inline int
-compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
-                        int perm, struct console_font_op *op, struct vc_data *vc)
-{
-       int i;
-
-       if (copy_from_user(op, fontop, sizeof(struct compat_console_font_op)))
-               return -EFAULT;
-       if (!perm && op->op != KD_FONT_OP_GET)
-               return -EPERM;
-       op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
-       op->flags |= KD_FONT_FLAG_OLD;
-       i = con_font_op(vc, op);
-       if (i)
-               return i;
-       ((struct compat_console_font_op *)op)->data = (unsigned long)op->data;
-       if (copy_to_user(fontop, op, sizeof(struct compat_console_font_op)))
-               return -EFAULT;
-       return 0;
-}
-
-struct compat_unimapdesc {
-       unsigned short entry_ct;
-       compat_caddr_t entries;
-};
-
-static inline int
-compat_unimap_ioctl(unsigned int cmd, struct compat_unimapdesc __user *user_ud,
-                        int perm, struct vc_data *vc)
-{
-       struct compat_unimapdesc tmp;
-       struct unipair __user *tmp_entries;
-
-       if (copy_from_user(&tmp, user_ud, sizeof tmp))
-               return -EFAULT;
-       tmp_entries = compat_ptr(tmp.entries);
-       if (tmp_entries)
-               if (!access_ok(VERIFY_WRITE, tmp_entries,
-                               tmp.entry_ct*sizeof(struct unipair)))
-                       return -EFAULT;
-       switch (cmd) {
-       case PIO_UNIMAP:
-               if (!perm)
-                       return -EPERM;
-               return con_set_unimap(vc, tmp.entry_ct, tmp_entries);
-       case GIO_UNIMAP:
-               if (!perm && fg_console != vc->vc_num)
-                       return -EPERM;
-               return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp_entries);
-       }
-       return 0;
-}
-
-long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
-            unsigned int cmd, unsigned long arg)
-{
-       struct vc_data *vc = tty->driver_data;
-       struct console_font_op op;      /* used in multiple places here */
-       struct kbd_struct *kbd;
-       unsigned int console;
-       void __user *up = (void __user *)arg;
-       int perm;
-       int ret = 0;
-
-       console = vc->vc_num;
-
-       tty_lock();
-
-       if (!vc_cons_allocated(console)) {      /* impossible? */
-               ret = -ENOIOCTLCMD;
-               goto out;
-       }
-
-       /*
-        * To have permissions to do most of the vt ioctls, we either have
-        * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
-        */
-       perm = 0;
-       if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
-               perm = 1;
-
-       kbd = kbd_table + console;
-       switch (cmd) {
-       /*
-        * these need special handlers for incompatible data structures
-        */
-       case PIO_FONTX:
-       case GIO_FONTX:
-               ret = compat_fontx_ioctl(cmd, up, perm, &op);
-               break;
-
-       case KDFONTOP:
-               ret = compat_kdfontop_ioctl(up, perm, &op, vc);
-               break;
-
-       case PIO_UNIMAP:
-       case GIO_UNIMAP:
-               ret = compat_unimap_ioctl(cmd, up, perm, vc);
-               break;
-
-       /*
-        * all these treat 'arg' as an integer
-        */
-       case KIOCSOUND:
-       case KDMKTONE:
-#ifdef CONFIG_X86
-       case KDADDIO:
-       case KDDELIO:
-#endif
-       case KDSETMODE:
-       case KDMAPDISP:
-       case KDUNMAPDISP:
-       case KDSKBMODE:
-       case KDSKBMETA:
-       case KDSKBLED:
-       case KDSETLED:
-       case KDSIGACCEPT:
-       case VT_ACTIVATE:
-       case VT_WAITACTIVE:
-       case VT_RELDISP:
-       case VT_DISALLOCATE:
-       case VT_RESIZE:
-       case VT_RESIZEX:
-               goto fallback;
-
-       /*
-        * the rest has a compatible data structure behind arg,
-        * but we have to convert it to a proper 64 bit pointer.
-        */
-       default:
-               arg = (unsigned long)compat_ptr(arg);
-               goto fallback;
-       }
-out:
-       tty_unlock();
-       return ret;
-
-fallback:
-       tty_unlock();
-       return vt_ioctl(tty, file, cmd, arg);
-}
-
-
-#endif /* CONFIG_COMPAT */
-
-
-/*
- * Performs the back end of a vt switch. Called under the console
- * semaphore.
- */
-static void complete_change_console(struct vc_data *vc)
-{
-       unsigned char old_vc_mode;
-       int old = fg_console;
-
-       last_console = fg_console;
-
-       /*
-        * If we're switching, we could be going from KD_GRAPHICS to
-        * KD_TEXT mode or vice versa, which means we need to blank or
-        * unblank the screen later.
-        */
-       old_vc_mode = vc_cons[fg_console].d->vc_mode;
-       switch_screen(vc);
-
-       /*
-        * This can't appear below a successful kill_pid().  If it did,
-        * then the *blank_screen operation could occur while X, having
-        * received acqsig, is waking up on another processor.  This
-        * condition can lead to overlapping accesses to the VGA range
-        * and the framebuffer (causing system lockups).
-        *
-        * To account for this we duplicate this code below only if the
-        * controlling process is gone and we've called reset_vc.
-        */
-       if (old_vc_mode != vc->vc_mode) {
-               if (vc->vc_mode == KD_TEXT)
-                       do_unblank_screen(1);
-               else
-                       do_blank_screen(1);
-       }
-
-       /*
-        * If this new console is under process control, send it a signal
-        * telling it that it has acquired. Also check if it has died and
-        * clean up (similar to logic employed in change_console())
-        */
-       if (vc->vt_mode.mode == VT_PROCESS) {
-               /*
-                * Send the signal as privileged - kill_pid() will
-                * tell us if the process has gone or something else
-                * is awry
-                */
-               if (kill_pid(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
-               /*
-                * The controlling process has died, so we revert back to
-                * normal operation. In this case, we'll also change back
-                * to KD_TEXT mode. I'm not sure if this is strictly correct
-                * but it saves the agony when the X server dies and the screen
-                * remains blanked due to KD_GRAPHICS! It would be nice to do
-                * this outside of VT_PROCESS but there is no single process
-                * to account for and tracking tty count may be undesirable.
-                */
-                       reset_vc(vc);
-
-                       if (old_vc_mode != vc->vc_mode) {
-                               if (vc->vc_mode == KD_TEXT)
-                                       do_unblank_screen(1);
-                               else
-                                       do_blank_screen(1);
-                       }
-               }
-       }
-
-       /*
-        * Wake anyone waiting for their VT to activate
-        */
-       vt_event_post(VT_EVENT_SWITCH, old, vc->vc_num);
-       return;
-}
-
-/*
- * Performs the front-end of a vt switch
- */
-void change_console(struct vc_data *new_vc)
-{
-       struct vc_data *vc;
-
-       if (!new_vc || new_vc->vc_num == fg_console || vt_dont_switch)
-               return;
-
-       /*
-        * If this vt is in process mode, then we need to handshake with
-        * that process before switching. Essentially, we store where that
-        * vt wants to switch to and wait for it to tell us when it's done
-        * (via VT_RELDISP ioctl).
-        *
-        * We also check to see if the controlling process still exists.
-        * If it doesn't, we reset this vt to auto mode and continue.
-        * This is a cheap way to track process control. The worst thing
-        * that can happen is: we send a signal to a process, it dies, and
-        * the switch gets "lost" waiting for a response; hopefully, the
-        * user will try again, we'll detect the process is gone (unless
-        * the user waits just the right amount of time :-) and revert the
-        * vt to auto control.
-        */
-       vc = vc_cons[fg_console].d;
-       if (vc->vt_mode.mode == VT_PROCESS) {
-               /*
-                * Send the signal as privileged - kill_pid() will
-                * tell us if the process has gone or something else
-                * is awry.
-                *
-                * We need to set vt_newvt *before* sending the signal or we
-                * have a race.
-                */
-               vc->vt_newvt = new_vc->vc_num;
-               if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
-                       /*
-                        * It worked. Mark the vt to switch to and
-                        * return. The process needs to send us a
-                        * VT_RELDISP ioctl to complete the switch.
-                        */
-                       return;
-               }
-
-               /*
-                * The controlling process has died, so we revert back to
-                * normal operation. In this case, we'll also change back
-                * to KD_TEXT mode. I'm not sure if this is strictly correct
-                * but it saves the agony when the X server dies and the screen
-                * remains blanked due to KD_GRAPHICS! It would be nice to do
-                * this outside of VT_PROCESS but there is no single process
-                * to account for and tracking tty count may be undesirable.
-                */
-               reset_vc(vc);
-
-               /*
-                * Fall through to normal (VT_AUTO) handling of the switch...
-                */
-       }
-
-       /*
-        * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
-        */
-       if (vc->vc_mode == KD_GRAPHICS)
-               return;
-
-       complete_change_console(new_vc);
-}
-
-/* Perform a kernel triggered VT switch for suspend/resume */
-
-static int disable_vt_switch;
-
-int vt_move_to_console(unsigned int vt, int alloc)
-{
-       int prev;
-
-       acquire_console_sem();
-       /* Graphics mode - up to X */
-       if (disable_vt_switch) {
-               release_console_sem();
-               return 0;
-       }
-       prev = fg_console;
-
-       if (alloc && vc_allocate(vt)) {
-               /* we can't have a free VC for now. Too bad,
-                * we don't want to mess the screen for now. */
-               release_console_sem();
-               return -ENOSPC;
-       }
-
-       if (set_console(vt)) {
-               /*
-                * We're unable to switch to the SUSPEND_CONSOLE.
-                * Let the calling function know so it can decide
-                * what to do.
-                */
-               release_console_sem();
-               return -EIO;
-       }
-       release_console_sem();
-       tty_lock();
-       if (vt_waitactive(vt + 1)) {
-               pr_debug("Suspend: Can't switch VCs.");
-               tty_unlock();
-               return -EINTR;
-       }
-       tty_unlock();
-       return prev;
-}
-
-/*
- * Normally during a suspend, we allocate a new console and switch to it.
- * When we resume, we switch back to the original console.  This switch
- * can be slow, so on systems where the framebuffer can handle restoration
- * of video registers anyways, there's little point in doing the console
- * switch.  This function allows you to disable it by passing it '0'.
- */
-void pm_set_vt_switch(int do_switch)
-{
-       acquire_console_sem();
-       disable_vt_switch = !do_switch;
-       release_console_sem();
-}
-EXPORT_SYMBOL(pm_set_vt_switch);
index a44611652282c6c173e70b861910d4bee1610db4..d68d3aa1814b4ac635017e98cebd9625b0e7b40a 100644 (file)
@@ -616,13 +616,9 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
        /* get hold of clock */
        p->clk = clk_get(&p->pdev->dev, "cmt_fck");
        if (IS_ERR(p->clk)) {
-               dev_warn(&p->pdev->dev, "using deprecated clock lookup\n");
-               p->clk = clk_get(&p->pdev->dev, cfg->clk);
-               if (IS_ERR(p->clk)) {
-                       dev_err(&p->pdev->dev, "cannot get clock\n");
-                       ret = PTR_ERR(p->clk);
-                       goto err1;
-               }
+               dev_err(&p->pdev->dev, "cannot get clock\n");
+               ret = PTR_ERR(p->clk);
+               goto err1;
        }
 
        if (resource_size(res) == 6) {
index ef7a5be8a09f5a36bb1ed545fccf64e2fa7e7f89..40630cb9823707423c84e2459b812165786c5a15 100644 (file)
@@ -287,13 +287,9 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev)
        /* get hold of clock */
        p->clk = clk_get(&p->pdev->dev, "mtu2_fck");
        if (IS_ERR(p->clk)) {
-               dev_warn(&p->pdev->dev, "using deprecated clock lookup\n");
-               p->clk = clk_get(&p->pdev->dev, cfg->clk);
-               if (IS_ERR(p->clk)) {
-                       dev_err(&p->pdev->dev, "cannot get clock\n");
-                       ret = PTR_ERR(p->clk);
-                       goto err1;
-               }
+               dev_err(&p->pdev->dev, "cannot get clock\n");
+               ret = PTR_ERR(p->clk);
+               goto err1;
        }
 
        return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev),
index de715901b82a28a09f8160dd1b62f17a25247a51..36aba9923060f5dfbd02d250a1de675e274e7695 100644 (file)
@@ -393,13 +393,9 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
        /* get hold of clock */
        p->clk = clk_get(&p->pdev->dev, "tmu_fck");
        if (IS_ERR(p->clk)) {
-               dev_warn(&p->pdev->dev, "using deprecated clock lookup\n");
-               p->clk = clk_get(&p->pdev->dev, cfg->clk);
-               if (IS_ERR(p->clk)) {
-                       dev_err(&p->pdev->dev, "cannot get clock\n");
-                       ret = PTR_ERR(p->clk);
-                       goto err1;
-               }
+               dev_err(&p->pdev->dev, "cannot get clock\n");
+               ret = PTR_ERR(p->clk);
+               goto err1;
        }
 
        return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev),
index 88ee01510ec0132d894763dc9ac967b101ea0439..76141262ea1d41b256ad4e70b4af5e5b1bc34f28 100644 (file)
@@ -1832,7 +1832,7 @@ static int __devinit get_irq_props(struct mdesc_handle *mdesc, u64 node,
                return -ENODEV;
 
        ino = mdesc_get_property(mdesc, node, "ino", &ino_len);
-       if (!intr)
+       if (!ino)
                return -ENODEV;
 
        if (intr_len != ino_len)
index 2e992bc8015b7bd63bf0c5b4b878b8da1bfa69c4..8a515baa38f7c2d554e786bb33ab6979d770bc00 100644 (file)
@@ -286,7 +286,7 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
        if (initial)
                asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"       /* rep xcryptcbc */
                              : "+S" (input), "+D" (output), "+a" (iv)
-                             : "d" (control_word), "b" (key), "c" (count));
+                             : "d" (control_word), "b" (key), "c" (initial));
 
        asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"       /* rep xcryptcbc */
                      : "+S" (input), "+D" (output), "+a" (iv)
index 79d1542f31c0aaaff95c114a63bdb2135f8524ee..6ee23592700a20ab249689c48a6053546647cb36 100644 (file)
@@ -200,11 +200,11 @@ config PL330_DMA
          platform_data for a dma-pl330 device.
 
 config PCH_DMA
-       tristate "Topcliff PCH DMA support"
+       tristate "Topcliff (Intel EG20T) PCH DMA support"
        depends on PCI && X86
        select DMA_ENGINE
        help
-         Enable support for the Topcliff PCH DMA engine.
+         Enable support for the Topcliff (Intel EG20T) PCH DMA engine.
 
 config IMX_SDMA
        tristate "i.MX SDMA support"
index 9dcb17d51aee737bcbb4ac478807c04311588d6c..84eb607d6c031b4275e834604d4c0c0729fa8502 100644 (file)
@@ -577,17 +577,11 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr,
        return ret;
 }
 
-static int ar_context_add_page(struct ar_context *ctx)
+static void ar_context_link_page(struct ar_context *ctx,
+                                struct ar_buffer *ab, dma_addr_t ab_bus)
 {
-       struct device *dev = ctx->ohci->card.device;
-       struct ar_buffer *ab;
-       dma_addr_t uninitialized_var(ab_bus);
        size_t offset;
 
-       ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
-       if (ab == NULL)
-               return -ENOMEM;
-
        ab->next = NULL;
        memset(&ab->descriptor, 0, sizeof(ab->descriptor));
        ab->descriptor.control        = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
@@ -606,6 +600,19 @@ static int ar_context_add_page(struct ar_context *ctx)
 
        reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
        flush_writes(ctx->ohci);
+}
+
+static int ar_context_add_page(struct ar_context *ctx)
+{
+       struct device *dev = ctx->ohci->card.device;
+       struct ar_buffer *ab;
+       dma_addr_t uninitialized_var(ab_bus);
+
+       ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
+       if (ab == NULL)
+               return -ENOMEM;
+
+       ar_context_link_page(ctx, ab, ab_bus);
 
        return 0;
 }
@@ -730,16 +737,17 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
 static void ar_context_tasklet(unsigned long data)
 {
        struct ar_context *ctx = (struct ar_context *)data;
-       struct fw_ohci *ohci = ctx->ohci;
        struct ar_buffer *ab;
        struct descriptor *d;
        void *buffer, *end;
+       __le16 res_count;
 
        ab = ctx->current_buffer;
        d = &ab->descriptor;
 
-       if (d->res_count == 0) {
-               size_t size, rest, offset;
+       res_count = ACCESS_ONCE(d->res_count);
+       if (res_count == 0) {
+               size_t size, size2, rest, pktsize, size3, offset;
                dma_addr_t start_bus;
                void *start;
 
@@ -750,29 +758,63 @@ static void ar_context_tasklet(unsigned long data)
                 */
 
                offset = offsetof(struct ar_buffer, data);
-               start = buffer = ab;
+               start = ab;
                start_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
+               buffer = ab->data;
 
                ab = ab->next;
                d = &ab->descriptor;
-               size = buffer + PAGE_SIZE - ctx->pointer;
+               size = start + PAGE_SIZE - ctx->pointer;
+               /* valid buffer data in the next page */
                rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count);
+               /* what actually fits in this page */
+               size2 = min(rest, (size_t)PAGE_SIZE - offset - size);
                memmove(buffer, ctx->pointer, size);
-               memcpy(buffer + size, ab->data, rest);
-               ctx->current_buffer = ab;
-               ctx->pointer = (void *) ab->data + rest;
-               end = buffer + size + rest;
+               memcpy(buffer + size, ab->data, size2);
+
+               while (size > 0) {
+                       void *next = handle_ar_packet(ctx, buffer);
+                       pktsize = next - buffer;
+                       if (pktsize >= size) {
+                               /*
+                                * We have handled all the data that was
+                                * originally in this page, so we can now
+                                * continue in the next page.
+                                */
+                               buffer = next;
+                               break;
+                       }
+                       /* move the next packet to the start of the buffer */
+                       memmove(buffer, next, size + size2 - pktsize);
+                       size -= pktsize;
+                       /* fill up this page again */
+                       size3 = min(rest - size2,
+                                   (size_t)PAGE_SIZE - offset - size - size2);
+                       memcpy(buffer + size + size2,
+                              (void *) ab->data + size2, size3);
+                       size2 += size3;
+               }
 
-               while (buffer < end)
-                       buffer = handle_ar_packet(ctx, buffer);
+               if (rest > 0) {
+                       /* handle the packets that are fully in the next page */
+                       buffer = (void *) ab->data +
+                                       (buffer - (start + offset + size));
+                       end = (void *) ab->data + rest;
+
+                       while (buffer < end)
+                               buffer = handle_ar_packet(ctx, buffer);
 
-               dma_free_coherent(ohci->card.device, PAGE_SIZE,
-                                 start, start_bus);
-               ar_context_add_page(ctx);
+                       ctx->current_buffer = ab;
+                       ctx->pointer = end;
+
+                       ar_context_link_page(ctx, start, start_bus);
+               } else {
+                       ctx->pointer = start + PAGE_SIZE;
+               }
        } else {
                buffer = ctx->pointer;
                ctx->pointer = end =
-                       (void *) ab + PAGE_SIZE - le16_to_cpu(d->res_count);
+                       (void *) ab + PAGE_SIZE - le16_to_cpu(res_count);
 
                while (buffer < end)
                        buffer = handle_ar_packet(ctx, buffer);
index dcbeb98f195a7addf665e0134af9ee799280a279..f7af91cb273d58232d41c68b712b2d6d4404671c 100644 (file)
@@ -276,7 +276,7 @@ static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
        struct drm_crtc *tmp;
        int crtc_mask = 1;
 
-       WARN(!crtc, "checking null crtc?");
+       WARN(!crtc, "checking null crtc?\n");
 
        dev = crtc->dev;
 
index c1a26217a5305ee65a07b85fa77e4c15db77436b..a245d17165ae28b4eab835d612c92e008e3ab5d4 100644 (file)
@@ -240,7 +240,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
                        .addr   = DDC_ADDR,
                        .flags  = I2C_M_RD,
                        .len    = len,
-                       .buf    = buf + start,
+                       .buf    = buf,
                }
        };
 
@@ -253,7 +253,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
 static u8 *
 drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
 {
-       int i, j = 0;
+       int i, j = 0, valid_extensions = 0;
        u8 *block, *new;
 
        if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
@@ -280,14 +280,28 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
 
        for (j = 1; j <= block[0x7e]; j++) {
                for (i = 0; i < 4; i++) {
-                       if (drm_do_probe_ddc_edid(adapter, block, j,
-                                                 EDID_LENGTH))
+                       if (drm_do_probe_ddc_edid(adapter,
+                                 block + (valid_extensions + 1) * EDID_LENGTH,
+                                 j, EDID_LENGTH))
                                goto out;
-                       if (drm_edid_block_valid(block + j * EDID_LENGTH))
+                       if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) {
+                               valid_extensions++;
                                break;
+                       }
                }
                if (i == 4)
-                       goto carp;
+                       dev_warn(connector->dev->dev,
+                        "%s: Ignoring invalid EDID block %d.\n",
+                        drm_get_connector_name(connector), j);
+       }
+
+       if (valid_extensions != block[0x7e]) {
+               block[EDID_LENGTH-1] += block[0x7e] - valid_extensions;
+               block[0x7e] = valid_extensions;
+               new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
+               if (!new)
+                       goto out;
+               block = new;
        }
 
        return block;
index 3467dd420760fa51084a2ba00d097b90d6c214a2..80745f85902cf73fe17bf2ec41863dcb36a38550 100644 (file)
@@ -44,7 +44,7 @@ unsigned int i915_fbpercrtc = 0;
 module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
 
 unsigned int i915_powersave = 1;
-module_param_named(powersave, i915_powersave, int, 0400);
+module_param_named(powersave, i915_powersave, int, 0600);
 
 unsigned int i915_lvds_downclock = 0;
 module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
index 2c2c19b6285ecf331edbac9c53e0bdd44b2093ad..90414ae86afcd0758d49b2c70dfb39f613ab22f5 100644 (file)
@@ -1321,6 +1321,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
 
 #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type)
 #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
+#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
index 8eb8453208b5ce491e77c1c06c77c1c0a2da41bc..ef188e391406a1b3a2763e92d578c8f9e03b28b3 100644 (file)
@@ -2172,7 +2172,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
 static int i915_ring_idle(struct drm_device *dev,
                          struct intel_ring_buffer *ring)
 {
-       if (list_empty(&ring->gpu_write_list))
+       if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list))
                return 0;
 
        i915_gem_flush_ring(dev, NULL, ring,
@@ -2190,9 +2190,7 @@ i915_gpu_idle(struct drm_device *dev)
        int ret;
 
        lists_empty = (list_empty(&dev_priv->mm.flushing_list) &&
-                      list_empty(&dev_priv->render_ring.active_list) &&
-                      list_empty(&dev_priv->bsd_ring.active_list) &&
-                      list_empty(&dev_priv->blt_ring.active_list));
+                      list_empty(&dev_priv->mm.active_list));
        if (lists_empty)
                return 0;
 
@@ -3108,7 +3106,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
         * write domain
         */
        if (obj->write_domain &&
-           obj->write_domain != obj->pending_read_domains) {
+           (obj->write_domain != obj->pending_read_domains ||
+            obj_priv->ring != ring)) {
                flush_domains |= obj->write_domain;
                invalidate_domains |=
                        obj->pending_read_domains & ~obj->write_domain;
@@ -3497,6 +3496,52 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
        return 0;
 }
 
+static int
+i915_gem_execbuffer_move_to_gpu(struct drm_device *dev,
+                               struct drm_file *file,
+                               struct intel_ring_buffer *ring,
+                               struct drm_gem_object **objects,
+                               int count)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int ret, i;
+
+       /* Zero the global flush/invalidate flags. These
+        * will be modified as new domains are computed
+        * for each object
+        */
+       dev->invalidate_domains = 0;
+       dev->flush_domains = 0;
+       dev_priv->mm.flush_rings = 0;
+       for (i = 0; i < count; i++)
+               i915_gem_object_set_to_gpu_domain(objects[i], ring);
+
+       if (dev->invalidate_domains | dev->flush_domains) {
+#if WATCH_EXEC
+               DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
+                         __func__,
+                        dev->invalidate_domains,
+                        dev->flush_domains);
+#endif
+               i915_gem_flush(dev, file,
+                              dev->invalidate_domains,
+                              dev->flush_domains,
+                              dev_priv->mm.flush_rings);
+       }
+
+       for (i = 0; i < count; i++) {
+               struct drm_i915_gem_object *obj = to_intel_bo(objects[i]);
+               /* XXX replace with semaphores */
+               if (obj->ring && ring != obj->ring) {
+                       ret = i915_gem_object_wait_rendering(&obj->base, true);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
 /* Throttle our rendering by waiting until the ring has completed our requests
  * emitted over 20 msec ago.
  *
@@ -3757,33 +3802,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                goto err;
        }
 
-       /* Zero the global flush/invalidate flags. These
-        * will be modified as new domains are computed
-        * for each object
-        */
-       dev->invalidate_domains = 0;
-       dev->flush_domains = 0;
-       dev_priv->mm.flush_rings = 0;
-
-       for (i = 0; i < args->buffer_count; i++) {
-               struct drm_gem_object *obj = object_list[i];
-
-               /* Compute new gpu domains and update invalidate/flush */
-               i915_gem_object_set_to_gpu_domain(obj, ring);
-       }
-
-       if (dev->invalidate_domains | dev->flush_domains) {
-#if WATCH_EXEC
-               DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
-                         __func__,
-                        dev->invalidate_domains,
-                        dev->flush_domains);
-#endif
-               i915_gem_flush(dev, file,
-                              dev->invalidate_domains,
-                              dev->flush_domains,
-                              dev_priv->mm.flush_rings);
-       }
+       ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring,
+                                             object_list, args->buffer_count);
+       if (ret)
+               goto err;
 
        for (i = 0; i < args->buffer_count; i++) {
                struct drm_gem_object *obj = object_list[i];
@@ -4043,8 +4065,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
                        alignment = i915_gem_get_gtt_alignment(obj);
                if (obj_priv->gtt_offset & (alignment - 1)) {
                        WARN(obj_priv->pin_count,
-                            "bo is already pinned with incorrect alignment:"
-                            " offset=%x, req.alignment=%x\n",
+                            "bo is already pinned with incorrect alignment: offset=%x, req.alignment=%x\n",
                             obj_priv->gtt_offset, alignment);
                        ret = i915_gem_object_unbind(obj);
                        if (ret)
@@ -4856,17 +4877,24 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
                     struct drm_file *file_priv)
 {
        struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
-       void *obj_addr;
-       int ret;
-       char __user *user_data;
+       void *vaddr = obj_priv->phys_obj->handle->vaddr + args->offset;
+       char __user *user_data = (char __user *) (uintptr_t) args->data_ptr;
 
-       user_data = (char __user *) (uintptr_t) args->data_ptr;
-       obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset;
+       DRM_DEBUG_DRIVER("vaddr %p, %lld\n", vaddr, args->size);
 
-       DRM_DEBUG_DRIVER("obj_addr %p, %lld\n", obj_addr, args->size);
-       ret = copy_from_user(obj_addr, user_data, args->size);
-       if (ret)
-               return -EFAULT;
+       if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) {
+               unsigned long unwritten;
+
+               /* The physical object once assigned is fixed for the lifetime
+                * of the obj, so we can safely drop the lock and continue
+                * to access vaddr.
+                */
+               mutex_unlock(&dev->struct_mutex);
+               unwritten = copy_from_user(vaddr, user_data, args->size);
+               mutex_lock(&dev->struct_mutex);
+               if (unwritten)
+                       return -EFAULT;
+       }
 
        drm_agp_chipset_flush(dev);
        return 0;
@@ -4900,9 +4928,7 @@ i915_gpu_is_active(struct drm_device *dev)
        int lists_empty;
 
        lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
-                     list_empty(&dev_priv->render_ring.active_list) &&
-                     list_empty(&dev_priv->bsd_ring.active_list) &&
-                     list_empty(&dev_priv->blt_ring.active_list);
+                     list_empty(&dev_priv->mm.active_list);
 
        return !lists_empty;
 }
index 43a4013f53fa24e212849af68940384b777d30a1..d8ae7d1d0cc671d9d59393fd2d11ddff317b322f 100644 (file)
@@ -165,9 +165,7 @@ i915_gem_evict_everything(struct drm_device *dev)
 
        lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
                       list_empty(&dev_priv->mm.flushing_list) &&
-                      list_empty(&dev_priv->render_ring.active_list) &&
-                      list_empty(&dev_priv->bsd_ring.active_list) &&
-                      list_empty(&dev_priv->blt_ring.active_list));
+                      list_empty(&dev_priv->mm.active_list));
        if (lists_empty)
                return -ENOSPC;
 
@@ -184,9 +182,7 @@ i915_gem_evict_everything(struct drm_device *dev)
 
        lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
                       list_empty(&dev_priv->mm.flushing_list) &&
-                      list_empty(&dev_priv->render_ring.active_list) &&
-                      list_empty(&dev_priv->bsd_ring.active_list) &&
-                      list_empty(&dev_priv->blt_ring.active_list));
+                      list_empty(&dev_priv->mm.active_list));
        BUG_ON(!lists_empty);
 
        return 0;
index 989c19d2d959b6bc6c54a0e4bf31d9aee093efe6..454c064f8ef7f8d0daffe0ed40394354b152ee55 100644 (file)
@@ -862,8 +862,10 @@ int i915_restore_state(struct drm_device *dev)
        /* Clock gating state */
        intel_init_clock_gating(dev);
 
-       if (HAS_PCH_SPLIT(dev))
+       if (HAS_PCH_SPLIT(dev)) {
                ironlake_enable_drps(dev);
+               intel_init_emon(dev);
+       }
 
        /* Cache mode state */
        I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
index 990f065374b22eacfc2fcddd68c873a5081ee773..48d8fd686ea91d9fb3ba307036ecd0f5388174e9 100644 (file)
@@ -1681,6 +1681,37 @@ static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock)
        udelay(500);
 }
 
+static void intel_fdi_normal_train(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       int pipe = intel_crtc->pipe;
+       u32 reg, temp;
+
+       /* enable normal train */
+       reg = FDI_TX_CTL(pipe);
+       temp = I915_READ(reg);
+       temp &= ~FDI_LINK_TRAIN_NONE;
+       temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
+       I915_WRITE(reg, temp);
+
+       reg = FDI_RX_CTL(pipe);
+       temp = I915_READ(reg);
+       if (HAS_PCH_CPT(dev)) {
+               temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+               temp |= FDI_LINK_TRAIN_NORMAL_CPT;
+       } else {
+               temp &= ~FDI_LINK_TRAIN_NONE;
+               temp |= FDI_LINK_TRAIN_NONE;
+       }
+       I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
+
+       /* wait one idle pattern time */
+       POSTING_READ(reg);
+       udelay(1000);
+}
+
 /* The FDI link training functions for ILK/Ibexpeak. */
 static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 {
@@ -1767,27 +1798,6 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 
        DRM_DEBUG_KMS("FDI train done\n");
 
-       /* enable normal train */
-       reg = FDI_TX_CTL(pipe);
-       temp = I915_READ(reg);
-       temp &= ~FDI_LINK_TRAIN_NONE;
-       temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
-       I915_WRITE(reg, temp);
-
-       reg = FDI_RX_CTL(pipe);
-       temp = I915_READ(reg);
-       if (HAS_PCH_CPT(dev)) {
-               temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
-               temp |= FDI_LINK_TRAIN_NORMAL_CPT;
-       } else {
-               temp &= ~FDI_LINK_TRAIN_NONE;
-               temp |= FDI_LINK_TRAIN_NONE;
-       }
-       I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
-
-       /* wait one idle pattern time */
-       POSTING_READ(reg);
-       udelay(1000);
 }
 
 static const int const snb_b_fdi_train_param [] = {
@@ -2090,6 +2100,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
        I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe)));
        I915_WRITE(TRANS_VSYNC(pipe),  I915_READ(VSYNC(pipe)));
 
+       intel_fdi_normal_train(crtc);
+
        /* For PCH DP, enable TRANS_DP_CTL */
        if (HAS_PCH_CPT(dev) &&
            intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
@@ -2200,9 +2212,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
        udelay(100);
 
        /* Ironlake workaround, disable clock pointer after downing FDI */
-       I915_WRITE(FDI_RX_CHICKEN(pipe),
-                  I915_READ(FDI_RX_CHICKEN(pipe) &
-                            ~FDI_RX_PHASE_SYNC_POINTER_ENABLE));
+       if (HAS_PCH_IBX(dev))
+               I915_WRITE(FDI_RX_CHICKEN(pipe),
+                          I915_READ(FDI_RX_CHICKEN(pipe) &
+                                    ~FDI_RX_PHASE_SYNC_POINTER_ENABLE));
 
        /* still set train pattern 1 */
        reg = FDI_TX_CTL(pipe);
@@ -5581,20 +5594,19 @@ void ironlake_enable_drps(struct drm_device *dev)
        fmin = (rgvmodectl & MEMMODE_FMIN_MASK);
        fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >>
                MEMMODE_FSTART_SHIFT;
-       fstart = fmax;
 
        vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >>
                PXVFREQ_PX_SHIFT;
 
-       dev_priv->fmax = fstart; /* IPS callback will increase this */
+       dev_priv->fmax = fmax; /* IPS callback will increase this */
        dev_priv->fstart = fstart;
 
-       dev_priv->max_delay = fmax;
+       dev_priv->max_delay = fstart;
        dev_priv->min_delay = fmin;
        dev_priv->cur_delay = fstart;
 
-       DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin,
-                        fstart);
+       DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n",
+                        fmax, fmin, fstart);
 
        I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN);
 
index 891f4f1d63b11570b7ede1c4e5e49814f2dcb5d0..c8e005553310a5eaeae98e4cb8ed349b4b204164 100644 (file)
@@ -1517,7 +1517,7 @@ g4x_dp_detect(struct intel_dp *intel_dp)
                        status = connector_status_connected;
        }
 
-       return bit;
+       return status;
 }
 
 /**
index 9af9f86a8765c82833706aa1320ca9baed3fa416..21551fe745416abb4597341b18d647f2529e85ce 100644 (file)
@@ -296,6 +296,7 @@ extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
 extern void intel_init_clock_gating(struct drm_device *dev);
 extern void ironlake_enable_drps(struct drm_device *dev);
 extern void ironlake_disable_drps(struct drm_device *dev);
+extern void intel_init_emon(struct drm_device *dev);
 
 extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
                                      struct drm_gem_object *obj,
index f1a649990ea9e61d5f7ff6f8b15e127d6fcc2f17..4324a326f98ee28f4d67936b7a4789556344c4fb 100644 (file)
@@ -481,11 +481,8 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
        struct drm_device *dev = connector->dev;
        struct drm_display_mode *mode;
 
-       if (intel_lvds->edid) {
-               drm_mode_connector_update_edid_property(connector,
-                                                       intel_lvds->edid);
+       if (intel_lvds->edid)
                return drm_add_edid_modes(connector, intel_lvds->edid);
-       }
 
        mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode);
        if (mode == 0)
@@ -939,7 +936,16 @@ void intel_lvds_init(struct drm_device *dev)
         */
        intel_lvds->edid = drm_get_edid(connector,
                                        &dev_priv->gmbus[pin].adapter);
-
+       if (intel_lvds->edid) {
+               if (drm_add_edid_modes(connector,
+                                      intel_lvds->edid)) {
+                       drm_mode_connector_update_edid_property(connector,
+                                                               intel_lvds->edid);
+               } else {
+                       kfree(intel_lvds->edid);
+                       intel_lvds->edid = NULL;
+               }
+       }
        if (!intel_lvds->edid) {
                /* Didn't get an EDID, so
                 * Set wide sync ranges so we get all modes
index 917c7dc3cd6b33ee151ad2e960743fe35016cec0..9b0d9a867aeada1f1c9d601e21f76e2d9e4e7351 100644 (file)
@@ -512,6 +512,6 @@ int intel_opregion_setup(struct drm_device *dev)
        return 0;
 
 err_out:
-       iounmap(opregion->header);
+       iounmap(base);
        return err;
 }
index afb96d25219afe473b116802f30616c0edb1cf86..02ff0a481f470cea6e3f4f109805e07fbd84725e 100644 (file)
@@ -946,7 +946,9 @@ static int check_overlay_src(struct drm_device *dev,
 {
        int uv_hscale = uv_hsubsampling(rec->flags);
        int uv_vscale = uv_vsubsampling(rec->flags);
-       u32 stride_mask, depth, tmp;
+       u32 stride_mask;
+       int depth;
+       u32 tmp;
 
        /* check src dimensions */
        if (IS_845G(dev) || IS_I830(dev)) {
index 09f2dc353ae239f0d2a6f86a5940c1d7b27656e4..b83306f9244b6c887d84976b4f1801449445941a 100644 (file)
@@ -177,7 +177,7 @@ static int init_ring_common(struct drm_device *dev,
 
        I915_WRITE_CTL(ring,
                        ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES)
-                       | RING_NO_REPORT | RING_VALID);
+                       | RING_REPORT_64K | RING_VALID);
 
        head = I915_READ_HEAD(ring) & HEAD_ADDR;
        /* If the head is still not zero, the ring is dead */
@@ -654,6 +654,10 @@ void intel_cleanup_ring_buffer(struct drm_device *dev,
        i915_gem_object_unpin(ring->gem_object);
        drm_gem_object_unreference(ring->gem_object);
        ring->gem_object = NULL;
+
+       if (ring->cleanup)
+               ring->cleanup(ring);
+
        cleanup_status_page(dev, ring);
 }
 
@@ -688,6 +692,17 @@ int intel_wait_ring_buffer(struct drm_device *dev,
 {
        unsigned long end;
        drm_i915_private_t *dev_priv = dev->dev_private;
+       u32 head;
+
+       head = intel_read_status_page(ring, 4);
+       if (head) {
+               ring->head = head & HEAD_ADDR;
+               ring->space = ring->head - (ring->tail + 8);
+               if (ring->space < 0)
+                       ring->space += ring->size;
+               if (ring->space >= n)
+                       return 0;
+       }
 
        trace_i915_ring_wait_begin (dev);
        end = jiffies + 3 * HZ;
@@ -854,19 +869,125 @@ blt_ring_put_user_irq(struct drm_device *dev,
        /* do nothing */
 }
 
+
+/* Workaround for some stepping of SNB,
+ * each time when BLT engine ring tail moved,
+ * the first command in the ring to be parsed
+ * should be MI_BATCH_BUFFER_START
+ */
+#define NEED_BLT_WORKAROUND(dev) \
+       (IS_GEN6(dev) && (dev->pdev->revision < 8))
+
+static inline struct drm_i915_gem_object *
+to_blt_workaround(struct intel_ring_buffer *ring)
+{
+       return ring->private;
+}
+
+static int blt_ring_init(struct drm_device *dev,
+                        struct intel_ring_buffer *ring)
+{
+       if (NEED_BLT_WORKAROUND(dev)) {
+               struct drm_i915_gem_object *obj;
+               u32 __iomem *ptr;
+               int ret;
+
+               obj = to_intel_bo(i915_gem_alloc_object(dev, 4096));
+               if (obj == NULL)
+                       return -ENOMEM;
+
+               ret = i915_gem_object_pin(&obj->base, 4096);
+               if (ret) {
+                       drm_gem_object_unreference(&obj->base);
+                       return ret;
+               }
+
+               ptr = kmap(obj->pages[0]);
+               iowrite32(MI_BATCH_BUFFER_END, ptr);
+               iowrite32(MI_NOOP, ptr+1);
+               kunmap(obj->pages[0]);
+
+               ret = i915_gem_object_set_to_gtt_domain(&obj->base, false);
+               if (ret) {
+                       i915_gem_object_unpin(&obj->base);
+                       drm_gem_object_unreference(&obj->base);
+                       return ret;
+               }
+
+               ring->private = obj;
+       }
+
+       return init_ring_common(dev, ring);
+}
+
+static void blt_ring_begin(struct drm_device *dev,
+                          struct intel_ring_buffer *ring,
+                         int num_dwords)
+{
+       if (ring->private) {
+               intel_ring_begin(dev, ring, num_dwords+2);
+               intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START);
+               intel_ring_emit(dev, ring, to_blt_workaround(ring)->gtt_offset);
+       } else
+               intel_ring_begin(dev, ring, 4);
+}
+
+static void blt_ring_flush(struct drm_device *dev,
+                          struct intel_ring_buffer *ring,
+                          u32 invalidate_domains,
+                          u32 flush_domains)
+{
+       blt_ring_begin(dev, ring, 4);
+       intel_ring_emit(dev, ring, MI_FLUSH_DW);
+       intel_ring_emit(dev, ring, 0);
+       intel_ring_emit(dev, ring, 0);
+       intel_ring_emit(dev, ring, 0);
+       intel_ring_advance(dev, ring);
+}
+
+static u32
+blt_ring_add_request(struct drm_device *dev,
+                    struct intel_ring_buffer *ring,
+                    u32 flush_domains)
+{
+       u32 seqno = i915_gem_get_seqno(dev);
+
+       blt_ring_begin(dev, ring, 4);
+       intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX);
+       intel_ring_emit(dev, ring,
+                       I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+       intel_ring_emit(dev, ring, seqno);
+       intel_ring_emit(dev, ring, MI_USER_INTERRUPT);
+       intel_ring_advance(dev, ring);
+
+       DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno);
+       return seqno;
+}
+
+static void blt_ring_cleanup(struct intel_ring_buffer *ring)
+{
+       if (!ring->private)
+               return;
+
+       i915_gem_object_unpin(ring->private);
+       drm_gem_object_unreference(ring->private);
+       ring->private = NULL;
+}
+
 static const struct intel_ring_buffer gen6_blt_ring = {
        .name                   = "blt ring",
        .id                     = RING_BLT,
        .mmio_base              = BLT_RING_BASE,
        .size                   = 32 * PAGE_SIZE,
-       .init                   = init_ring_common,
+       .init                   = blt_ring_init,
        .write_tail             = ring_write_tail,
-       .flush                  = gen6_ring_flush,
-       .add_request            = ring_add_request,
+       .flush                  = blt_ring_flush,
+       .add_request            = blt_ring_add_request,
        .get_seqno              = ring_status_page_get_seqno,
        .user_irq_get           = blt_ring_get_user_irq,
        .user_irq_put           = blt_ring_put_user_irq,
        .dispatch_gem_execbuffer        = gen6_ring_dispatch_gem_execbuffer,
+       .cleanup                        = blt_ring_cleanup,
 };
 
 int intel_init_render_ring_buffer(struct drm_device *dev)
index a05aff0e5764d67e421a5a4995f2b0b92dfcd925..3126c2681983e21ba729d9ca599d104f4f1323de 100644 (file)
@@ -63,6 +63,7 @@ struct  intel_ring_buffer {
                        struct drm_i915_gem_execbuffer2 *exec,
                        struct drm_clip_rect *cliprects,
                        uint64_t exec_offset);
+       void            (*cleanup)(struct intel_ring_buffer *ring);
 
        /**
         * List of objects currently involved in rendering from the
@@ -98,6 +99,8 @@ struct  intel_ring_buffer {
 
        wait_queue_head_t irq_queue;
        drm_local_map_t map;
+
+       void *private;
 };
 
 static inline u32
index f12a5b3ec050320505c6dc0b1cb44dcdde3fbeed..488c36c8f5e6069ebbb6cf5f9b830747a61c062e 100644 (file)
@@ -2033,7 +2033,7 @@ int evergreen_irq_set(struct radeon_device *rdev)
        u32 grbm_int_cntl = 0;
 
        if (!rdev->irq.installed) {
-               WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
+               WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
                return -EINVAL;
        }
        /* don't enable anything if the ih is disabled */
@@ -2295,6 +2295,7 @@ restart_ih:
                        case 0: /* D1 vblank */
                                if (disp_int & LB_D1_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 0);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int &= ~LB_D1_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D1 vblank\n");
@@ -2316,6 +2317,7 @@ restart_ih:
                        case 0: /* D2 vblank */
                                if (disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 1);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D2 vblank\n");
@@ -2337,6 +2339,7 @@ restart_ih:
                        case 0: /* D3 vblank */
                                if (disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 2);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D3 vblank\n");
@@ -2358,6 +2361,7 @@ restart_ih:
                        case 0: /* D4 vblank */
                                if (disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 3);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D4 vblank\n");
@@ -2379,6 +2383,7 @@ restart_ih:
                        case 0: /* D5 vblank */
                                if (disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 4);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D5 vblank\n");
@@ -2400,6 +2405,7 @@ restart_ih:
                        case 0: /* D6 vblank */
                                if (disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 5);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D6 vblank\n");
index 0e8f28a689271c88a88d3865ead4890089049dca..8e10aa9f74b052a25e86d04e65173c8a7a19eb76 100644 (file)
@@ -442,7 +442,7 @@ int r100_pci_gart_init(struct radeon_device *rdev)
        int r;
 
        if (rdev->gart.table.ram.ptr) {
-               WARN(1, "R100 PCI GART already initialized.\n");
+               WARN(1, "R100 PCI GART already initialized\n");
                return 0;
        }
        /* Initialize common gart structure */
@@ -516,7 +516,7 @@ int r100_irq_set(struct radeon_device *rdev)
        uint32_t tmp = 0;
 
        if (!rdev->irq.installed) {
-               WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
+               WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
                WREG32(R_000040_GEN_INT_CNTL, 0);
                return -EINVAL;
        }
index 34527e600fe94f91ab33da78285b695afbb6cd6e..cde1d3480d932c55ae33855c3a2336eadfe9ab54 100644 (file)
@@ -91,7 +91,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev)
        int r;
 
        if (rdev->gart.table.vram.robj) {
-               WARN(1, "RV370 PCIE GART already initialized.\n");
+               WARN(1, "RV370 PCIE GART already initialized\n");
                return 0;
        }
        /* Initialize common gart structure */
index 33952a12f0a31a49986a248a39c38cb48cdf618c..0f806cc7dc75f02f5bb00f98fc0d65b662aad688 100644 (file)
@@ -97,14 +97,8 @@ u32 rv6xx_get_temp(struct radeon_device *rdev)
 {
        u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >>
                ASIC_T_SHIFT;
-       u32 actual_temp = 0;
 
-       if ((temp >> 7) & 1)
-               actual_temp = 0;
-       else
-               actual_temp = (temp >> 1) & 0xff;
-
-       return actual_temp * 1000;
+       return temp * 1000;
 }
 
 void r600_pm_get_dynpm_state(struct radeon_device *rdev)
@@ -919,7 +913,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev)
        int r;
 
        if (rdev->gart.table.vram.robj) {
-               WARN(1, "R600 PCIE GART already initialized.\n");
+               WARN(1, "R600 PCIE GART already initialized\n");
                return 0;
        }
        /* Initialize common gart structure */
@@ -2995,7 +2989,7 @@ int r600_irq_set(struct radeon_device *rdev)
        u32 hdmi1, hdmi2;
 
        if (!rdev->irq.installed) {
-               WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
+               WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
                return -EINVAL;
        }
        /* don't enable anything if the ih is disabled */
index 04cac7ec90397fa7f4f46f9d966fb41b2d3c5368..87ead090c7d5a5195af6cf8d15be5a5809ff9678 100644 (file)
@@ -526,8 +526,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
        if (crev < 2)
                return false;
 
-       router.valid = false;
-
        obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset);
        path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
            (ctx->bios + data_offset +
@@ -624,6 +622,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                        if (connector_type == DRM_MODE_CONNECTOR_Unknown)
                                continue;
 
+                       router.ddc_valid = false;
+                       router.cd_valid = false;
                        for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) {
                                uint8_t grph_obj_id, grph_obj_num, grph_obj_type;
 
@@ -647,9 +647,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                                 usDeviceTag));
 
                                } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) {
-                                       router.valid = false;
                                        for (k = 0; k < router_obj->ucNumberOfObjects; k++) {
-                                               u16 router_obj_id = le16_to_cpu(router_obj->asObjects[j].usObjectID);
+                                               u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID);
                                                if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) {
                                                        ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *)
                                                                (ctx->bios + data_offset +
@@ -657,6 +656,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                        ATOM_I2C_RECORD *i2c_record;
                                                        ATOM_I2C_ID_CONFIG_ACCESS *i2c_config;
                                                        ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path;
+                                                       ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path;
                                                        ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table =
                                                                (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
                                                                (ctx->bios + data_offset +
@@ -690,10 +690,18 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
                                                                case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE:
                                                                        ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *)
                                                                                record;
-                                                                       router.valid = true;
-                                                                       router.mux_type = ddc_path->ucMuxType;
-                                                                       router.mux_control_pin = ddc_path->ucMuxControlPin;
-                                                                       router.mux_state = ddc_path->ucMuxState[enum_id];
+                                                                       router.ddc_valid = true;
+                                                                       router.ddc_mux_type = ddc_path->ucMuxType;
+                                                                       router.ddc_mux_control_pin = ddc_path->ucMuxControlPin;
+                                                                       router.ddc_mux_state = ddc_path->ucMuxState[enum_id];
+                                                                       break;
+                                                               case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE:
+                                                                       cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *)
+                                                                               record;
+                                                                       router.cd_valid = true;
+                                                                       router.cd_mux_type = cd_path->ucMuxType;
+                                                                       router.cd_mux_control_pin = cd_path->ucMuxControlPin;
+                                                                       router.cd_mux_state = cd_path->ucMuxState[enum_id];
                                                                        break;
                                                                }
                                                                record = (ATOM_COMMON_RECORD_HEADER *)
@@ -860,7 +868,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
        size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE;
        struct radeon_router router;
 
-       router.valid = false;
+       router.ddc_valid = false;
+       router.cd_valid = false;
 
        bios_connectors = kzalloc(bc_size, GFP_KERNEL);
        if (!bios_connectors)
index 4dac4b0a02eea1928837c7009f88e84f227a81f5..fe6c74780f18e67bb55ea5fdeefdbb038ffadbf1 100644 (file)
@@ -183,13 +183,13 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
                                        continue;
 
                                if (priority == true) {
-                                       DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
-                                       DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
+                                       DRM_DEBUG_KMS("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
+                                       DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(connector));
                                        conflict->status = connector_status_disconnected;
                                        radeon_connector_update_scratch_regs(conflict, connector_status_disconnected);
                                } else {
-                                       DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector));
-                                       DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict));
+                                       DRM_DEBUG_KMS("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector));
+                                       DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(conflict));
                                        current_status = connector_status_disconnected;
                                }
                                break;
@@ -432,13 +432,13 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
                            mode->vdisplay == native_mode->vdisplay) {
                                *native_mode = *mode;
                                drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V);
-                               DRM_INFO("Determined LVDS native mode details from EDID\n");
+                               DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n");
                                break;
                        }
                }
        }
        if (!native_mode->clock) {
-               DRM_INFO("No LVDS native mode details, disabling RMX\n");
+               DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n");
                radeon_encoder->rmx_type = RMX_OFF;
        }
 }
@@ -1116,7 +1116,7 @@ radeon_add_atom_connector(struct drm_device *dev,
                                radeon_connector->shared_ddc = true;
                                shared_ddc = true;
                        }
-                       if (radeon_connector->router_bus && router->valid &&
+                       if (radeon_connector->router_bus && router->ddc_valid &&
                            (radeon_connector->router.router_id == router->router_id)) {
                                radeon_connector->shared_ddc = false;
                                shared_ddc = false;
@@ -1136,7 +1136,7 @@ radeon_add_atom_connector(struct drm_device *dev,
        radeon_connector->connector_object_id = connector_object_id;
        radeon_connector->hpd = *hpd;
        radeon_connector->router = *router;
-       if (router->valid) {
+       if (router->ddc_valid || router->cd_valid) {
                radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info);
                if (!radeon_connector->router_bus)
                        goto failed;
index 0383631da69c42db417f27f6b87ddf58f19eb24e..1df4dc6c063cc44e0e7e943da9b62e6c85d27d38 100644 (file)
@@ -315,10 +315,14 @@ static void radeon_print_display_setup(struct drm_device *dev)
                                 radeon_connector->ddc_bus->rec.en_data_reg,
                                 radeon_connector->ddc_bus->rec.y_clk_reg,
                                 radeon_connector->ddc_bus->rec.y_data_reg);
-                       if (radeon_connector->router_bus)
+                       if (radeon_connector->router.ddc_valid)
                                DRM_INFO("  DDC Router 0x%x/0x%x\n",
-                                        radeon_connector->router.mux_control_pin,
-                                        radeon_connector->router.mux_state);
+                                        radeon_connector->router.ddc_mux_control_pin,
+                                        radeon_connector->router.ddc_mux_state);
+                       if (radeon_connector->router.cd_valid)
+                               DRM_INFO("  Clock/Data Router 0x%x/0x%x\n",
+                                        radeon_connector->router.cd_mux_control_pin,
+                                        radeon_connector->router.cd_mux_state);
                } else {
                        if (connector->connector_type == DRM_MODE_CONNECTOR_VGA ||
                            connector->connector_type == DRM_MODE_CONNECTOR_DVII ||
@@ -398,8 +402,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
        int ret = 0;
 
        /* on hw with routers, select right port */
-       if (radeon_connector->router.valid)
-               radeon_router_select_port(radeon_connector);
+       if (radeon_connector->router.ddc_valid)
+               radeon_router_select_ddc_port(radeon_connector);
 
        if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
            (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
@@ -432,8 +436,8 @@ static int radeon_ddc_dump(struct drm_connector *connector)
        int ret = 0;
 
        /* on hw with routers, select right port */
-       if (radeon_connector->router.valid)
-               radeon_router_select_port(radeon_connector);
+       if (radeon_connector->router.ddc_valid)
+               radeon_router_select_ddc_port(radeon_connector);
 
        if (!radeon_connector->ddc_bus)
                return -1;
index ae58b6849a2eaa4fd259b88f3d43d2497733161b..f678257c42e6ab54f668951b93e685cf04d287d5 100644 (file)
@@ -1520,6 +1520,7 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
 static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
 {
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
 
        if (radeon_encoder->active_device &
            (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
@@ -1531,6 +1532,13 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
        radeon_atom_output_lock(encoder, true);
        radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
 
+       /* select the clock/data port if it uses a router */
+       if (connector) {
+               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+               if (radeon_connector->router.cd_valid)
+                       radeon_router_select_cd_port(radeon_connector);
+       }
+
        /* this is needed for the pll/ss setup to work correctly in some cases */
        atombios_set_encoder_crtc_source(encoder);
 }
@@ -1547,6 +1555,23 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct radeon_encoder_atom_dig *dig;
+
+       /* check for pre-DCE3 cards with shared encoders;
+        * can't really use the links individually, so don't disable
+        * the encoder if it's in use by another connector
+        */
+       if (!ASIC_IS_DCE3(rdev)) {
+               struct drm_encoder *other_encoder;
+               struct radeon_encoder *other_radeon_encoder;
+
+               list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
+                       other_radeon_encoder = to_radeon_encoder(other_encoder);
+                       if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) &&
+                           drm_helper_encoder_in_use(other_encoder))
+                               goto disable_done;
+               }
+       }
+
        radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
 
        switch (radeon_encoder->encoder_id) {
@@ -1586,6 +1611,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
                break;
        }
 
+disable_done:
        if (radeon_encoder_is_digital(encoder)) {
                if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
                        r600_hdmi_disable(encoder);
index 216392d0353bcace87cd2a80d06dda358e285ee4..daacb281dfafea57f26ac258dfbdca3c6d0c0767 100644 (file)
@@ -240,7 +240,8 @@ retry:
                 */
                if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) {
                        /* good news we believe it's a lockup */
-                       WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq);
+                       WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n",
+                            fence->seq, seq);
                        /* FIXME: what should we do ? marking everyone
                         * as signaled for now
                         */
index 6a13ee38a5b9fc71201a0a9a38dd93b3ab5957eb..0cfbba02c4d03773df29eb07efe74010a989002b 100644 (file)
@@ -53,8 +53,8 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
        };
 
        /* on hw with routers, select right port */
-       if (radeon_connector->router.valid)
-               radeon_router_select_port(radeon_connector);
+       if (radeon_connector->router.ddc_valid)
+               radeon_router_select_ddc_port(radeon_connector);
 
        ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
        if (ret == 2)
@@ -1084,26 +1084,51 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus,
                          addr, val);
 }
 
-/* router switching */
-void radeon_router_select_port(struct radeon_connector *radeon_connector)
+/* ddc router switching */
+void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector)
 {
        u8 val;
 
-       if (!radeon_connector->router.valid)
+       if (!radeon_connector->router.ddc_valid)
                return;
 
        radeon_i2c_get_byte(radeon_connector->router_bus,
                            radeon_connector->router.i2c_addr,
                            0x3, &val);
-       val &= radeon_connector->router.mux_control_pin;
+       val &= ~radeon_connector->router.ddc_mux_control_pin;
        radeon_i2c_put_byte(radeon_connector->router_bus,
                            radeon_connector->router.i2c_addr,
                            0x3, val);
        radeon_i2c_get_byte(radeon_connector->router_bus,
                            radeon_connector->router.i2c_addr,
                            0x1, &val);
-       val &= radeon_connector->router.mux_control_pin;
-       val |= radeon_connector->router.mux_state;
+       val &= ~radeon_connector->router.ddc_mux_control_pin;
+       val |= radeon_connector->router.ddc_mux_state;
+       radeon_i2c_put_byte(radeon_connector->router_bus,
+                           radeon_connector->router.i2c_addr,
+                           0x1, val);
+}
+
+/* clock/data router switching */
+void radeon_router_select_cd_port(struct radeon_connector *radeon_connector)
+{
+       u8 val;
+
+       if (!radeon_connector->router.cd_valid)
+               return;
+
+       radeon_i2c_get_byte(radeon_connector->router_bus,
+                           radeon_connector->router.i2c_addr,
+                           0x3, &val);
+       val &= ~radeon_connector->router.cd_mux_control_pin;
+       radeon_i2c_put_byte(radeon_connector->router_bus,
+                           radeon_connector->router.i2c_addr,
+                           0x3, val);
+       radeon_i2c_get_byte(radeon_connector->router_bus,
+                           radeon_connector->router.i2c_addr,
+                           0x1, &val);
+       val &= ~radeon_connector->router.cd_mux_control_pin;
+       val |= radeon_connector->router.cd_mux_state;
        radeon_i2c_put_byte(radeon_connector->router_bus,
                            radeon_connector->router.i2c_addr,
                            0x1, val);
index 92457163d07094dba9bd5975dc63dfb4968e92a6..680f57644e865ce2a5e4fdc97b5154a7dffb11a5 100644 (file)
@@ -401,13 +401,19 @@ struct radeon_hpd {
 };
 
 struct radeon_router {
-       bool valid;
        u32 router_id;
        struct radeon_i2c_bus_rec i2c_info;
        u8 i2c_addr;
-       u8 mux_type;
-       u8 mux_control_pin;
-       u8 mux_state;
+       /* i2c mux */
+       bool ddc_valid;
+       u8 ddc_mux_type;
+       u8 ddc_mux_control_pin;
+       u8 ddc_mux_state;
+       /* clock/data mux */
+       bool cd_valid;
+       u8 cd_mux_type;
+       u8 cd_mux_control_pin;
+       u8 cd_mux_state;
 };
 
 struct radeon_connector {
@@ -488,7 +494,8 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
                                u8 slave_addr,
                                u8 addr,
                                u8 val);
-extern void radeon_router_select_port(struct radeon_connector *radeon_connector);
+extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector);
+extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
 extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
 extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
 
index d7ab914164103bdda7bf9ea72e8e35a2c78a5f37..8eb183466015326f7ca93b2647e85a610fe91f6f 100644 (file)
@@ -102,6 +102,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
                type = ttm_bo_type_device;
        }
        *bo_ptr = NULL;
+
+retry:
        bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
        if (bo == NULL)
                return -ENOMEM;
@@ -109,8 +111,6 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
        bo->gobj = gobj;
        bo->surface_reg = -1;
        INIT_LIST_HEAD(&bo->list);
-
-retry:
        radeon_ttm_placement_from_domain(bo, domain);
        /* Kernel allocation are uninterruptible */
        mutex_lock(&rdev->vram_mutex);
index fe95bb35317ea26c2cabe33fc0bae285bfc32cef..01c2c736a1daff116284db0f84f3896977e6eecb 100644 (file)
@@ -689,7 +689,8 @@ static int radeon_ttm_backend_bind(struct ttm_backend *backend,
        gtt = container_of(backend, struct radeon_ttm_backend, backend);
        gtt->offset = bo_mem->start << PAGE_SHIFT;
        if (!gtt->num_pages) {
-               WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", gtt->num_pages, bo_mem, backend);
+               WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n",
+                    gtt->num_pages, bo_mem, backend);
        }
        r = radeon_gart_bind(gtt->rdev, gtt->offset,
                             gtt->num_pages, gtt->pages);
index f683e51a2a0674518b476d6a2157b39a303170a6..5512e4e5e636ebb91ea73e99d63a4e60bb95bbe6 100644 (file)
@@ -78,7 +78,7 @@ int rs400_gart_init(struct radeon_device *rdev)
        int r;
 
        if (rdev->gart.table.ram.ptr) {
-               WARN(1, "RS400 GART already initialized.\n");
+               WARN(1, "RS400 GART already initialized\n");
                return 0;
        }
        /* Check gart size */
index b091a1f6fa4ed2b86dc1975717abbf017667c251..f1c6e02c2e6b41f18338688b1dc9d49b33dbe8bb 100644 (file)
@@ -375,7 +375,7 @@ int rs600_gart_init(struct radeon_device *rdev)
        int r;
 
        if (rdev->gart.table.vram.robj) {
-               WARN(1, "RS600 GART already initialized.\n");
+               WARN(1, "RS600 GART already initialized\n");
                return 0;
        }
        /* Initialize common gart structure */
@@ -505,7 +505,7 @@ int rs600_irq_set(struct radeon_device *rdev)
                ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1);
 
        if (!rdev->irq.installed) {
-               WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
+               WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
                WREG32(R_000040_GEN_INT_CNTL, 0);
                return -EINVAL;
        }
index a1cb783c7131c56de8aa19cf5afb6a668e5e4345..3ca77dc03915017e78d0e7f7e8e479d9f279fc56 100644 (file)
 /*
  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
  */
-/* Notes:
- *
- * We store bo pointer in drm_mm_node struct so we know which bo own a
- * specific node. There is no protection on the pointer, thus to make
- * sure things don't go berserk you have to access this pointer while
- * holding the global lru lock and make sure anytime you free a node you
- * reset the pointer to NULL.
- */
 
 #include "ttm/ttm_module.h"
 #include "ttm/ttm_bo_driver.h"
@@ -45,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/file.h>
 #include <linux/module.h>
+#include <asm/atomic.h>
 
 #define TTM_ASSERT_LOCKED(param)
 #define TTM_DEBUG(fmt, arg...)
@@ -452,6 +445,11 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
        ttm_bo_mem_put(bo, &bo->mem);
 
        atomic_set(&bo->reserved, 0);
+
+       /*
+        * Make processes trying to reserve really pick it up.
+        */
+       smp_mb__after_atomic_dec();
        wake_up_all(&bo->event_queue);
 }
 
@@ -460,7 +458,7 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
        struct ttm_bo_device *bdev = bo->bdev;
        struct ttm_bo_global *glob = bo->glob;
        struct ttm_bo_driver *driver;
-       void *sync_obj;
+       void *sync_obj = NULL;
        void *sync_obj_arg;
        int put_count;
        int ret;
@@ -495,17 +493,20 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
                spin_lock(&glob->lru_lock);
        }
 queue:
-       sync_obj = bo->sync_obj;
-       sync_obj_arg = bo->sync_obj_arg;
        driver = bdev->driver;
+       if (bo->sync_obj)
+               sync_obj = driver->sync_obj_ref(bo->sync_obj);
+       sync_obj_arg = bo->sync_obj_arg;
 
        kref_get(&bo->list_kref);
        list_add_tail(&bo->ddestroy, &bdev->ddestroy);
        spin_unlock(&glob->lru_lock);
        spin_unlock(&bo->lock);
 
-       if (sync_obj)
+       if (sync_obj) {
                driver->sync_obj_flush(sync_obj, sync_obj_arg);
+               driver->sync_obj_unref(&sync_obj);
+       }
        schedule_delayed_work(&bdev->wq,
                              ((HZ / 100) < 1) ? 1 : HZ / 100);
 }
@@ -822,7 +823,6 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
                                        bool no_wait_gpu)
 {
        struct ttm_bo_device *bdev = bo->bdev;
-       struct ttm_bo_global *glob = bdev->glob;
        struct ttm_mem_type_manager *man = &bdev->man[mem_type];
        int ret;
 
@@ -832,12 +832,6 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
                        return ret;
                if (mem->mm_node)
                        break;
-               spin_lock(&glob->lru_lock);
-               if (list_empty(&man->lru)) {
-                       spin_unlock(&glob->lru_lock);
-                       break;
-               }
-               spin_unlock(&glob->lru_lock);
                ret = ttm_mem_evict_first(bdev, mem_type, interruptible,
                                                no_wait_reserve, no_wait_gpu);
                if (unlikely(ret != 0))
@@ -1125,35 +1119,9 @@ EXPORT_SYMBOL(ttm_bo_validate);
 int ttm_bo_check_placement(struct ttm_buffer_object *bo,
                                struct ttm_placement *placement)
 {
-       int i;
+       BUG_ON((placement->fpfn || placement->lpfn) &&
+              (bo->mem.num_pages > (placement->lpfn - placement->fpfn)));
 
-       if (placement->fpfn || placement->lpfn) {
-               if (bo->mem.num_pages > (placement->lpfn - placement->fpfn)) {
-                       printk(KERN_ERR TTM_PFX "Page number range to small "
-                               "Need %lu pages, range is [%u, %u]\n",
-                               bo->mem.num_pages, placement->fpfn,
-                               placement->lpfn);
-                       return -EINVAL;
-               }
-       }
-       for (i = 0; i < placement->num_placement; i++) {
-               if (!capable(CAP_SYS_ADMIN)) {
-                       if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) {
-                               printk(KERN_ERR TTM_PFX "Need to be root to "
-                                       "modify NO_EVICT status.\n");
-                               return -EINVAL;
-                       }
-               }
-       }
-       for (i = 0; i < placement->num_busy_placement; i++) {
-               if (!capable(CAP_SYS_ADMIN)) {
-                       if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) {
-                               printk(KERN_ERR TTM_PFX "Need to be root to "
-                                       "modify NO_EVICT status.\n");
-                               return -EINVAL;
-                       }
-               }
-       }
        return 0;
 }
 
@@ -1176,6 +1144,10 @@ int ttm_bo_init(struct ttm_bo_device *bdev,
        num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
        if (num_pages == 0) {
                printk(KERN_ERR TTM_PFX "Illegal buffer object size.\n");
+               if (destroy)
+                       (*destroy)(bo);
+               else
+                       kfree(bo);
                return -EINVAL;
        }
        bo->destroy = destroy;
@@ -1369,18 +1341,9 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
        int ret = -EINVAL;
        struct ttm_mem_type_manager *man;
 
-       if (type >= TTM_NUM_MEM_TYPES) {
-               printk(KERN_ERR TTM_PFX "Illegal memory type %d\n", type);
-               return ret;
-       }
-
+       BUG_ON(type >= TTM_NUM_MEM_TYPES);
        man = &bdev->man[type];
-       if (man->has_type) {
-               printk(KERN_ERR TTM_PFX
-                      "Memory manager already initialized for type %d\n",
-                      type);
-               return ret;
-       }
+       BUG_ON(man->has_type);
 
        ret = bdev->driver->init_mem_type(bdev, type, man);
        if (ret)
@@ -1389,13 +1352,6 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
 
        ret = 0;
        if (type != TTM_PL_SYSTEM) {
-               if (!p_size) {
-                       printk(KERN_ERR TTM_PFX
-                              "Zero size memory manager type %d\n",
-                              type);
-                       return ret;
-               }
-
                ret = (*man->func->init)(man, p_size);
                if (ret)
                        return ret;
index 7410c190c8911a9342ba57ea616d77a722061312..038e947d00f986ef987ef914fd8432f2202c25f3 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2007-2010 VMware, Inc., Palo Alto, CA., USA
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
 #include "ttm/ttm_module.h"
 #include "ttm/ttm_bo_driver.h"
 #include "ttm/ttm_placement.h"
-#include <linux/jiffies.h>
+#include "drm_mm.h"
 #include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/file.h>
+#include <linux/spinlock.h>
 #include <linux/module.h>
 
+/**
+ * Currently we use a spinlock for the lock, but a mutex *may* be
+ * more appropriate to reduce scheduling latency if the range manager
+ * ends up with very fragmented allocation patterns.
+ */
+
+struct ttm_range_manager {
+       struct drm_mm mm;
+       spinlock_t lock;
+};
+
 static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
                               struct ttm_buffer_object *bo,
                               struct ttm_placement *placement,
                               struct ttm_mem_reg *mem)
 {
-       struct ttm_bo_global *glob = man->bdev->glob;
-       struct drm_mm *mm = man->priv;
+       struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
+       struct drm_mm *mm = &rman->mm;
        struct drm_mm_node *node = NULL;
        unsigned long lpfn;
        int ret;
@@ -57,19 +66,19 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
                if (unlikely(ret))
                        return ret;
 
-               spin_lock(&glob->lru_lock);
+               spin_lock(&rman->lock);
                node = drm_mm_search_free_in_range(mm,
                                        mem->num_pages, mem->page_alignment,
                                        placement->fpfn, lpfn, 1);
                if (unlikely(node == NULL)) {
-                       spin_unlock(&glob->lru_lock);
+                       spin_unlock(&rman->lock);
                        return 0;
                }
                node = drm_mm_get_block_atomic_range(node, mem->num_pages,
-                                                       mem->page_alignment,
-                                                       placement->fpfn,
-                                                       lpfn);
-               spin_unlock(&glob->lru_lock);
+                                                    mem->page_alignment,
+                                                    placement->fpfn,
+                                                    lpfn);
+               spin_unlock(&rman->lock);
        } while (node == NULL);
 
        mem->mm_node = node;
@@ -80,12 +89,12 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
 static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man,
                                struct ttm_mem_reg *mem)
 {
-       struct ttm_bo_global *glob = man->bdev->glob;
+       struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
 
        if (mem->mm_node) {
-               spin_lock(&glob->lru_lock);
+               spin_lock(&rman->lock);
                drm_mm_put_block(mem->mm_node);
-               spin_unlock(&glob->lru_lock);
+               spin_unlock(&rman->lock);
                mem->mm_node = NULL;
        }
 }
@@ -93,49 +102,49 @@ static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man,
 static int ttm_bo_man_init(struct ttm_mem_type_manager *man,
                           unsigned long p_size)
 {
-       struct drm_mm *mm;
+       struct ttm_range_manager *rman;
        int ret;
 
-       mm = kzalloc(sizeof(*mm), GFP_KERNEL);
-       if (!mm)
+       rman = kzalloc(sizeof(*rman), GFP_KERNEL);
+       if (!rman)
                return -ENOMEM;
 
-       ret = drm_mm_init(mm, 0, p_size);
+       ret = drm_mm_init(&rman->mm, 0, p_size);
        if (ret) {
-               kfree(mm);
+               kfree(rman);
                return ret;
        }
 
-       man->priv = mm;
+       spin_lock_init(&rman->lock);
+       man->priv = rman;
        return 0;
 }
 
 static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
 {
-       struct ttm_bo_global *glob = man->bdev->glob;
-       struct drm_mm *mm = man->priv;
-       int ret = 0;
+       struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
+       struct drm_mm *mm = &rman->mm;
 
-       spin_lock(&glob->lru_lock);
+       spin_lock(&rman->lock);
        if (drm_mm_clean(mm)) {
                drm_mm_takedown(mm);
-               kfree(mm);
+               spin_unlock(&rman->lock);
+               kfree(rman);
                man->priv = NULL;
-       } else
-               ret = -EBUSY;
-       spin_unlock(&glob->lru_lock);
-       return ret;
+               return 0;
+       }
+       spin_unlock(&rman->lock);
+       return -EBUSY;
 }
 
 static void ttm_bo_man_debug(struct ttm_mem_type_manager *man,
                             const char *prefix)
 {
-       struct ttm_bo_global *glob = man->bdev->glob;
-       struct drm_mm *mm = man->priv;
+       struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
 
-       spin_lock(&glob->lru_lock);
-       drm_mm_debug_table(mm, prefix);
-       spin_unlock(&glob->lru_lock);
+       spin_lock(&rman->lock);
+       drm_mm_debug_table(&rman->mm, prefix);
+       spin_unlock(&rman->lock);
 }
 
 const struct ttm_mem_type_manager_func ttm_bo_manager_func = {
index a7bab87a548bd25de465d5fff45436a177346e33..af789dc869b94e997621ff615c184383c857377c 100644 (file)
@@ -440,10 +440,8 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
                return ret;
 
        ret = be->func->bind(be, bo_mem);
-       if (ret) {
-               printk(KERN_ERR TTM_PFX "Couldn't bind backend.\n");
+       if (unlikely(ret != 0))
                return ret;
-       }
 
        ttm->state = tt_bound;
 
index 9b5b4d9dd62c9fceffe9c5fa0dd218ff7119d5a7..3e038a394c510efd6194618a7f3a1f185380f7fc 100644 (file)
@@ -235,9 +235,9 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg,  drm_via_dmablit_t *xfer)
        vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) -
                first_pfn + 1;
 
-       if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages)))
+       vsg->pages = vzalloc(sizeof(struct page *) * vsg->num_pages);
+       if (NULL == vsg->pages)
                return -ENOMEM;
-       memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages);
        down_read(&current->mm->mmap_sem);
        ret = get_user_pages(current, current->mm,
                             (unsigned long)xfer->mem_addr,
index 51d9f9f1d7f2aa1b2ea04f309569d71bd9244600..76954e3528c1d6ccb763973c22b7f7979ad4f1b4 100644 (file)
@@ -691,6 +691,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
 
        fence_rep.error = ret;
        fence_rep.fence_seq = (uint64_t) sequence;
+       fence_rep.pad64 = 0;
 
        user_fence_rep = (struct drm_vmw_fence_rep __user *)
            (unsigned long)arg->fence_rep;
index 87c6e6156d7de8bc809a62bab06dbf64a7da512b..cceeb42789b655e82e5431d9810b9fa033f883fd 100644 (file)
@@ -720,6 +720,8 @@ static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb)
                               &vmw_vram_ne_placement,
                               false, &vmw_dmabuf_bo_free);
        vmw_overlay_resume_all(dev_priv);
+       if (unlikely(ret != 0))
+               vfbs->buffer = NULL;
 
        return ret;
 }
@@ -730,6 +732,9 @@ static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb)
        struct vmw_framebuffer_surface *vfbs =
                vmw_framebuffer_to_vfbs(&vfb->base);
 
+       if (unlikely(vfbs->buffer == NULL))
+               return 0;
+
        bo = &vfbs->buffer->base;
        ttm_bo_unref(&bo);
        vfbs->buffer = NULL;
index a01c47ddb5bc724617b74c15ad3bffc2ed63067f..29113c9b26a8c01cc217cc82906e98a83a8fa36c 100644 (file)
@@ -557,7 +557,7 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
                return -EINVAL;
        }
 
-       dev_priv->ldu_priv = kmalloc(GFP_KERNEL, sizeof(*dev_priv->ldu_priv));
+       dev_priv->ldu_priv = kmalloc(sizeof(*dev_priv->ldu_priv), GFP_KERNEL);
 
        if (!dev_priv->ldu_priv)
                return -ENOMEM;
index df2036ed18d5f2c920ba61f99b716998a6f25329..f1a52f9e72988da041c77f19b1035f5b3f160592 100644 (file)
@@ -585,7 +585,7 @@ int vmw_overlay_init(struct vmw_private *dev_priv)
                return -ENOSYS;
        }
 
-       overlay = kmalloc(GFP_KERNEL, sizeof(*overlay));
+       overlay = kmalloc(sizeof(*overlay), GFP_KERNEL);
        if (!overlay)
                return -ENOMEM;
 
index 742c423567cf180e0b46da6477924ac5c7fdcac7..0e1edd7311ff72f5805b8ee616edbe59d52472d1 100644 (file)
@@ -3,6 +3,9 @@ config STUB_POULSBO
        depends on PCI
        # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled
        # but for select to work, need to select ACPI_VIDEO's dependencies, ick
+       select VIDEO_OUTPUT_CONTROL if ACPI
+       select BACKLIGHT_CLASS_DEVICE if ACPI
+       select INPUT if ACPI
        select ACPI_VIDEO if ACPI
        help
          Choose this option if you have a system that has Intel GMA500
index 1e4c21fc1a890b38894e26f0b0713fef1bb0fd63..86d822aa9bbf78a75ff20d1e4bff1bb0623d3a79 100644 (file)
@@ -178,11 +178,13 @@ static int ad7414_probe(struct i2c_client *client,
 {
        struct ad7414_data *data;
        int conf;
-       int err = 0;
+       int err;
 
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
-                                    I2C_FUNC_SMBUS_READ_WORD_DATA))
+                                    I2C_FUNC_SMBUS_READ_WORD_DATA)) {
+               err = -EOPNOTSUPP;
                goto exit;
+       }
 
        data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL);
        if (!data) {
index 9e775717abb7f36ab8c7aaf8103de53264e95951..87d92a56a939fcc531c934a1dd70f6ab6f83ab0c 100644 (file)
@@ -1286,8 +1286,10 @@ static int adt7470_probe(struct i2c_client *client,
        init_completion(&data->auto_update_stop);
        data->auto_update = kthread_run(adt7470_update_thread, client,
                                        dev_name(data->hwmon_dev));
-       if (IS_ERR(data->auto_update))
+       if (IS_ERR(data->auto_update)) {
+               err = PTR_ERR(data->auto_update);
                goto exit_unregister;
+       }
 
        return 0;
 
index fa9708c2d723d27b52eece60e6a2c525ee65246c..4033974d1bb371223a51e61a17d5c29b9b9a0fa5 100644 (file)
@@ -4,7 +4,7 @@
        Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si>
 
        Based on max6650.c:
-       Copyright (C) 2007 Hans J. Koch <hjk@linutronix.de>
+       Copyright (C) 2007 Hans J. Koch <hjk@hansjkoch.de>
 
        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
index aa701a18370793a080a40be5e865465e83820159..f141a1de519cb2af822deef686229734c6d94249 100644 (file)
@@ -376,10 +376,6 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data,
                }
        }
 
-       err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group);
-       if (err)
-               goto err_free_gpio;
-
        fan_data->num_ctrl = num_ctrl;
        fan_data->ctrl = ctrl;
        fan_data->num_speed = pdata->num_speed;
@@ -391,6 +387,10 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data,
                goto err_free_gpio;
        }
 
+       err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group);
+       if (err)
+               goto err_free_gpio;
+
        return 0;
 
 err_free_gpio:
index 6669255aadcfcefc783c01f0c345a72b411f70c9..c9ed14eba5a69eb3af13e750d4f563190234a76b 100644 (file)
@@ -20,7 +20,7 @@
     Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org>
         Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab
 
-    Modified for mainline integration by Hans J. Koch <hjk@linutronix.de>
+    Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de>
         Copyright (c) 2007 Hans J. Koch, Linutronix GmbH
 
     This program is free software; you can redistribute it and/or modify
@@ -2629,7 +2629,7 @@ static void __exit lm93_exit(void)
 }
 
 MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, "
-               "Hans J. Koch <hjk@linutronix.de");
+               "Hans J. Koch <hjk@hansjkoch.de>");
 MODULE_DESCRIPTION("LM93 driver");
 MODULE_LICENSE("GPL");
 
index 464340f25496402dd15a69e2d59281544e267c37..4546d82f024a4c2acacf3c6d93e0ad2a4a4bf3e6 100644 (file)
@@ -128,9 +128,12 @@ static ssize_t set_interval(struct device *dev, struct device_attribute *attr,
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct lm95241_data *data = i2c_get_clientdata(client);
+       unsigned long val;
 
-       strict_strtol(buf, 10, &data->interval);
-       data->interval = data->interval * HZ / 1000;
+       if (strict_strtoul(buf, 10, &val) < 0)
+               return -EINVAL;
+
+       data->interval = val * HZ / 1000;
 
        return count;
 }
@@ -188,7 +191,9 @@ static ssize_t set_type##flag(struct device *dev, \
        struct lm95241_data *data = i2c_get_clientdata(client); \
 \
        long val; \
-       strict_strtol(buf, 10, &val); \
+\
+       if (strict_strtol(buf, 10, &val) < 0) \
+               return -EINVAL; \
 \
        if ((val == 1) || (val == 2)) { \
 \
@@ -227,7 +232,9 @@ static ssize_t set_min##flag(struct device *dev, \
        struct lm95241_data *data = i2c_get_clientdata(client); \
 \
        long val; \
-       strict_strtol(buf, 10, &val); \
+\
+       if (strict_strtol(buf, 10, &val) < 0) \
+               return -EINVAL;\
 \
        mutex_lock(&data->update_lock); \
 \
@@ -256,7 +263,9 @@ static ssize_t set_max##flag(struct device *dev, \
        struct lm95241_data *data = i2c_get_clientdata(client); \
 \
        long val; \
-       strict_strtol(buf, 10, &val); \
+\
+       if (strict_strtol(buf, 10, &val) < 0) \
+               return -EINVAL; \
 \
        mutex_lock(&data->update_lock); \
 \
index 267626178678363882ad14d01e96122ccfbfe2d2..4b50601027d3f4787249651c8d58da5126603f12 100644 (file)
@@ -82,7 +82,7 @@ static struct ltc4261_data *ltc4261_update_device(struct device *dev)
                        val = i2c_smbus_read_byte_data(client, i);
                        if (unlikely(val < 0)) {
                                dev_dbg(dev,
-                                       "Failed to read ADC value: error %d",
+                                       "Failed to read ADC value: error %d\n",
                                        val);
                                ret = ERR_PTR(val);
                                goto abort;
@@ -230,8 +230,7 @@ static int ltc4261_probe(struct i2c_client *client,
                return -ENODEV;
 
        if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) {
-               dev_err(&client->dev, "Failed to read register %d:%02x:%02x\n",
-                       adapter->id, client->addr, LTC4261_STATUS);
+               dev_err(&client->dev, "Failed to read status register\n");
                return -ENODEV;
        }
 
index a0160ee5caeffcefc6d7da22a7513a13b32fcf43..9a11532ecae84384d105e1f2c0b070a5107c0c3c 100644 (file)
@@ -2,7 +2,7 @@
  * max6650.c - Part of lm_sensors, Linux kernel modules for hardware
  *             monitoring.
  *
- * (C) 2007 by Hans J. Koch <hjk@linutronix.de>
+ * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
  *
  * based on code written by John Morris <john.morris@spirentcom.com>
  * Copyright (c) 2003 Spirent Communications
index 1d840aa837823a9b0ee6e6f2fe84f7af950d26a8..cdbc7448491e127d8c11e599b57314625010b261 100644 (file)
@@ -165,10 +165,14 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = {
 
 #define W83795_REG_VID_CTRL            0x6A
 
+#define W83795_REG_ALARM_CTRL          0x40
+#define ALARM_CTRL_RTSACS              (1 << 7)
 #define W83795_REG_ALARM(index)                (0x41 + (index))
+#define W83795_REG_CLR_CHASSIS         0x4D
 #define W83795_REG_BEEP(index)         (0x50 + (index))
 
-#define W83795_REG_CLR_CHASSIS         0x4D
+#define W83795_REG_OVT_CFG             0x58
+#define OVT_CFG_SEL                    (1 << 7)
 
 
 #define W83795_REG_FCMS1               0x201
@@ -178,6 +182,14 @@ static const u8 IN_LSB_SHIFT_IDX[][2] = {
 
 #define W83795_REG_TSS(index)          (0x209 + (index))
 
+#define TSS_MAP_RESERVED               0xff
+static const u8 tss_map[4][6] = {
+       { 0,  1,  2,  3,  4,  5},
+       { 6,  7,  8,  9,  0,  1},
+       {10, 11, 12, 13,  2,  3},
+       { 4,  5,  4,  5, TSS_MAP_RESERVED, TSS_MAP_RESERVED},
+};
+
 #define PWM_OUTPUT                     0
 #define PWM_FREQ                       1
 #define PWM_START                      2
@@ -369,6 +381,7 @@ struct w83795_data {
        u8 setup_pwm[3];        /* Register value */
 
        u8 alarms[6];           /* Register value */
+       u8 enable_beep;
        u8 beeps[6];            /* Register value */
 
        char valid;
@@ -499,8 +512,11 @@ static void w83795_update_limits(struct i2c_client *client)
        }
 
        /* Read beep settings */
-       for (i = 0; i < ARRAY_SIZE(data->beeps); i++)
-               data->beeps[i] = w83795_read(client, W83795_REG_BEEP(i));
+       if (data->enable_beep) {
+               for (i = 0; i < ARRAY_SIZE(data->beeps); i++)
+                       data->beeps[i] =
+                               w83795_read(client, W83795_REG_BEEP(i));
+       }
 
        data->valid_limits = 1;
 }
@@ -577,6 +593,7 @@ static struct w83795_data *w83795_update_device(struct device *dev)
        struct i2c_client *client = to_i2c_client(dev);
        struct w83795_data *data = i2c_get_clientdata(client);
        u16 tmp;
+       u8 intrusion;
        int i;
 
        mutex_lock(&data->update_lock);
@@ -648,9 +665,24 @@ static struct w83795_data *w83795_update_device(struct device *dev)
                    w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT));
        }
 
-       /* update alarm */
+       /* Update intrusion and alarms
+        * It is important to read intrusion first, because reading from
+        * register SMI STS6 clears the interrupt status temporarily. */
+       tmp = w83795_read(client, W83795_REG_ALARM_CTRL);
+       /* Switch to interrupt status for intrusion if needed */
+       if (tmp & ALARM_CTRL_RTSACS)
+               w83795_write(client, W83795_REG_ALARM_CTRL,
+                            tmp & ~ALARM_CTRL_RTSACS);
+       intrusion = w83795_read(client, W83795_REG_ALARM(5)) & (1 << 6);
+       /* Switch to real-time alarms */
+       w83795_write(client, W83795_REG_ALARM_CTRL, tmp | ALARM_CTRL_RTSACS);
        for (i = 0; i < ARRAY_SIZE(data->alarms); i++)
                data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i));
+       data->alarms[5] |= intrusion;
+       /* Restore original configuration if needed */
+       if (!(tmp & ALARM_CTRL_RTSACS))
+               w83795_write(client, W83795_REG_ALARM_CTRL,
+                            tmp & ~ALARM_CTRL_RTSACS);
 
        data->last_updated = jiffies;
        data->valid = 1;
@@ -730,6 +762,10 @@ store_chassis_clear(struct device *dev,
        val = w83795_read(client, W83795_REG_CLR_CHASSIS);
        val |= 0x80;
        w83795_write(client, W83795_REG_CLR_CHASSIS, val);
+
+       /* Clear status and force cache refresh */
+       w83795_read(client, W83795_REG_ALARM(5));
+       data->valid = 0;
        mutex_unlock(&data->update_lock);
        return count;
 }
@@ -857,20 +893,20 @@ show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
        int index = sensor_attr->index;
        u8 tmp;
 
-       if (1 == (data->pwm_fcms[0] & (1 << index))) {
+       /* Speed cruise mode */
+       if (data->pwm_fcms[0] & (1 << index)) {
                tmp = 2;
                goto out;
        }
+       /* Thermal cruise or SmartFan IV mode */
        for (tmp = 0; tmp < 6; tmp++) {
                if (data->pwm_tfmr[tmp] & (1 << index)) {
                        tmp = 3;
                        goto out;
                }
        }
-       if (data->pwm_fomc & (1 << index))
-               tmp = 0;
-       else
-               tmp = 1;
+       /* Manual mode */
+       tmp = 1;
 
 out:
        return sprintf(buf, "%u\n", tmp);
@@ -890,23 +926,21 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
 
        if (strict_strtoul(buf, 10, &val) < 0)
                return -EINVAL;
-       if (val > 2)
+       if (val < 1 || val > 2)
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
        switch (val) {
-       case 0:
        case 1:
+               /* Clear speed cruise mode bits */
                data->pwm_fcms[0] &= ~(1 << index);
                w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]);
+               /* Clear thermal cruise mode bits */
                for (i = 0; i < 6; i++) {
                        data->pwm_tfmr[i] &= ~(1 << index);
                        w83795_write(client, W83795_REG_TFMR(i),
                                data->pwm_tfmr[i]);
                }
-               data->pwm_fomc |= 1 << index;
-               data->pwm_fomc ^= val << index;
-               w83795_write(client, W83795_REG_FOMC, data->pwm_fomc);
                break;
        case 2:
                data->pwm_fcms[0] |= (1 << index);
@@ -917,6 +951,42 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
+static ssize_t
+show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct w83795_data *data = w83795_update_pwm_config(dev);
+       int index = to_sensor_dev_attr_2(attr)->index;
+       unsigned int mode;
+
+       if (data->pwm_fomc & (1 << index))
+               mode = 0;       /* DC */
+       else
+               mode = 1;       /* PWM */
+
+       return sprintf(buf, "%u\n", mode);
+}
+
+/*
+ * Check whether a given temperature source can ever be useful.
+ * Returns the number of selectable temperature channels which are
+ * enabled.
+ */
+static int w83795_tss_useful(const struct w83795_data *data, int tsrc)
+{
+       int useful = 0, i;
+
+       for (i = 0; i < 4; i++) {
+               if (tss_map[i][tsrc] == TSS_MAP_RESERVED)
+                       continue;
+               if (tss_map[i][tsrc] < 6)       /* Analog */
+                       useful += (data->has_temp >> tss_map[i][tsrc]) & 1;
+               else                            /* Digital */
+                       useful += (data->has_dts >> (tss_map[i][tsrc] - 6)) & 1;
+       }
+
+       return useful;
+}
+
 static ssize_t
 show_temp_src(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -924,17 +994,18 @@ show_temp_src(struct device *dev, struct device_attribute *attr, char *buf)
            to_sensor_dev_attr_2(attr);
        struct w83795_data *data = w83795_update_pwm_config(dev);
        int index = sensor_attr->index;
-       u8 val = index / 2;
-       u8 tmp = data->temp_src[val];
+       u8 tmp = data->temp_src[index / 2];
 
        if (index & 1)
-               val = 4;
+               tmp >>= 4;      /* Pick high nibble */
        else
-               val = 0;
-       tmp >>= val;
-       tmp &= 0x0f;
+               tmp &= 0x0f;    /* Pick low nibble */
 
-       return sprintf(buf, "%u\n", tmp);
+       /* Look-up the actual temperature channel number */
+       if (tmp >= 4 || tss_map[tmp][index] == TSS_MAP_RESERVED)
+               return -EINVAL;         /* Shouldn't happen */
+
+       return sprintf(buf, "%u\n", (unsigned int)tss_map[tmp][index] + 1);
 }
 
 static ssize_t
@@ -946,12 +1017,21 @@ store_temp_src(struct device *dev, struct device_attribute *attr,
        struct sensor_device_attribute_2 *sensor_attr =
            to_sensor_dev_attr_2(attr);
        int index = sensor_attr->index;
-       unsigned long tmp;
+       int tmp;
+       unsigned long channel;
        u8 val = index / 2;
 
-       if (strict_strtoul(buf, 10, &tmp) < 0)
+       if (strict_strtoul(buf, 10, &channel) < 0 ||
+           channel < 1 || channel > 14)
+               return -EINVAL;
+
+       /* Check if request can be fulfilled */
+       for (tmp = 0; tmp < 4; tmp++) {
+               if (tss_map[tmp][index] == channel - 1)
+                       break;
+       }
+       if (tmp == 4)   /* No match */
                return -EINVAL;
-       tmp = SENSORS_LIMIT(tmp, 0, 15);
 
        mutex_lock(&data->update_lock);
        if (index & 1) {
@@ -1515,7 +1595,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
 
 #define NOT_USED                       -1
 
-/* Don't change the attribute order, _max and _min are accessed by index
+/* Don't change the attribute order, _max, _min and _beep are accessed by index
  * somewhere else in the code */
 #define SENSOR_ATTR_IN(index) {                                                \
        SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL,        \
@@ -1530,6 +1610,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
                show_alarm_beep, store_beep, BEEP_ENABLE,               \
                index + ((index > 14) ? 1 : 0)) }
 
+/* Don't change the attribute order, _beep is accessed by index
+ * somewhere else in the code */
 #define SENSOR_ATTR_FAN(index) {                                       \
        SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan,            \
                NULL, FAN_INPUT, index - 1), \
@@ -1553,9 +1635,13 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
                show_pwm, store_pwm, PWM_FREQ, index - 1),       \
        SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO,           \
                show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \
+       SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO,                       \
+               show_pwm_mode, NULL, NOT_USED, index - 1),              \
        SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \
                show_fanin, store_fanin, FANIN_TARGET, index - 1) }
 
+/* Don't change the attribute order, _beep is accessed by index
+ * somewhere else in the code */
 #define SENSOR_ATTR_DTS(index) {                                       \
        SENSOR_ATTR_2(temp##index##_type, S_IRUGO ,             \
                show_dts_mode, NULL, NOT_USED, index - 7),      \
@@ -1574,6 +1660,8 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
        SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO,            \
                show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) }
 
+/* Don't change the attribute order, _beep is accessed by index
+ * somewhere else in the code */
 #define SENSOR_ATTR_TEMP(index) {                                      \
        SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \
                show_temp_mode, store_temp_mode, NOT_USED, index - 1),  \
@@ -1593,8 +1681,6 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
        SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO,            \
                show_alarm_beep, store_beep, BEEP_ENABLE,               \
                index + (index > 4 ? 11 : 17)),                         \
-       SENSOR_ATTR_2(temp##index##_source_sel, S_IWUSR | S_IRUGO,      \
-               show_temp_src, store_temp_src, NOT_USED, index - 1),    \
        SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO,      \
                show_temp_pwm_enable, store_temp_pwm_enable,            \
                TEMP_PWM_ENABLE, index - 1),                            \
@@ -1680,7 +1766,7 @@ static const struct sensor_device_attribute_2 w83795_fan[][4] = {
        SENSOR_ATTR_FAN(14),
 };
 
-static const struct sensor_device_attribute_2 w83795_temp[][29] = {
+static const struct sensor_device_attribute_2 w83795_temp[][28] = {
        SENSOR_ATTR_TEMP(1),
        SENSOR_ATTR_TEMP(2),
        SENSOR_ATTR_TEMP(3),
@@ -1700,7 +1786,7 @@ static const struct sensor_device_attribute_2 w83795_dts[][8] = {
        SENSOR_ATTR_DTS(14),
 };
 
-static const struct sensor_device_attribute_2 w83795_pwm[][7] = {
+static const struct sensor_device_attribute_2 w83795_pwm[][8] = {
        SENSOR_ATTR_PWM(1),
        SENSOR_ATTR_PWM(2),
        SENSOR_ATTR_PWM(3),
@@ -1711,13 +1797,24 @@ static const struct sensor_device_attribute_2 w83795_pwm[][7] = {
        SENSOR_ATTR_PWM(8),
 };
 
+static const struct sensor_device_attribute_2 w83795_tss[6] = {
+       SENSOR_ATTR_2(temp1_source_sel, S_IWUSR | S_IRUGO,
+                     show_temp_src, store_temp_src, NOT_USED, 0),
+       SENSOR_ATTR_2(temp2_source_sel, S_IWUSR | S_IRUGO,
+                     show_temp_src, store_temp_src, NOT_USED, 1),
+       SENSOR_ATTR_2(temp3_source_sel, S_IWUSR | S_IRUGO,
+                     show_temp_src, store_temp_src, NOT_USED, 2),
+       SENSOR_ATTR_2(temp4_source_sel, S_IWUSR | S_IRUGO,
+                     show_temp_src, store_temp_src, NOT_USED, 3),
+       SENSOR_ATTR_2(temp5_source_sel, S_IWUSR | S_IRUGO,
+                     show_temp_src, store_temp_src, NOT_USED, 4),
+       SENSOR_ATTR_2(temp6_source_sel, S_IWUSR | S_IRUGO,
+                     show_temp_src, store_temp_src, NOT_USED, 5),
+};
+
 static const struct sensor_device_attribute_2 sda_single_files[] = {
        SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep,
                      store_chassis_clear, ALARM_STATUS, 46),
-       SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep,
-                     store_beep, BEEP_ENABLE, 46),
-       SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep,
-                     store_beep, BEEP_ENABLE, 47),
 #ifdef CONFIG_SENSORS_W83795_FANCTRL
        SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin,
                store_fanin, FANIN_TOL, NOT_USED),
@@ -1730,6 +1827,13 @@ static const struct sensor_device_attribute_2 sda_single_files[] = {
 #endif
 };
 
+static const struct sensor_device_attribute_2 sda_beep_files[] = {
+       SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep,
+                     store_beep, BEEP_ENABLE, 46),
+       SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep,
+                     store_beep, BEEP_ENABLE, 47),
+};
+
 /*
  * Driver interface
  */
@@ -1859,6 +1963,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *,
                if (!(data->has_in & (1 << i)))
                        continue;
                for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) {
+                       if (j == 4 && !data->enable_beep)
+                               continue;
                        err = fn(dev, &w83795_in[i][j].dev_attr);
                        if (err)
                                return err;
@@ -1869,18 +1975,37 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *,
                if (!(data->has_fan & (1 << i)))
                        continue;
                for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) {
+                       if (j == 3 && !data->enable_beep)
+                               continue;
                        err = fn(dev, &w83795_fan[i][j].dev_attr);
                        if (err)
                                return err;
                }
        }
 
+       for (i = 0; i < ARRAY_SIZE(w83795_tss); i++) {
+               j = w83795_tss_useful(data, i);
+               if (!j)
+                       continue;
+               err = fn(dev, &w83795_tss[i].dev_attr);
+               if (err)
+                       return err;
+       }
+
        for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) {
                err = fn(dev, &sda_single_files[i].dev_attr);
                if (err)
                        return err;
        }
 
+       if (data->enable_beep) {
+               for (i = 0; i < ARRAY_SIZE(sda_beep_files); i++) {
+                       err = fn(dev, &sda_beep_files[i].dev_attr);
+                       if (err)
+                               return err;
+               }
+       }
+
 #ifdef CONFIG_SENSORS_W83795_FANCTRL
        for (i = 0; i < data->has_pwm; i++) {
                for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) {
@@ -1899,6 +2024,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *,
 #else
                for (j = 0; j < 8; j++) {
 #endif
+                       if (j == 7 && !data->enable_beep)
+                               continue;
                        err = fn(dev, &w83795_temp[i][j].dev_attr);
                        if (err)
                                return err;
@@ -1910,6 +2037,8 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *,
                        if (!(data->has_dts & (1 << i)))
                                continue;
                        for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) {
+                               if (j == 7 && !data->enable_beep)
+                                       continue;
                                err = fn(dev, &w83795_dts[i][j].dev_attr);
                                if (err)
                                        return err;
@@ -2049,6 +2178,18 @@ static int w83795_probe(struct i2c_client *client,
        else
                data->has_pwm = 2;
 
+       /* Check if BEEP pin is available */
+       if (data->chip_type == w83795g) {
+               /* The W83795G has a dedicated BEEP pin */
+               data->enable_beep = 1;
+       } else {
+               /* The W83795ADG has a shared pin for OVT# and BEEP, so you
+                * can't have both */
+               tmp = w83795_read(client, W83795_REG_OVT_CFG);
+               if ((tmp & OVT_CFG_SEL) == 0)
+                       data->enable_beep = 1;
+       }
+
        err = w83795_handle_files(dev, device_create_file);
        if (err)
                goto exit_remove;
index fd455a2fdd12b80f75cc05b3eec4d54e5f3a57ac..3a6321cb8030e617aabda9f122fcea901d083f2b 100644 (file)
@@ -99,6 +99,7 @@ config I2C_I801
            ICH10
            5/3400 Series (PCH)
            Cougar Point (PCH)
+           Patsburg (PCH)
 
          This driver can also be built as a module.  If so, the module
          will be called i2c-i801.
@@ -396,6 +397,16 @@ config I2C_IMX
          This driver can also be built as a module.  If so, the module
          will be called i2c-imx.
 
+config I2C_INTEL_MID
+       tristate "Intel Moorestown/Medfield Platform I2C controller"
+       depends on PCI
+       help
+         Say Y here if you have an Intel Moorestown/Medfield platform I2C
+         controller.
+
+         This support is also available as a module. If so, the module
+         will be called i2c-intel-mid.
+
 config I2C_IOP3XX
        tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
        depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
index 033ad413f328d63494543ee650f4542a358ddf53..84cb16ae6f9eabaded3ee4d12c1a2d7613a61b8c 100644 (file)
@@ -38,6 +38,7 @@ obj-$(CONFIG_I2C_GPIO)                += i2c-gpio.o
 obj-$(CONFIG_I2C_HIGHLANDER)   += i2c-highlander.o
 obj-$(CONFIG_I2C_IBM_IIC)      += i2c-ibm_iic.o
 obj-$(CONFIG_I2C_IMX)          += i2c-imx.o
+obj-$(CONFIG_I2C_INTEL_MID)    += i2c-intel-mid.o
 obj-$(CONFIG_I2C_IOP3XX)       += i2c-iop3xx.o
 obj-$(CONFIG_I2C_IXP2000)      += i2c-ixp2000.o
 obj-$(CONFIG_I2C_MPC)          += i2c-mpc.o
index 59d65981eed7edae2704c75fc85672ad08a2983b..02835ce7ff4b1a8969e44b7549b6f93b36b5b3e2 100644 (file)
@@ -3,6 +3,8 @@
     Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
     <mdsxyz123@yahoo.com>
     Copyright (C) 2007, 2008   Jean Delvare <khali@linux-fr.org>
+    Copyright (C) 2010         Intel Corporation,
+                               David Woodhouse <dwmw2@infradead.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
   ICH10                 0x3a60     32     hard     yes     yes     yes
   5/3400 Series (PCH)   0x3b30     32     hard     yes     yes     yes
   Cougar Point (PCH)    0x1c22     32     hard     yes     yes     yes
+  Patsburg (PCH)        0x1d22     32     hard     yes     yes     yes
+  Patsburg (PCH) IDF    0x1d70     32     hard     yes     yes     yes
+  Patsburg (PCH) IDF    0x1d71     32     hard     yes     yes     yes
+  Patsburg (PCH) IDF    0x1d72     32     hard     yes     yes     yes
 
   Features supported by this driver:
   Software PEC                     no
   Block buffer                     yes
   Block process call transaction   no
   I2C block read transaction       yes  (doesn't use the block buffer)
+  Slave mode                       no
 
   See the file Documentation/i2c/busses/i2c-i801 for details.
 */
 
-/* Note: we assume there can only be one I801, with one SMBus interface */
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/dmi.h>
 
 /* I801 SMBus address offsets */
-#define SMBHSTSTS      (0 + i801_smba)
-#define SMBHSTCNT      (2 + i801_smba)
-#define SMBHSTCMD      (3 + i801_smba)
-#define SMBHSTADD      (4 + i801_smba)
-#define SMBHSTDAT0     (5 + i801_smba)
-#define SMBHSTDAT1     (6 + i801_smba)
-#define SMBBLKDAT      (7 + i801_smba)
-#define SMBPEC         (8 + i801_smba)         /* ICH3 and later */
-#define SMBAUXSTS      (12 + i801_smba)        /* ICH4 and later */
-#define SMBAUXCTL      (13 + i801_smba)        /* ICH4 and later */
+#define SMBHSTSTS(p)   (0 + (p)->smba)
+#define SMBHSTCNT(p)   (2 + (p)->smba)
+#define SMBHSTCMD(p)   (3 + (p)->smba)
+#define SMBHSTADD(p)   (4 + (p)->smba)
+#define SMBHSTDAT0(p)  (5 + (p)->smba)
+#define SMBHSTDAT1(p)  (6 + (p)->smba)
+#define SMBBLKDAT(p)   (7 + (p)->smba)
+#define SMBPEC(p)      (8 + (p)->smba)         /* ICH3 and later */
+#define SMBAUXSTS(p)   (12 + (p)->smba)        /* ICH4 and later */
+#define SMBAUXCTL(p)   (13 + (p)->smba)        /* ICH4 and later */
 
 /* PCI Address Constants */
 #define SMBBAR         4
                                 SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \
                                 SMBHSTSTS_INTR)
 
-static unsigned long i801_smba;
-static unsigned char i801_original_hstcfg;
+/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
+#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0        0x1d70
+#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1        0x1d71
+#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2        0x1d72
+
+struct i801_priv {
+       struct i2c_adapter adapter;
+       unsigned long smba;
+       unsigned char original_hstcfg;
+       struct pci_dev *pci_dev;
+       unsigned int features;
+};
+
 static struct pci_driver i801_driver;
-static struct pci_dev *I801_dev;
 
 #define FEATURE_SMBUS_PEC      (1 << 0)
 #define FEATURE_BLOCK_BUFFER   (1 << 1)
 #define FEATURE_BLOCK_PROC     (1 << 2)
 #define FEATURE_I2C_BLOCK_READ (1 << 3)
-static unsigned int i801_features;
 
 static const char *i801_feature_names[] = {
        "SMBus PEC",
@@ -151,24 +165,24 @@ MODULE_PARM_DESC(disable_features, "Disable selected driver features");
 
 /* Make sure the SMBus host is ready to start transmitting.
    Return 0 if it is, -EBUSY if it is not. */
-static int i801_check_pre(void)
+static int i801_check_pre(struct i801_priv *priv)
 {
        int status;
 
-       status = inb_p(SMBHSTSTS);
+       status = inb_p(SMBHSTSTS(priv));
        if (status & SMBHSTSTS_HOST_BUSY) {
-               dev_err(&I801_dev->dev, "SMBus is busy, can't use it!\n");
+               dev_err(&priv->pci_dev->dev, "SMBus is busy, can't use it!\n");
                return -EBUSY;
        }
 
        status &= STATUS_FLAGS;
        if (status) {
-               dev_dbg(&I801_dev->dev, "Clearing status flags (%02x)\n",
+               dev_dbg(&priv->pci_dev->dev, "Clearing status flags (%02x)\n",
                        status);
-               outb_p(status, SMBHSTSTS);
-               status = inb_p(SMBHSTSTS) & STATUS_FLAGS;
+               outb_p(status, SMBHSTSTS(priv));
+               status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS;
                if (status) {
-                       dev_err(&I801_dev->dev,
+                       dev_err(&priv->pci_dev->dev,
                                "Failed clearing status flags (%02x)\n",
                                status);
                        return -EBUSY;
@@ -179,48 +193,50 @@ static int i801_check_pre(void)
 }
 
 /* Convert the status register to an error code, and clear it. */
-static int i801_check_post(int status, int timeout)
+static int i801_check_post(struct i801_priv *priv, int status, int timeout)
 {
        int result = 0;
 
        /* If the SMBus is still busy, we give up */
        if (timeout) {
-               dev_err(&I801_dev->dev, "Transaction timeout\n");
+               dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
                /* try to stop the current command */
-               dev_dbg(&I801_dev->dev, "Terminating the current operation\n");
-               outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
+               dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
+               outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL,
+                      SMBHSTCNT(priv));
                msleep(1);
-               outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT);
+               outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL),
+                      SMBHSTCNT(priv));
 
                /* Check if it worked */
-               status = inb_p(SMBHSTSTS);
+               status = inb_p(SMBHSTSTS(priv));
                if ((status & SMBHSTSTS_HOST_BUSY) ||
                    !(status & SMBHSTSTS_FAILED))
-                       dev_err(&I801_dev->dev,
+                       dev_err(&priv->pci_dev->dev,
                                "Failed terminating the transaction\n");
-               outb_p(STATUS_FLAGS, SMBHSTSTS);
+               outb_p(STATUS_FLAGS, SMBHSTSTS(priv));
                return -ETIMEDOUT;
        }
 
        if (status & SMBHSTSTS_FAILED) {
                result = -EIO;
-               dev_err(&I801_dev->dev, "Transaction failed\n");
+               dev_err(&priv->pci_dev->dev, "Transaction failed\n");
        }
        if (status & SMBHSTSTS_DEV_ERR) {
                result = -ENXIO;
-               dev_dbg(&I801_dev->dev, "No response\n");
+               dev_dbg(&priv->pci_dev->dev, "No response\n");
        }
        if (status & SMBHSTSTS_BUS_ERR) {
                result = -EAGAIN;
-               dev_dbg(&I801_dev->dev, "Lost arbitration\n");
+               dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n");
        }
 
        if (result) {
                /* Clear error flags */
-               outb_p(status & STATUS_FLAGS, SMBHSTSTS);
-               status = inb_p(SMBHSTSTS) & STATUS_FLAGS;
+               outb_p(status & STATUS_FLAGS, SMBHSTSTS(priv));
+               status = inb_p(SMBHSTSTS(priv)) & STATUS_FLAGS;
                if (status) {
-                       dev_warn(&I801_dev->dev, "Failed clearing status "
+                       dev_warn(&priv->pci_dev->dev, "Failed clearing status "
                                 "flags at end of transaction (%02x)\n",
                                 status);
                }
@@ -229,86 +245,88 @@ static int i801_check_post(int status, int timeout)
        return result;
 }
 
-static int i801_transaction(int xact)
+static int i801_transaction(struct i801_priv *priv, int xact)
 {
        int status;
        int result;
        int timeout = 0;
 
-       result = i801_check_pre();
+       result = i801_check_pre(priv);
        if (result < 0)
                return result;
 
        /* the current contents of SMBHSTCNT can be overwritten, since PEC,
         * INTREN, SMBSCMD are passed in xact */
-       outb_p(xact | I801_START, SMBHSTCNT);
+       outb_p(xact | I801_START, SMBHSTCNT(priv));
 
        /* We will always wait for a fraction of a second! */
        do {
                msleep(1);
-               status = inb_p(SMBHSTSTS);
+               status = inb_p(SMBHSTSTS(priv));
        } while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
 
-       result = i801_check_post(status, timeout > MAX_TIMEOUT);
+       result = i801_check_post(priv, status, timeout > MAX_TIMEOUT);
        if (result < 0)
                return result;
 
-       outb_p(SMBHSTSTS_INTR, SMBHSTSTS);
+       outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv));
        return 0;
 }
 
 /* wait for INTR bit as advised by Intel */
-static void i801_wait_hwpec(void)
+static void i801_wait_hwpec(struct i801_priv *priv)
 {
        int timeout = 0;
        int status;
 
        do {
                msleep(1);
-               status = inb_p(SMBHSTSTS);
+               status = inb_p(SMBHSTSTS(priv));
        } while ((!(status & SMBHSTSTS_INTR))
                 && (timeout++ < MAX_TIMEOUT));
 
        if (timeout > MAX_TIMEOUT)
-               dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
+               dev_dbg(&priv->pci_dev->dev, "PEC Timeout!\n");
 
-       outb_p(status, SMBHSTSTS);
+       outb_p(status, SMBHSTSTS(priv));
 }
 
-static int i801_block_transaction_by_block(union i2c_smbus_data *data,
+static int i801_block_transaction_by_block(struct i801_priv *priv,
+                                          union i2c_smbus_data *data,
                                           char read_write, int hwpec)
 {
        int i, len;
        int status;
 
-       inb_p(SMBHSTCNT); /* reset the data buffer index */
+       inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
 
        /* Use 32-byte buffer to process this transaction */
        if (read_write == I2C_SMBUS_WRITE) {
                len = data->block[0];
-               outb_p(len, SMBHSTDAT0);
+               outb_p(len, SMBHSTDAT0(priv));
                for (i = 0; i < len; i++)
-                       outb_p(data->block[i+1], SMBBLKDAT);
+                       outb_p(data->block[i+1], SMBBLKDAT(priv));
        }
 
-       status = i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
+       status = i801_transaction(priv, I801_BLOCK_DATA | ENABLE_INT9 |
                                  I801_PEC_EN * hwpec);
        if (status)
                return status;
 
        if (read_write == I2C_SMBUS_READ) {
-               len = inb_p(SMBHSTDAT0);
+               len = inb_p(SMBHSTDAT0(priv));
                if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
                        return -EPROTO;
 
                data->block[0] = len;
                for (i = 0; i < len; i++)
-                       data->block[i + 1] = inb_p(SMBBLKDAT);
+                       data->block[i + 1] = inb_p(SMBBLKDAT(priv));
        }
        return 0;
 }
 
-static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
+static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
+                                              union i2c_smbus_data *data,
                                               char read_write, int command,
                                               int hwpec)
 {
@@ -318,15 +336,15 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
        int result;
        int timeout;
 
-       result = i801_check_pre();
+       result = i801_check_pre(priv);
        if (result < 0)
                return result;
 
        len = data->block[0];
 
        if (read_write == I2C_SMBUS_WRITE) {
-               outb_p(len, SMBHSTDAT0);
-               outb_p(data->block[1], SMBBLKDAT);
+               outb_p(len, SMBHSTDAT0(priv));
+               outb_p(data->block[1], SMBBLKDAT(priv));
        }
 
        for (i = 1; i <= len; i++) {
@@ -342,34 +360,37 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
                        else
                                smbcmd = I801_BLOCK_DATA;
                }
-               outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);
+               outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT(priv));
 
                if (i == 1)
-                       outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
+                       outb_p(inb(SMBHSTCNT(priv)) | I801_START,
+                              SMBHSTCNT(priv));
 
                /* We will always wait for a fraction of a second! */
                timeout = 0;
                do {
                        msleep(1);
-                       status = inb_p(SMBHSTSTS);
+                       status = inb_p(SMBHSTSTS(priv));
                } while ((!(status & SMBHSTSTS_BYTE_DONE))
                         && (timeout++ < MAX_TIMEOUT));
 
-               result = i801_check_post(status, timeout > MAX_TIMEOUT);
+               result = i801_check_post(priv, status, timeout > MAX_TIMEOUT);
                if (result < 0)
                        return result;
 
                if (i == 1 && read_write == I2C_SMBUS_READ
                 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
-                       len = inb_p(SMBHSTDAT0);
+                       len = inb_p(SMBHSTDAT0(priv));
                        if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
-                               dev_err(&I801_dev->dev,
+                               dev_err(&priv->pci_dev->dev,
                                        "Illegal SMBus block read size %d\n",
                                        len);
                                /* Recover */
-                               while (inb_p(SMBHSTSTS) & SMBHSTSTS_HOST_BUSY)
-                                       outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS);
-                               outb_p(SMBHSTSTS_INTR, SMBHSTSTS);
+                               while (inb_p(SMBHSTSTS(priv)) &
+                                      SMBHSTSTS_HOST_BUSY)
+                                       outb_p(SMBHSTSTS_BYTE_DONE,
+                                              SMBHSTSTS(priv));
+                               outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv));
                                return -EPROTO;
                        }
                        data->block[0] = len;
@@ -377,27 +398,28 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
 
                /* Retrieve/store value in SMBBLKDAT */
                if (read_write == I2C_SMBUS_READ)
-                       data->block[i] = inb_p(SMBBLKDAT);
+                       data->block[i] = inb_p(SMBBLKDAT(priv));
                if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
-                       outb_p(data->block[i+1], SMBBLKDAT);
+                       outb_p(data->block[i+1], SMBBLKDAT(priv));
 
                /* signals SMBBLKDAT ready */
-               outb_p(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR, SMBHSTSTS);
+               outb_p(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR, SMBHSTSTS(priv));
        }
 
        return 0;
 }
 
-static int i801_set_block_buffer_mode(void)
+static int i801_set_block_buffer_mode(struct i801_priv *priv)
 {
-       outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL);
-       if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0)
+       outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv));
+       if ((inb_p(SMBAUXCTL(priv)) & SMBAUXCTL_E32B) == 0)
                return -EIO;
        return 0;
 }
 
 /* Block transaction function */
-static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+static int i801_block_transaction(struct i801_priv *priv,
+                                 union i2c_smbus_data *data, char read_write,
                                  int command, int hwpec)
 {
        int result = 0;
@@ -406,11 +428,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
        if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
                if (read_write == I2C_SMBUS_WRITE) {
                        /* set I2C_EN bit in configuration register */
-                       pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
-                       pci_write_config_byte(I801_dev, SMBHSTCFG,
+                       pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc);
+                       pci_write_config_byte(priv->pci_dev, SMBHSTCFG,
                                              hostc | SMBHSTCFG_I2C_EN);
-               } else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) {
-                       dev_err(&I801_dev->dev,
+               } else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) {
+                       dev_err(&priv->pci_dev->dev,
                                "I2C block read is unsupported!\n");
                        return -EOPNOTSUPP;
                }
@@ -429,22 +451,23 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
        /* Experience has shown that the block buffer can only be used for
           SMBus (not I2C) block transactions, even though the datasheet
           doesn't mention this limitation. */
-       if ((i801_features & FEATURE_BLOCK_BUFFER)
+       if ((priv->features & FEATURE_BLOCK_BUFFER)
         && command != I2C_SMBUS_I2C_BLOCK_DATA
-        && i801_set_block_buffer_mode() == 0)
-               result = i801_block_transaction_by_block(data, read_write,
-                                                        hwpec);
+        && i801_set_block_buffer_mode(priv) == 0)
+               result = i801_block_transaction_by_block(priv, data,
+                                                        read_write, hwpec);
        else
-               result = i801_block_transaction_byte_by_byte(data, read_write,
+               result = i801_block_transaction_byte_by_byte(priv, data,
+                                                            read_write,
                                                             command, hwpec);
 
        if (result == 0 && hwpec)
-               i801_wait_hwpec();
+               i801_wait_hwpec(priv);
 
        if (command == I2C_SMBUS_I2C_BLOCK_DATA
         && read_write == I2C_SMBUS_WRITE) {
                /* restore saved configuration register value */
-               pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
+               pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc);
        }
        return result;
 }
@@ -457,81 +480,85 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
        int hwpec;
        int block = 0;
        int ret, xact = 0;
+       struct i801_priv *priv = i2c_get_adapdata(adap);
 
-       hwpec = (i801_features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
+       hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
                && size != I2C_SMBUS_QUICK
                && size != I2C_SMBUS_I2C_BLOCK_DATA;
 
        switch (size) {
        case I2C_SMBUS_QUICK:
                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
-                      SMBHSTADD);
+                      SMBHSTADD(priv));
                xact = I801_QUICK;
                break;
        case I2C_SMBUS_BYTE:
                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
-                      SMBHSTADD);
+                      SMBHSTADD(priv));
                if (read_write == I2C_SMBUS_WRITE)
-                       outb_p(command, SMBHSTCMD);
+                       outb_p(command, SMBHSTCMD(priv));
                xact = I801_BYTE;
                break;
        case I2C_SMBUS_BYTE_DATA:
                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
-                      SMBHSTADD);
-               outb_p(command, SMBHSTCMD);
+                      SMBHSTADD(priv));
+               outb_p(command, SMBHSTCMD(priv));
                if (read_write == I2C_SMBUS_WRITE)
-                       outb_p(data->byte, SMBHSTDAT0);
+                       outb_p(data->byte, SMBHSTDAT0(priv));
                xact = I801_BYTE_DATA;
                break;
        case I2C_SMBUS_WORD_DATA:
                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
-                      SMBHSTADD);
-               outb_p(command, SMBHSTCMD);
+                      SMBHSTADD(priv));
+               outb_p(command, SMBHSTCMD(priv));
                if (read_write == I2C_SMBUS_WRITE) {
-                       outb_p(data->word & 0xff, SMBHSTDAT0);
-                       outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
+                       outb_p(data->word & 0xff, SMBHSTDAT0(priv));
+                       outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1(priv));
                }
                xact = I801_WORD_DATA;
                break;
        case I2C_SMBUS_BLOCK_DATA:
                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
-                      SMBHSTADD);
-               outb_p(command, SMBHSTCMD);
+                      SMBHSTADD(priv));
+               outb_p(command, SMBHSTCMD(priv));
                block = 1;
                break;
        case I2C_SMBUS_I2C_BLOCK_DATA:
                /* NB: page 240 of ICH5 datasheet shows that the R/#W
                 * bit should be cleared here, even when reading */
-               outb_p((addr & 0x7f) << 1, SMBHSTADD);
+               outb_p((addr & 0x7f) << 1, SMBHSTADD(priv));
                if (read_write == I2C_SMBUS_READ) {
                        /* NB: page 240 of ICH5 datasheet also shows
                         * that DATA1 is the cmd field when reading */
-                       outb_p(command, SMBHSTDAT1);
+                       outb_p(command, SMBHSTDAT1(priv));
                } else
-                       outb_p(command, SMBHSTCMD);
+                       outb_p(command, SMBHSTCMD(priv));
                block = 1;
                break;
        default:
-               dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
+               dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
+                       size);
                return -EOPNOTSUPP;
        }
 
        if (hwpec)      /* enable/disable hardware PEC */
-               outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_CRC, SMBAUXCTL);
+               outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
        else
-               outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
+               outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
+                      SMBAUXCTL(priv));
 
        if (block)
-               ret = i801_block_transaction(data, read_write, size, hwpec);
+               ret = i801_block_transaction(priv, data, read_write, size,
+                                            hwpec);
        else
-               ret = i801_transaction(xact | ENABLE_INT9);
+               ret = i801_transaction(priv, xact | ENABLE_INT9);
 
        /* Some BIOSes don't like it when PEC is enabled at reboot or resume
           time, so we forcibly disable it after every transaction. Turn off
           E32B for the same reason. */
        if (hwpec || block)
-               outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
-                      SMBAUXCTL);
+               outb_p(inb_p(SMBAUXCTL(priv)) &
+                      ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
 
        if (block)
                return ret;
@@ -543,10 +570,11 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
        switch (xact & 0x7f) {
        case I801_BYTE: /* Result put in SMBHSTDAT0 */
        case I801_BYTE_DATA:
-               data->byte = inb_p(SMBHSTDAT0);
+               data->byte = inb_p(SMBHSTDAT0(priv));
                break;
        case I801_WORD_DATA:
-               data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
+               data->word = inb_p(SMBHSTDAT0(priv)) +
+                            (inb_p(SMBHSTDAT1(priv)) << 8);
                break;
        }
        return 0;
@@ -555,11 +583,13 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
 
 static u32 i801_func(struct i2c_adapter *adapter)
 {
+       struct i801_priv *priv = i2c_get_adapdata(adapter);
+
        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
               I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
               I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
-              ((i801_features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) |
-              ((i801_features & FEATURE_I2C_BLOCK_READ) ?
+              ((priv->features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) |
+              ((priv->features & FEATURE_I2C_BLOCK_READ) ?
                I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0);
 }
 
@@ -568,12 +598,6 @@ static const struct i2c_algorithm smbus_algorithm = {
        .functionality  = i801_func,
 };
 
-static struct i2c_adapter i801_adapter = {
-       .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
-       .algo           = &smbus_algorithm,
-};
-
 static const struct pci_device_id i801_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
@@ -592,6 +616,10 @@ static const struct pci_device_id i801_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) },
        { 0, }
 };
 
@@ -704,16 +732,25 @@ static int __devinit i801_probe(struct pci_dev *dev,
 {
        unsigned char temp;
        int err, i;
+       struct i801_priv *priv;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       i2c_set_adapdata(&priv->adapter, priv);
+       priv->adapter.owner = THIS_MODULE;
+       priv->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+       priv->adapter.algo = &smbus_algorithm;
 
-       I801_dev = dev;
-       i801_features = 0;
+       priv->pci_dev = dev;
        switch (dev->device) {
        default:
-               i801_features |= FEATURE_I2C_BLOCK_READ;
+               priv->features |= FEATURE_I2C_BLOCK_READ;
                /* fall through */
        case PCI_DEVICE_ID_INTEL_82801DB_3:
-               i801_features |= FEATURE_SMBUS_PEC;
-               i801_features |= FEATURE_BLOCK_BUFFER;
+               priv->features |= FEATURE_SMBUS_PEC;
+               priv->features |= FEATURE_BLOCK_BUFFER;
                /* fall through */
        case PCI_DEVICE_ID_INTEL_82801CA_3:
        case PCI_DEVICE_ID_INTEL_82801BA_2:
@@ -724,11 +761,11 @@ static int __devinit i801_probe(struct pci_dev *dev,
 
        /* Disable features on user request */
        for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) {
-               if (i801_features & disable_features & (1 << i))
+               if (priv->features & disable_features & (1 << i))
                        dev_notice(&dev->dev, "%s disabled by user\n",
                                   i801_feature_names[i]);
        }
-       i801_features &= ~disable_features;
+       priv->features &= ~disable_features;
 
        err = pci_enable_device(dev);
        if (err) {
@@ -738,8 +775,8 @@ static int __devinit i801_probe(struct pci_dev *dev,
        }
 
        /* Determine the address of the SMBus area */
-       i801_smba = pci_resource_start(dev, SMBBAR);
-       if (!i801_smba) {
+       priv->smba = pci_resource_start(dev, SMBBAR);
+       if (!priv->smba) {
                dev_err(&dev->dev, "SMBus base address uninitialized, "
                        "upgrade BIOS\n");
                err = -ENODEV;
@@ -755,19 +792,19 @@ static int __devinit i801_probe(struct pci_dev *dev,
        err = pci_request_region(dev, SMBBAR, i801_driver.name);
        if (err) {
                dev_err(&dev->dev, "Failed to request SMBus region "
-                       "0x%lx-0x%Lx\n", i801_smba,
+                       "0x%lx-0x%Lx\n", priv->smba,
                        (unsigned long long)pci_resource_end(dev, SMBBAR));
                goto exit;
        }
 
-       pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
-       i801_original_hstcfg = temp;
+       pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp);
+       priv->original_hstcfg = temp;
        temp &= ~SMBHSTCFG_I2C_EN;      /* SMBus timing */
        if (!(temp & SMBHSTCFG_HST_EN)) {
                dev_info(&dev->dev, "Enabling SMBus device\n");
                temp |= SMBHSTCFG_HST_EN;
        }
-       pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
+       pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp);
 
        if (temp & SMBHSTCFG_SMB_SMI_EN)
                dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
@@ -775,19 +812,19 @@ static int __devinit i801_probe(struct pci_dev *dev,
                dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n");
 
        /* Clear special mode bits */
-       if (i801_features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER))
-               outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
-                      SMBAUXCTL);
+       if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER))
+               outb_p(inb_p(SMBAUXCTL(priv)) &
+                      ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
 
        /* set up the sysfs linkage to our parent device */
-       i801_adapter.dev.parent = &dev->dev;
+       priv->adapter.dev.parent = &dev->dev;
 
        /* Retry up to 3 times on lost arbitration */
-       i801_adapter.retries = 3;
+       priv->adapter.retries = 3;
 
-       snprintf(i801_adapter.name, sizeof(i801_adapter.name),
-               "SMBus I801 adapter at %04lx", i801_smba);
-       err = i2c_add_adapter(&i801_adapter);
+       snprintf(priv->adapter.name, sizeof(priv->adapter.name),
+               "SMBus I801 adapter at %04lx", priv->smba);
+       err = i2c_add_adapter(&priv->adapter);
        if (err) {
                dev_err(&dev->dev, "Failed to add SMBus adapter\n");
                goto exit_release;
@@ -801,27 +838,33 @@ static int __devinit i801_probe(struct pci_dev *dev,
                memset(&info, 0, sizeof(struct i2c_board_info));
                info.addr = apanel_addr;
                strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
-               i2c_new_device(&i801_adapter, &info);
+               i2c_new_device(&priv->adapter, &info);
        }
 #endif
 #if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
        if (dmi_name_in_vendors("FUJITSU"))
-               dmi_walk(dmi_check_onboard_devices, &i801_adapter);
+               dmi_walk(dmi_check_onboard_devices, &priv->adapter);
 #endif
 
+       pci_set_drvdata(dev, priv);
        return 0;
 
 exit_release:
        pci_release_region(dev, SMBBAR);
 exit:
+       kfree(priv);
        return err;
 }
 
 static void __devexit i801_remove(struct pci_dev *dev)
 {
-       i2c_del_adapter(&i801_adapter);
-       pci_write_config_byte(I801_dev, SMBHSTCFG, i801_original_hstcfg);
+       struct i801_priv *priv = pci_get_drvdata(dev);
+
+       i2c_del_adapter(&priv->adapter);
+       pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
        pci_release_region(dev, SMBBAR);
+       pci_set_drvdata(dev, NULL);
+       kfree(priv);
        /*
         * do not call pci_disable_device(dev) since it can cause hard hangs on
         * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010)
@@ -831,8 +874,10 @@ static void __devexit i801_remove(struct pci_dev *dev)
 #ifdef CONFIG_PM
 static int i801_suspend(struct pci_dev *dev, pm_message_t mesg)
 {
+       struct i801_priv *priv = pci_get_drvdata(dev);
+
        pci_save_state(dev);
-       pci_write_config_byte(dev, SMBHSTCFG, i801_original_hstcfg);
+       pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
        pci_set_power_state(dev, pci_choose_state(dev, mesg));
        return 0;
 }
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c
new file mode 100644 (file)
index 0000000..80f70d3
--- /dev/null
@@ -0,0 +1,1135 @@
+/*
+ * Support for Moorestown/Medfield I2C chip
+ *
+ * Copyright (c) 2009 Intel Corporation.
+ * Copyright (c) 2009 Synopsys. Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License, version
+ * 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/io.h>
+
+#define DRIVER_NAME    "i2c-intel-mid"
+#define VERSION                "Version 0.5ac2"
+#define PLATFORM       "Moorestown/Medfield"
+
+/* Tables use: 0 Moorestown, 1 Medfield */
+#define NUM_PLATFORMS  2
+enum platform_enum {
+       MOORESTOWN = 0,
+       MEDFIELD = 1,
+};
+
+enum mid_i2c_status {
+       STATUS_IDLE = 0,
+       STATUS_READ_START,
+       STATUS_READ_IN_PROGRESS,
+       STATUS_READ_SUCCESS,
+       STATUS_WRITE_START,
+       STATUS_WRITE_SUCCESS,
+       STATUS_XFER_ABORT,
+       STATUS_STANDBY
+};
+
+/**
+ * struct intel_mid_i2c_private        - per device I²C context
+ * @adap: core i2c layer adapter information
+ * @dev: device reference for power management
+ * @base: register base
+ * @speed: speed mode for this port
+ * @complete: completion object for transaction wait
+ * @abort: reason for last abort
+ * @rx_buf: pointer into working receive buffer
+ * @rx_buf_len: receive buffer length
+ * @status: adapter state machine
+ * @msg: the message we are currently processing
+ * @platform: the MID device type we are part of
+ * @lock: transaction serialization
+ *
+ * We allocate one of these per device we discover, it holds the core
+ * i2c layer objects and the data we need to track privately.
+ */
+struct intel_mid_i2c_private {
+       struct i2c_adapter adap;
+       struct device *dev;
+       void __iomem *base;
+       int speed;
+       struct completion complete;
+       int abort;
+       u8 *rx_buf;
+       int rx_buf_len;
+       enum mid_i2c_status status;
+       struct i2c_msg *msg;
+       enum platform_enum platform;
+       struct mutex lock;
+};
+
+#define NUM_SPEEDS             3
+
+#define ACTIVE                 0
+#define STANDBY                        1
+
+
+/* Control register */
+#define IC_CON                 0x00
+#define SLV_DIS                        (1 << 6)        /* Disable slave mode */
+#define RESTART                        (1 << 5)        /* Send a Restart condition */
+#define        ADDR_10BIT              (1 << 4)        /* 10-bit addressing */
+#define        STANDARD_MODE           (1 << 1)        /* standard mode */
+#define FAST_MODE              (2 << 1)        /* fast mode */
+#define HIGH_MODE              (3 << 1)        /* high speed mode */
+#define        MASTER_EN               (1 << 0)        /* Master mode */
+
+/* Target address register */
+#define IC_TAR                 0x04
+#define IC_TAR_10BIT_ADDR      (1 << 12)       /* 10-bit addressing */
+#define IC_TAR_SPECIAL         (1 << 11)       /* Perform special I2C cmd */
+#define IC_TAR_GC_OR_START     (1 << 10)       /* 0: Gerneral Call Address */
+                                               /* 1: START BYTE */
+/* Slave Address Register */
+#define IC_SAR                 0x08            /* Not used in Master mode */
+
+/* High Speed Master Mode Code Address Register */
+#define IC_HS_MADDR            0x0c
+
+/* Rx/Tx Data Buffer and Command Register */
+#define IC_DATA_CMD            0x10
+#define IC_RD                  (1 << 8)        /* 1: Read 0: Write */
+
+/* Standard Speed Clock SCL High Count Register */
+#define IC_SS_SCL_HCNT         0x14
+
+/* Standard Speed Clock SCL Low Count Register */
+#define IC_SS_SCL_LCNT         0x18
+
+/* Fast Speed Clock SCL High Count Register */
+#define IC_FS_SCL_HCNT         0x1c
+
+/* Fast Spedd Clock SCL Low Count Register */
+#define IC_FS_SCL_LCNT         0x20
+
+/* High Speed Clock SCL High Count Register */
+#define IC_HS_SCL_HCNT         0x24
+
+/* High Speed Clock SCL Low Count Register */
+#define IC_HS_SCL_LCNT         0x28
+
+/* Interrupt Status Register */
+#define IC_INTR_STAT           0x2c            /* Read only */
+#define R_GEN_CALL             (1 << 11)
+#define R_START_DET            (1 << 10)
+#define R_STOP_DET             (1 << 9)
+#define R_ACTIVITY             (1 << 8)
+#define R_RX_DONE              (1 << 7)
+#define        R_TX_ABRT               (1 << 6)
+#define R_RD_REQ               (1 << 5)
+#define R_TX_EMPTY             (1 << 4)
+#define R_TX_OVER              (1 << 3)
+#define        R_RX_FULL               (1 << 2)
+#define        R_RX_OVER               (1 << 1)
+#define R_RX_UNDER             (1 << 0)
+
+/* Interrupt Mask Register */
+#define IC_INTR_MASK           0x30            /* Read and Write */
+#define M_GEN_CALL             (1 << 11)
+#define M_START_DET            (1 << 10)
+#define M_STOP_DET             (1 << 9)
+#define M_ACTIVITY             (1 << 8)
+#define M_RX_DONE              (1 << 7)
+#define        M_TX_ABRT               (1 << 6)
+#define M_RD_REQ               (1 << 5)
+#define M_TX_EMPTY             (1 << 4)
+#define M_TX_OVER              (1 << 3)
+#define        M_RX_FULL               (1 << 2)
+#define        M_RX_OVER               (1 << 1)
+#define M_RX_UNDER             (1 << 0)
+
+/* Raw Interrupt Status Register */
+#define IC_RAW_INTR_STAT       0x34            /* Read Only */
+#define GEN_CALL               (1 << 11)       /* General call */
+#define START_DET              (1 << 10)       /* (RE)START occured */
+#define STOP_DET               (1 << 9)        /* STOP occured */
+#define ACTIVITY               (1 << 8)        /* Bus busy */
+#define RX_DONE                        (1 << 7)        /* Not used in Master mode */
+#define        TX_ABRT                 (1 << 6)        /* Transmit Abort */
+#define RD_REQ                 (1 << 5)        /* Not used in Master mode */
+#define TX_EMPTY               (1 << 4)        /* TX FIFO <= threshold */
+#define TX_OVER                        (1 << 3)        /* TX FIFO overflow */
+#define        RX_FULL                 (1 << 2)        /* RX FIFO >= threshold */
+#define        RX_OVER                 (1 << 1)        /* RX FIFO overflow */
+#define RX_UNDER               (1 << 0)        /* RX FIFO empty */
+
+/* Receive FIFO Threshold Register */
+#define IC_RX_TL               0x38
+
+/* Transmit FIFO Treshold Register */
+#define IC_TX_TL               0x3c
+
+/* Clear Combined and Individual Interrupt Register */
+#define IC_CLR_INTR            0x40
+#define CLR_INTR               (1 << 0)
+
+/* Clear RX_UNDER Interrupt Register */
+#define IC_CLR_RX_UNDER                0x44
+#define CLR_RX_UNDER           (1 << 0)
+
+/* Clear RX_OVER Interrupt Register */
+#define IC_CLR_RX_OVER         0x48
+#define CLR_RX_OVER            (1 << 0)
+
+/* Clear TX_OVER Interrupt Register */
+#define IC_CLR_TX_OVER         0x4c
+#define CLR_TX_OVER            (1 << 0)
+
+#define IC_CLR_RD_REQ          0x50
+
+/* Clear TX_ABRT Interrupt Register */
+#define IC_CLR_TX_ABRT         0x54
+#define CLR_TX_ABRT            (1 << 0)
+#define IC_CLR_RX_DONE         0x58
+
+/* Clear ACTIVITY Interrupt Register */
+#define IC_CLR_ACTIVITY                0x5c
+#define CLR_ACTIVITY           (1 << 0)
+
+/* Clear STOP_DET Interrupt Register */
+#define IC_CLR_STOP_DET                0x60
+#define CLR_STOP_DET           (1 << 0)
+
+/* Clear START_DET Interrupt Register */
+#define IC_CLR_START_DET       0x64
+#define CLR_START_DET          (1 << 0)
+
+/* Clear GEN_CALL Interrupt Register */
+#define IC_CLR_GEN_CALL                0x68
+#define CLR_GEN_CALL           (1 << 0)
+
+/* Enable Register */
+#define IC_ENABLE              0x6c
+#define ENABLE                 (1 << 0)
+
+/* Status Register */
+#define IC_STATUS              0x70            /* Read Only */
+#define STAT_SLV_ACTIVITY      (1 << 6)        /* Slave not in idle */
+#define STAT_MST_ACTIVITY      (1 << 5)        /* Master not in idle */
+#define STAT_RFF               (1 << 4)        /* RX FIFO Full */
+#define STAT_RFNE              (1 << 3)        /* RX FIFO Not Empty */
+#define STAT_TFE               (1 << 2)        /* TX FIFO Empty */
+#define STAT_TFNF              (1 << 1)        /* TX FIFO Not Full */
+#define STAT_ACTIVITY          (1 << 0)        /* Activity Status */
+
+/* Transmit FIFO Level Register */
+#define IC_TXFLR               0x74            /* Read Only */
+#define TXFLR                  (1 << 0)        /* TX FIFO level */
+
+/* Receive FIFO Level Register */
+#define IC_RXFLR               0x78            /* Read Only */
+#define RXFLR                  (1 << 0)        /* RX FIFO level */
+
+/* Transmit Abort Source Register */
+#define IC_TX_ABRT_SOURCE      0x80
+#define ABRT_SLVRD_INTX                (1 << 15)
+#define ABRT_SLV_ARBLOST       (1 << 14)
+#define ABRT_SLVFLUSH_TXFIFO   (1 << 13)
+#define        ARB_LOST                (1 << 12)
+#define ABRT_MASTER_DIS                (1 << 11)
+#define ABRT_10B_RD_NORSTRT    (1 << 10)
+#define ABRT_SBYTE_NORSTRT     (1 << 9)
+#define ABRT_HS_NORSTRT                (1 << 8)
+#define ABRT_SBYTE_ACKDET      (1 << 7)
+#define ABRT_HS_ACKDET         (1 << 6)
+#define ABRT_GCALL_READ                (1 << 5)
+#define ABRT_GCALL_NOACK       (1 << 4)
+#define ABRT_TXDATA_NOACK      (1 << 3)
+#define ABRT_10ADDR2_NOACK     (1 << 2)
+#define ABRT_10ADDR1_NOACK     (1 << 1)
+#define ABRT_7B_ADDR_NOACK     (1 << 0)
+
+/* Enable Status Register */
+#define IC_ENABLE_STATUS       0x9c
+#define IC_EN                  (1 << 0)        /* I2C in an enabled state */
+
+/* Component Parameter Register 1*/
+#define IC_COMP_PARAM_1                0xf4
+#define APB_DATA_WIDTH         (0x3 << 0)
+
+/* added by xiaolin --begin */
+#define SS_MIN_SCL_HIGH         4000
+#define SS_MIN_SCL_LOW          4700
+#define FS_MIN_SCL_HIGH         600
+#define FS_MIN_SCL_LOW          1300
+#define HS_MIN_SCL_HIGH_100PF   60
+#define HS_MIN_SCL_LOW_100PF    120
+
+#define STANDARD               0
+#define FAST                   1
+#define HIGH                   2
+
+#define NUM_SPEEDS             3
+
+static int speed_mode[6] = {
+       FAST,
+       FAST,
+       FAST,
+       STANDARD,
+       FAST,
+       FAST
+};
+
+static int ctl_num = 6;
+module_param_array(speed_mode, int, &ctl_num, S_IRUGO);
+MODULE_PARM_DESC(speed_mode, "Set the speed of the i2c interface (0-2)");
+
+/**
+ * intel_mid_i2c_disable - Disable I2C controller
+ * @adap: struct pointer to i2c_adapter
+ *
+ * Return Value:
+ * 0           success
+ * -EBUSY      if device is busy
+ * -ETIMEDOUT  if i2c cannot be disabled within the given time
+ *
+ * I2C bus state should be checked prior to disabling the hardware. If bus is
+ * not in idle state, an errno is returned. Write "0" to IC_ENABLE to disable
+ * I2C controller.
+ */
+static int intel_mid_i2c_disable(struct i2c_adapter *adap)
+{
+       struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
+       int err = 0;
+       int count = 0;
+       int ret1, ret2;
+       static const u16 delay[NUM_SPEEDS] = {100, 25, 3};
+
+       /* Set IC_ENABLE to 0 */
+       writel(0, i2c->base + IC_ENABLE);
+
+       /* Check if device is busy */
+       dev_dbg(&adap->dev, "mrst i2c disable\n");
+       while ((ret1 = readl(i2c->base + IC_ENABLE_STATUS) & 0x1)
+               || (ret2 = readl(i2c->base + IC_STATUS) & 0x1)) {
+               udelay(delay[i2c->speed]);
+               writel(0, i2c->base + IC_ENABLE);
+               dev_dbg(&adap->dev, "i2c is busy, count is %d speed %d\n",
+                       count, i2c->speed);
+               if (count++ > 10) {
+                       err = -ETIMEDOUT;
+                       break;
+               }
+       }
+
+       /* Clear all interrupts */
+       readl(i2c->base + IC_CLR_INTR);
+       readl(i2c->base + IC_CLR_STOP_DET);
+       readl(i2c->base + IC_CLR_START_DET);
+       readl(i2c->base + IC_CLR_ACTIVITY);
+       readl(i2c->base + IC_CLR_TX_ABRT);
+       readl(i2c->base + IC_CLR_RX_OVER);
+       readl(i2c->base + IC_CLR_RX_UNDER);
+       readl(i2c->base + IC_CLR_TX_OVER);
+       readl(i2c->base + IC_CLR_RX_DONE);
+       readl(i2c->base + IC_CLR_GEN_CALL);
+
+       /* Disable all interupts */
+       writel(0x0000, i2c->base + IC_INTR_MASK);
+
+       return err;
+}
+
+/**
+ * intel_mid_i2c_hwinit - Initialize the I2C hardware registers
+ * @dev: pci device struct pointer
+ *
+ * This function will be called in intel_mid_i2c_probe() before device
+ * registration.
+ *
+ * Return Values:
+ * 0           success
+ * -EBUSY      i2c cannot be disabled
+ * -ETIMEDOUT  i2c cannot be disabled
+ * -EFAULT     If APB data width is not 32-bit wide
+ *
+ * I2C should be disabled prior to other register operation. If failed, an
+ * errno is returned. Mask and Clear all interrpts, this should be done at
+ * first.  Set common registers which will not be modified during normal
+ * transfers, including: controll register, FIFO threshold and clock freq.
+ * Check APB data width at last.
+ */
+static int intel_mid_i2c_hwinit(struct intel_mid_i2c_private *i2c)
+{
+       int err;
+
+       static const u16 hcnt[NUM_PLATFORMS][NUM_SPEEDS] = {
+               { 0x75,  0x15, 0x07 },
+               { 0x04c,  0x10, 0x06 }
+       };
+       static const u16 lcnt[NUM_PLATFORMS][NUM_SPEEDS] = {
+               { 0x7C,  0x21, 0x0E },
+               { 0x053, 0x19, 0x0F }
+       };
+
+       /* Disable i2c first */
+       err = intel_mid_i2c_disable(&i2c->adap);
+       if (err)
+               return err;
+
+       /*
+        * Setup clock frequency and speed mode
+        * Enable restart condition,
+        * enable master FSM, disable slave FSM,
+        * use target address when initiating transfer
+        */
+
+       writel((i2c->speed + 1) << 1 | SLV_DIS | RESTART | MASTER_EN,
+               i2c->base + IC_CON);
+       writel(hcnt[i2c->platform][i2c->speed],
+               i2c->base + (IC_SS_SCL_HCNT + (i2c->speed << 3)));
+       writel(lcnt[i2c->platform][i2c->speed],
+               i2c->base + (IC_SS_SCL_LCNT + (i2c->speed << 3)));
+
+       /* Set tranmit & receive FIFO threshold to zero */
+       writel(0x0, i2c->base + IC_RX_TL);
+       writel(0x0, i2c->base + IC_TX_TL);
+
+       return 0;
+}
+
+/**
+ * intel_mid_i2c_func - Return the supported three I2C operations.
+ * @adapter: i2c_adapter struct pointer
+ */
+static u32 intel_mid_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
+}
+
+/**
+ * intel_mid_i2c_address_neq - To check if the addresses for different i2c messages
+ * are equal.
+ * @p1: first i2c_msg
+ * @p2: second i2c_msg
+ *
+ * Return Values:
+ * 0    if addresses are equal
+ * 1    if not equal
+ *
+ * Within a single transfer, the I2C client may need to send its address more
+ * than once. So a check if the addresses match is needed.
+ */
+static inline bool intel_mid_i2c_address_neq(const struct i2c_msg *p1,
+                                      const struct i2c_msg *p2)
+{
+       if (p1->addr != p2->addr)
+               return 1;
+       if ((p1->flags ^ p2->flags) & I2C_M_TEN)
+               return 1;
+       return 0;
+}
+
+/**
+ * intel_mid_i2c_abort - To handle transfer abortions and print error messages.
+ * @adap: i2c_adapter struct pointer
+ *
+ * By reading register IC_TX_ABRT_SOURCE, various transfer errors can be
+ * distingushed. At present, no circumstances have been found out that
+ * multiple errors would be occured simutaneously, so we simply use the
+ * register value directly.
+ *
+ * At last the error bits are cleared. (Note clear ABRT_SBYTE_NORSTRT bit need
+ * a few extra steps)
+ */
+static void intel_mid_i2c_abort(struct intel_mid_i2c_private *i2c)
+{
+       /* Read about source register */
+       int abort = i2c->abort;
+       struct i2c_adapter *adap = &i2c->adap;
+
+       /* Single transfer error check:
+        * According to databook, TX/RX FIFOs would be flushed when
+        * the abort interrupt occured.
+        */
+       if (abort & ABRT_MASTER_DIS)
+               dev_err(&adap->dev,
+               "initiate master operation with master mode disabled.\n");
+       if (abort & ABRT_10B_RD_NORSTRT)
+               dev_err(&adap->dev,
+       "RESTART disabled and master sent READ cmd in 10-bit addressing.\n");
+
+       if (abort & ABRT_SBYTE_NORSTRT) {
+               dev_err(&adap->dev,
+               "RESTART disabled and user is trying to send START byte.\n");
+               writel(~ABRT_SBYTE_NORSTRT, i2c->base + IC_TX_ABRT_SOURCE);
+               writel(RESTART, i2c->base + IC_CON);
+               writel(~IC_TAR_SPECIAL, i2c->base + IC_TAR);
+       }
+
+       if (abort & ABRT_SBYTE_ACKDET)
+               dev_err(&adap->dev,
+                       "START byte was not acknowledged.\n");
+       if (abort & ABRT_TXDATA_NOACK)
+               dev_dbg(&adap->dev,
+                       "No acknowledgement received from slave.\n");
+       if (abort & ABRT_10ADDR2_NOACK)
+               dev_dbg(&adap->dev,
+       "The 2nd address byte of the 10-bit address was not acknowledged.\n");
+       if (abort & ABRT_10ADDR1_NOACK)
+               dev_dbg(&adap->dev,
+       "The 1st address byte of 10-bit address was not acknowledged.\n");
+       if (abort & ABRT_7B_ADDR_NOACK)
+               dev_dbg(&adap->dev,
+                       "I2C slave device not acknowledged.\n");
+
+       /* Clear TX_ABRT bit */
+       readl(i2c->base + IC_CLR_TX_ABRT);
+       i2c->status = STATUS_XFER_ABORT;
+}
+
+/**
+ * xfer_read - Internal function to implement master read transfer.
+ * @adap: i2c_adapter struct pointer
+ * @buf: buffer in i2c_msg
+ * @length: number of bytes to be read
+ *
+ * Return Values:
+ * 0           if the read transfer succeeds
+ * -ETIMEDOUT  if cannot read the "raw" interrupt register
+ * -EINVAL     if a transfer abort occurred
+ *
+ * For every byte, a "READ" command will be loaded into IC_DATA_CMD prior to
+ * data transfer. The actual "read" operation will be performed if an RX_FULL
+ * interrupt occurred.
+ *
+ * Note there may be two interrupt signals captured, one should read
+ * IC_RAW_INTR_STAT to separate between errors and actual data.
+ */
+static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
+{
+       struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
+       int i = length;
+       int err;
+
+       if (length >= 256) {
+               dev_err(&adap->dev,
+                       "I2C FIFO cannot support larger than 256 bytes\n");
+               return -EMSGSIZE;
+       }
+
+       INIT_COMPLETION(i2c->complete);
+
+       readl(i2c->base + IC_CLR_INTR);
+       writel(0x0044, i2c->base + IC_INTR_MASK);
+
+       i2c->status = STATUS_READ_START;
+
+       while (i--)
+               writel(IC_RD, i2c->base + IC_DATA_CMD);
+
+       i2c->status = STATUS_READ_START;
+       err = wait_for_completion_interruptible_timeout(&i2c->complete, HZ);
+       if (!err) {
+               dev_err(&adap->dev, "Timeout for ACK from I2C slave device\n");
+               intel_mid_i2c_hwinit(i2c);
+               return -ETIMEDOUT;
+       }
+       if (i2c->status == STATUS_READ_SUCCESS)
+               return 0;
+       else
+               return -EIO;
+}
+
+/**
+ * xfer_write - Internal function to implement master write transfer.
+ * @adap: i2c_adapter struct pointer
+ * @buf: buffer in i2c_msg
+ * @length: number of bytes to be read
+ *
+ * Return Values:
+ * 0   if the read transfer succeeds
+ * -ETIMEDOUT  if we cannot read the "raw" interrupt register
+ * -EINVAL     if a transfer abort occured
+ *
+ * For every byte, a "WRITE" command will be loaded into IC_DATA_CMD prior to
+ * data transfer. The actual "write" operation will be performed when the
+ * RX_FULL interrupt signal occurs.
+ *
+ * Note there may be two interrupt signals captured, one should read
+ * IC_RAW_INTR_STAT to separate between errors and actual data.
+ */
+static int xfer_write(struct i2c_adapter *adap,
+                     unsigned char *buf, int length)
+{
+       struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
+       int i, err;
+
+       if (length >= 256) {
+               dev_err(&adap->dev,
+                       "I2C FIFO cannot support larger than 256 bytes\n");
+               return -EMSGSIZE;
+       }
+
+       INIT_COMPLETION(i2c->complete);
+
+       readl(i2c->base + IC_CLR_INTR);
+       writel(0x0050, i2c->base + IC_INTR_MASK);
+
+       i2c->status = STATUS_WRITE_START;
+       for (i = 0; i < length; i++)
+               writel((u16)(*(buf + i)), i2c->base + IC_DATA_CMD);
+
+       i2c->status = STATUS_WRITE_START;
+       err = wait_for_completion_interruptible_timeout(&i2c->complete, HZ);
+       if (!err) {
+               dev_err(&adap->dev, "Timeout for ACK from I2C slave device\n");
+               intel_mid_i2c_hwinit(i2c);
+               return -ETIMEDOUT;
+       } else {
+               if (i2c->status == STATUS_WRITE_SUCCESS)
+                       return 0;
+               else
+                       return -EIO;
+       }
+}
+
+static int intel_mid_i2c_setup(struct i2c_adapter *adap,  struct i2c_msg *pmsg)
+{
+       struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
+       int err;
+       u32 reg;
+       u32 bit_mask;
+       u32 mode;
+
+       /* Disable device first */
+       err = intel_mid_i2c_disable(adap);
+       if (err) {
+               dev_err(&adap->dev,
+                       "Cannot disable i2c controller, timeout\n");
+               return err;
+       }
+
+       mode = (1 + i2c->speed) << 1;
+       /* set the speed mode */
+       reg = readl(i2c->base + IC_CON);
+       if ((reg & 0x06) != mode) {
+               dev_dbg(&adap->dev, "set mode %d\n", i2c->speed);
+               writel((reg & ~0x6) | mode, i2c->base + IC_CON);
+       }
+
+       reg = readl(i2c->base + IC_CON);
+       /* use 7-bit addressing */
+       if (pmsg->flags & I2C_M_TEN) {
+               if ((reg & ADDR_10BIT) != ADDR_10BIT) {
+                       dev_dbg(&adap->dev, "set i2c 10 bit address mode\n");
+                       writel(reg | ADDR_10BIT, i2c->base + IC_CON);
+               }
+       } else {
+               if ((reg & ADDR_10BIT) != 0x0) {
+                       dev_dbg(&adap->dev, "set i2c 7 bit address mode\n");
+                       writel(reg & ~ADDR_10BIT, i2c->base + IC_CON);
+               }
+       }
+       /* enable restart conditions */
+       reg = readl(i2c->base + IC_CON);
+       if ((reg & RESTART) != RESTART) {
+               dev_dbg(&adap->dev, "enable restart conditions\n");
+               writel(reg | RESTART, i2c->base + IC_CON);
+       }
+
+       /* enable master FSM */
+       reg = readl(i2c->base + IC_CON);
+       dev_dbg(&adap->dev, "ic_con reg is 0x%x\n", reg);
+       writel(reg | MASTER_EN, i2c->base + IC_CON);
+       if ((reg & SLV_DIS) != SLV_DIS) {
+               dev_dbg(&adap->dev, "enable master FSM\n");
+               writel(reg | SLV_DIS, i2c->base + IC_CON);
+               dev_dbg(&adap->dev, "ic_con reg is 0x%x\n", reg);
+       }
+
+       /* use target address when initiating transfer */
+       reg = readl(i2c->base + IC_TAR);
+       bit_mask = IC_TAR_SPECIAL | IC_TAR_GC_OR_START;
+
+       if ((reg & bit_mask) != 0x0) {
+               dev_dbg(&adap->dev,
+        "WR: use target address when intiating transfer, i2c_tx_target\n");
+               writel(reg & ~bit_mask, i2c->base + IC_TAR);
+       }
+
+       /* set target address to the I2C slave address */
+       dev_dbg(&adap->dev,
+               "set target address to the I2C slave address, addr is %x\n",
+                       pmsg->addr);
+       writel(pmsg->addr | (pmsg->flags & I2C_M_TEN ? IC_TAR_10BIT_ADDR : 0),
+               i2c->base + IC_TAR);
+
+       /* Enable I2C controller */
+       writel(ENABLE, i2c->base + IC_ENABLE);
+
+       return 0;
+}
+
+/**
+ * intel_mid_i2c_xfer - Main master transfer routine.
+ * @adap: i2c_adapter struct pointer
+ * @pmsg: i2c_msg struct pointer
+ * @num: number of i2c_msg
+ *
+ * Return Values:
+ * +           number of messages transfered
+ * -ETIMEDOUT  If cannot disable I2C controller or read IC_STATUS
+ * -EINVAL     If the address in i2c_msg is invalid
+ *
+ * This function will be registered in i2c-core and exposed to external
+ * I2C clients.
+ * 1. Disable I2C controller
+ * 2. Unmask three interrupts: RX_FULL, TX_EMPTY, TX_ABRT
+ * 3. Check if address in i2c_msg is valid
+ * 4. Enable I2C controller
+ * 5. Perform real transfer (call xfer_read or xfer_write)
+ * 6. Wait until the current transfer is finished (check bus state)
+ * 7. Mask and clear all interrupts
+ */
+static int intel_mid_i2c_xfer(struct i2c_adapter *adap,
+                        struct i2c_msg *pmsg,
+                        int num)
+{
+       struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
+       int i, err = 0;
+
+       /* if number of messages equal 0*/
+       if (num == 0)
+               return 0;
+
+       pm_runtime_get(i2c->dev);
+
+       mutex_lock(&i2c->lock);
+       dev_dbg(&adap->dev, "intel_mid_i2c_xfer, process %d msg(s)\n", num);
+       dev_dbg(&adap->dev, "slave address is %x\n", pmsg->addr);
+
+
+       if (i2c->status != STATUS_IDLE) {
+               dev_err(&adap->dev, "Adapter %d in transfer/standby\n",
+                                                               adap->nr);
+               mutex_unlock(&i2c->lock);
+               pm_runtime_put(i2c->dev);
+               return -1;
+       }
+
+
+       for (i = 1; i < num; i++) {
+               /* Message address equal? */
+               if (unlikely(intel_mid_i2c_address_neq(&pmsg[0], &pmsg[i]))) {
+                       dev_err(&adap->dev, "Invalid address in msg[%d]\n", i);
+                       mutex_unlock(&i2c->lock);
+                       pm_runtime_put(i2c->dev);
+                       return -EINVAL;
+               }
+       }
+
+       if (intel_mid_i2c_setup(adap, pmsg)) {
+               mutex_unlock(&i2c->lock);
+               pm_runtime_put(i2c->dev);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < num; i++) {
+               i2c->msg = pmsg;
+               i2c->status = STATUS_IDLE;
+               /* Read or Write */
+               if (pmsg->flags & I2C_M_RD) {
+                       dev_dbg(&adap->dev, "I2C_M_RD\n");
+                       err = xfer_read(adap, pmsg->buf, pmsg->len);
+               } else {
+                       dev_dbg(&adap->dev, "I2C_M_WR\n");
+                       err = xfer_write(adap, pmsg->buf, pmsg->len);
+               }
+               if (err < 0)
+                       break;
+               dev_dbg(&adap->dev, "msg[%d] transfer complete\n", i);
+               pmsg++;         /* next message */
+       }
+
+       /* Mask interrupts */
+       writel(0x0000, i2c->base + IC_INTR_MASK);
+       /* Clear all interrupts */
+       readl(i2c->base + IC_CLR_INTR);
+
+       i2c->status = STATUS_IDLE;
+       mutex_unlock(&i2c->lock);
+       pm_runtime_put(i2c->dev);
+
+       return err;
+}
+
+static int intel_mid_i2c_runtime_suspend(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct intel_mid_i2c_private *i2c = pci_get_drvdata(pdev);
+       struct i2c_adapter *adap = to_i2c_adapter(dev);
+       int err;
+
+       if (i2c->status != STATUS_IDLE)
+               return -1;
+
+       intel_mid_i2c_disable(adap);
+
+       err = pci_save_state(pdev);
+       if (err) {
+               dev_err(dev, "pci_save_state failed\n");
+               return err;
+       }
+
+       err = pci_set_power_state(pdev, PCI_D3hot);
+       if (err) {
+               dev_err(dev, "pci_set_power_state failed\n");
+               return err;
+       }
+       i2c->status = STATUS_STANDBY;
+
+       return 0;
+}
+
+static int intel_mid_i2c_runtime_resume(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct intel_mid_i2c_private *i2c = pci_get_drvdata(pdev);
+       int err;
+
+       if (i2c->status != STATUS_STANDBY)
+               return 0;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       err = pci_enable_device(pdev);
+       if (err) {
+               dev_err(dev, "pci_enable_device failed\n");
+               return err;
+       }
+
+       i2c->status = STATUS_IDLE;
+
+       intel_mid_i2c_hwinit(i2c);
+       return err;
+}
+
+static void i2c_isr_read(struct intel_mid_i2c_private *i2c)
+{
+       struct i2c_msg *msg = i2c->msg;
+       int rx_num;
+       u32 len;
+       u8 *buf;
+
+       if (!(msg->flags & I2C_M_RD))
+               return;
+
+       if (i2c->status != STATUS_READ_IN_PROGRESS) {
+               len = msg->len;
+               buf = msg->buf;
+       } else {
+               len = i2c->rx_buf_len;
+               buf = i2c->rx_buf;
+       }
+
+       rx_num = readl(i2c->base + IC_RXFLR);
+
+       for (; len > 0 && rx_num > 0; len--, rx_num--)
+               *buf++ = readl(i2c->base + IC_DATA_CMD);
+
+       if (len > 0) {
+               i2c->status = STATUS_READ_IN_PROGRESS;
+               i2c->rx_buf_len = len;
+               i2c->rx_buf = buf;
+       } else
+               i2c->status = STATUS_READ_SUCCESS;
+
+       return;
+}
+
+static irqreturn_t intel_mid_i2c_isr(int this_irq, void *dev)
+{
+       struct intel_mid_i2c_private *i2c = dev;
+       u32 stat = readl(i2c->base + IC_INTR_STAT);
+
+       if (!stat)
+               return IRQ_NONE;
+
+       dev_dbg(&i2c->adap.dev, "%s, stat = 0x%x\n", __func__, stat);
+       stat &= 0x54;
+
+       if (i2c->status != STATUS_WRITE_START &&
+           i2c->status != STATUS_READ_START &&
+           i2c->status != STATUS_READ_IN_PROGRESS)
+               goto err;
+
+       if (stat & TX_ABRT)
+               i2c->abort = readl(i2c->base + IC_TX_ABRT_SOURCE);
+
+       readl(i2c->base + IC_CLR_INTR);
+
+       if (stat & TX_ABRT) {
+               intel_mid_i2c_abort(i2c);
+               goto exit;
+       }
+
+       if (stat & RX_FULL) {
+               i2c_isr_read(i2c);
+               goto exit;
+       }
+
+       if (stat & TX_EMPTY) {
+               if (readl(i2c->base + IC_STATUS) & 0x4)
+                       i2c->status = STATUS_WRITE_SUCCESS;
+       }
+
+exit:
+       if (i2c->status == STATUS_READ_SUCCESS ||
+           i2c->status == STATUS_WRITE_SUCCESS ||
+           i2c->status == STATUS_XFER_ABORT) {
+               /* Clear all interrupts */
+               readl(i2c->base + IC_CLR_INTR);
+               /* Mask interrupts */
+               writel(0, i2c->base + IC_INTR_MASK);
+               complete(&i2c->complete);
+       }
+err:
+       return IRQ_HANDLED;
+}
+
+static struct i2c_algorithm intel_mid_i2c_algorithm = {
+       .master_xfer    = intel_mid_i2c_xfer,
+       .functionality  = intel_mid_i2c_func,
+};
+
+
+static const struct dev_pm_ops intel_mid_i2c_pm_ops = {
+       .runtime_suspend = intel_mid_i2c_runtime_suspend,
+       .runtime_resume = intel_mid_i2c_runtime_resume,
+};
+
+/**
+ * intel_mid_i2c_probe - I2C controller initialization routine
+ * @dev: pci device
+ * @id: device id
+ *
+ * Return Values:
+ * 0           success
+ * -ENODEV     If cannot allocate pci resource
+ * -ENOMEM     If the register base remapping failed, or
+ *             if kzalloc failed
+ *
+ * Initialization steps:
+ * 1. Request for PCI resource
+ * 2. Remap the start address of PCI resource to register base
+ * 3. Request for device memory region
+ * 4. Fill in the struct members of intel_mid_i2c_private
+ * 5. Call intel_mid_i2c_hwinit() for hardware initialization
+ * 6. Register I2C adapter in i2c-core
+ */
+static int __devinit intel_mid_i2c_probe(struct pci_dev *dev,
+                                   const struct pci_device_id *id)
+{
+       struct intel_mid_i2c_private *mrst;
+       unsigned long start, len;
+       int err, busnum;
+       void __iomem *base = NULL;
+
+       dev_dbg(&dev->dev, "Get into probe function for I2C\n");
+       err = pci_enable_device(dev);
+       if (err) {
+               dev_err(&dev->dev, "Failed to enable I2C PCI device (%d)\n",
+                       err);
+               goto exit;
+       }
+
+       /* Determine the address of the I2C area */
+       start = pci_resource_start(dev, 0);
+       len = pci_resource_len(dev, 0);
+       if (!start || len == 0) {
+               dev_err(&dev->dev, "base address not set\n");
+               err = -ENODEV;
+               goto exit;
+       }
+       dev_dbg(&dev->dev, "%s i2c resource start 0x%lx, len=%ld\n",
+               PLATFORM, start, len);
+
+       err = pci_request_region(dev, 0, DRIVER_NAME);
+       if (err) {
+               dev_err(&dev->dev, "failed to request I2C region "
+                       "0x%lx-0x%lx\n", start,
+                       (unsigned long)pci_resource_end(dev, 0));
+               goto exit;
+       }
+
+       base = ioremap_nocache(start, len);
+       if (!base) {
+               dev_err(&dev->dev, "I/O memory remapping failed\n");
+               err = -ENOMEM;
+               goto fail0;
+       }
+
+       /* Allocate the per-device data structure, intel_mid_i2c_private */
+       mrst = kzalloc(sizeof(struct intel_mid_i2c_private), GFP_KERNEL);
+       if (mrst == NULL) {
+               dev_err(&dev->dev, "can't allocate interface\n");
+               err = -ENOMEM;
+               goto fail1;
+       }
+
+       /* Initialize struct members */
+       snprintf(mrst->adap.name, sizeof(mrst->adap.name),
+               "MRST/Medfield I2C at %lx", start);
+       mrst->adap.owner = THIS_MODULE;
+       mrst->adap.algo = &intel_mid_i2c_algorithm;
+       mrst->adap.dev.parent = &dev->dev;
+       mrst->dev = &dev->dev;
+       mrst->base = base;
+       mrst->speed = STANDARD;
+       mrst->abort = 0;
+       mrst->rx_buf_len = 0;
+       mrst->status = STATUS_IDLE;
+
+       pci_set_drvdata(dev, mrst);
+       i2c_set_adapdata(&mrst->adap, mrst);
+
+       mrst->adap.nr = busnum = id->driver_data;
+       if (dev->device <= 0x0804)
+               mrst->platform = MOORESTOWN;
+       else
+               mrst->platform = MEDFIELD;
+
+       dev_dbg(&dev->dev, "I2C%d\n", busnum);
+
+       if (ctl_num > busnum) {
+               if (speed_mode[busnum] < 0 || speed_mode[busnum] >= NUM_SPEEDS)
+                       dev_warn(&dev->dev, "invalid speed %d ignored.\n",
+                                                       speed_mode[busnum]);
+               else
+                       mrst->speed = speed_mode[busnum];
+       }
+
+       /* Initialize i2c controller */
+       err = intel_mid_i2c_hwinit(mrst);
+       if (err < 0) {
+               dev_err(&dev->dev, "I2C interface initialization failed\n");
+               goto fail2;
+       }
+
+       mutex_init(&mrst->lock);
+       init_completion(&mrst->complete);
+
+       /* Clear all interrupts */
+       readl(mrst->base + IC_CLR_INTR);
+       writel(0x0000, mrst->base + IC_INTR_MASK);
+
+       err = request_irq(dev->irq, intel_mid_i2c_isr, IRQF_SHARED,
+                                       mrst->adap.name, mrst);
+       if (err) {
+               dev_err(&dev->dev, "Failed to request IRQ for I2C controller: "
+                       "%s", mrst->adap.name);
+               goto fail2;
+       }
+
+       /* Adapter registration */
+       err = i2c_add_numbered_adapter(&mrst->adap);
+       if (err) {
+               dev_err(&dev->dev, "Adapter %s registration failed\n",
+                       mrst->adap.name);
+               goto fail3;
+       }
+
+       dev_dbg(&dev->dev, "%s I2C bus %d driver bind success.\n",
+               (mrst->platform == MOORESTOWN) ? "Moorestown" : "Medfield",
+               busnum);
+
+       pm_runtime_enable(&dev->dev);
+       return 0;
+
+fail3:
+       free_irq(dev->irq, mrst);
+fail2:
+       pci_set_drvdata(dev, NULL);
+       kfree(mrst);
+fail1:
+       iounmap(base);
+fail0:
+       pci_release_region(dev, 0);
+exit:
+       return err;
+}
+
+static void __devexit intel_mid_i2c_remove(struct pci_dev *dev)
+{
+       struct intel_mid_i2c_private *mrst = pci_get_drvdata(dev);
+       intel_mid_i2c_disable(&mrst->adap);
+       if (i2c_del_adapter(&mrst->adap))
+               dev_err(&dev->dev, "Failed to delete i2c adapter");
+
+       free_irq(dev->irq, mrst);
+       pci_set_drvdata(dev, NULL);
+       iounmap(mrst->base);
+       kfree(mrst);
+       pci_release_region(dev, 0);
+}
+
+static struct pci_device_id intel_mid_i2c_ids[] = {
+       /* Moorestown */
+       { PCI_VDEVICE(INTEL, 0x0802), 0 },
+       { PCI_VDEVICE(INTEL, 0x0803), 1 },
+       { PCI_VDEVICE(INTEL, 0x0804), 2 },
+       /* Medfield */
+       { PCI_VDEVICE(INTEL, 0x0817), 3,},
+       { PCI_VDEVICE(INTEL, 0x0818), 4 },
+       { PCI_VDEVICE(INTEL, 0x0819), 5 },
+       { PCI_VDEVICE(INTEL, 0x082C), 0 },
+       { PCI_VDEVICE(INTEL, 0x082D), 1 },
+       { PCI_VDEVICE(INTEL, 0x082E), 2 },
+       { 0,}
+};
+MODULE_DEVICE_TABLE(pci, intel_mid_i2c_ids);
+
+static struct pci_driver intel_mid_i2c_driver = {
+       .name           = DRIVER_NAME,
+       .id_table       = intel_mid_i2c_ids,
+       .probe          = intel_mid_i2c_probe,
+       .remove         = __devexit_p(intel_mid_i2c_remove),
+};
+
+static int __init intel_mid_i2c_init(void)
+{
+       return pci_register_driver(&intel_mid_i2c_driver);
+}
+
+static void __exit intel_mid_i2c_exit(void)
+{
+       pci_unregister_driver(&intel_mid_i2c_driver);
+}
+
+module_init(intel_mid_i2c_init);
+module_exit(intel_mid_i2c_exit);
+
+MODULE_AUTHOR("Ba Zheng <zheng.ba@intel.com>");
+MODULE_DESCRIPTION("I2C driver for Moorestown Platform");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(VERSION);
index 73de8ade10b107ae22c426fd36051aad5352da90..c9fffd0389fe39eac24731e60732658f32b98ec6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 ST-Ericsson
+ * Copyright (C) 2009 ST-Ericsson SA
  * Copyright (C) 2009 STMicroelectronics
  *
  * I2C master mode controller driver, used in Nomadik 8815
 /* maximum threshold value */
 #define MAX_I2C_FIFO_THRESHOLD 15
 
+/* per-transfer delay, required for the hardware to stabilize */
+#define I2C_DELAY              150
+
 enum i2c_status {
        I2C_NOP,
        I2C_ON_GOING,
@@ -118,7 +121,7 @@ enum i2c_operation {
 };
 
 /* controller response timeout in ms */
-#define I2C_TIMEOUT_MS 500
+#define I2C_TIMEOUT_MS 2000
 
 /**
  * struct i2c_nmk_client - client specific data
@@ -250,6 +253,8 @@ static int init_hw(struct nmk_i2c_dev *dev)
 {
        int stat;
 
+       clk_enable(dev->clk);
+
        stat = flush_i2c_fifo(dev);
        if (stat)
                return stat;
@@ -263,6 +268,9 @@ static int init_hw(struct nmk_i2c_dev *dev)
 
        dev->cli.operation = I2C_NO_OPERATION;
 
+       clk_disable(dev->clk);
+
+       udelay(I2C_DELAY);
        return 0;
 }
 
@@ -431,7 +439,6 @@ static int read_i2c(struct nmk_i2c_dev *dev)
                (void) init_hw(dev);
                status = -ETIMEDOUT;
        }
-
        return status;
 }
 
@@ -502,9 +509,9 @@ static int write_i2c(struct nmk_i2c_dev *dev)
 
 /**
  * nmk_i2c_xfer() - I2C transfer function used by kernel framework
- * @i2c_adap   - Adapter pointer to the controller
- * @msgs[] - Pointer to data to be written.
- * @num_msgs - Number of messages to be executed
+ * @i2c_adap: Adapter pointer to the controller
+ * @msgs: Pointer to data to be written.
+ * @num_msgs: Number of messages to be executed
  *
  * This is the function called by the generic kernel i2c_transfer()
  * or i2c_smbus...() API calls. Note that this code is protected by the
@@ -559,6 +566,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
        if (status)
                return status;
 
+       clk_enable(dev->clk);
+
        /* setup the i2c controller */
        setup_i2c_controller(dev);
 
@@ -591,10 +600,13 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
                        dev_err(&dev->pdev->dev, "%s\n",
                                cause >= ARRAY_SIZE(abort_causes)
                                ? "unknown reason" : abort_causes[cause]);
+                       clk_disable(dev->clk);
                        return status;
                }
-               mdelay(1);
+               udelay(I2C_DELAY);
        }
+       clk_disable(dev->clk);
+
        /* return the no. messages processed */
        if (status)
                return status;
@@ -605,6 +617,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
 /**
  * disable_interrupts() - disable the interrupts
  * @dev: private data of controller
+ * @irq: interrupt number
  */
 static int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq)
 {
@@ -794,10 +807,7 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
 
 static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
 {
-       return I2C_FUNC_I2C
-               | I2C_FUNC_SMBUS_BYTE_DATA
-               | I2C_FUNC_SMBUS_WORD_DATA
-               | I2C_FUNC_SMBUS_I2C_BLOCK;
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 
 static const struct i2c_algorithm nmk_i2c_algo = {
@@ -857,8 +867,6 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev)
                goto err_no_clk;
        }
 
-       clk_enable(dev->clk);
-
        adap = &dev->adap;
        adap->dev.parent = &pdev->dev;
        adap->owner     = THIS_MODULE;
@@ -895,7 +903,6 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev)
        return 0;
 
  err_init_hw:
-       clk_disable(dev->clk);
  err_add_adap:
        clk_put(dev->clk);
  err_no_clk:
@@ -928,7 +935,6 @@ static int __devexit nmk_i2c_remove(struct platform_device *pdev)
        iounmap(dev->virtbase);
        if (res)
                release_mem_region(res->start, resource_size(res));
-       clk_disable(dev->clk);
        clk_put(dev->clk);
        platform_set_drvdata(pdev, NULL);
        kfree(dev);
index 6a292ea5e35c3ca4dcd5f9f24c1dda4d3c3e6181..6c00c107ebf30af4360bd3fef78fac03b62a4683 100644 (file)
@@ -554,18 +554,23 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
        int retry;
        int ret;
 
+       clk_enable(i2c->clk);
+
        for (retry = 0; retry < adap->retries; retry++) {
 
                ret = s3c24xx_i2c_doxfer(i2c, msgs, num);
 
-               if (ret != -EAGAIN)
+               if (ret != -EAGAIN) {
+                       clk_disable(i2c->clk);
                        return ret;
+               }
 
                dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry);
 
                udelay(100);
        }
 
+       clk_disable(i2c->clk);
        return -EREMOTEIO;
 }
 
@@ -910,6 +915,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, i2c);
 
        dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev));
+       clk_disable(i2c->clk);
        return 0;
 
  err_cpufreq:
@@ -977,7 +983,9 @@ static int s3c24xx_i2c_resume(struct device *dev)
        struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
 
        i2c->suspended = 0;
+       clk_enable(i2c->clk);
        s3c24xx_i2c_init(i2c);
+       clk_disable(i2c->clk);
 
        return 0;
 }
index d231f683f5763bc286e98200fc46286b35ef65a6..6b4cc567645b4e9d936b47bc0c777a05dc9222b9 100644 (file)
@@ -848,6 +848,18 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
                goto out_list;
        }
 
+       /* Sanity checks */
+       if (unlikely(adap->name[0] == '\0')) {
+               pr_err("i2c-core: Attempt to register an adapter with "
+                      "no name!\n");
+               return -EINVAL;
+       }
+       if (unlikely(!adap->algo)) {
+               pr_err("i2c-core: Attempt to register adapter '%s' with "
+                      "no algo!\n", adap->name);
+               return -EINVAL;
+       }
+
        rt_mutex_init(&adap->bus_lock);
        mutex_init(&adap->userspace_clients_lock);
        INIT_LIST_HEAD(&adap->userspace_clients);
index d32a4843fc3a2b0c502b11a0dcd32d6cf6ebf1b0..d7a4833be4161d37bd4883dfa474b068224ab466 100644 (file)
@@ -120,7 +120,6 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
        snprintf(priv->adap.name, sizeof(priv->adap.name),
                 "i2c-%d-mux (chan_id %d)", i2c_adapter_id(parent), chan_id);
        priv->adap.owner = THIS_MODULE;
-       priv->adap.id = parent->id;
        priv->adap.algo = &priv->algo;
        priv->adap.algo_data = priv;
        priv->adap.dev.parent = &parent->dev;
index 97d98fbf5849e5997fa42cf1ddf97be3040043d8..58c51cddc1002500b67d5799d70a55f21fab74bb 100644 (file)
@@ -838,7 +838,7 @@ static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
 
 static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
 {
-       hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x23 : 0x21);
+       hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x21 : 0x23);
 }
 
 /**
@@ -1173,8 +1173,9 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
                u16 mcr;
 
                pci_read_config_word(dev, mcr_addr, &mcr);
-               pci_write_config_word(dev, mcr_addr, (mcr | 0x8000));
-               /* now read cable id register */
+               pci_write_config_word(dev, mcr_addr, mcr | 0x8000);
+               /* Debounce, then read cable ID register */
+               udelay(10);
                pci_read_config_byte(dev, 0x5a, &scr1);
                pci_write_config_word(dev, mcr_addr, mcr);
        } else if (chip_type >= HPT370) {
@@ -1185,10 +1186,11 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
                u8 scr2 = 0;
 
                pci_read_config_byte(dev, 0x5b, &scr2);
-               pci_write_config_byte(dev, 0x5b, (scr2 & ~1));
-               /* now read cable id register */
+               pci_write_config_byte(dev, 0x5b, scr2 & ~1);
+               /* Debounce, then read cable ID register */
+               udelay(10);
                pci_read_config_byte(dev, 0x5a, &scr1);
-               pci_write_config_byte(dev, 0x5b,  scr2);
+               pci_write_config_byte(dev, 0x5b, scr2);
        } else
                pci_read_config_byte(dev, 0x5a, &scr1);
 
index 06b14bc9a1d42ebccc2f5dc80774a6a89f9cd19f..d4136908f9166a6dbb7b6e991397e289e50c5623 100644 (file)
@@ -449,7 +449,6 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
        ide_hwif_t *hwif = drive->hwif;
        const struct ide_dma_ops *dma_ops = hwif->dma_ops;
        struct ide_cmd *cmd = &hwif->cmd;
-       struct request *rq;
        ide_startstop_t ret = ide_stopped;
 
        /*
@@ -487,14 +486,10 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
        ide_dma_off_quietly(drive);
 
        /*
-        * un-busy drive etc and make sure request is sane
+        * make sure request is sane
         */
-       rq = hwif->rq;
-       if (rq) {
-               hwif->rq = NULL;
-               rq->errors = 0;
-               ide_requeue_and_plug(drive, rq);
-       }
+       if (hwif->rq)
+               hwif->rq->errors = 0;
        return ret;
 }
 
index 12d5bf76302cc0eff403b5538607350f4e554e42..8c8afc716b984863694f6f15ea0131ae491cde59 100644 (file)
@@ -362,13 +362,13 @@ bail:
        return ret;
 }
 
-static int ipathfs_get_sb(struct file_system_type *fs_type, int flags,
-                       const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *ipathfs_mount(struct file_system_type *fs_type,
+                       int flags, const char *dev_name, void *data)
 {
-       int ret = get_sb_single(fs_type, flags, data,
-                                   ipathfs_fill_super, mnt);
-       if (ret >= 0)
-               ipath_super = mnt->mnt_sb;
+       struct dentry *ret;
+       ret = mount_single(fs_type, flags, data, ipathfs_fill_super);
+       if (!IS_ERR(ret))
+               ipath_super = ret->d_sb;
        return ret;
 }
 
@@ -411,7 +411,7 @@ bail:
 static struct file_system_type ipathfs_fs_type = {
        .owner =        THIS_MODULE,
        .name =         "ipathfs",
-       .get_sb =       ipathfs_get_sb,
+       .mount =        ipathfs_mount,
        .kill_sb =      ipathfs_kill_super,
 };
 
index 7e433d75c775a963fdedb38612ef734a6211ce79..f99bddc017163e01fec54ae30ac5c121ccc25186 100644 (file)
@@ -555,13 +555,13 @@ bail:
        return ret;
 }
 
-static int qibfs_get_sb(struct file_system_type *fs_type, int flags,
-                       const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *qibfs_mount(struct file_system_type *fs_type, int flags,
+                       const char *dev_name, void *data)
 {
-       int ret = get_sb_single(fs_type, flags, data,
-                               qibfs_fill_super, mnt);
-       if (ret >= 0)
-               qib_super = mnt->mnt_sb;
+       struct dentry *ret;
+       ret = mount_single(fs_type, flags, data, qibfs_fill_super);
+       if (!IS_ERR(ret))
+               qib_super = ret->d_sb;
        return ret;
 }
 
@@ -603,7 +603,7 @@ int qibfs_remove(struct qib_devdata *dd)
 static struct file_system_type qibfs_fs_type = {
        .owner =        THIS_MODULE,
        .name =         "ipathfs",
-       .get_sb =       qibfs_get_sb,
+       .mount =        qibfs_mount,
        .kill_sb =      qibfs_kill_super,
 };
 
index d092ef9291dabe1301006bc94310bc1973037808..7f26ca6ecf75dc6f15185771a8bae6cfb24ce58d 100644 (file)
@@ -74,6 +74,7 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
  * dev->event_lock held and interrupts disabled.
  */
 static void input_pass_event(struct input_dev *dev,
+                            struct input_handler *src_handler,
                             unsigned int type, unsigned int code, int value)
 {
        struct input_handler *handler;
@@ -92,6 +93,15 @@ static void input_pass_event(struct input_dev *dev,
                                continue;
 
                        handler = handle->handler;
+
+                       /*
+                        * If this is the handler that injected this
+                        * particular event we want to skip it to avoid
+                        * filters firing again and again.
+                        */
+                       if (handler == src_handler)
+                               continue;
+
                        if (!handler->filter) {
                                if (filtered)
                                        break;
@@ -121,7 +131,7 @@ static void input_repeat_key(unsigned long data)
        if (test_bit(dev->repeat_key, dev->key) &&
            is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
 
-               input_pass_event(dev, EV_KEY, dev->repeat_key, 2);
+               input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2);
 
                if (dev->sync) {
                        /*
@@ -130,7 +140,7 @@ static void input_repeat_key(unsigned long data)
                         * Otherwise assume that the driver will send
                         * SYN_REPORT once it's done.
                         */
-                       input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+                       input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
                }
 
                if (dev->rep[REP_PERIOD])
@@ -163,6 +173,7 @@ static void input_stop_autorepeat(struct input_dev *dev)
 #define INPUT_PASS_TO_ALL      (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
 
 static int input_handle_abs_event(struct input_dev *dev,
+                                 struct input_handler *src_handler,
                                  unsigned int code, int *pval)
 {
        bool is_mt_event;
@@ -206,13 +217,15 @@ static int input_handle_abs_event(struct input_dev *dev,
        /* Flush pending "slot" event */
        if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
                input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
-               input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
+               input_pass_event(dev, src_handler,
+                                EV_ABS, ABS_MT_SLOT, dev->slot);
        }
 
        return INPUT_PASS_TO_HANDLERS;
 }
 
 static void input_handle_event(struct input_dev *dev,
+                              struct input_handler *src_handler,
                               unsigned int type, unsigned int code, int value)
 {
        int disposition = INPUT_IGNORE_EVENT;
@@ -265,7 +278,8 @@ static void input_handle_event(struct input_dev *dev,
 
        case EV_ABS:
                if (is_event_supported(code, dev->absbit, ABS_MAX))
-                       disposition = input_handle_abs_event(dev, code, &value);
+                       disposition = input_handle_abs_event(dev, src_handler,
+                                                            code, &value);
 
                break;
 
@@ -323,7 +337,7 @@ static void input_handle_event(struct input_dev *dev,
                dev->event(dev, type, code, value);
 
        if (disposition & INPUT_PASS_TO_HANDLERS)
-               input_pass_event(dev, type, code, value);
+               input_pass_event(dev, src_handler, type, code, value);
 }
 
 /**
@@ -352,7 +366,7 @@ void input_event(struct input_dev *dev,
 
                spin_lock_irqsave(&dev->event_lock, flags);
                add_input_randomness(type, code, value);
-               input_handle_event(dev, type, code, value);
+               input_handle_event(dev, NULL, type, code, value);
                spin_unlock_irqrestore(&dev->event_lock, flags);
        }
 }
@@ -382,7 +396,8 @@ void input_inject_event(struct input_handle *handle,
                rcu_read_lock();
                grab = rcu_dereference(dev->grab);
                if (!grab || grab == handle)
-                       input_handle_event(dev, type, code, value);
+                       input_handle_event(dev, handle->handler,
+                                          type, code, value);
                rcu_read_unlock();
 
                spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -595,10 +610,10 @@ static void input_dev_release_keys(struct input_dev *dev)
                for (code = 0; code <= KEY_MAX; code++) {
                        if (is_event_supported(code, dev->keybit, KEY_MAX) &&
                            __test_and_clear_bit(code, dev->key)) {
-                               input_pass_event(dev, EV_KEY, code, 0);
+                               input_pass_event(dev, NULL, EV_KEY, code, 0);
                        }
                }
-               input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+               input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
        }
 }
 
@@ -873,9 +888,9 @@ int input_set_keycode(struct input_dev *dev,
            !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
            __test_and_clear_bit(old_keycode, dev->key)) {
 
-               input_pass_event(dev, EV_KEY, old_keycode, 0);
+               input_pass_event(dev, NULL, EV_KEY, old_keycode, 0);
                if (dev->sync)
-                       input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+                       input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
        }
 
  out:
@@ -1565,8 +1580,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
                }                                                       \
        } while (0)
 
-#ifdef CONFIG_PM
-static void input_dev_reset(struct input_dev *dev, bool activate)
+static void input_dev_toggle(struct input_dev *dev, bool activate)
 {
        if (!dev->event)
                return;
@@ -1580,12 +1594,44 @@ static void input_dev_reset(struct input_dev *dev, bool activate)
        }
 }
 
+/**
+ * input_reset_device() - reset/restore the state of input device
+ * @dev: input device whose state needs to be reset
+ *
+ * This function tries to reset the state of an opened input device and
+ * bring internal state and state if the hardware in sync with each other.
+ * We mark all keys as released, restore LED state, repeat rate, etc.
+ */
+void input_reset_device(struct input_dev *dev)
+{
+       mutex_lock(&dev->mutex);
+
+       if (dev->users) {
+               input_dev_toggle(dev, true);
+
+               /*
+                * Keys that have been pressed at suspend time are unlikely
+                * to be still pressed when we resume.
+                */
+               spin_lock_irq(&dev->event_lock);
+               input_dev_release_keys(dev);
+               spin_unlock_irq(&dev->event_lock);
+       }
+
+       mutex_unlock(&dev->mutex);
+}
+EXPORT_SYMBOL(input_reset_device);
+
+#ifdef CONFIG_PM
 static int input_dev_suspend(struct device *dev)
 {
        struct input_dev *input_dev = to_input_dev(dev);
 
        mutex_lock(&input_dev->mutex);
-       input_dev_reset(input_dev, false);
+
+       if (input_dev->users)
+               input_dev_toggle(input_dev, false);
+
        mutex_unlock(&input_dev->mutex);
 
        return 0;
@@ -1595,18 +1641,7 @@ static int input_dev_resume(struct device *dev)
 {
        struct input_dev *input_dev = to_input_dev(dev);
 
-       mutex_lock(&input_dev->mutex);
-       input_dev_reset(input_dev, true);
-
-       /*
-        * Keys that have been pressed at suspend time are unlikely
-        * to be still pressed when we resume.
-        */
-       spin_lock_irq(&input_dev->event_lock);
-       input_dev_release_keys(input_dev);
-       spin_unlock_irq(&input_dev->event_lock);
-
-       mutex_unlock(&input_dev->mutex);
+       input_reset_device(input_dev);
 
        return 0;
 }
index b92d1cd5cba1e4ee83923b7bce43c80a7075f5b8..af45d275f6862924979f48def9b1aa43ece095eb 100644 (file)
@@ -4,7 +4,7 @@
  *              I2C QWERTY Keypad and IO Expander
  * Bugs: Enter bugs at http://blackfin.uclinux.org/
  *
- * Copyright (C) 2008-2009 Analog Devices Inc.
+ * Copyright (C) 2008-2010 Analog Devices Inc.
  * Licensed under the GPL-2 or later.
  */
 
 
 #include <linux/i2c/adp5588.h>
 
- /* Configuration Register1 */
-#define AUTO_INC       (1 << 7)
-#define GPIEM_CFG      (1 << 6)
-#define OVR_FLOW_M     (1 << 5)
-#define INT_CFG                (1 << 4)
-#define OVR_FLOW_IEN   (1 << 3)
-#define K_LCK_IM       (1 << 2)
-#define GPI_IEN                (1 << 1)
-#define KE_IEN         (1 << 0)
-
-/* Interrupt Status Register */
-#define CMP2_INT       (1 << 5)
-#define CMP1_INT       (1 << 4)
-#define OVR_FLOW_INT   (1 << 3)
-#define K_LCK_INT      (1 << 2)
-#define GPI_INT                (1 << 1)
-#define KE_INT         (1 << 0)
-
-/* Key Lock and Event Counter Register */
-#define K_LCK_EN       (1 << 6)
-#define LCK21          0x30
-#define KEC            0xF
-
 /* Key Event Register xy */
 #define KEY_EV_PRESSED         (1 << 7)
 #define KEY_EV_MASK            (0x7F)
 
 #define KEYP_MAX_EVENT         10
 
-#define MAXGPIO                        18
-#define ADP_BANK(offs)         ((offs) >> 3)
-#define ADP_BIT(offs)          (1u << ((offs) & 0x7))
-
 /*
  * Early pre 4.0 Silicon required to delay readout by at least 25ms,
  * since the Event Counter Register updated 25ms after the interrupt
@@ -75,7 +48,7 @@ struct adp5588_kpad {
        const struct adp5588_gpi_map *gpimap;
        unsigned short gpimapsize;
 #ifdef CONFIG_GPIOLIB
-       unsigned char gpiomap[MAXGPIO];
+       unsigned char gpiomap[ADP5588_MAXGPIO];
        bool export_gpio;
        struct gpio_chip gc;
        struct mutex gpio_lock; /* Protect cached dir, dat_out */
@@ -103,8 +76,8 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val)
 static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
 {
        struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
-       unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
-       unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
+       unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
+       unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
 
        return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit);
 }
@@ -113,8 +86,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip,
                                   unsigned off, int val)
 {
        struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
-       unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
-       unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
+       unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
+       unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
 
        mutex_lock(&kpad->gpio_lock);
 
@@ -132,8 +105,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip,
 static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
 {
        struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
-       unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
-       unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
+       unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
+       unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
        int ret;
 
        mutex_lock(&kpad->gpio_lock);
@@ -150,8 +123,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
                                         unsigned off, int val)
 {
        struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
-       unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
-       unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
+       unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
+       unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
        int ret;
 
        mutex_lock(&kpad->gpio_lock);
@@ -176,7 +149,7 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
 static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad,
                                const struct adp5588_kpad_platform_data *pdata)
 {
-       bool pin_used[MAXGPIO];
+       bool pin_used[ADP5588_MAXGPIO];
        int n_unused = 0;
        int i;
 
@@ -191,7 +164,7 @@ static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad,
        for (i = 0; i < kpad->gpimapsize; i++)
                pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true;
 
-       for (i = 0; i < MAXGPIO; i++)
+       for (i = 0; i < ADP5588_MAXGPIO; i++)
                if (!pin_used[i])
                        kpad->gpiomap[n_unused++] = i;
 
@@ -234,7 +207,7 @@ static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad)
                return error;
        }
 
-       for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
+       for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
                kpad->dat_out[i] = adp5588_read(kpad->client,
                                                GPIO_DAT_OUT1 + i);
                kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i);
@@ -318,11 +291,11 @@ static void adp5588_work(struct work_struct *work)
 
        status = adp5588_read(client, INT_STAT);
 
-       if (status & OVR_FLOW_INT)      /* Unlikely and should never happen */
+       if (status & ADP5588_OVR_FLOW_INT)      /* Unlikely and should never happen */
                dev_err(&client->dev, "Event Overflow Error\n");
 
-       if (status & KE_INT) {
-               ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC;
+       if (status & ADP5588_KE_INT) {
+               ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC;
                if (ev_cnt) {
                        adp5588_report_events(kpad, ev_cnt);
                        input_sync(kpad->input);
@@ -360,7 +333,7 @@ static int __devinit adp5588_setup(struct i2c_client *client)
        if (pdata->en_keylock) {
                ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1);
                ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2);
-               ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN);
+               ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN);
        }
 
        for (i = 0; i < KEYP_MAX_EVENT; i++)
@@ -384,7 +357,7 @@ static int __devinit adp5588_setup(struct i2c_client *client)
        }
 
        if (gpio_data) {
-               for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
+               for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
                        int pull_mask = gpio_data->pullup_dis_mask;
 
                        ret |= adp5588_write(client, GPIO_PULL1 + i,
@@ -392,11 +365,14 @@ static int __devinit adp5588_setup(struct i2c_client *client)
                }
        }
 
-       ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT |
-                                       OVR_FLOW_INT | K_LCK_INT |
-                                       GPI_INT | KE_INT); /* Status is W1C */
+       ret |= adp5588_write(client, INT_STAT,
+                               ADP5588_CMP2_INT | ADP5588_CMP1_INT |
+                               ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT |
+                               ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */
 
-       ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN);
+       ret |= adp5588_write(client, CFG, ADP5588_INT_CFG |
+                                         ADP5588_OVR_FLOW_IEN |
+                                         ADP5588_KE_IEN);
 
        if (ret < 0) {
                dev_err(&client->dev, "Write Error\n");
index d358ef8623f490709875b901d82580b1afc7a7fc..11478eb2c27de1ec332b8f3e4a5b1a56408b49ce 100644 (file)
@@ -63,6 +63,10 @@ static bool atkbd_extra;
 module_param_named(extra, atkbd_extra, bool, 0);
 MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards");
 
+static bool atkbd_terminal;
+module_param_named(terminal, atkbd_terminal, bool, 0);
+MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2");
+
 /*
  * Scancode to keycode tables. These are just the default setting, and
  * are loadable via a userland utility.
@@ -136,7 +140,8 @@ static const unsigned short atkbd_unxlate_table[128] = {
 #define ATKBD_CMD_ENABLE       0x00f4
 #define ATKBD_CMD_RESET_DIS    0x00f5  /* Reset to defaults and disable */
 #define ATKBD_CMD_RESET_DEF    0x00f6  /* Reset to defaults */
-#define ATKBD_CMD_SETALL_MBR   0x00fa
+#define ATKBD_CMD_SETALL_MB    0x00f8  /* Set all keys to give break codes */
+#define ATKBD_CMD_SETALL_MBR   0x00fa  /* ... and repeat */
 #define ATKBD_CMD_RESET_BAT    0x02ff
 #define ATKBD_CMD_RESEND       0x00fe
 #define ATKBD_CMD_EX_ENABLE    0x10ea
@@ -764,6 +769,11 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra
                }
        }
 
+       if (atkbd_terminal) {
+               ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MB);
+               return 3;
+       }
+
        if (target_set != 3)
                return 2;
 
index 4b42ffc0532af1c6a3b36ca64ab411decfac89d9..d1583aea17212b72e4b30f69c5a640d42652dfe2 100644 (file)
@@ -127,14 +127,6 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2
        idev->id.product = 0x0001;
        idev->id.version = 0x0100;
 
-       input_set_drvdata(idev, lp);
-
-       ret = input_register_device(idev);
-       if (ret) {
-               dev_err(&client->dev, "input_register_device() failed\n");
-               goto fail_register;
-       }
-
        lp->laststate = read_state(lp);
 
        ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler,
@@ -142,16 +134,21 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2
                                   DRV_NAME, lp);
        if (ret) {
                dev_err(&client->dev, "IRQ %d is not free\n", client->irq);
-               goto fail_irq;
+               goto fail_free_device;
+       }
+
+       ret = input_register_device(idev);
+       if (ret) {
+               dev_err(&client->dev, "input_register_device() failed\n");
+               goto fail_free_irq;
        }
 
        i2c_set_clientdata(client, lp);
        return 0;
 
- fail_irq:
-       input_unregister_device(idev);
- fail_register:
-       input_set_drvdata(idev, NULL);
+ fail_free_irq:
+       free_irq(client->irq, lp);
+ fail_free_device:
        input_free_device(idev);
  fail_allocate:
        kfree(lp);
index a9cf768316343df7eafeda3f7c4bb58876c3f571..b77f9991278e791557e47638ce078b157cf52993 100644 (file)
@@ -630,7 +630,7 @@ static void atp_complete_geyser_3_4(struct urb *urb)
        /* Just update the base values (i.e. touchpad in untouched state) */
        if (dev->data[dev->info->datalen - 1] & ATP_STATUS_BASE_UPDATE) {
 
-               dprintk(KERN_DEBUG "appletouch: updated base values\n");
+               dprintk("appletouch: updated base values\n");
 
                memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
                goto exit;
index ed7ad7416b24d8f40c9cccd61d8371f732b73441..a5475b5770863298609f7ab40850e03286529046 100644 (file)
@@ -350,6 +350,17 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
                },
        },
+       {
+               /*
+                * Most (all?) VAIOs do not have external PS/2 ports nor
+                * they implement active multiplexing properly, and
+                * MUX discovery usually messes up keyboard/touchpad.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
+               },
+       },
        {
                /* Amoi M636/A737 */
                .matches = {
index aea9a9399a36b43a18663b4fd46d8bd3c7303808..d94f7e9aa997f13cbafba7739d59a234bf117726 100644 (file)
@@ -229,12 +229,13 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
 
        err = input_register_device(acecad->input);
        if (err)
-               goto fail2;
+               goto fail3;
 
        usb_set_intfdata(intf, acecad);
 
        return 0;
 
+ fail3:        usb_free_urb(acecad->irq);
  fail2:        usb_free_coherent(dev, 8, acecad->data, acecad->data_dma);
  fail1: input_free_device(input_dev);
        kfree(acecad);
index ba6f0bd1e762e494961f6eab23204fb37eff63c0..bc3b5187f3a391504f275567d7143e878dda5c9b 100644 (file)
@@ -129,6 +129,9 @@ struct ad7879 {
        u16                     cmd_crtl1;
        u16                     cmd_crtl2;
        u16                     cmd_crtl3;
+       int                     x;
+       int                     y;
+       int                     Rt;
 };
 
 static int ad7879_read(struct ad7879 *ts, u8 reg)
@@ -175,13 +178,32 @@ static int ad7879_report(struct ad7879 *ts)
                Rt /= z1;
                Rt = (Rt + 2047) >> 12;
 
-               if (!timer_pending(&ts->timer))
+               /*
+                * Sample found inconsistent, pressure is beyond
+                * the maximum. Don't report it to user space.
+                */
+               if (Rt > ts->pressure_max)
+                       return -EINVAL;
+
+               /*
+                * Note that we delay reporting events by one sample.
+                * This is done to avoid reporting last sample of the
+                * touch sequence, which may be incomplete if finger
+                * leaves the surface before last reading is taken.
+                */
+               if (timer_pending(&ts->timer)) {
+                       /* Touch continues */
                        input_report_key(input_dev, BTN_TOUCH, 1);
+                       input_report_abs(input_dev, ABS_X, ts->x);
+                       input_report_abs(input_dev, ABS_Y, ts->y);
+                       input_report_abs(input_dev, ABS_PRESSURE, ts->Rt);
+                       input_sync(input_dev);
+               }
+
+               ts->x = x;
+               ts->y = y;
+               ts->Rt = Rt;
 
-               input_report_abs(input_dev, ABS_X, x);
-               input_report_abs(input_dev, ABS_Y, y);
-               input_report_abs(input_dev, ABS_PRESSURE, Rt);
-               input_sync(input_dev);
                return 0;
        }
 
index ccde586025632671d5ea6279b89a3602262600a3..2ca9e5d6646028c428ec06fd525ad971629d98a2 100644 (file)
@@ -514,7 +514,7 @@ err_free_irq:
 err_cs_disable:
        pdata->cs_dis(pdata->cs_pin);
 err_free_mem:
-       input_free_device(bu21013_data->in_dev);
+       input_free_device(in_dev);
        kfree(bu21013_data);
 
        return error;
index 2b83850997c3903df974e6088b81854e9d5c1ebb..b4faed7fe0d338dffd6e57aaf4256cf859af5e10 100644 (file)
@@ -125,16 +125,16 @@ fail:
        return -ENOMEM;
 }
 
-static int capifs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *capifs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, capifs_fill_super, mnt);
+       return mount_single(fs_type, flags, data, capifs_fill_super);
 }
 
 static struct file_system_type capifs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "capifs",
-       .get_sb         = capifs_get_sb,
+       .mount          = capifs_mount,
        .kill_sb        = kill_anon_super,
 };
 
index 40b914bded8c2a3237abca74d295d8d80a02b2e3..2e72227bd071b9d18329e60a0e4b06a444700ec9 100644 (file)
@@ -1427,8 +1427,8 @@ modeisar(struct BCState *bcs, int mode, int bc)
                                        &bcs->hw.isar.reg->Flags))
                                        bcs->hw.isar.dpath = 1;
                                else {
-                                       printk(KERN_WARNING"isar modeisar analog funktions only with DP1\n");
-                                       debugl1(cs, "isar modeisar analog funktions only with DP1");
+                                       printk(KERN_WARNING"isar modeisar analog functions only with DP1\n");
+                                       debugl1(cs, "isar modeisar analog functions only with DP1");
                                        return(1);
                                }
                                break;
index 3232206406b15bcdba06b39b837545307902d3e1..7446d8b4282d58cee32d435c930c23b1b43092a4 100644 (file)
@@ -392,6 +392,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                if (dev) {
                        struct mISDN_devinfo di;
 
+                       memset(&di, 0, sizeof(di));
                        di.id = dev->id;
                        di.Dprotocols = dev->Dprotocols;
                        di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
@@ -672,6 +673,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                if (dev) {
                        struct mISDN_devinfo di;
 
+                       memset(&di, 0, sizeof(di));
                        di.id = dev->id;
                        di.Dprotocols = dev->Dprotocols;
                        di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
index cc2a88d5192fbb359f3027082c0843ad34055d97..77b8fd20cd9046b8e0c785c041c7569285aa6043 100644 (file)
@@ -10,7 +10,7 @@ menuconfig NEW_LEDS
 if NEW_LEDS
 
 config LEDS_CLASS
-       tristate "LED Class Support"
+       bool "LED Class Support"
        help
          This option enables the led sysfs class in /sys/class/leds.  You'll
          need this to do anything useful with LEDs.  If unsure, say N.
@@ -176,6 +176,24 @@ config LEDS_LP3944
          To compile this driver as a module, choose M here: the
          module will be called leds-lp3944.
 
+config LEDS_LP5521
+       tristate "LED Support for N.S. LP5521 LED driver chip"
+       depends on LEDS_CLASS && I2C
+       help
+         If you say yes here you get support for the National Semiconductor
+         LP5521 LED driver. It is 3 channel chip with programmable engines.
+         Driver provides direct control via LED class and interface for
+         programming the engines.
+
+config LEDS_LP5523
+       tristate "LED Support for N.S. LP5523 LED driver chip"
+       depends on LEDS_CLASS && I2C
+       help
+         If you say yes here you get support for the National Semiconductor
+         LP5523 LED driver. It is 9 channel chip with programmable engines.
+         Driver provides direct control via LED class and interface for
+         programming the engines.
+
 config LEDS_CLEVO_MAIL
        tristate "Mail LED on Clevo notebook"
        depends on X86 && SERIO_I8042 && DMI
index 9c96db40ef6d7d3a12f776ab4d764371a71026a5..aae6989ff6b63445e6b6c974df537f0f0784fe3f 100644 (file)
@@ -23,6 +23,8 @@ 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_LP5521)              += leds-lp5521.o
+obj-$(CONFIG_LEDS_LP5523)              += leds-lp5523.o
 obj-$(CONFIG_LEDS_CLEVO_MAIL)          += leds-clevo-mail.o
 obj-$(CONFIG_LEDS_HP6XX)               += leds-hp6xx.o
 obj-$(CONFIG_LEDS_FSG)                 += leds-fsg.o
index 2606600765079f946501717888a411eef20ac3fd..211e21f34bd57d5f6e2b079dcd22194713b3d5f5 100644 (file)
@@ -81,6 +81,79 @@ static struct device_attribute led_class_attrs[] = {
        __ATTR_NULL,
 };
 
+static void led_timer_function(unsigned long data)
+{
+       struct led_classdev *led_cdev = (void *)data;
+       unsigned long brightness;
+       unsigned long delay;
+
+       if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) {
+               led_set_brightness(led_cdev, LED_OFF);
+               return;
+       }
+
+       brightness = led_get_brightness(led_cdev);
+       if (!brightness) {
+               /* Time to switch the LED on. */
+               brightness = led_cdev->blink_brightness;
+               delay = led_cdev->blink_delay_on;
+       } else {
+               /* Store the current brightness value to be able
+                * to restore it when the delay_off period is over.
+                */
+               led_cdev->blink_brightness = brightness;
+               brightness = LED_OFF;
+               delay = led_cdev->blink_delay_off;
+       }
+
+       led_set_brightness(led_cdev, brightness);
+
+       mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
+}
+
+static void led_stop_software_blink(struct led_classdev *led_cdev)
+{
+       /* deactivate previous settings */
+       del_timer_sync(&led_cdev->blink_timer);
+       led_cdev->blink_delay_on = 0;
+       led_cdev->blink_delay_off = 0;
+}
+
+static void led_set_software_blink(struct led_classdev *led_cdev,
+                                  unsigned long delay_on,
+                                  unsigned long delay_off)
+{
+       int current_brightness;
+
+       current_brightness = led_get_brightness(led_cdev);
+       if (current_brightness)
+               led_cdev->blink_brightness = current_brightness;
+       if (!led_cdev->blink_brightness)
+               led_cdev->blink_brightness = led_cdev->max_brightness;
+
+       if (delay_on == led_cdev->blink_delay_on &&
+           delay_off == led_cdev->blink_delay_off)
+               return;
+
+       led_stop_software_blink(led_cdev);
+
+       led_cdev->blink_delay_on = delay_on;
+       led_cdev->blink_delay_off = delay_off;
+
+       /* never on - don't blink */
+       if (!delay_on)
+               return;
+
+       /* never off - just set to brightness */
+       if (!delay_off) {
+               led_set_brightness(led_cdev, led_cdev->blink_brightness);
+               return;
+       }
+
+       mod_timer(&led_cdev->blink_timer, jiffies + 1);
+}
+
+
 /**
  * led_classdev_suspend - suspend an led_classdev.
  * @led_cdev: the led_classdev to suspend.
@@ -148,6 +221,10 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 
        led_update_brightness(led_cdev);
 
+       init_timer(&led_cdev->blink_timer);
+       led_cdev->blink_timer.function = led_timer_function;
+       led_cdev->blink_timer.data = (unsigned long)led_cdev;
+
 #ifdef CONFIG_LEDS_TRIGGERS
        led_trigger_set_default(led_cdev);
 #endif
@@ -157,7 +234,6 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 
        return 0;
 }
-
 EXPORT_SYMBOL_GPL(led_classdev_register);
 
 /**
@@ -175,6 +251,9 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
        up_write(&led_cdev->trigger_lock);
 #endif
 
+       /* Stop blinking */
+       led_brightness_set(led_cdev, LED_OFF);
+
        device_unregister(led_cdev->dev);
 
        down_write(&leds_list_lock);
@@ -183,6 +262,30 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
 }
 EXPORT_SYMBOL_GPL(led_classdev_unregister);
 
+void led_blink_set(struct led_classdev *led_cdev,
+                  unsigned long *delay_on,
+                  unsigned long *delay_off)
+{
+       if (led_cdev->blink_set &&
+           led_cdev->blink_set(led_cdev, delay_on, delay_off))
+               return;
+
+       /* blink with 1 Hz as default if nothing specified */
+       if (!*delay_on && !*delay_off)
+               *delay_on = *delay_off = 500;
+
+       led_set_software_blink(led_cdev, *delay_on, *delay_off);
+}
+EXPORT_SYMBOL(led_blink_set);
+
+void led_brightness_set(struct led_classdev *led_cdev,
+                       enum led_brightness brightness)
+{
+       led_stop_software_blink(led_cdev);
+       led_cdev->brightness_set(led_cdev, brightness);
+}
+EXPORT_SYMBOL(led_brightness_set);
+
 static int __init leds_init(void)
 {
        leds_class = class_create(THIS_MODULE, "leds");
index f1c00db88b5e148fd229410d5959f4c4e0e9580b..c41eb6180c9c2eb2e88ce2dfbfc64d7ff90daf2a 100644 (file)
@@ -113,7 +113,7 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
                if (led_cdev->trigger->deactivate)
                        led_cdev->trigger->deactivate(led_cdev);
                led_cdev->trigger = NULL;
-               led_set_brightness(led_cdev, LED_OFF);
+               led_brightness_set(led_cdev, LED_OFF);
        }
        if (trigger) {
                write_lock_irqsave(&trigger->leddev_list_lock, flags);
index ea57e05d08f3f757e67f7a3ed7c5d2c5c0a28aae..4d9fa38d9ff6a3cffb2063823c92b0d147ce13d8 100644 (file)
@@ -316,7 +316,7 @@ static struct of_platform_driver of_gpio_leds_driver = {
 
 static int __init gpio_led_init(void)
 {
-       int ret;
+       int ret = 0;
 
 #ifdef CONFIG_LEDS_GPIO_PLATFORM       
        ret = platform_driver_register(&gpio_led_driver);
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
new file mode 100644 (file)
index 0000000..3782f31
--- /dev/null
@@ -0,0 +1,821 @@
+/*
+ * LP5521 LED chip driver.
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/ctype.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/leds.h>
+#include <linux/leds-lp5521.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+
+#define LP5521_PROGRAM_LENGTH          32      /* in bytes */
+
+#define LP5521_MAX_LEDS                        3       /* Maximum number of LEDs */
+#define LP5521_MAX_ENGINES             3       /* Maximum number of engines */
+
+#define LP5521_ENG_MASK_BASE           0x30    /* 00110000 */
+#define LP5521_ENG_STATUS_MASK         0x07    /* 00000111 */
+
+#define LP5521_CMD_LOAD                        0x15    /* 00010101 */
+#define LP5521_CMD_RUN                 0x2a    /* 00101010 */
+#define LP5521_CMD_DIRECT              0x3f    /* 00111111 */
+#define LP5521_CMD_DISABLED            0x00    /* 00000000 */
+
+/* Registers */
+#define LP5521_REG_ENABLE              0x00
+#define LP5521_REG_OP_MODE             0x01
+#define LP5521_REG_R_PWM               0x02
+#define LP5521_REG_G_PWM               0x03
+#define LP5521_REG_B_PWM               0x04
+#define LP5521_REG_R_CURRENT           0x05
+#define LP5521_REG_G_CURRENT           0x06
+#define LP5521_REG_B_CURRENT           0x07
+#define LP5521_REG_CONFIG              0x08
+#define LP5521_REG_R_CHANNEL_PC                0x09
+#define LP5521_REG_G_CHANNEL_PC                0x0A
+#define LP5521_REG_B_CHANNEL_PC                0x0B
+#define LP5521_REG_STATUS              0x0C
+#define LP5521_REG_RESET               0x0D
+#define LP5521_REG_GPO                 0x0E
+#define LP5521_REG_R_PROG_MEM          0x10
+#define LP5521_REG_G_PROG_MEM          0x30
+#define LP5521_REG_B_PROG_MEM          0x50
+
+#define LP5521_PROG_MEM_BASE           LP5521_REG_R_PROG_MEM
+#define LP5521_PROG_MEM_SIZE           0x20
+
+/* Base register to set LED current */
+#define LP5521_REG_LED_CURRENT_BASE    LP5521_REG_R_CURRENT
+
+/* Base register to set the brightness */
+#define LP5521_REG_LED_PWM_BASE                LP5521_REG_R_PWM
+
+/* Bits in ENABLE register */
+#define LP5521_MASTER_ENABLE           0x40    /* Chip master enable */
+#define LP5521_LOGARITHMIC_PWM         0x80    /* Logarithmic PWM adjustment */
+#define LP5521_EXEC_RUN                        0x2A
+
+/* Bits in CONFIG register */
+#define LP5521_PWM_HF                  0x40    /* PWM: 0 = 256Hz, 1 = 558Hz */
+#define LP5521_PWRSAVE_EN              0x20    /* 1 = Power save mode */
+#define LP5521_CP_MODE_OFF             0       /* Charge pump (CP) off */
+#define LP5521_CP_MODE_BYPASS          8       /* CP forced to bypass mode */
+#define LP5521_CP_MODE_1X5             0x10    /* CP forced to 1.5x mode */
+#define LP5521_CP_MODE_AUTO            0x18    /* Automatic mode selection */
+#define LP5521_R_TO_BATT               4       /* R out: 0 = CP, 1 = Vbat */
+#define LP5521_CLK_SRC_EXT             0       /* Ext-clk source (CLK_32K) */
+#define LP5521_CLK_INT                 1       /* Internal clock */
+#define LP5521_CLK_AUTO                        2       /* Automatic clock selection */
+
+/* Status */
+#define LP5521_EXT_CLK_USED            0x08
+
+struct lp5521_engine {
+       const struct attribute_group *attributes;
+       int             id;
+       u8              mode;
+       u8              prog_page;
+       u8              engine_mask;
+};
+
+struct lp5521_led {
+       int                     id;
+       u8                      chan_nr;
+       u8                      led_current;
+       u8                      max_current;
+       struct led_classdev     cdev;
+       struct work_struct      brightness_work;
+       u8                      brightness;
+};
+
+struct lp5521_chip {
+       struct lp5521_platform_data *pdata;
+       struct mutex            lock; /* Serialize control */
+       struct i2c_client       *client;
+       struct lp5521_engine    engines[LP5521_MAX_ENGINES];
+       struct lp5521_led       leds[LP5521_MAX_LEDS];
+       u8                      num_channels;
+       u8                      num_leds;
+};
+
+#define cdev_to_led(c)         container_of(c, struct lp5521_led, cdev)
+#define engine_to_lp5521(eng)  container_of((eng), struct lp5521_chip, \
+                                               engines[(eng)->id - 1])
+#define led_to_lp5521(led)     container_of((led), struct lp5521_chip, \
+                                               leds[(led)->id])
+
+static void lp5521_led_brightness_work(struct work_struct *work);
+
+static inline int lp5521_write(struct i2c_client *client, u8 reg, u8 value)
+{
+       return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int lp5521_read(struct i2c_client *client, u8 reg, u8 *buf)
+{
+       s32 ret;
+
+       ret = i2c_smbus_read_byte_data(client, reg);
+       if (ret < 0)
+               return -EIO;
+
+       *buf = ret;
+       return 0;
+}
+
+static int lp5521_set_engine_mode(struct lp5521_engine *engine, u8 mode)
+{
+       struct lp5521_chip *chip = engine_to_lp5521(engine);
+       struct i2c_client *client = chip->client;
+       int ret;
+       u8 engine_state;
+
+       /* Only transition between RUN and DIRECT mode are handled here */
+       if (mode == LP5521_CMD_LOAD)
+               return 0;
+
+       if (mode == LP5521_CMD_DISABLED)
+               mode = LP5521_CMD_DIRECT;
+
+       ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state);
+
+       /* set mode only for this engine */
+       engine_state &= ~(engine->engine_mask);
+       mode &= engine->engine_mask;
+       engine_state |= mode;
+       ret |= lp5521_write(client, LP5521_REG_OP_MODE, engine_state);
+
+       return ret;
+}
+
+static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern)
+{
+       struct lp5521_chip *chip = engine_to_lp5521(eng);
+       struct i2c_client *client = chip->client;
+       int ret;
+       int addr;
+       u8 mode;
+
+       /* move current engine to direct mode and remember the state */
+       ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT);
+       usleep_range(1000, 10000);
+       ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode);
+
+       /* For loading, all the engines to load mode */
+       lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
+       usleep_range(1000, 10000);
+       lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD);
+       usleep_range(1000, 10000);
+
+       addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE;
+       i2c_smbus_write_i2c_block_data(client,
+                               addr,
+                               LP5521_PROG_MEM_SIZE,
+                               pattern);
+
+       ret |= lp5521_write(client, LP5521_REG_OP_MODE, mode);
+       return ret;
+}
+
+static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr)
+{
+       return lp5521_write(chip->client,
+                   LP5521_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr,
+                   curr);
+}
+
+static void lp5521_init_engine(struct lp5521_chip *chip,
+                       const struct attribute_group *attr_group)
+{
+       int i;
+       for (i = 0; i < ARRAY_SIZE(chip->engines); i++) {
+               chip->engines[i].id = i + 1;
+               chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2);
+               chip->engines[i].prog_page = i;
+               chip->engines[i].attributes = &attr_group[i];
+       }
+}
+
+static int lp5521_configure(struct i2c_client *client,
+                       const struct attribute_group *attr_group)
+{
+       struct lp5521_chip *chip = i2c_get_clientdata(client);
+       int ret;
+
+       lp5521_init_engine(chip, attr_group);
+
+       lp5521_write(client, LP5521_REG_RESET, 0xff);
+
+       usleep_range(10000, 20000);
+
+       /* Set all PWMs to direct control mode */
+       ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F);
+
+       /* Enable auto-powersave, set charge pump to auto, red to battery */
+       ret |= lp5521_write(client, LP5521_REG_CONFIG,
+               LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT);
+
+       /* Initialize all channels PWM to zero -> leds off */
+       ret |= lp5521_write(client, LP5521_REG_R_PWM, 0);
+       ret |= lp5521_write(client, LP5521_REG_G_PWM, 0);
+       ret |= lp5521_write(client, LP5521_REG_B_PWM, 0);
+
+       /* Set engines are set to run state when OP_MODE enables engines */
+       ret |= lp5521_write(client, LP5521_REG_ENABLE,
+                       LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM |
+                       LP5521_EXEC_RUN);
+       /* enable takes 500us */
+       usleep_range(500, 20000);
+
+       return ret;
+}
+
+static int lp5521_run_selftest(struct lp5521_chip *chip, char *buf)
+{
+       int ret;
+       u8 status;
+
+       ret = lp5521_read(chip->client, LP5521_REG_STATUS, &status);
+       if (ret < 0)
+               return ret;
+
+       /* Check that ext clock is really in use if requested */
+       if (chip->pdata && chip->pdata->clock_mode == LP5521_CLOCK_EXT)
+               if  ((status & LP5521_EXT_CLK_USED) == 0)
+                       return -EIO;
+       return 0;
+}
+
+static void lp5521_set_brightness(struct led_classdev *cdev,
+                            enum led_brightness brightness)
+{
+       struct lp5521_led *led = cdev_to_led(cdev);
+       led->brightness = (u8)brightness;
+       schedule_work(&led->brightness_work);
+}
+
+static void lp5521_led_brightness_work(struct work_struct *work)
+{
+       struct lp5521_led *led = container_of(work,
+                                             struct lp5521_led,
+                                             brightness_work);
+       struct lp5521_chip *chip = led_to_lp5521(led);
+       struct i2c_client *client = chip->client;
+
+       mutex_lock(&chip->lock);
+       lp5521_write(client, LP5521_REG_LED_PWM_BASE + led->chan_nr,
+               led->brightness);
+       mutex_unlock(&chip->lock);
+}
+
+/* Detect the chip by setting its ENABLE register and reading it back. */
+static int lp5521_detect(struct i2c_client *client)
+{
+       int ret;
+       u8 buf;
+
+       ret = lp5521_write(client, LP5521_REG_ENABLE,
+                       LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM);
+       if (ret)
+               return ret;
+       usleep_range(1000, 10000);
+       ret = lp5521_read(client, LP5521_REG_ENABLE, &buf);
+       if (ret)
+               return ret;
+       if (buf != (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM))
+               return -ENODEV;
+
+       return 0;
+}
+
+/* Set engine mode and create appropriate sysfs attributes, if required. */
+static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode)
+{
+       struct lp5521_chip *chip = engine_to_lp5521(engine);
+       struct i2c_client *client = chip->client;
+       struct device *dev = &client->dev;
+       int ret = 0;
+
+       /* if in that mode already do nothing, except for run */
+       if (mode == engine->mode && mode != LP5521_CMD_RUN)
+               return 0;
+
+       if (mode == LP5521_CMD_RUN) {
+               ret = lp5521_set_engine_mode(engine, LP5521_CMD_RUN);
+       } else if (mode == LP5521_CMD_LOAD) {
+               lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED);
+               lp5521_set_engine_mode(engine, LP5521_CMD_LOAD);
+
+               ret = sysfs_create_group(&dev->kobj, engine->attributes);
+               if (ret)
+                       return ret;
+       } else if (mode == LP5521_CMD_DISABLED) {
+               lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED);
+       }
+
+       /* remove load attribute from sysfs if not in load mode */
+       if (engine->mode == LP5521_CMD_LOAD && mode != LP5521_CMD_LOAD)
+               sysfs_remove_group(&dev->kobj, engine->attributes);
+
+       engine->mode = mode;
+
+       return ret;
+}
+
+static int lp5521_do_store_load(struct lp5521_engine *engine,
+                               const char *buf, size_t len)
+{
+       struct lp5521_chip *chip = engine_to_lp5521(engine);
+       struct i2c_client *client = chip->client;
+       int  ret, nrchars, offset = 0, i = 0;
+       char c[3];
+       unsigned cmd;
+       u8 pattern[LP5521_PROGRAM_LENGTH] = {0};
+
+       while ((offset < len - 1) && (i < LP5521_PROGRAM_LENGTH)) {
+               /* separate sscanfs because length is working only for %s */
+               ret = sscanf(buf + offset, "%2s%n ", c, &nrchars);
+               ret = sscanf(c, "%2x", &cmd);
+               if (ret != 1)
+                       goto fail;
+               pattern[i] = (u8)cmd;
+
+               offset += nrchars;
+               i++;
+       }
+
+       /* Each instruction is 16bit long. Check that length is even */
+       if (i % 2)
+               goto fail;
+
+       mutex_lock(&chip->lock);
+       ret = lp5521_load_program(engine, pattern);
+       mutex_unlock(&chip->lock);
+
+       if (ret) {
+               dev_err(&client->dev, "failed loading pattern\n");
+               return ret;
+       }
+
+       return len;
+fail:
+       dev_err(&client->dev, "wrong pattern format\n");
+       return -EINVAL;
+}
+
+static ssize_t store_engine_load(struct device *dev,
+                                    struct device_attribute *attr,
+                                    const char *buf, size_t len, int nr)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5521_chip *chip = i2c_get_clientdata(client);
+       return lp5521_do_store_load(&chip->engines[nr - 1], buf, len);
+}
+
+#define store_load(nr)                                                 \
+static ssize_t store_engine##nr##_load(struct device *dev,             \
+                                    struct device_attribute *attr,     \
+                                    const char *buf, size_t len)       \
+{                                                                      \
+       return store_engine_load(dev, attr, buf, len, nr);              \
+}
+store_load(1)
+store_load(2)
+store_load(3)
+
+static ssize_t show_engine_mode(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf, int nr)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5521_chip *chip = i2c_get_clientdata(client);
+       switch (chip->engines[nr - 1].mode) {
+       case LP5521_CMD_RUN:
+               return sprintf(buf, "run\n");
+       case LP5521_CMD_LOAD:
+               return sprintf(buf, "load\n");
+       case LP5521_CMD_DISABLED:
+               return sprintf(buf, "disabled\n");
+       default:
+               return sprintf(buf, "disabled\n");
+       }
+}
+
+#define show_mode(nr)                                                  \
+static ssize_t show_engine##nr##_mode(struct device *dev,              \
+                                   struct device_attribute *attr,      \
+                                   char *buf)                          \
+{                                                                      \
+       return show_engine_mode(dev, attr, buf, nr);                    \
+}
+show_mode(1)
+show_mode(2)
+show_mode(3)
+
+static ssize_t store_engine_mode(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t len, int nr)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5521_chip *chip = i2c_get_clientdata(client);
+       struct lp5521_engine *engine = &chip->engines[nr - 1];
+       mutex_lock(&chip->lock);
+
+       if (!strncmp(buf, "run", 3))
+               lp5521_set_mode(engine, LP5521_CMD_RUN);
+       else if (!strncmp(buf, "load", 4))
+               lp5521_set_mode(engine, LP5521_CMD_LOAD);
+       else if (!strncmp(buf, "disabled", 8))
+               lp5521_set_mode(engine, LP5521_CMD_DISABLED);
+
+       mutex_unlock(&chip->lock);
+       return len;
+}
+
+#define store_mode(nr)                                                 \
+static ssize_t store_engine##nr##_mode(struct device *dev,             \
+                                    struct device_attribute *attr,     \
+                                    const char *buf, size_t len)       \
+{                                                                      \
+       return store_engine_mode(dev, attr, buf, len, nr);              \
+}
+store_mode(1)
+store_mode(2)
+store_mode(3)
+
+static ssize_t show_max_current(struct device *dev,
+                           struct device_attribute *attr,
+                           char *buf)
+{
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct lp5521_led *led = cdev_to_led(led_cdev);
+
+       return sprintf(buf, "%d\n", led->max_current);
+}
+
+static ssize_t show_current(struct device *dev,
+                           struct device_attribute *attr,
+                           char *buf)
+{
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct lp5521_led *led = cdev_to_led(led_cdev);
+
+       return sprintf(buf, "%d\n", led->led_current);
+}
+
+static ssize_t store_current(struct device *dev,
+                            struct device_attribute *attr,
+                            const char *buf, size_t len)
+{
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct lp5521_led *led = cdev_to_led(led_cdev);
+       struct lp5521_chip *chip = led_to_lp5521(led);
+       ssize_t ret;
+       unsigned long curr;
+
+       if (strict_strtoul(buf, 0, &curr))
+               return -EINVAL;
+
+       if (curr > led->max_current)
+               return -EINVAL;
+
+       mutex_lock(&chip->lock);
+       ret = lp5521_set_led_current(chip, led->id, curr);
+       mutex_unlock(&chip->lock);
+
+       if (ret < 0)
+               return ret;
+
+       led->led_current = (u8)curr;
+
+       return len;
+}
+
+static ssize_t lp5521_selftest(struct device *dev,
+                              struct device_attribute *attr,
+                              char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5521_chip *chip = i2c_get_clientdata(client);
+       int ret;
+
+       mutex_lock(&chip->lock);
+       ret = lp5521_run_selftest(chip, buf);
+       mutex_unlock(&chip->lock);
+       return sprintf(buf, "%s\n", ret ? "FAIL" : "OK");
+}
+
+/* led class device attributes */
+static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current);
+static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
+
+static struct attribute *lp5521_led_attributes[] = {
+       &dev_attr_led_current.attr,
+       &dev_attr_max_current.attr,
+       NULL,
+};
+
+static struct attribute_group lp5521_led_attribute_group = {
+       .attrs = lp5521_led_attributes
+};
+
+/* device attributes */
+static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO,
+                  show_engine1_mode, store_engine1_mode);
+static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO,
+                  show_engine2_mode, store_engine2_mode);
+static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO,
+                  show_engine3_mode, store_engine3_mode);
+static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load);
+static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load);
+static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load);
+static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL);
+
+static struct attribute *lp5521_attributes[] = {
+       &dev_attr_engine1_mode.attr,
+       &dev_attr_engine2_mode.attr,
+       &dev_attr_engine3_mode.attr,
+       &dev_attr_selftest.attr,
+       NULL
+};
+
+static struct attribute *lp5521_engine1_attributes[] = {
+       &dev_attr_engine1_load.attr,
+       NULL
+};
+
+static struct attribute *lp5521_engine2_attributes[] = {
+       &dev_attr_engine2_load.attr,
+       NULL
+};
+
+static struct attribute *lp5521_engine3_attributes[] = {
+       &dev_attr_engine3_load.attr,
+       NULL
+};
+
+static const struct attribute_group lp5521_group = {
+       .attrs = lp5521_attributes,
+};
+
+static const struct attribute_group lp5521_engine_group[] = {
+       {.attrs = lp5521_engine1_attributes },
+       {.attrs = lp5521_engine2_attributes },
+       {.attrs = lp5521_engine3_attributes },
+};
+
+static int lp5521_register_sysfs(struct i2c_client *client)
+{
+       struct device *dev = &client->dev;
+       return sysfs_create_group(&dev->kobj, &lp5521_group);
+}
+
+static void lp5521_unregister_sysfs(struct i2c_client *client)
+{
+       struct lp5521_chip *chip = i2c_get_clientdata(client);
+       struct device *dev = &client->dev;
+       int i;
+
+       sysfs_remove_group(&dev->kobj, &lp5521_group);
+
+       for (i = 0; i <  ARRAY_SIZE(chip->engines); i++) {
+               if (chip->engines[i].mode == LP5521_CMD_LOAD)
+                       sysfs_remove_group(&dev->kobj,
+                                       chip->engines[i].attributes);
+       }
+
+       for (i = 0; i < chip->num_leds; i++)
+               sysfs_remove_group(&chip->leds[i].cdev.dev->kobj,
+                               &lp5521_led_attribute_group);
+}
+
+static int __init lp5521_init_led(struct lp5521_led *led,
+                               struct i2c_client *client,
+                               int chan, struct lp5521_platform_data *pdata)
+{
+       struct device *dev = &client->dev;
+       char name[32];
+       int res;
+
+       if (chan >= LP5521_MAX_LEDS)
+               return -EINVAL;
+
+       if (pdata->led_config[chan].led_current == 0)
+               return 0;
+
+       led->led_current = pdata->led_config[chan].led_current;
+       led->max_current = pdata->led_config[chan].max_current;
+       led->chan_nr = pdata->led_config[chan].chan_nr;
+
+       if (led->chan_nr >= LP5521_MAX_LEDS) {
+               dev_err(dev, "Use channel numbers between 0 and %d\n",
+                       LP5521_MAX_LEDS - 1);
+               return -EINVAL;
+       }
+
+       snprintf(name, sizeof(name), "%s:channel%d", client->name, chan);
+       led->cdev.brightness_set = lp5521_set_brightness;
+       led->cdev.name = name;
+       res = led_classdev_register(dev, &led->cdev);
+       if (res < 0) {
+               dev_err(dev, "couldn't register led on channel %d\n", chan);
+               return res;
+       }
+
+       res = sysfs_create_group(&led->cdev.dev->kobj,
+                       &lp5521_led_attribute_group);
+       if (res < 0) {
+               dev_err(dev, "couldn't register current attribute\n");
+               led_classdev_unregister(&led->cdev);
+               return res;
+       }
+       return 0;
+}
+
+static int lp5521_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       struct lp5521_chip              *chip;
+       struct lp5521_platform_data     *pdata;
+       int ret, i, led;
+
+       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, chip);
+       chip->client = client;
+
+       pdata = client->dev.platform_data;
+
+       if (!pdata) {
+               dev_err(&client->dev, "no platform data\n");
+               ret = -EINVAL;
+               goto fail1;
+       }
+
+       mutex_init(&chip->lock);
+
+       chip->pdata   = pdata;
+
+       if (pdata->setup_resources) {
+               ret = pdata->setup_resources();
+               if (ret < 0)
+                       goto fail1;
+       }
+
+       if (pdata->enable) {
+               pdata->enable(0);
+               usleep_range(1000, 10000);
+               pdata->enable(1);
+               usleep_range(1000, 10000); /* Spec says min 500us */
+       }
+
+       ret = lp5521_detect(client);
+
+       if (ret) {
+               dev_err(&client->dev, "Chip not found\n");
+               goto fail2;
+       }
+
+       dev_info(&client->dev, "%s programmable led chip found\n", id->name);
+
+       ret = lp5521_configure(client, lp5521_engine_group);
+       if (ret < 0) {
+               dev_err(&client->dev, "error configuring chip\n");
+               goto fail2;
+       }
+
+       /* Initialize leds */
+       chip->num_channels = pdata->num_channels;
+       chip->num_leds = 0;
+       led = 0;
+       for (i = 0; i < pdata->num_channels; i++) {
+               /* Do not initialize channels that are not connected */
+               if (pdata->led_config[i].led_current == 0)
+                       continue;
+
+               ret = lp5521_init_led(&chip->leds[led], client, i, pdata);
+               if (ret) {
+                       dev_err(&client->dev, "error initializing leds\n");
+                       goto fail3;
+               }
+               chip->num_leds++;
+
+               chip->leds[led].id = led;
+               /* Set initial LED current */
+               lp5521_set_led_current(chip, led,
+                               chip->leds[led].led_current);
+
+               INIT_WORK(&(chip->leds[led].brightness_work),
+                       lp5521_led_brightness_work);
+
+               led++;
+       }
+
+       ret = lp5521_register_sysfs(client);
+       if (ret) {
+               dev_err(&client->dev, "registering sysfs failed\n");
+               goto fail3;
+       }
+       return ret;
+fail3:
+       for (i = 0; i < chip->num_leds; i++) {
+               led_classdev_unregister(&chip->leds[i].cdev);
+               cancel_work_sync(&chip->leds[i].brightness_work);
+       }
+fail2:
+       if (pdata->enable)
+               pdata->enable(0);
+       if (pdata->release_resources)
+               pdata->release_resources();
+fail1:
+       kfree(chip);
+       return ret;
+}
+
+static int lp5521_remove(struct i2c_client *client)
+{
+       struct lp5521_chip *chip = i2c_get_clientdata(client);
+       int i;
+
+       lp5521_unregister_sysfs(client);
+
+       for (i = 0; i < chip->num_leds; i++) {
+               led_classdev_unregister(&chip->leds[i].cdev);
+               cancel_work_sync(&chip->leds[i].brightness_work);
+       }
+
+       if (chip->pdata->enable)
+               chip->pdata->enable(0);
+       if (chip->pdata->release_resources)
+               chip->pdata->release_resources();
+       kfree(chip);
+       return 0;
+}
+
+static const struct i2c_device_id lp5521_id[] = {
+       { "lp5521", 0 }, /* Three channel chip */
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, lp5521_id);
+
+static struct i2c_driver lp5521_driver = {
+       .driver = {
+               .name   = "lp5521",
+       },
+       .probe          = lp5521_probe,
+       .remove         = lp5521_remove,
+       .id_table       = lp5521_id,
+};
+
+static int __init lp5521_init(void)
+{
+       int ret;
+
+       ret = i2c_add_driver(&lp5521_driver);
+
+       if (ret < 0)
+               printk(KERN_ALERT "Adding lp5521 driver failed\n");
+
+       return ret;
+}
+
+static void __exit lp5521_exit(void)
+{
+       i2c_del_driver(&lp5521_driver);
+}
+
+module_init(lp5521_init);
+module_exit(lp5521_exit);
+
+MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo");
+MODULE_DESCRIPTION("LP5521 LED engine");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
new file mode 100644 (file)
index 0000000..1e11fcc
--- /dev/null
@@ -0,0 +1,1065 @@
+/*
+ * lp5523.c - LP5523 LED Driver
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/ctype.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/leds.h>
+#include <linux/leds-lp5523.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+
+#define LP5523_REG_ENABLE              0x00
+#define LP5523_REG_OP_MODE             0x01
+#define LP5523_REG_RATIOMETRIC_MSB     0x02
+#define LP5523_REG_RATIOMETRIC_LSB     0x03
+#define LP5523_REG_ENABLE_LEDS_MSB     0x04
+#define LP5523_REG_ENABLE_LEDS_LSB     0x05
+#define LP5523_REG_LED_CNTRL_BASE      0x06
+#define LP5523_REG_LED_PWM_BASE                0x16
+#define LP5523_REG_LED_CURRENT_BASE    0x26
+#define LP5523_REG_CONFIG              0x36
+#define LP5523_REG_CHANNEL1_PC         0x37
+#define LP5523_REG_CHANNEL2_PC         0x38
+#define LP5523_REG_CHANNEL3_PC         0x39
+#define LP5523_REG_STATUS              0x3a
+#define LP5523_REG_GPO                 0x3b
+#define LP5523_REG_VARIABLE            0x3c
+#define LP5523_REG_RESET               0x3d
+#define LP5523_REG_TEMP_CTRL           0x3e
+#define LP5523_REG_TEMP_READ           0x3f
+#define LP5523_REG_TEMP_WRITE          0x40
+#define LP5523_REG_LED_TEST_CTRL       0x41
+#define LP5523_REG_LED_TEST_ADC                0x42
+#define LP5523_REG_ENG1_VARIABLE       0x45
+#define LP5523_REG_ENG2_VARIABLE       0x46
+#define LP5523_REG_ENG3_VARIABLE       0x47
+#define LP5523_REG_MASTER_FADER1       0x48
+#define LP5523_REG_MASTER_FADER2       0x49
+#define LP5523_REG_MASTER_FADER3       0x4a
+#define LP5523_REG_CH1_PROG_START      0x4c
+#define LP5523_REG_CH2_PROG_START      0x4d
+#define LP5523_REG_CH3_PROG_START      0x4e
+#define LP5523_REG_PROG_PAGE_SEL       0x4f
+#define LP5523_REG_PROG_MEM            0x50
+
+#define LP5523_CMD_LOAD                        0x15 /* 00010101 */
+#define LP5523_CMD_RUN                 0x2a /* 00101010 */
+#define LP5523_CMD_DISABLED            0x00 /* 00000000 */
+
+#define LP5523_ENABLE                  0x40
+#define LP5523_AUTO_INC                        0x40
+#define LP5523_PWR_SAVE                        0x20
+#define LP5523_PWM_PWR_SAVE            0x04
+#define LP5523_CP_1                    0x08
+#define LP5523_CP_1_5                  0x10
+#define LP5523_CP_AUTO                 0x18
+#define LP5523_INT_CLK                 0x01
+#define LP5523_AUTO_CLK                        0x02
+#define LP5523_EN_LEDTEST              0x80
+#define LP5523_LEDTEST_DONE            0x80
+
+#define LP5523_DEFAULT_CURRENT         50 /* microAmps */
+#define LP5523_PROGRAM_LENGTH          32 /* in bytes */
+#define LP5523_PROGRAM_PAGES           6
+#define LP5523_ADC_SHORTCIRC_LIM       80
+
+#define LP5523_LEDS                    9
+#define LP5523_ENGINES                 3
+
+#define LP5523_ENG_MASK_BASE           0x30 /* 00110000 */
+
+#define LP5523_ENG_STATUS_MASK          0x07 /* 00000111 */
+
+#define LP5523_IRQ_FLAGS                IRQF_TRIGGER_FALLING
+
+#define LP5523_EXT_CLK_USED            0x08
+
+#define LED_ACTIVE(mux, led)           (!!(mux & (0x0001 << led)))
+#define SHIFT_MASK(id)                 (((id) - 1) * 2)
+
+struct lp5523_engine {
+       const struct attribute_group *attributes;
+       int             id;
+       u8              mode;
+       u8              prog_page;
+       u8              mux_page;
+       u16             led_mux;
+       u8              engine_mask;
+};
+
+struct lp5523_led {
+       int                     id;
+       u8                      chan_nr;
+       u8                      led_current;
+       u8                      max_current;
+       struct led_classdev     cdev;
+       struct work_struct      brightness_work;
+       u8                      brightness;
+};
+
+struct lp5523_chip {
+       struct mutex            lock; /* Serialize control */
+       struct i2c_client       *client;
+       struct lp5523_engine    engines[LP5523_ENGINES];
+       struct lp5523_led       leds[LP5523_LEDS];
+       struct lp5523_platform_data *pdata;
+       u8                      num_channels;
+       u8                      num_leds;
+};
+
+#define cdev_to_led(c)          container_of(c, struct lp5523_led, cdev)
+
+static struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine)
+{
+       return container_of(engine, struct lp5523_chip,
+                           engines[engine->id - 1]);
+}
+
+static struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
+{
+       return container_of(led, struct lp5523_chip,
+                           leds[led->id]);
+}
+
+static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
+static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode);
+static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern);
+
+static void lp5523_led_brightness_work(struct work_struct *work);
+
+static int lp5523_write(struct i2c_client *client, u8 reg, u8 value)
+{
+       return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int lp5523_read(struct i2c_client *client, u8 reg, u8 *buf)
+{
+       s32 ret = i2c_smbus_read_byte_data(client, reg);
+
+       if (ret < 0)
+               return -EIO;
+
+       *buf = ret;
+       return 0;
+}
+
+static int lp5523_detect(struct i2c_client *client)
+{
+       int ret;
+       u8 buf;
+
+       ret = lp5523_write(client, LP5523_REG_ENABLE, 0x40);
+       if (ret)
+               return ret;
+       ret = lp5523_read(client, LP5523_REG_ENABLE, &buf);
+       if (ret)
+               return ret;
+       if (buf == 0x40)
+               return 0;
+       else
+               return -ENODEV;
+}
+
+static int lp5523_configure(struct i2c_client *client)
+{
+       struct lp5523_chip *chip = i2c_get_clientdata(client);
+       int ret = 0;
+       u8 status;
+
+       /* one pattern per engine setting led mux start and stop addresses */
+       u8 pattern[][LP5523_PROGRAM_LENGTH] =  {
+               { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0},
+               { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
+               { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
+       };
+
+       lp5523_write(client, LP5523_REG_RESET, 0xff);
+
+       usleep_range(10000, 100000);
+
+       ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE);
+       /* Chip startup time after reset is 500 us */
+       usleep_range(1000, 10000);
+
+       ret |= lp5523_write(client, LP5523_REG_CONFIG,
+                           LP5523_AUTO_INC | LP5523_PWR_SAVE |
+                           LP5523_CP_AUTO | LP5523_AUTO_CLK |
+                           LP5523_PWM_PWR_SAVE);
+
+       /* turn on all leds */
+       ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_MSB, 0x01);
+       ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_LSB, 0xff);
+
+       /* hardcode 32 bytes of memory for each engine from program memory */
+       ret |= lp5523_write(client, LP5523_REG_CH1_PROG_START, 0x00);
+       ret |= lp5523_write(client, LP5523_REG_CH2_PROG_START, 0x10);
+       ret |= lp5523_write(client, LP5523_REG_CH3_PROG_START, 0x20);
+
+       /* write led mux address space for each channel */
+       ret |= lp5523_load_program(&chip->engines[0], pattern[0]);
+       ret |= lp5523_load_program(&chip->engines[1], pattern[1]);
+       ret |= lp5523_load_program(&chip->engines[2], pattern[2]);
+
+       if (ret) {
+               dev_err(&client->dev, "could not load mux programs\n");
+               return -1;
+       }
+
+       /* set all engines exec state and mode to run 00101010 */
+       ret |= lp5523_write(client, LP5523_REG_ENABLE,
+                           (LP5523_CMD_RUN | LP5523_ENABLE));
+
+       ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_RUN);
+
+       if (ret) {
+               dev_err(&client->dev, "could not start mux programs\n");
+               return -1;
+       }
+
+       /* Wait 3ms and check the engine status */
+       usleep_range(3000, 20000);
+       lp5523_read(client, LP5523_REG_STATUS, &status);
+       status &= LP5523_ENG_STATUS_MASK;
+
+       if (status == LP5523_ENG_STATUS_MASK) {
+               dev_dbg(&client->dev, "all engines configured\n");
+       } else {
+               dev_info(&client->dev, "status == %x\n", status);
+               dev_err(&client->dev, "cound not configure LED engine\n");
+               return -1;
+       }
+
+       dev_info(&client->dev, "disabling engines\n");
+
+       ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_DISABLED);
+
+       return ret;
+}
+
+static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode)
+{
+       struct lp5523_chip *chip = engine_to_lp5523(engine);
+       struct i2c_client *client = chip->client;
+       int ret;
+       u8 engine_state;
+
+       ret = lp5523_read(client, LP5523_REG_OP_MODE, &engine_state);
+       if (ret)
+               goto fail;
+
+       engine_state &= ~(engine->engine_mask);
+
+       /* set mode only for this engine */
+       mode &= engine->engine_mask;
+
+       engine_state |= mode;
+
+       ret |= lp5523_write(client, LP5523_REG_OP_MODE, engine_state);
+fail:
+       return ret;
+}
+
+static int lp5523_load_mux(struct lp5523_engine *engine, u16 mux)
+{
+       struct lp5523_chip *chip = engine_to_lp5523(engine);
+       struct i2c_client *client = chip->client;
+       int ret = 0;
+
+       ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
+
+       ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL, engine->mux_page);
+       ret |= lp5523_write(client, LP5523_REG_PROG_MEM,
+                           (u8)(mux >> 8));
+       ret |= lp5523_write(client, LP5523_REG_PROG_MEM + 1, (u8)(mux));
+       engine->led_mux = mux;
+
+       return ret;
+}
+
+static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern)
+{
+       struct lp5523_chip *chip = engine_to_lp5523(engine);
+       struct i2c_client *client = chip->client;
+
+       int ret = 0;
+
+       ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
+
+       ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL,
+                           engine->prog_page);
+       ret |= i2c_smbus_write_i2c_block_data(client, LP5523_REG_PROG_MEM,
+                                             LP5523_PROGRAM_LENGTH, pattern);
+
+       return ret;
+}
+
+static int lp5523_run_program(struct lp5523_engine *engine)
+{
+       struct lp5523_chip *chip = engine_to_lp5523(engine);
+       struct i2c_client *client = chip->client;
+       int ret;
+
+       ret = lp5523_write(client, LP5523_REG_ENABLE,
+                                       LP5523_CMD_RUN | LP5523_ENABLE);
+       if (ret)
+               goto fail;
+
+       ret = lp5523_set_engine_mode(engine, LP5523_CMD_RUN);
+fail:
+       return ret;
+}
+
+static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len)
+{
+       int i;
+       u16 tmp_mux = 0;
+       len = len < LP5523_LEDS ? len : LP5523_LEDS;
+       for (i = 0; i < len; i++) {
+               switch (buf[i]) {
+               case '1':
+                       tmp_mux |= (1 << i);
+                       break;
+               case '0':
+                       break;
+               case '\n':
+                       i = len;
+                       break;
+               default:
+                       return -1;
+               }
+       }
+       *mux = tmp_mux;
+
+       return 0;
+}
+
+static void lp5523_mux_to_array(u16 led_mux, char *array)
+{
+       int i, pos = 0;
+       for (i = 0; i < LP5523_LEDS; i++)
+               pos += sprintf(array + pos, "%x", LED_ACTIVE(led_mux, i));
+
+       array[pos] = '\0';
+}
+
+/*--------------------------------------------------------------*/
+/*                     Sysfs interface                         */
+/*--------------------------------------------------------------*/
+
+static ssize_t show_engine_leds(struct device *dev,
+                           struct device_attribute *attr,
+                           char *buf, int nr)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5523_chip *chip = i2c_get_clientdata(client);
+       char mux[LP5523_LEDS + 1];
+
+       lp5523_mux_to_array(chip->engines[nr - 1].led_mux, mux);
+
+       return sprintf(buf, "%s\n", mux);
+}
+
+#define show_leds(nr)                                                  \
+static ssize_t show_engine##nr##_leds(struct device *dev,              \
+                           struct device_attribute *attr,              \
+                           char *buf)                                  \
+{                                                                      \
+       return show_engine_leds(dev, attr, buf, nr);                    \
+}
+show_leds(1)
+show_leds(2)
+show_leds(3)
+
+static ssize_t store_engine_leds(struct device *dev,
+                            struct device_attribute *attr,
+                            const char *buf, size_t len, int nr)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5523_chip *chip = i2c_get_clientdata(client);
+       u16 mux = 0;
+
+       if (lp5523_mux_parse(buf, &mux, len))
+               return -EINVAL;
+
+       if (lp5523_load_mux(&chip->engines[nr - 1], mux))
+               return -EINVAL;
+
+       return len;
+}
+
+#define store_leds(nr)                                         \
+static ssize_t store_engine##nr##_leds(struct device *dev,     \
+                            struct device_attribute *attr,     \
+                            const char *buf, size_t len)       \
+{                                                              \
+       return store_engine_leds(dev, attr, buf, len, nr);      \
+}
+store_leds(1)
+store_leds(2)
+store_leds(3)
+
+static ssize_t lp5523_selftest(struct device *dev,
+                              struct device_attribute *attr,
+                              char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5523_chip *chip = i2c_get_clientdata(client);
+       int i, ret, pos = 0;
+       int led = 0;
+       u8 status, adc, vdd;
+
+       mutex_lock(&chip->lock);
+
+       ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
+       if (ret < 0)
+               goto fail;
+
+       /* Check that ext clock is really in use if requested */
+       if ((chip->pdata) && (chip->pdata->clock_mode == LP5523_CLOCK_EXT))
+               if  ((status & LP5523_EXT_CLK_USED) == 0)
+                       goto fail;
+
+       /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */
+       lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL,
+                                   LP5523_EN_LEDTEST | 16);
+       usleep_range(3000, 10000);
+       ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
+       if (!(status & LP5523_LEDTEST_DONE))
+               usleep_range(3000, 10000);
+
+       ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd);
+       vdd--;  /* There may be some fluctuation in measurement */
+
+       for (i = 0; i < LP5523_LEDS; i++) {
+               /* Skip non-existing channels */
+               if (chip->pdata->led_config[i].led_current == 0)
+                       continue;
+
+               /* Set default current */
+               lp5523_write(chip->client,
+                       LP5523_REG_LED_CURRENT_BASE + i,
+                       chip->pdata->led_config[i].led_current);
+
+               lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff);
+               /* let current stabilize 2ms before measurements start */
+               usleep_range(2000, 10000);
+               lp5523_write(chip->client,
+                            LP5523_REG_LED_TEST_CTRL,
+                            LP5523_EN_LEDTEST | i);
+               /* ledtest takes 2.7ms */
+               usleep_range(3000, 10000);
+               ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
+               if (!(status & LP5523_LEDTEST_DONE))
+                       usleep_range(3000, 10000);
+               ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc);
+
+               if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
+                       pos += sprintf(buf + pos, "LED %d FAIL\n", i);
+
+               lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0x00);
+
+               /* Restore current */
+               lp5523_write(chip->client,
+                       LP5523_REG_LED_CURRENT_BASE + i,
+                       chip->leds[led].led_current);
+               led++;
+       }
+       if (pos == 0)
+               pos = sprintf(buf, "OK\n");
+       goto release_lock;
+fail:
+       pos = sprintf(buf, "FAIL\n");
+
+release_lock:
+       mutex_unlock(&chip->lock);
+
+       return pos;
+}
+
+static void lp5523_set_brightness(struct led_classdev *cdev,
+                            enum led_brightness brightness)
+{
+       struct lp5523_led *led = cdev_to_led(cdev);
+
+       led->brightness = (u8)brightness;
+
+       schedule_work(&led->brightness_work);
+}
+
+static void lp5523_led_brightness_work(struct work_struct *work)
+{
+       struct lp5523_led *led = container_of(work,
+                                             struct lp5523_led,
+                                             brightness_work);
+       struct lp5523_chip *chip = led_to_lp5523(led);
+       struct i2c_client *client = chip->client;
+
+       mutex_lock(&chip->lock);
+
+       lp5523_write(client, LP5523_REG_LED_PWM_BASE + led->chan_nr,
+                    led->brightness);
+
+       mutex_unlock(&chip->lock);
+}
+
+static int lp5523_do_store_load(struct lp5523_engine *engine,
+                               const char *buf, size_t len)
+{
+       struct lp5523_chip *chip = engine_to_lp5523(engine);
+       struct i2c_client *client = chip->client;
+       int  ret, nrchars, offset = 0, i = 0;
+       char c[3];
+       unsigned cmd;
+       u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
+
+       while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) {
+               /* separate sscanfs because length is working only for %s */
+               ret = sscanf(buf + offset, "%2s%n ", c, &nrchars);
+               ret = sscanf(c, "%2x", &cmd);
+               if (ret != 1)
+                       goto fail;
+               pattern[i] = (u8)cmd;
+
+               offset += nrchars;
+               i++;
+       }
+
+       /* Each instruction is 16bit long. Check that length is even */
+       if (i % 2)
+               goto fail;
+
+       mutex_lock(&chip->lock);
+
+       ret = lp5523_load_program(engine, pattern);
+       mutex_unlock(&chip->lock);
+
+       if (ret) {
+               dev_err(&client->dev, "failed loading pattern\n");
+               return ret;
+       }
+
+       return len;
+fail:
+       dev_err(&client->dev, "wrong pattern format\n");
+       return -EINVAL;
+}
+
+static ssize_t store_engine_load(struct device *dev,
+                                    struct device_attribute *attr,
+                                    const char *buf, size_t len, int nr)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5523_chip *chip = i2c_get_clientdata(client);
+       return lp5523_do_store_load(&chip->engines[nr - 1], buf, len);
+}
+
+#define store_load(nr)                                                 \
+static ssize_t store_engine##nr##_load(struct device *dev,             \
+                                    struct device_attribute *attr,     \
+                                    const char *buf, size_t len)       \
+{                                                                      \
+       return store_engine_load(dev, attr, buf, len, nr);              \
+}
+store_load(1)
+store_load(2)
+store_load(3)
+
+static ssize_t show_engine_mode(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf, int nr)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5523_chip *chip = i2c_get_clientdata(client);
+       switch (chip->engines[nr - 1].mode) {
+       case LP5523_CMD_RUN:
+               return sprintf(buf, "run\n");
+       case LP5523_CMD_LOAD:
+               return sprintf(buf, "load\n");
+       case LP5523_CMD_DISABLED:
+               return sprintf(buf, "disabled\n");
+       default:
+               return sprintf(buf, "disabled\n");
+       }
+}
+
+#define show_mode(nr)                                                  \
+static ssize_t show_engine##nr##_mode(struct device *dev,              \
+                                   struct device_attribute *attr,      \
+                                   char *buf)                          \
+{                                                                      \
+       return show_engine_mode(dev, attr, buf, nr);                    \
+}
+show_mode(1)
+show_mode(2)
+show_mode(3)
+
+static ssize_t store_engine_mode(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t len, int nr)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct lp5523_chip *chip = i2c_get_clientdata(client);
+       struct lp5523_engine *engine = &chip->engines[nr - 1];
+       mutex_lock(&chip->lock);
+
+       if (!strncmp(buf, "run", 3))
+               lp5523_set_mode(engine, LP5523_CMD_RUN);
+       else if (!strncmp(buf, "load", 4))
+               lp5523_set_mode(engine, LP5523_CMD_LOAD);
+       else if (!strncmp(buf, "disabled", 8))
+               lp5523_set_mode(engine, LP5523_CMD_DISABLED);
+
+       mutex_unlock(&chip->lock);
+       return len;
+}
+
+#define store_mode(nr)                                                 \
+static ssize_t store_engine##nr##_mode(struct device *dev,             \
+                                    struct device_attribute *attr,     \
+                                    const char *buf, size_t len)       \
+{                                                                      \
+       return store_engine_mode(dev, attr, buf, len, nr);              \
+}
+store_mode(1)
+store_mode(2)
+store_mode(3)
+
+static ssize_t show_max_current(struct device *dev,
+                           struct device_attribute *attr,
+                           char *buf)
+{
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct lp5523_led *led = cdev_to_led(led_cdev);
+
+       return sprintf(buf, "%d\n", led->max_current);
+}
+
+static ssize_t show_current(struct device *dev,
+                           struct device_attribute *attr,
+                           char *buf)
+{
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct lp5523_led *led = cdev_to_led(led_cdev);
+
+       return sprintf(buf, "%d\n", led->led_current);
+}
+
+static ssize_t store_current(struct device *dev,
+                            struct device_attribute *attr,
+                            const char *buf, size_t len)
+{
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct lp5523_led *led = cdev_to_led(led_cdev);
+       struct lp5523_chip *chip = led_to_lp5523(led);
+       ssize_t ret;
+       unsigned long curr;
+
+       if (strict_strtoul(buf, 0, &curr))
+               return -EINVAL;
+
+       if (curr > led->max_current)
+               return -EINVAL;
+
+       mutex_lock(&chip->lock);
+       ret = lp5523_write(chip->client,
+                       LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
+                       (u8)curr);
+       mutex_unlock(&chip->lock);
+
+       if (ret < 0)
+               return ret;
+
+       led->led_current = (u8)curr;
+
+       return len;
+}
+
+/* led class device attributes */
+static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current);
+static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
+
+static struct attribute *lp5523_led_attributes[] = {
+       &dev_attr_led_current.attr,
+       &dev_attr_max_current.attr,
+       NULL,
+};
+
+static struct attribute_group lp5523_led_attribute_group = {
+       .attrs = lp5523_led_attributes
+};
+
+/* device attributes */
+static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO,
+                  show_engine1_mode, store_engine1_mode);
+static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO,
+                  show_engine2_mode, store_engine2_mode);
+static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO,
+                  show_engine3_mode, store_engine3_mode);
+static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUGO,
+                  show_engine1_leds, store_engine1_leds);
+static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUGO,
+                  show_engine2_leds, store_engine2_leds);
+static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUGO,
+                  show_engine3_leds, store_engine3_leds);
+static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load);
+static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load);
+static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load);
+static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL);
+
+static struct attribute *lp5523_attributes[] = {
+       &dev_attr_engine1_mode.attr,
+       &dev_attr_engine2_mode.attr,
+       &dev_attr_engine3_mode.attr,
+       &dev_attr_selftest.attr,
+       NULL
+};
+
+static struct attribute *lp5523_engine1_attributes[] = {
+       &dev_attr_engine1_load.attr,
+       &dev_attr_engine1_leds.attr,
+       NULL
+};
+
+static struct attribute *lp5523_engine2_attributes[] = {
+       &dev_attr_engine2_load.attr,
+       &dev_attr_engine2_leds.attr,
+       NULL
+};
+
+static struct attribute *lp5523_engine3_attributes[] = {
+       &dev_attr_engine3_load.attr,
+       &dev_attr_engine3_leds.attr,
+       NULL
+};
+
+static const struct attribute_group lp5523_group = {
+       .attrs = lp5523_attributes,
+};
+
+static const struct attribute_group lp5523_engine_group[] = {
+       {.attrs = lp5523_engine1_attributes },
+       {.attrs = lp5523_engine2_attributes },
+       {.attrs = lp5523_engine3_attributes },
+};
+
+static int lp5523_register_sysfs(struct i2c_client *client)
+{
+       struct device *dev = &client->dev;
+       int ret;
+
+       ret = sysfs_create_group(&dev->kobj, &lp5523_group);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static void lp5523_unregister_sysfs(struct i2c_client *client)
+{
+       struct lp5523_chip *chip = i2c_get_clientdata(client);
+       struct device *dev = &client->dev;
+       int i;
+
+       sysfs_remove_group(&dev->kobj, &lp5523_group);
+
+       for (i = 0; i < ARRAY_SIZE(chip->engines); i++)
+               if (chip->engines[i].mode == LP5523_CMD_LOAD)
+                       sysfs_remove_group(&dev->kobj, &lp5523_engine_group[i]);
+
+       for (i = 0; i < chip->num_leds; i++)
+               sysfs_remove_group(&chip->leds[i].cdev.dev->kobj,
+                               &lp5523_led_attribute_group);
+}
+
+/*--------------------------------------------------------------*/
+/*                     Set chip operating mode                 */
+/*--------------------------------------------------------------*/
+static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode)
+{
+       /*  engine to chip */
+       struct lp5523_chip *chip = engine_to_lp5523(engine);
+       struct i2c_client *client = chip->client;
+       struct device *dev = &client->dev;
+       int ret = 0;
+
+       /* if in that mode already do nothing, except for run */
+       if (mode == engine->mode && mode != LP5523_CMD_RUN)
+               return 0;
+
+       if (mode == LP5523_CMD_RUN) {
+               ret = lp5523_run_program(engine);
+       } else if (mode == LP5523_CMD_LOAD) {
+               lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
+               lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
+
+               ret = sysfs_create_group(&dev->kobj, engine->attributes);
+               if (ret)
+                       return ret;
+       } else if (mode == LP5523_CMD_DISABLED) {
+               lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
+       }
+
+       /* remove load attribute from sysfs if not in load mode */
+       if (engine->mode == LP5523_CMD_LOAD && mode != LP5523_CMD_LOAD)
+               sysfs_remove_group(&dev->kobj, engine->attributes);
+
+       engine->mode = mode;
+
+       return ret;
+}
+
+/*--------------------------------------------------------------*/
+/*                     Probe, Attach, Remove                   */
+/*--------------------------------------------------------------*/
+static int __init lp5523_init_engine(struct lp5523_engine *engine, int id)
+{
+       if (id < 1 || id > LP5523_ENGINES)
+               return -1;
+       engine->id = id;
+       engine->engine_mask = LP5523_ENG_MASK_BASE >> SHIFT_MASK(id);
+       engine->prog_page = id - 1;
+       engine->mux_page = id + 2;
+       engine->attributes = &lp5523_engine_group[id - 1];
+
+       return 0;
+}
+
+static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev,
+                          int chan, struct lp5523_platform_data *pdata)
+{
+       char name[32];
+       int res;
+
+       if (chan >= LP5523_LEDS)
+               return -EINVAL;
+
+       if (pdata->led_config[chan].led_current) {
+               led->led_current = pdata->led_config[chan].led_current;
+               led->max_current = pdata->led_config[chan].max_current;
+               led->chan_nr = pdata->led_config[chan].chan_nr;
+
+               if (led->chan_nr >= LP5523_LEDS) {
+                       dev_err(dev, "Use channel numbers between 0 and %d\n",
+                               LP5523_LEDS - 1);
+                       return -EINVAL;
+               }
+
+               snprintf(name, 32, "lp5523:channel%d", chan);
+
+               led->cdev.name = name;
+               led->cdev.brightness_set = lp5523_set_brightness;
+               res = led_classdev_register(dev, &led->cdev);
+               if (res < 0) {
+                       dev_err(dev, "couldn't register led on channel %d\n",
+                               chan);
+                       return res;
+               }
+               res = sysfs_create_group(&led->cdev.dev->kobj,
+                               &lp5523_led_attribute_group);
+               if (res < 0) {
+                       dev_err(dev, "couldn't register current attribute\n");
+                       led_classdev_unregister(&led->cdev);
+                       return res;
+               }
+       } else {
+               led->led_current = 0;
+       }
+       return 0;
+}
+
+static struct i2c_driver lp5523_driver;
+
+static int lp5523_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       struct lp5523_chip              *chip;
+       struct lp5523_platform_data     *pdata;
+       int ret, i, led;
+
+       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, chip);
+       chip->client = client;
+
+       pdata = client->dev.platform_data;
+
+       if (!pdata) {
+               dev_err(&client->dev, "no platform data\n");
+               ret = -EINVAL;
+               goto fail1;
+       }
+
+       mutex_init(&chip->lock);
+
+       chip->pdata   = pdata;
+
+       if (pdata->setup_resources) {
+               ret = pdata->setup_resources();
+               if (ret < 0)
+                       goto fail1;
+       }
+
+       if (pdata->enable) {
+               pdata->enable(0);
+               usleep_range(1000, 10000);
+               pdata->enable(1);
+               usleep_range(1000, 10000); /* Spec says min 500us */
+       }
+
+       ret = lp5523_detect(client);
+       if (ret)
+               goto fail2;
+
+       dev_info(&client->dev, "LP5523 Programmable led chip found\n");
+
+       /* Initialize engines */
+       for (i = 0; i < ARRAY_SIZE(chip->engines); i++) {
+               ret = lp5523_init_engine(&chip->engines[i], i + 1);
+               if (ret) {
+                       dev_err(&client->dev, "error initializing engine\n");
+                       goto fail2;
+               }
+       }
+       ret = lp5523_configure(client);
+       if (ret < 0) {
+               dev_err(&client->dev, "error configuring chip\n");
+               goto fail2;
+       }
+
+       /* Initialize leds */
+       chip->num_channels = pdata->num_channels;
+       chip->num_leds = 0;
+       led = 0;
+       for (i = 0; i < pdata->num_channels; i++) {
+               /* Do not initialize channels that are not connected */
+               if (pdata->led_config[i].led_current == 0)
+                       continue;
+
+               ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata);
+               if (ret) {
+                       dev_err(&client->dev, "error initializing leds\n");
+                       goto fail3;
+               }
+               chip->num_leds++;
+
+               chip->leds[led].id = led;
+               /* Set LED current */
+               lp5523_write(client,
+                         LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr,
+                         chip->leds[led].led_current);
+
+               INIT_WORK(&(chip->leds[led].brightness_work),
+                       lp5523_led_brightness_work);
+
+               led++;
+       }
+
+       ret = lp5523_register_sysfs(client);
+       if (ret) {
+               dev_err(&client->dev, "registering sysfs failed\n");
+               goto fail3;
+       }
+       return ret;
+fail3:
+       for (i = 0; i < chip->num_leds; i++) {
+               led_classdev_unregister(&chip->leds[i].cdev);
+               cancel_work_sync(&chip->leds[i].brightness_work);
+       }
+fail2:
+       if (pdata->enable)
+               pdata->enable(0);
+       if (pdata->release_resources)
+               pdata->release_resources();
+fail1:
+       kfree(chip);
+       return ret;
+}
+
+static int lp5523_remove(struct i2c_client *client)
+{
+       struct lp5523_chip *chip = i2c_get_clientdata(client);
+       int i;
+
+       lp5523_unregister_sysfs(client);
+
+       for (i = 0; i < chip->num_leds; i++) {
+               led_classdev_unregister(&chip->leds[i].cdev);
+               cancel_work_sync(&chip->leds[i].brightness_work);
+       }
+
+       if (chip->pdata->enable)
+               chip->pdata->enable(0);
+       if (chip->pdata->release_resources)
+               chip->pdata->release_resources();
+       kfree(chip);
+       return 0;
+}
+
+static const struct i2c_device_id lp5523_id[] = {
+       { "lp5523", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, lp5523_id);
+
+static struct i2c_driver lp5523_driver = {
+       .driver = {
+               .name   = "lp5523",
+       },
+       .probe          = lp5523_probe,
+       .remove         = lp5523_remove,
+       .id_table       = lp5523_id,
+};
+
+static int __init lp5523_init(void)
+{
+       int ret;
+
+       ret = i2c_add_driver(&lp5523_driver);
+
+       if (ret < 0)
+               printk(KERN_ALERT "Adding lp5523 driver failed\n");
+
+       return ret;
+}
+
+static void __exit lp5523_exit(void)
+{
+       i2c_del_driver(&lp5523_driver);
+}
+
+module_init(lp5523_init);
+module_exit(lp5523_exit);
+
+MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>");
+MODULE_DESCRIPTION("LP5523 LED engine");
+MODULE_LICENSE("GPL");
index 3063f591f0dca0e0eb809bb4b490039d8bcf2943..1739557a903881a246c14d5047cca5a454081894 100644 (file)
@@ -92,3 +92,5 @@ unmap:
 }
 
 arch_initcall(soekris_init);
+
+MODULE_LICENSE("GPL");
index 82b77bd482ffdb4f952f0785c197db6efe1e8736..b09bcbeade9c433c56365204b4848690bf08a366 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
 #include <linux/device.h>
-#include <linux/sysdev.h>
-#include <linux/timer.h>
 #include <linux/ctype.h>
 #include <linux/leds.h>
-#include <linux/slab.h>
 #include "leds.h"
 
-struct timer_trig_data {
-       int brightness_on;              /* LED brightness during "on" period.
-                                        * (LED_OFF < brightness_on <= LED_FULL)
-                                        */
-       unsigned long delay_on;         /* milliseconds on */
-       unsigned long delay_off;        /* milliseconds off */
-       struct timer_list timer;
-};
-
-static void led_timer_function(unsigned long data)
-{
-       struct led_classdev *led_cdev = (struct led_classdev *) data;
-       struct timer_trig_data *timer_data = led_cdev->trigger_data;
-       unsigned long brightness;
-       unsigned long delay;
-
-       if (!timer_data->delay_on || !timer_data->delay_off) {
-               led_set_brightness(led_cdev, LED_OFF);
-               return;
-       }
-
-       brightness = led_get_brightness(led_cdev);
-       if (!brightness) {
-               /* Time to switch the LED on. */
-               brightness = timer_data->brightness_on;
-               delay = timer_data->delay_on;
-       } else {
-               /* Store the current brightness value to be able
-                * to restore it when the delay_off period is over.
-                */
-               timer_data->brightness_on = brightness;
-               brightness = LED_OFF;
-               delay = timer_data->delay_off;
-       }
-
-       led_set_brightness(led_cdev, brightness);
-
-       mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay));
-}
-
 static ssize_t led_delay_on_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
        struct led_classdev *led_cdev = dev_get_drvdata(dev);
-       struct timer_trig_data *timer_data = led_cdev->trigger_data;
 
-       return sprintf(buf, "%lu\n", timer_data->delay_on);
+       return sprintf(buf, "%lu\n", led_cdev->blink_delay_on);
 }
 
 static ssize_t led_delay_on_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t size)
 {
        struct led_classdev *led_cdev = dev_get_drvdata(dev);
-       struct timer_trig_data *timer_data = led_cdev->trigger_data;
        int ret = -EINVAL;
        char *after;
        unsigned long state = simple_strtoul(buf, &after, 10);
@@ -88,21 +40,7 @@ static ssize_t led_delay_on_store(struct device *dev,
                count++;
 
        if (count == size) {
-               if (timer_data->delay_on != state) {
-                       /* the new value differs from the previous */
-                       timer_data->delay_on = state;
-
-                       /* deactivate previous settings */
-                       del_timer_sync(&timer_data->timer);
-
-                       /* try to activate hardware acceleration, if any */
-                       if (!led_cdev->blink_set ||
-                           led_cdev->blink_set(led_cdev,
-                             &timer_data->delay_on, &timer_data->delay_off)) {
-                               /* no hardware acceleration, blink via timer */
-                               mod_timer(&timer_data->timer, jiffies + 1);
-                       }
-               }
+               led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off);
                ret = count;
        }
 
@@ -113,16 +51,14 @@ static ssize_t led_delay_off_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
        struct led_classdev *led_cdev = dev_get_drvdata(dev);
-       struct timer_trig_data *timer_data = led_cdev->trigger_data;
 
-       return sprintf(buf, "%lu\n", timer_data->delay_off);
+       return sprintf(buf, "%lu\n", led_cdev->blink_delay_off);
 }
 
 static ssize_t led_delay_off_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t size)
 {
        struct led_classdev *led_cdev = dev_get_drvdata(dev);
-       struct timer_trig_data *timer_data = led_cdev->trigger_data;
        int ret = -EINVAL;
        char *after;
        unsigned long state = simple_strtoul(buf, &after, 10);
@@ -132,21 +68,7 @@ static ssize_t led_delay_off_store(struct device *dev,
                count++;
 
        if (count == size) {
-               if (timer_data->delay_off != state) {
-                       /* the new value differs from the previous */
-                       timer_data->delay_off = state;
-
-                       /* deactivate previous settings */
-                       del_timer_sync(&timer_data->timer);
-
-                       /* try to activate hardware acceleration, if any */
-                       if (!led_cdev->blink_set ||
-                           led_cdev->blink_set(led_cdev,
-                             &timer_data->delay_on, &timer_data->delay_off)) {
-                               /* no hardware acceleration, blink via timer */
-                               mod_timer(&timer_data->timer, jiffies + 1);
-                       }
-               }
+               led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state);
                ret = count;
        }
 
@@ -158,60 +80,34 @@ static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store);
 
 static void timer_trig_activate(struct led_classdev *led_cdev)
 {
-       struct timer_trig_data *timer_data;
        int rc;
 
-       timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL);
-       if (!timer_data)
-               return;
-
-       timer_data->brightness_on = led_get_brightness(led_cdev);
-       if (timer_data->brightness_on == LED_OFF)
-               timer_data->brightness_on = led_cdev->max_brightness;
-       led_cdev->trigger_data = timer_data;
-
-       init_timer(&timer_data->timer);
-       timer_data->timer.function = led_timer_function;
-       timer_data->timer.data = (unsigned long) led_cdev;
+       led_cdev->trigger_data = NULL;
 
        rc = device_create_file(led_cdev->dev, &dev_attr_delay_on);
        if (rc)
-               goto err_out;
+               return;
        rc = device_create_file(led_cdev->dev, &dev_attr_delay_off);
        if (rc)
                goto err_out_delayon;
 
-       /* If there is hardware support for blinking, start one
-        * user friendly blink rate chosen by the driver.
-        */
-       if (led_cdev->blink_set)
-               led_cdev->blink_set(led_cdev,
-                       &timer_data->delay_on, &timer_data->delay_off);
+       led_cdev->trigger_data = (void *)1;
 
        return;
 
 err_out_delayon:
        device_remove_file(led_cdev->dev, &dev_attr_delay_on);
-err_out:
-       led_cdev->trigger_data = NULL;
-       kfree(timer_data);
 }
 
 static void timer_trig_deactivate(struct led_classdev *led_cdev)
 {
-       struct timer_trig_data *timer_data = led_cdev->trigger_data;
-       unsigned long on = 0, off = 0;
-
-       if (timer_data) {
+       if (led_cdev->trigger_data) {
                device_remove_file(led_cdev->dev, &dev_attr_delay_on);
                device_remove_file(led_cdev->dev, &dev_attr_delay_off);
-               del_timer_sync(&timer_data->timer);
-               kfree(timer_data);
        }
 
-       /* If there is hardware support for blinking, stop it */
-       if (led_cdev->blink_set)
-               led_cdev->blink_set(led_cdev, &on, &off);
+       /* Stop blinking */
+       led_brightness_set(led_cdev, LED_OFF);
 }
 
 static struct led_trigger timer_led_trigger = {
index 444696625171e42a6948eb858299a8a489626510..f5f4da3d0b675644963af93f327f03f455368bd8 100644 (file)
@@ -80,7 +80,7 @@ static void adb_iop_end_req(struct adb_request *req, int state)
 static void adb_iop_complete(struct iop_msg *msg)
 {
        struct adb_request *req;
-       uint flags;
+       unsigned long flags;
 
        local_irq_save(flags);
 
@@ -103,7 +103,7 @@ static void adb_iop_listen(struct iop_msg *msg)
 {
        struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message;
        struct adb_request *req;
-       uint flags;
+       unsigned long flags;
 #ifdef DEBUG_ADB_IOP
        int i;
 #endif
index e4fb58db5454d4bfc5cc5257bb74435907b3b3f2..5a1ffe3527aadbdac87f6a31773fcf02e728a765 100644 (file)
@@ -212,7 +212,7 @@ static struct page *read_sb_page(mddev_t *mddev, loff_t offset,
 
                target = rdev->sb_start + offset + index * (PAGE_SIZE/512);
 
-               if (sync_page_io(rdev->bdev, target,
+               if (sync_page_io(rdev, target,
                                 roundup(size, bdev_logical_block_size(rdev->bdev)),
                                 page, READ)) {
                        page->index = index;
@@ -343,7 +343,7 @@ static void write_page(struct bitmap *bitmap, struct page *page, int wait)
                        atomic_inc(&bitmap->pending_writes);
                        set_buffer_locked(bh);
                        set_buffer_mapped(bh);
-                       submit_bh(WRITE, bh);
+                       submit_bh(WRITE | REQ_UNPLUG | REQ_SYNC, bh);
                        bh = bh->b_this_page;
                }
 
@@ -1101,7 +1101,7 @@ static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc)
        bitmap_checkfree(bitmap, page);
 }
 static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
-                                           sector_t offset, int *blocks,
+                                           sector_t offset, sector_t *blocks,
                                            int create);
 
 /*
@@ -1115,7 +1115,7 @@ void bitmap_daemon_work(mddev_t *mddev)
        unsigned long j;
        unsigned long flags;
        struct page *page = NULL, *lastpage = NULL;
-       int blocks;
+       sector_t blocks;
        void *paddr;
        struct dm_dirty_log *log = mddev->bitmap_info.log;
 
@@ -1258,7 +1258,7 @@ void bitmap_daemon_work(mddev_t *mddev)
 }
 
 static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
-                                           sector_t offset, int *blocks,
+                                           sector_t offset, sector_t *blocks,
                                            int create)
 __releases(bitmap->lock)
 __acquires(bitmap->lock)
@@ -1316,7 +1316,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
        }
 
        while (sectors) {
-               int blocks;
+               sector_t blocks;
                bitmap_counter_t *bmc;
 
                spin_lock_irq(&bitmap->lock);
@@ -1381,7 +1381,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
                success = 0;
 
        while (sectors) {
-               int blocks;
+               sector_t blocks;
                unsigned long flags;
                bitmap_counter_t *bmc;
 
@@ -1423,7 +1423,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
 }
 EXPORT_SYMBOL(bitmap_endwrite);
 
-static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
                               int degraded)
 {
        bitmap_counter_t *bmc;
@@ -1452,7 +1452,7 @@ static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *bloc
        return rv;
 }
 
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
                      int degraded)
 {
        /* bitmap_start_sync must always report on multiples of whole
@@ -1463,7 +1463,7 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
         * Return the 'or' of the result.
         */
        int rv = 0;
-       int blocks1;
+       sector_t blocks1;
 
        *blocks = 0;
        while (*blocks < (PAGE_SIZE>>9)) {
@@ -1476,7 +1476,7 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
 }
 EXPORT_SYMBOL(bitmap_start_sync);
 
-void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
+void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted)
 {
        bitmap_counter_t *bmc;
        unsigned long flags;
@@ -1515,7 +1515,7 @@ void bitmap_close_sync(struct bitmap *bitmap)
         * RESYNC bit wherever it is still on
         */
        sector_t sector = 0;
-       int blocks;
+       sector_t blocks;
        if (!bitmap)
                return;
        while (sector < bitmap->mddev->resync_max_sectors) {
@@ -1528,7 +1528,7 @@ EXPORT_SYMBOL(bitmap_close_sync);
 void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
 {
        sector_t s = 0;
-       int blocks;
+       sector_t blocks;
 
        if (!bitmap)
                return;
@@ -1562,7 +1562,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
         * be 0 at this point
         */
 
-       int secs;
+       sector_t secs;
        bitmap_counter_t *bmc;
        spin_lock_irq(&bitmap->lock);
        bmc = bitmap_get_counter(bitmap, offset, &secs, 1);
@@ -1790,7 +1790,7 @@ int bitmap_load(mddev_t *mddev)
         * All chunks should be clean, but some might need_sync.
         */
        while (sector < mddev->resync_max_sectors) {
-               int blocks;
+               sector_t blocks;
                bitmap_start_sync(bitmap, sector, &blocks, 0);
                sector += blocks;
        }
index e872a7bad6b8feeeb610e9da689aaf5b29826ba2..931a7a7c3796e5f389537579c65fa9364a0567b8 100644 (file)
@@ -271,8 +271,8 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset,
                        unsigned long sectors, int behind);
 void bitmap_endwrite(struct bitmap *bitmap, sector_t offset,
                        unsigned long sectors, int success, int behind);
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded);
-void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int degraded);
+void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted);
 void bitmap_close_sync(struct bitmap *bitmap);
 void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector);
 
index 1a898788461429d45929494f9aaf2faf1fe5d4c1..339fdc670751c086e760d89cedd22937b5639a7f 100644 (file)
@@ -210,7 +210,7 @@ static int make_request(mddev_t *mddev, struct bio *bio)
                }
        }
        if (failit) {
-               struct bio *b = bio_clone(bio, GFP_NOIO);
+               struct bio *b = bio_clone_mddev(bio, GFP_NOIO, mddev);
                b->bi_bdev = conf->rdev->bdev;
                b->bi_private = bio;
                b->bi_end_io = faulty_fail;
index 225815197a3d69fba134433ab269d0c9a255681b..324a3663fcdaa35dc9d0553f532543aa8019dd38 100644 (file)
@@ -57,8 +57,6 @@
 #define DEBUG 0
 #define dprintk(x...) ((void)(DEBUG && printk(x)))
 
-static DEFINE_MUTEX(md_mutex);
-
 #ifndef MODULE
 static void autostart_arrays(int part);
 #endif
@@ -69,6 +67,8 @@ static DEFINE_SPINLOCK(pers_lock);
 static void md_print_devices(void);
 
 static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
+static struct workqueue_struct *md_wq;
+static struct workqueue_struct *md_misc_wq;
 
 #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); }
 
@@ -149,6 +149,72 @@ static const struct block_device_operations md_fops;
 
 static int start_readonly;
 
+/* bio_clone_mddev
+ * like bio_clone, but with a local bio set
+ */
+
+static void mddev_bio_destructor(struct bio *bio)
+{
+       mddev_t *mddev, **mddevp;
+
+       mddevp = (void*)bio;
+       mddev = mddevp[-1];
+
+       bio_free(bio, mddev->bio_set);
+}
+
+struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
+                           mddev_t *mddev)
+{
+       struct bio *b;
+       mddev_t **mddevp;
+
+       if (!mddev || !mddev->bio_set)
+               return bio_alloc(gfp_mask, nr_iovecs);
+
+       b = bio_alloc_bioset(gfp_mask, nr_iovecs,
+                            mddev->bio_set);
+       if (!b)
+               return NULL;
+       mddevp = (void*)b;
+       mddevp[-1] = mddev;
+       b->bi_destructor = mddev_bio_destructor;
+       return b;
+}
+EXPORT_SYMBOL_GPL(bio_alloc_mddev);
+
+struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
+                           mddev_t *mddev)
+{
+       struct bio *b;
+       mddev_t **mddevp;
+
+       if (!mddev || !mddev->bio_set)
+               return bio_clone(bio, gfp_mask);
+
+       b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs,
+                            mddev->bio_set);
+       if (!b)
+               return NULL;
+       mddevp = (void*)b;
+       mddevp[-1] = mddev;
+       b->bi_destructor = mddev_bio_destructor;
+       __bio_clone(b, bio);
+       if (bio_integrity(bio)) {
+               int ret;
+
+               ret = bio_integrity_clone(b, bio, gfp_mask, mddev->bio_set);
+
+               if (ret < 0) {
+                       bio_put(b);
+                       return NULL;
+               }
+       }
+
+       return b;
+}
+EXPORT_SYMBOL_GPL(bio_clone_mddev);
+
 /*
  * We have a system wide 'event count' that is incremented
  * on any 'interesting' event, and readers of /proc/mdstat
@@ -300,7 +366,7 @@ static void md_end_flush(struct bio *bio, int err)
 
        if (atomic_dec_and_test(&mddev->flush_pending)) {
                /* The pre-request flush has finished */
-               schedule_work(&mddev->flush_work);
+               queue_work(md_wq, &mddev->flush_work);
        }
        bio_put(bio);
 }
@@ -321,7 +387,7 @@ static void submit_flushes(mddev_t *mddev)
                        atomic_inc(&rdev->nr_pending);
                        atomic_inc(&rdev->nr_pending);
                        rcu_read_unlock();
-                       bi = bio_alloc(GFP_KERNEL, 0);
+                       bi = bio_alloc_mddev(GFP_KERNEL, 0, mddev);
                        bi->bi_end_io = md_end_flush;
                        bi->bi_private = rdev;
                        bi->bi_bdev = rdev->bdev;
@@ -369,7 +435,7 @@ void md_flush_request(mddev_t *mddev, struct bio *bio)
        submit_flushes(mddev);
 
        if (atomic_dec_and_test(&mddev->flush_pending))
-               schedule_work(&mddev->flush_work);
+               queue_work(md_wq, &mddev->flush_work);
 }
 EXPORT_SYMBOL(md_flush_request);
 
@@ -428,6 +494,8 @@ static void mddev_delayed_delete(struct work_struct *ws);
 
 static void mddev_put(mddev_t *mddev)
 {
+       struct bio_set *bs = NULL;
+
        if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
                return;
        if (!mddev->raid_disks && list_empty(&mddev->disks) &&
@@ -435,19 +503,22 @@ static void mddev_put(mddev_t *mddev)
                /* Array is not configured at all, and not held active,
                 * so destroy it */
                list_del(&mddev->all_mddevs);
+               bs = mddev->bio_set;
+               mddev->bio_set = NULL;
                if (mddev->gendisk) {
-                       /* we did a probe so need to clean up.
-                        * Call schedule_work inside the spinlock
-                        * so that flush_scheduled_work() after
-                        * mddev_find will succeed in waiting for the
-                        * work to be done.
+                       /* We did a probe so need to clean up.  Call
+                        * queue_work inside the spinlock so that
+                        * flush_workqueue() after mddev_find will
+                        * succeed in waiting for the work to be done.
                         */
                        INIT_WORK(&mddev->del_work, mddev_delayed_delete);
-                       schedule_work(&mddev->del_work);
+                       queue_work(md_misc_wq, &mddev->del_work);
                } else
                        kfree(mddev);
        }
        spin_unlock(&all_mddevs_lock);
+       if (bs)
+               bioset_free(bs);
 }
 
 void mddev_init(mddev_t *mddev)
@@ -635,7 +706,7 @@ static struct mdk_personality *find_pers(int level, char *clevel)
 /* return the offset of the super block in 512byte sectors */
 static inline sector_t calc_dev_sboffset(struct block_device *bdev)
 {
-       sector_t num_sectors = bdev->bd_inode->i_size / 512;
+       sector_t num_sectors = i_size_read(bdev->bd_inode) / 512;
        return MD_NEW_SIZE_SECTORS(num_sectors);
 }
 
@@ -691,7 +762,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
         * if zero is reached.
         * If an error occurred, call md_error
         */
-       struct bio *bio = bio_alloc(GFP_NOIO, 1);
+       struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, mddev);
 
        bio->bi_bdev = rdev->bdev;
        bio->bi_sector = sector;
@@ -722,16 +793,16 @@ static void bi_complete(struct bio *bio, int error)
        complete((struct completion*)bio->bi_private);
 }
 
-int sync_page_io(struct block_device *bdev, sector_t sector, int size,
-                  struct page *page, int rw)
+int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size,
+                struct page *page, int rw)
 {
-       struct bio *bio = bio_alloc(GFP_NOIO, 1);
+       struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, rdev->mddev);
        struct completion event;
        int ret;
 
        rw |= REQ_SYNC | REQ_UNPLUG;
 
-       bio->bi_bdev = bdev;
+       bio->bi_bdev = rdev->bdev;
        bio->bi_sector = sector;
        bio_add_page(bio, page, size, 0);
        init_completion(&event);
@@ -757,7 +828,7 @@ static int read_disk_sb(mdk_rdev_t * rdev, int size)
                return 0;
 
 
-       if (!sync_page_io(rdev->bdev, rdev->sb_start, size, rdev->sb_page, READ))
+       if (!sync_page_io(rdev, rdev->sb_start, size, rdev->sb_page, READ))
                goto fail;
        rdev->sb_loaded = 1;
        return 0;
@@ -1315,7 +1386,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
         */
        switch(minor_version) {
        case 0:
-               sb_start = rdev->bdev->bd_inode->i_size >> 9;
+               sb_start = i_size_read(rdev->bdev->bd_inode) >> 9;
                sb_start -= 8*2;
                sb_start &= ~(sector_t)(4*2-1);
                break;
@@ -1401,7 +1472,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
                        ret = 0;
        }
        if (minor_version)
-               rdev->sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+               rdev->sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) -
                        le64_to_cpu(sb->data_offset);
        else
                rdev->sectors = rdev->sb_start;
@@ -1609,7 +1680,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
                return 0; /* component must fit device */
        if (rdev->sb_start < rdev->data_offset) {
                /* minor versions 1 and 2; superblock before data */
-               max_sectors = rdev->bdev->bd_inode->i_size >> 9;
+               max_sectors = i_size_read(rdev->bdev->bd_inode) >> 9;
                max_sectors -= rdev->data_offset;
                if (!num_sectors || num_sectors > max_sectors)
                        num_sectors = max_sectors;
@@ -1619,7 +1690,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
        } else {
                /* minor version 0; superblock after data */
                sector_t sb_start;
-               sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2;
+               sb_start = (i_size_read(rdev->bdev->bd_inode) >> 9) - 8*2;
                sb_start &= ~(sector_t)(4*2 - 1);
                max_sectors = rdev->sectors + sb_start - rdev->sb_start;
                if (!num_sectors || num_sectors > max_sectors)
@@ -1850,7 +1921,7 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
        synchronize_rcu();
        INIT_WORK(&rdev->del_work, md_delayed_delete);
        kobject_get(&rdev->kobj);
-       schedule_work(&rdev->del_work);
+       queue_work(md_misc_wq, &rdev->del_work);
 }
 
 /*
@@ -2108,6 +2179,8 @@ repeat:
        if (!mddev->persistent) {
                clear_bit(MD_CHANGE_CLEAN, &mddev->flags);
                clear_bit(MD_CHANGE_DEVS, &mddev->flags);
+               if (!mddev->external)
+                       clear_bit(MD_CHANGE_PENDING, &mddev->flags);
                wake_up(&mddev->sb_wait);
                return;
        }
@@ -2511,7 +2584,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                        if (!sectors)
                                return -EBUSY;
                } else if (!sectors)
-                       sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+                       sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) -
                                rdev->data_offset;
        }
        if (sectors < my_mddev->dev_sectors)
@@ -2724,7 +2797,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
 
        kobject_init(&rdev->kobj, &rdev_ktype);
 
-       size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
+       size = i_size_read(rdev->bdev->bd_inode) >> BLOCK_SIZE_BITS;
        if (!size) {
                printk(KERN_WARNING 
                        "md: %s has zero or unknown size, marking faulty!\n",
@@ -4192,10 +4265,10 @@ static int md_alloc(dev_t dev, char *name)
        shift = partitioned ? MdpMinorShift : 0;
        unit = MINOR(mddev->unit) >> shift;
 
-       /* wait for any previous instance if this device
-        * to be completed removed (mddev_delayed_delete).
+       /* wait for any previous instance of this device to be
+        * completely removed (mddev_delayed_delete).
         */
-       flush_scheduled_work();
+       flush_workqueue(md_misc_wq);
 
        mutex_lock(&disks_mutex);
        error = -EEXIST;
@@ -4378,6 +4451,9 @@ int md_run(mddev_t *mddev)
                sysfs_notify_dirent_safe(rdev->sysfs_state);
        }
 
+       if (mddev->bio_set == NULL)
+               mddev->bio_set = bioset_create(BIO_POOL_SIZE, sizeof(mddev));
+
        spin_lock(&pers_lock);
        pers = find_pers(mddev->level, mddev->clevel);
        if (!pers || !try_module_get(pers->owner)) {
@@ -5159,8 +5235,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
 
                if (!mddev->persistent) {
                        printk(KERN_INFO "md: nonpersistent superblock ...\n");
-                       rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
-               } else 
+                       rdev->sb_start = i_size_read(rdev->bdev->bd_inode) / 512;
+               } else
                        rdev->sb_start = calc_dev_sboffset(rdev->bdev);
                rdev->sectors = rdev->sb_start;
 
@@ -5230,7 +5306,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
        if (mddev->persistent)
                rdev->sb_start = calc_dev_sboffset(rdev->bdev);
        else
-               rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
+               rdev->sb_start = i_size_read(rdev->bdev->bd_inode) / 512;
 
        rdev->sectors = rdev->sb_start;
 
@@ -5885,16 +5961,14 @@ static int md_open(struct block_device *bdev, fmode_t mode)
        mddev_t *mddev = mddev_find(bdev->bd_dev);
        int err;
 
-       mutex_lock(&md_mutex);
        if (mddev->gendisk != bdev->bd_disk) {
                /* we are racing with mddev_put which is discarding this
                 * bd_disk.
                 */
                mddev_put(mddev);
                /* Wait until bdev->bd_disk is definitely gone */
-               flush_scheduled_work();
+               flush_workqueue(md_misc_wq);
                /* Then retry the open from the top */
-               mutex_unlock(&md_mutex);
                return -ERESTARTSYS;
        }
        BUG_ON(mddev != bdev->bd_disk->private_data);
@@ -5908,7 +5982,6 @@ static int md_open(struct block_device *bdev, fmode_t mode)
 
        check_disk_size_change(mddev->gendisk, bdev);
  out:
-       mutex_unlock(&md_mutex);
        return err;
 }
 
@@ -5917,10 +5990,8 @@ static int md_release(struct gendisk *disk, fmode_t mode)
        mddev_t *mddev = disk->private_data;
 
        BUG_ON(!mddev);
-       mutex_lock(&md_mutex);
        atomic_dec(&mddev->openers);
        mddev_put(mddev);
-       mutex_unlock(&md_mutex);
 
        return 0;
 }
@@ -6052,7 +6123,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
        md_wakeup_thread(mddev->thread);
        if (mddev->event_work.func)
-               schedule_work(&mddev->event_work);
+               queue_work(md_misc_wq, &mddev->event_work);
        md_new_event_inintr(mddev);
 }
 
@@ -7212,12 +7283,23 @@ static void md_geninit(void)
 
 static int __init md_init(void)
 {
-       if (register_blkdev(MD_MAJOR, "md"))
-               return -1;
-       if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
-               unregister_blkdev(MD_MAJOR, "md");
-               return -1;
-       }
+       int ret = -ENOMEM;
+
+       md_wq = alloc_workqueue("md", WQ_RESCUER, 0);
+       if (!md_wq)
+               goto err_wq;
+
+       md_misc_wq = alloc_workqueue("md_misc", 0, 0);
+       if (!md_misc_wq)
+               goto err_misc_wq;
+
+       if ((ret = register_blkdev(MD_MAJOR, "md")) < 0)
+               goto err_md;
+
+       if ((ret = register_blkdev(0, "mdp")) < 0)
+               goto err_mdp;
+       mdp_major = ret;
+
        blk_register_region(MKDEV(MD_MAJOR, 0), 1UL<<MINORBITS, THIS_MODULE,
                            md_probe, NULL, NULL);
        blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
@@ -7228,8 +7310,16 @@ static int __init md_init(void)
 
        md_geninit();
        return 0;
-}
 
+err_mdp:
+       unregister_blkdev(MD_MAJOR, "md");
+err_md:
+       destroy_workqueue(md_misc_wq);
+err_misc_wq:
+       destroy_workqueue(md_wq);
+err_wq:
+       return ret;
+}
 
 #ifndef MODULE
 
@@ -7316,6 +7406,8 @@ static __exit void md_exit(void)
                export_array(mddev);
                mddev->hold_active = 0;
        }
+       destroy_workqueue(md_misc_wq);
+       destroy_workqueue(md_wq);
 }
 
 subsys_initcall(md_init);
index 112a2c32db0cb4b613b5c784bff0638f717ad791..d05bab55df4e7d3b49a500ad196610bfd1d2e67c 100644 (file)
@@ -331,6 +331,8 @@ struct mddev_s
        struct attribute_group          *to_remove;
        struct plug_handle              *plug; /* if used by personality */
 
+       struct bio_set                  *bio_set;
+
        /* Generic flush handling.
         * The last to finish preflush schedules a worker to submit
         * the rest of the request (without the REQ_FLUSH flag).
@@ -495,7 +497,7 @@ extern void md_flush_request(mddev_t *mddev, struct bio *bio);
 extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
                           sector_t sector, int size, struct page *page);
 extern void md_super_wait(mddev_t *mddev);
-extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
+extern int sync_page_io(mdk_rdev_t *rdev, sector_t sector, int size,
                        struct page *page, int rw);
 extern void md_do_sync(mddev_t *mddev);
 extern void md_new_event(mddev_t *mddev);
@@ -517,4 +519,8 @@ extern void md_rdev_init(mdk_rdev_t *rdev);
 
 extern void mddev_suspend(mddev_t *mddev);
 extern void mddev_resume(mddev_t *mddev);
+extern struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
+                                  mddev_t *mddev);
+extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
+                                  mddev_t *mddev);
 #endif /* _MD_MD_H */
index 378a25894c57755afa27ab4fe87fd46f74834a97..45f8324196ec61c86cd7164868e3f8bc66ada03c 100644 (file)
@@ -100,7 +100,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
         * Allocate bios : 1 for reading, n-1 for writing
         */
        for (j = pi->raid_disks ; j-- ; ) {
-               bio = bio_alloc(gfp_flags, RESYNC_PAGES);
+               bio = bio_kmalloc(gfp_flags, RESYNC_PAGES);
                if (!bio)
                        goto out_free_bio;
                r1_bio->bios[j] = bio;
@@ -306,6 +306,28 @@ static void raid1_end_read_request(struct bio *bio, int error)
        rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
 }
 
+static void r1_bio_write_done(r1bio_t *r1_bio, int vcnt, struct bio_vec *bv,
+                             int behind)
+{
+       if (atomic_dec_and_test(&r1_bio->remaining))
+       {
+               /* it really is the end of this request */
+               if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
+                       /* free extra copy of the data pages */
+                       int i = vcnt;
+                       while (i--)
+                               safe_put_page(bv[i].bv_page);
+               }
+               /* clear the bitmap if all writes complete successfully */
+               bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
+                               r1_bio->sectors,
+                               !test_bit(R1BIO_Degraded, &r1_bio->state),
+                               behind);
+               md_write_end(r1_bio->mddev);
+               raid_end_bio_io(r1_bio);
+       }
+}
+
 static void raid1_end_write_request(struct bio *bio, int error)
 {
        int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
@@ -373,21 +395,7 @@ static void raid1_end_write_request(struct bio *bio, int error)
         * Let's see if all mirrored write operations have finished
         * already.
         */
-       if (atomic_dec_and_test(&r1_bio->remaining)) {
-               if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
-                       /* free extra copy of the data pages */
-                       int i = bio->bi_vcnt;
-                       while (i--)
-                               safe_put_page(bio->bi_io_vec[i].bv_page);
-               }
-               /* clear the bitmap if all writes complete successfully */
-               bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
-                               r1_bio->sectors,
-                               !test_bit(R1BIO_Degraded, &r1_bio->state),
-                               behind);
-               md_write_end(r1_bio->mddev);
-               raid_end_bio_io(r1_bio);
-       }
+       r1_bio_write_done(r1_bio, bio->bi_vcnt, bio->bi_io_vec, behind);
 
        if (to_put)
                bio_put(to_put);
@@ -411,11 +419,13 @@ static void raid1_end_write_request(struct bio *bio, int error)
 static int read_balance(conf_t *conf, r1bio_t *r1_bio)
 {
        const sector_t this_sector = r1_bio->sector;
-       int new_disk = conf->last_used, disk = new_disk;
-       int wonly_disk = -1;
        const int sectors = r1_bio->sectors;
+       int new_disk = -1;
+       int start_disk;
+       int i;
        sector_t new_distance, current_distance;
        mdk_rdev_t *rdev;
+       int choose_first;
 
        rcu_read_lock();
        /*
@@ -426,54 +436,33 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
  retry:
        if (conf->mddev->recovery_cp < MaxSector &&
            (this_sector + sectors >= conf->next_resync)) {
-               /* Choose the first operational device, for consistancy */
-               new_disk = 0;
-
-               for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
-                    r1_bio->bios[new_disk] == IO_BLOCKED ||
-                    !rdev || !test_bit(In_sync, &rdev->flags)
-                            || test_bit(WriteMostly, &rdev->flags);
-                    rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) {
-
-                       if (rdev && test_bit(In_sync, &rdev->flags) &&
-                               r1_bio->bios[new_disk] != IO_BLOCKED)
-                               wonly_disk = new_disk;
-
-                       if (new_disk == conf->raid_disks - 1) {
-                               new_disk = wonly_disk;
-                               break;
-                       }
-               }
-               goto rb_out;
+               choose_first = 1;
+               start_disk = 0;
+       } else {
+               choose_first = 0;
+               start_disk = conf->last_used;
        }
 
-
        /* make sure the disk is operational */
-       for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
-            r1_bio->bios[new_disk] == IO_BLOCKED ||
-            !rdev || !test_bit(In_sync, &rdev->flags) ||
-                    test_bit(WriteMostly, &rdev->flags);
-            rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) {
-
-               if (rdev && test_bit(In_sync, &rdev->flags) &&
-                   r1_bio->bios[new_disk] != IO_BLOCKED)
-                       wonly_disk = new_disk;
-
-               if (new_disk <= 0)
-                       new_disk = conf->raid_disks;
-               new_disk--;
-               if (new_disk == disk) {
-                       new_disk = wonly_disk;
+       for (i = 0 ; i < conf->raid_disks ; i++) {
+               int disk = start_disk + i;
+               if (disk >= conf->raid_disks)
+                       disk -= conf->raid_disks;
+
+               rdev = rcu_dereference(conf->mirrors[disk].rdev);
+               if (r1_bio->bios[disk] == IO_BLOCKED
+                   || rdev == NULL
+                   || !test_bit(In_sync, &rdev->flags))
+                       continue;
+
+               new_disk = disk;
+               if (!test_bit(WriteMostly, &rdev->flags))
                        break;
-               }
        }
 
-       if (new_disk < 0)
+       if (new_disk < 0 || choose_first)
                goto rb_out;
 
-       disk = new_disk;
-       /* now disk == new_disk == starting point for search */
-
        /*
         * Don't change to another disk for sequential reads:
         */
@@ -482,20 +471,21 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
        if (this_sector == conf->mirrors[new_disk].head_position)
                goto rb_out;
 
-       current_distance = abs(this_sector - conf->mirrors[disk].head_position);
-
-       /* Find the disk whose head is closest */
+       current_distance = abs(this_sector 
+                              - conf->mirrors[new_disk].head_position);
 
-       do {
-               if (disk <= 0)
-                       disk = conf->raid_disks;
-               disk--;
+       /* look for a better disk - i.e. head is closer */
+       start_disk = new_disk;
+       for (i = 1; i < conf->raid_disks; i++) {
+               int disk = start_disk + 1;
+               if (disk >= conf->raid_disks)
+                       disk -= conf->raid_disks;
 
                rdev = rcu_dereference(conf->mirrors[disk].rdev);
-
-               if (!rdev || r1_bio->bios[disk] == IO_BLOCKED ||
-                   !test_bit(In_sync, &rdev->flags) ||
-                   test_bit(WriteMostly, &rdev->flags))
+               if (r1_bio->bios[disk] == IO_BLOCKED
+                   || rdev == NULL
+                   || !test_bit(In_sync, &rdev->flags)
+                   || test_bit(WriteMostly, &rdev->flags))
                        continue;
 
                if (!atomic_read(&rdev->nr_pending)) {
@@ -507,11 +497,9 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
                        current_distance = new_distance;
                        new_disk = disk;
                }
-       } while (disk != conf->last_used);
+       }
 
  rb_out:
-
-
        if (new_disk >= 0) {
                rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
                if (!rdev)
@@ -658,7 +646,7 @@ static void raise_barrier(conf_t *conf)
        /* block any new IO from starting */
        conf->barrier++;
 
-       /* No wait for all pending IO to complete */
+       /* Now wait for all pending IO to complete */
        wait_event_lock_irq(conf->wait_barrier,
                            !conf->nr_pending && conf->barrier < RESYNC_DEPTH,
                            conf->resync_lock,
@@ -735,23 +723,26 @@ static void unfreeze_array(conf_t *conf)
 }
 
 
-/* duplicate the data pages for behind I/O */
-static struct page **alloc_behind_pages(struct bio *bio)
+/* duplicate the data pages for behind I/O 
+ * We return a list of bio_vec rather than just page pointers
+ * as it makes freeing easier
+ */
+static struct bio_vec *alloc_behind_pages(struct bio *bio)
 {
        int i;
        struct bio_vec *bvec;
-       struct page **pages = kzalloc(bio->bi_vcnt * sizeof(struct page *),
+       struct bio_vec *pages = kzalloc(bio->bi_vcnt * sizeof(struct bio_vec),
                                        GFP_NOIO);
        if (unlikely(!pages))
                goto do_sync_io;
 
        bio_for_each_segment(bvec, bio, i) {
-               pages[i] = alloc_page(GFP_NOIO);
-               if (unlikely(!pages[i]))
+               pages[i].bv_page = alloc_page(GFP_NOIO);
+               if (unlikely(!pages[i].bv_page))
                        goto do_sync_io;
-               memcpy(kmap(pages[i]) + bvec->bv_offset,
+               memcpy(kmap(pages[i].bv_page) + bvec->bv_offset,
                        kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len);
-               kunmap(pages[i]);
+               kunmap(pages[i].bv_page);
                kunmap(bvec->bv_page);
        }
 
@@ -759,8 +750,8 @@ static struct page **alloc_behind_pages(struct bio *bio)
 
 do_sync_io:
        if (pages)
-               for (i = 0; i < bio->bi_vcnt && pages[i]; i++)
-                       put_page(pages[i]);
+               for (i = 0; i < bio->bi_vcnt && pages[i].bv_page; i++)
+                       put_page(pages[i].bv_page);
        kfree(pages);
        PRINTK("%dB behind alloc failed, doing sync I/O\n", bio->bi_size);
        return NULL;
@@ -775,8 +766,7 @@ static int make_request(mddev_t *mddev, struct bio * bio)
        int i, targets = 0, disks;
        struct bitmap *bitmap;
        unsigned long flags;
-       struct bio_list bl;
-       struct page **behind_pages = NULL;
+       struct bio_vec *behind_pages = NULL;
        const int rw = bio_data_dir(bio);
        const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
        const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
@@ -851,7 +841,7 @@ static int make_request(mddev_t *mddev, struct bio * bio)
                }
                r1_bio->read_disk = rdisk;
 
-               read_bio = bio_clone(bio, GFP_NOIO);
+               read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev);
 
                r1_bio->bios[rdisk] = read_bio;
 
@@ -873,13 +863,6 @@ static int make_request(mddev_t *mddev, struct bio * bio)
         * bios[x] to bio
         */
        disks = conf->raid_disks;
-#if 0
-       { static int first=1;
-       if (first) printk("First Write sector %llu disks %d\n",
-                         (unsigned long long)r1_bio->sector, disks);
-       first = 0;
-       }
-#endif
  retry_write:
        blocked_rdev = NULL;
        rcu_read_lock();
@@ -937,16 +920,17 @@ static int make_request(mddev_t *mddev, struct bio * bio)
            (behind_pages = alloc_behind_pages(bio)) != NULL)
                set_bit(R1BIO_BehindIO, &r1_bio->state);
 
-       atomic_set(&r1_bio->remaining, 0);
+       atomic_set(&r1_bio->remaining, 1);
        atomic_set(&r1_bio->behind_remaining, 0);
 
-       bio_list_init(&bl);
+       bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors,
+                               test_bit(R1BIO_BehindIO, &r1_bio->state));
        for (i = 0; i < disks; i++) {
                struct bio *mbio;
                if (!r1_bio->bios[i])
                        continue;
 
-               mbio = bio_clone(bio, GFP_NOIO);
+               mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
                r1_bio->bios[i] = mbio;
 
                mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
@@ -963,39 +947,29 @@ static int make_request(mddev_t *mddev, struct bio * bio)
                         * we clear any unused pointer in the io_vec, rather
                         * than leave them unchanged.  This is important
                         * because when we come to free the pages, we won't
-                        * know the originial bi_idx, so we just free
+                        * know the original bi_idx, so we just free
                         * them all
                         */
                        __bio_for_each_segment(bvec, mbio, j, 0)
-                               bvec->bv_page = behind_pages[j];
+                               bvec->bv_page = behind_pages[j].bv_page;
                        if (test_bit(WriteMostly, &conf->mirrors[i].rdev->flags))
                                atomic_inc(&r1_bio->behind_remaining);
                }
 
                atomic_inc(&r1_bio->remaining);
-
-               bio_list_add(&bl, mbio);
+               spin_lock_irqsave(&conf->device_lock, flags);
+               bio_list_add(&conf->pending_bio_list, mbio);
+               blk_plug_device(mddev->queue);
+               spin_unlock_irqrestore(&conf->device_lock, flags);
        }
+       r1_bio_write_done(r1_bio, bio->bi_vcnt, behind_pages, behind_pages != NULL);
        kfree(behind_pages); /* the behind pages are attached to the bios now */
 
-       bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors,
-                               test_bit(R1BIO_BehindIO, &r1_bio->state));
-       spin_lock_irqsave(&conf->device_lock, flags);
-       bio_list_merge(&conf->pending_bio_list, &bl);
-       bio_list_init(&bl);
-
-       blk_plug_device(mddev->queue);
-       spin_unlock_irqrestore(&conf->device_lock, flags);
-
-       /* In case raid1d snuck into freeze_array */
+       /* In case raid1d snuck in to freeze_array */
        wake_up(&conf->wait_barrier);
 
        if (do_sync)
                md_wakeup_thread(mddev->thread);
-#if 0
-       while ((bio = bio_list_pop(&bl)) != NULL)
-               generic_make_request(bio);
-#endif
 
        return 0;
 }
@@ -1183,7 +1157,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
                        err = -EBUSY;
                        goto abort;
                }
-               /* Only remove non-faulty devices is recovery
+               /* Only remove non-faulty devices if recovery
                 * is not possible.
                 */
                if (!test_bit(Faulty, &rdev->flags) &&
@@ -1245,7 +1219,7 @@ static void end_sync_write(struct bio *bio, int error)
                        break;
                }
        if (!uptodate) {
-               int sync_blocks = 0;
+               sector_t sync_blocks = 0;
                sector_t s = r1_bio->sector;
                long sectors_to_go = r1_bio->sectors;
                /* make sure these bits doesn't get cleared. */
@@ -1388,7 +1362,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
                                         * active, and resync is currently active
                                         */
                                        rdev = conf->mirrors[d].rdev;
-                                       if (sync_page_io(rdev->bdev,
+                                       if (sync_page_io(rdev,
                                                         sect + rdev->data_offset,
                                                         s<<9,
                                                         bio->bi_io_vec[idx].bv_page,
@@ -1414,7 +1388,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
                                                continue;
                                        rdev = conf->mirrors[d].rdev;
                                        atomic_add(s, &rdev->corrected_errors);
-                                       if (sync_page_io(rdev->bdev,
+                                       if (sync_page_io(rdev,
                                                         sect + rdev->data_offset,
                                                         s<<9,
                                                         bio->bi_io_vec[idx].bv_page,
@@ -1429,7 +1403,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
                                        if (r1_bio->bios[d]->bi_end_io != end_sync_read)
                                                continue;
                                        rdev = conf->mirrors[d].rdev;
-                                       if (sync_page_io(rdev->bdev,
+                                       if (sync_page_io(rdev,
                                                         sect + rdev->data_offset,
                                                         s<<9,
                                                         bio->bi_io_vec[idx].bv_page,
@@ -1513,7 +1487,7 @@ static void fix_read_error(conf_t *conf, int read_disk,
                        rdev = conf->mirrors[d].rdev;
                        if (rdev &&
                            test_bit(In_sync, &rdev->flags) &&
-                           sync_page_io(rdev->bdev,
+                           sync_page_io(rdev,
                                         sect + rdev->data_offset,
                                         s<<9,
                                         conf->tmppage, READ))
@@ -1539,7 +1513,7 @@ static void fix_read_error(conf_t *conf, int read_disk,
                        rdev = conf->mirrors[d].rdev;
                        if (rdev &&
                            test_bit(In_sync, &rdev->flags)) {
-                               if (sync_page_io(rdev->bdev,
+                               if (sync_page_io(rdev,
                                                 sect + rdev->data_offset,
                                                 s<<9, conf->tmppage, WRITE)
                                    == 0)
@@ -1556,7 +1530,7 @@ static void fix_read_error(conf_t *conf, int read_disk,
                        rdev = conf->mirrors[d].rdev;
                        if (rdev &&
                            test_bit(In_sync, &rdev->flags)) {
-                               if (sync_page_io(rdev->bdev,
+                               if (sync_page_io(rdev,
                                                 sect + rdev->data_offset,
                                                 s<<9, conf->tmppage, READ)
                                    == 0)
@@ -1646,7 +1620,8 @@ static void raid1d(mddev_t *mddev)
                                        mddev->ro ? IO_BLOCKED : NULL;
                                r1_bio->read_disk = disk;
                                bio_put(bio);
-                               bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
+                               bio = bio_clone_mddev(r1_bio->master_bio,
+                                                     GFP_NOIO, mddev);
                                r1_bio->bios[r1_bio->read_disk] = bio;
                                rdev = conf->mirrors[disk].rdev;
                                if (printk_ratelimit())
@@ -1705,7 +1680,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
        int i;
        int wonly = -1;
        int write_targets = 0, read_targets = 0;
-       int sync_blocks;
+       sector_t sync_blocks;
        int still_degraded = 0;
 
        if (!conf->r1buf_pool)
@@ -1755,11 +1730,11 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                msleep_interruptible(1000);
 
        bitmap_cond_end_sync(mddev->bitmap, sector_nr);
+       r1_bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO);
        raise_barrier(conf);
 
        conf->next_resync = sector_nr;
 
-       r1_bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO);
        rcu_read_lock();
        /*
         * If we get a correctably read error during resync or recovery,
@@ -1971,7 +1946,6 @@ static conf_t *setup_conf(mddev_t *mddev)
        init_waitqueue_head(&conf->wait_barrier);
 
        bio_list_init(&conf->pending_bio_list);
-       bio_list_init(&conf->flushing_bio_list);
 
        conf->last_used = -1;
        for (i = 0; i < conf->raid_disks; i++) {
index adf8cfd73313a253e43d234dd3c1c42b0f1da87e..cbfdf1a6acd98e6f501d29912c2bc718c39450df 100644 (file)
@@ -35,8 +35,6 @@ struct r1_private_data_s {
        struct list_head        retry_list;
        /* queue pending writes and submit them on unplug */
        struct bio_list         pending_bio_list;
-       /* queue of writes that have been unplugged */
-       struct bio_list         flushing_bio_list;
 
        /* for use when syncing mirrors: */
 
index f0d082f749bea117522d7fc45be67320fb5ce9fc..c67aa54694ae72605b2165949fe1033dc2d542b9 100644 (file)
@@ -120,7 +120,7 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data)
         * Allocate bios.
         */
        for (j = nalloc ; j-- ; ) {
-               bio = bio_alloc(gfp_flags, RESYNC_PAGES);
+               bio = bio_kmalloc(gfp_flags, RESYNC_PAGES);
                if (!bio)
                        goto out_free_bio;
                r10_bio->devs[j].bio = bio;
@@ -801,7 +801,6 @@ static int make_request(mddev_t *mddev, struct bio * bio)
        const int rw = bio_data_dir(bio);
        const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
        const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
-       struct bio_list bl;
        unsigned long flags;
        mdk_rdev_t *blocked_rdev;
 
@@ -890,7 +889,7 @@ static int make_request(mddev_t *mddev, struct bio * bio)
                }
                mirror = conf->mirrors + disk;
 
-               read_bio = bio_clone(bio, GFP_NOIO);
+               read_bio = bio_clone_mddev(bio, GFP_NOIO, mddev);
 
                r10_bio->devs[slot].bio = read_bio;
 
@@ -950,16 +949,16 @@ static int make_request(mddev_t *mddev, struct bio * bio)
                goto retry_write;
        }
 
-       atomic_set(&r10_bio->remaining, 0);
+       atomic_set(&r10_bio->remaining, 1);
+       bitmap_startwrite(mddev->bitmap, bio->bi_sector, r10_bio->sectors, 0);
 
-       bio_list_init(&bl);
        for (i = 0; i < conf->copies; i++) {
                struct bio *mbio;
                int d = r10_bio->devs[i].devnum;
                if (!r10_bio->devs[i].bio)
                        continue;
 
-               mbio = bio_clone(bio, GFP_NOIO);
+               mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
                r10_bio->devs[i].bio = mbio;
 
                mbio->bi_sector = r10_bio->devs[i].addr+
@@ -970,22 +969,22 @@ static int make_request(mddev_t *mddev, struct bio * bio)
                mbio->bi_private = r10_bio;
 
                atomic_inc(&r10_bio->remaining);
-               bio_list_add(&bl, mbio);
+               spin_lock_irqsave(&conf->device_lock, flags);
+               bio_list_add(&conf->pending_bio_list, mbio);
+               blk_plug_device(mddev->queue);
+               spin_unlock_irqrestore(&conf->device_lock, flags);
        }
 
-       if (unlikely(!atomic_read(&r10_bio->remaining))) {
-               /* the array is dead */
+       if (atomic_dec_and_test(&r10_bio->remaining)) {
+               /* This matches the end of raid10_end_write_request() */
+               bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector,
+                               r10_bio->sectors,
+                               !test_bit(R10BIO_Degraded, &r10_bio->state),
+                               0);
                md_write_end(mddev);
                raid_end_bio_io(r10_bio);
-               return 0;
        }
 
-       bitmap_startwrite(mddev->bitmap, bio->bi_sector, r10_bio->sectors, 0);
-       spin_lock_irqsave(&conf->device_lock, flags);
-       bio_list_merge(&conf->pending_bio_list, &bl);
-       blk_plug_device(mddev->queue);
-       spin_unlock_irqrestore(&conf->device_lock, flags);
-
        /* In case raid10d snuck in to freeze_array */
        wake_up(&conf->wait_barrier);
 
@@ -1558,7 +1557,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
                            test_bit(In_sync, &rdev->flags)) {
                                atomic_inc(&rdev->nr_pending);
                                rcu_read_unlock();
-                               success = sync_page_io(rdev->bdev,
+                               success = sync_page_io(rdev,
                                                       r10_bio->devs[sl].addr +
                                                       sect + rdev->data_offset,
                                                       s<<9,
@@ -1597,7 +1596,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
                                atomic_inc(&rdev->nr_pending);
                                rcu_read_unlock();
                                atomic_add(s, &rdev->corrected_errors);
-                               if (sync_page_io(rdev->bdev,
+                               if (sync_page_io(rdev,
                                                 r10_bio->devs[sl].addr +
                                                 sect + rdev->data_offset,
                                                 s<<9, conf->tmppage, WRITE)
@@ -1634,7 +1633,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
                                char b[BDEVNAME_SIZE];
                                atomic_inc(&rdev->nr_pending);
                                rcu_read_unlock();
-                               if (sync_page_io(rdev->bdev,
+                               if (sync_page_io(rdev,
                                                 r10_bio->devs[sl].addr +
                                                 sect + rdev->data_offset,
                                                 s<<9, conf->tmppage,
@@ -1747,7 +1746,8 @@ static void raid10d(mddev_t *mddev)
                                               mdname(mddev),
                                               bdevname(rdev->bdev,b),
                                               (unsigned long long)r10_bio->sector);
-                               bio = bio_clone(r10_bio->master_bio, GFP_NOIO);
+                               bio = bio_clone_mddev(r10_bio->master_bio,
+                                                     GFP_NOIO, mddev);
                                r10_bio->devs[r10_bio->read_slot].bio = bio;
                                bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr
                                        + rdev->data_offset;
@@ -1820,7 +1820,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
        int disk;
        int i;
        int max_sync;
-       int sync_blocks;
+       sector_t sync_blocks;
 
        sector_t sectors_skipped = 0;
        int chunks_skipped = 0;
index 31140d1259dcdd84e373c3affeee5e529de3af8b..dc574f303f8b049eb38285c60039c24233266c48 100644 (file)
@@ -3876,9 +3876,9 @@ static int chunk_aligned_read(mddev_t *mddev, struct bio * raid_bio)
                return 0;
        }
        /*
-        * use bio_clone to make a copy of the bio
+        * use bio_clone_mddev to make a copy of the bio
         */
-       align_bi = bio_clone(raid_bio, GFP_NOIO);
+       align_bi = bio_clone_mddev(raid_bio, GFP_NOIO, mddev);
        if (!align_bi)
                return 0;
        /*
@@ -4360,7 +4360,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
        raid5_conf_t *conf = mddev->private;
        struct stripe_head *sh;
        sector_t max_sector = mddev->dev_sectors;
-       int sync_blocks;
+       sector_t sync_blocks;
        int still_degraded = 0;
        int i;
 
index 9186b45132ed8d14d9274b6d32315a460a8ba471..f60107c3b091b966895e48f6e1860112bbaa3482 100644 (file)
@@ -325,9 +325,9 @@ static int ir_setkeytable(struct ir_input_dev *ir_dev,
 static unsigned int ir_lookup_by_scancode(const struct ir_scancode_table *rc_tab,
                                          unsigned int scancode)
 {
-       unsigned int start = 0;
-       unsigned int end = rc_tab->len - 1;
-       unsigned int mid;
+       int start = 0;
+       int end = rc_tab->len - 1;
+       int mid;
 
        while (start <= end) {
                mid = (start + end) / 2;
@@ -389,6 +389,8 @@ static int ir_getkeycode(struct input_dev *dev,
        ke->len = sizeof(entry->scancode);
        memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
 
+       retval = 0;
+
 out:
        spin_unlock_irqrestore(&rc_tab->lock, flags);
        return retval;
index bad2cedb8d96886cec38af4b0003c476fbdd11f9..a28541b2b1a219e5a2804f20201191f1ff98c953 100644 (file)
@@ -19,7 +19,6 @@ comment "Multimedia core support"
 
 config VIDEO_DEV
        tristate "Video For Linux"
-       depends on BKL # used in many drivers for ioctl handling, need to kill
        ---help---
          V4L core support for video capture and overlay devices, webcams and
          AM/FM radio cards.
index 3d88542612eabfffc799a348c88c8c4a1bf551df..74ee172b5bc992d8dd151338b67ab5d9d65cb271 100644 (file)
@@ -391,7 +391,6 @@ static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, in
 
 /*****************************************************************************/
 /* i2c-adapter helper functions                                              */
-#include <linux/i2c-id.h>
 
 /* exported algorithm data */
 static struct i2c_algorithm saa7146_algo = {
index a4991026254dc0223c71f06f475634338c8e2e2d..2311c0a3406c953e4199c627a135be7fdc97843c 100644 (file)
@@ -130,6 +130,7 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
                            struct dibx000_i2c_master *mst)
 {
        strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
+       i2c_adap->algo = algo;
        i2c_adap->algo_data = NULL;
        i2c_set_adapdata(i2c_adap, mst);
        if (i2c_add_adapter(i2c_adap) < 0)
index 2934770dacc3fee149baef4a20f7d6ed770addad..7bc36670071a8ba333ed0d67999d5f9079adc895 100644 (file)
@@ -2065,8 +2065,9 @@ static int cafe_pci_probe(struct pci_dev *pdev,
                sensor_cfg.clock_speed = 45;
 
        cam->sensor_addr = 0x42;
-       cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter,
-                       NULL, "ov7670", cam->sensor_addr, NULL);
+       cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter,
+                       "ov7670", "ov7670", 0, &sensor_cfg, cam->sensor_addr,
+                       NULL);
        if (cam->sensor == NULL) {
                ret = -ENODEV;
                goto out_smbus;
index aab21f3ce4721591c4773b80879524acac1dd43c..4c7cac3b6254eb9ed0b9ca7c47bd525d12cc1c81 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
-#include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
@@ -1927,10 +1926,9 @@ static int mpeg_open(struct file *file)
                        dev = h;
        }
 
-       if (dev == NULL) {
-               unlock_kernel();
+       if (dev == NULL)
                return -ENODEV;
-       }
+
        mutex_lock(&dev->lock);
 
        /* allocate + initialize per filehandle data */
index a6cc12f8736c803cc1418a0fc0b4b86e3d248f66..9a98dc55f6572fac82e0c6e0936d1af8a03218d9 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
@@ -1576,12 +1575,8 @@ static int mpeg_open(struct file *file)
 
        /* allocate + initialize per filehandle data */
        fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-       if (NULL == fh) {
-               unlock_kernel();
+       if (!fh)
                return -ENOMEM;
-       }
-
-       lock_kernel();
 
        file->private_data = fh;
        fh->dev      = dev;
@@ -1592,8 +1587,6 @@ static int mpeg_open(struct file *file)
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct cx23885_buffer),
                            fh, NULL);
-       unlock_kernel();
-
        return 0;
 }
 
index 93af9c65b484d26e361bf5f69c7e7318f742a399..3cc9f462d08d9d1d391b8cfcec5fbebc6b6c66d4 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/kmod.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
@@ -743,8 +742,6 @@ static int video_open(struct file *file)
        if (NULL == fh)
                return -ENOMEM;
 
-       lock_kernel();
-
        file->private_data = fh;
        fh->dev      = dev;
        fh->radio    = radio;
@@ -762,8 +759,6 @@ static int video_open(struct file *file)
 
        dprintk(1, "post videobuf_queue_init()\n");
 
-       unlock_kernel();
-
        return 0;
 }
 
index 380e459f899d3ff0105a274987a7940cd426a5e9..27b5dfdfbb931253fb3f02567084e39ecd97858c 100644 (file)
@@ -451,7 +451,6 @@ static int imx074_probe(struct i2c_client *client,
        ret = imx074_video_probe(icd, client);
        if (ret < 0) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(priv);
                return ret;
        }
@@ -468,7 +467,6 @@ static int imx074_remove(struct i2c_client *client)
        icd->ops = NULL;
        if (icl->free_bus)
                icl->free_bus(icl);
-       i2c_set_clientdata(client, NULL);
        client->driver = NULL;
        kfree(priv);
 
index 5a000c65ae98ab3f4fa75b26b4f87ba885874290..ce4a75375909b6872e7860f55bc1d66d3e90a414 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
-#include <linux/i2c-id.h>
 #include <linux/workqueue.h>
 
 #include <media/ir-core.h>
index 4a27862da30d3d0810efb11965ae7019bb1c15c9..072bd2d1cfad46f4c5a25ea33f789409c2848a5c 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
+#include <media/videobuf-core.h>
 #include <media/videobuf-dma-contig.h>
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
@@ -903,8 +904,6 @@ static int mx2_camera_set_crop(struct soc_camera_device *icd,
 static int mx2_camera_set_fmt(struct soc_camera_device *icd,
                               struct v4l2_format *f)
 {
-       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-       struct mx2_camera_dev *pcdev = ici->priv;
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        const struct soc_camera_format_xlate *xlate;
        struct v4l2_pix_format *pix = &f->fmt.pix;
@@ -943,8 +942,6 @@ static int mx2_camera_set_fmt(struct soc_camera_device *icd,
 static int mx2_camera_try_fmt(struct soc_camera_device *icd,
                                  struct v4l2_format *f)
 {
-       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-       struct mx2_camera_dev *pcdev = ici->priv;
        struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        const struct soc_camera_format_xlate *xlate;
        struct v4l2_pix_format *pix = &f->fmt.pix;
@@ -1024,13 +1021,13 @@ static int mx2_camera_querycap(struct soc_camera_host *ici,
        return 0;
 }
 
-static int mx2_camera_reqbufs(struct soc_camera_file *icf,
+static int mx2_camera_reqbufs(struct soc_camera_device *icd,
                              struct v4l2_requestbuffers *p)
 {
        int i;
 
        for (i = 0; i < p->count; i++) {
-               struct mx2_buffer *buf = container_of(icf->vb_vidq.bufs[i],
+               struct mx2_buffer *buf = container_of(icd->vb_vidq.bufs[i],
                                                      struct mx2_buffer, vb);
                INIT_LIST_HEAD(&buf->vb.queue);
        }
@@ -1151,9 +1148,9 @@ err_out:
 
 static unsigned int mx2_camera_poll(struct file *file, poll_table *pt)
 {
-       struct soc_camera_file *icf = file->private_data;
+       struct soc_camera_device *icd = file->private_data;
 
-       return videobuf_poll_stream(file, &icf->vb_vidq, pt);
+       return videobuf_poll_stream(file, &icd->vb_vidq, pt);
 }
 
 static struct soc_camera_host_ops mx2_soc_camera_host_ops = {
index 29c5fc3481331eb7055dff25f09a90cfc52709b9..aa871c2936b31d9bb821067932f2103889392539 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <mach/ipu.h>
 #include <mach/mx3_camera.h>
+#include <mach/dma.h>
 
 #define MX3_CAM_DRV_NAME "mx3-camera"
 
@@ -638,6 +639,9 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
        struct dma_chan_request *rq = arg;
        struct mx3_camera_pdata *pdata;
 
+       if (!imx_dma_is_ipu(chan))
+               return false;
+
        if (!rq)
                return false;
 
index 7c30e62b50db29357aabbf700203b0c1f7809e03..cbfd07f2d9da71e6563d4b317f51084c438ebc96 100644 (file)
@@ -235,7 +235,7 @@ static void free_buffer(struct videobuf_queue *vq, struct omap1_cam_buf *buf,
 
        BUG_ON(in_interrupt());
 
-       videobuf_waiton(vb, 0, 0);
+       videobuf_waiton(vq, vb, 0, 0);
 
        if (vb_mode == OMAP1_CAM_DMA_CONTIG) {
                videobuf_dma_contig_free(vq, vb);
@@ -504,7 +504,7 @@ static void omap1_videobuf_queue(struct videobuf_queue *vq,
                 * empty. Since the transfer of the DMA programming register set
                 * content to the DMA working register set is done automatically
                 * by the DMA hardware, this can pretty well happen while we
-                * are keeping the lock here. Levae fetching it from the queue
+                * are keeping the lock here. Leave fetching it from the queue
                 * to be done when a next DMA interrupt occures instead.
                 */
                return;
@@ -1365,12 +1365,12 @@ static void omap1_cam_init_videobuf(struct videobuf_queue *q,
                videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops,
                                icd->dev.parent, &pcdev->lock,
                                V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
-                               sizeof(struct omap1_cam_buf), icd);
+                               sizeof(struct omap1_cam_buf), icd, NULL);
        else
                videobuf_queue_sg_init(q, &omap1_videobuf_ops,
                                icd->dev.parent, &pcdev->lock,
                                V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
-                               sizeof(struct omap1_cam_buf), icd);
+                               sizeof(struct omap1_cam_buf), icd, NULL);
 
        /* use videobuf mode (auto)selected with the module parameter */
        pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG;
@@ -1386,7 +1386,7 @@ static void omap1_cam_init_videobuf(struct videobuf_queue *q,
        }
 }
 
-static int omap1_cam_reqbufs(struct soc_camera_file *icf,
+static int omap1_cam_reqbufs(struct soc_camera_device *icd,
                              struct v4l2_requestbuffers *p)
 {
        int i;
@@ -1398,7 +1398,7 @@ static int omap1_cam_reqbufs(struct soc_camera_file *icf,
         * it hadn't triggered
         */
        for (i = 0; i < p->count; i++) {
-               struct omap1_cam_buf *buf = container_of(icf->vb_vidq.bufs[i],
+               struct omap1_cam_buf *buf = container_of(icd->vb_vidq.bufs[i],
                                                      struct omap1_cam_buf, vb);
                buf->inwork = 0;
                INIT_LIST_HEAD(&buf->vb.queue);
@@ -1485,10 +1485,10 @@ static int omap1_cam_set_bus_param(struct soc_camera_device *icd,
 
 static unsigned int omap1_cam_poll(struct file *file, poll_table *pt)
 {
-       struct soc_camera_file *icf = file->private_data;
+       struct soc_camera_device *icd = file->private_data;
        struct omap1_cam_buf *buf;
 
-       buf = list_entry(icf->vb_vidq.stream.next, struct omap1_cam_buf,
+       buf = list_entry(icd->vb_vidq.stream.next, struct omap1_cam_buf,
                         vb.stream);
 
        poll_wait(file, &buf->vb.done, pt);
index b7cfeab0948c9519477725650a1f262db16fad43..cf93de98806894f36ff0a4504efe88d9658f06bf 100644 (file)
@@ -754,7 +754,7 @@ static int ov6650_g_fmt(struct v4l2_subdev *sd,
 
 static bool is_unscaled_ok(int width, int height, struct v4l2_rect *rect)
 {
-       return (width > rect->width >> 1 || height > rect->height >> 1);
+       return width > rect->width >> 1 || height > rect->height >> 1;
 }
 
 static u8 to_clkrc(struct v4l2_fract *timeperframe,
@@ -840,8 +840,6 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
                coma_mask |= COMA_BW | COMA_BYTE_SWAP | COMA_WORD_SWAP;
                coma_set |= COMA_RAW_RGB | COMA_RGB;
                break;
-       case 0:
-               break;
        default:
                dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code);
                return -EINVAL;
@@ -1176,7 +1174,6 @@ static int ov6650_probe(struct i2c_client *client,
 
        if (ret) {
                icd->ops = NULL;
-               i2c_set_clientdata(client, NULL);
                kfree(priv);
        }
 
@@ -1187,7 +1184,6 @@ static int ov6650_remove(struct i2c_client *client)
 {
        struct ov6650 *priv = to_ov6650(client);
 
-       i2c_set_clientdata(client, NULL);
        kfree(priv);
        return 0;
 }
index 10a6cbf6a790b05e9bf84df4e1d8e2e3a8ea7a83..0911cb580e186a61ac8a2f781eea1eee05954089 100644 (file)
@@ -6660,6 +6660,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x13c2,
                .subdevice    = 0x2804,
                .driver_data  = SAA7134_BOARD_TECHNOTREND_BUDGET_T3000,
+       }, {
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x5ace, /* Beholder Intl. Ltd. */
+               .subdevice    = 0x7190,
+               .driver_data  = SAA7134_BOARD_BEHOLD_H7,
+       }, {
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x5ace, /* Beholder Intl. Ltd. */
+               .subdevice    = 0x7090,
+               .driver_data  = SAA7134_BOARD_BEHOLD_A7,
        }, {
                /* --- boards without eeprom + subsystem ID --- */
                .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -6698,18 +6710,6 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = PCI_ANY_ID,
                .subdevice    = PCI_ANY_ID,
                .driver_data  = SAA7134_BOARD_UNKNOWN,
-       }, {
-               .vendor       = PCI_VENDOR_ID_PHILIPS,
-               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-               .subvendor    = 0x5ace, /* Beholder Intl. Ltd. */
-               .subdevice    = 0x7190,
-               .driver_data  = SAA7134_BOARD_BEHOLD_H7,
-       }, {
-               .vendor       = PCI_VENDOR_ID_PHILIPS,
-               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-               .subvendor    = 0x5ace, /* Beholder Intl. Ltd. */
-               .subdevice    = 0x7090,
-               .driver_data  = SAA7134_BOARD_BEHOLD_A7,
        },{
                /* --- end of list --- */
        }
index 41d0166c0f95b5ff8156770155d3affe6ce874c5..41360d7c3e96237d50f9aec1bb449ec2b084eb7e 100644 (file)
@@ -31,7 +31,6 @@ static const char version[] = "0.24";
 #include <linux/init.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/usb.h>
 #include "se401.h"
@@ -951,9 +950,9 @@ static int se401_open(struct file *file)
        struct usb_se401 *se401 = (struct usb_se401 *)dev;
        int err = 0;
 
-       lock_kernel();
+       mutex_lock(&se401->lock);
        if (se401->user) {
-               unlock_kernel();
+               mutex_unlock(&se401->lock);
                return -EBUSY;
        }
        se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
@@ -962,7 +961,7 @@ static int se401_open(struct file *file)
        else
                err = -ENOMEM;
        se401->user = !err;
-       unlock_kernel();
+       mutex_unlock(&se401->lock);
 
        return err;
 }
index f07a0f6b71c455a253845df29705ed96c3b32083..b5afe5f841ce27fb5aac5fd259d10d43fb53a837 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 
 #include <linux/usb.h>
 #include <linux/mm.h>
@@ -673,14 +672,11 @@ static int v4l_stk_open(struct file *fp)
        vdev = video_devdata(fp);
        dev = vdev_to_camera(vdev);
 
-       lock_kernel();
        if (dev == NULL || !is_present(dev)) {
-               unlock_kernel();
                return -ENXIO;
        }
        fp->private_data = dev;
        usb_autopm_get_interface(dev->interface);
-       unlock_kernel();
 
        return 0;
 }
index 4555f4a5f4c84b94f532d6993a5d0591e4569ae9..c91424c0c1353565f4f599004c46b81d5eaa83bd 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/firmware.h>
-#include <linux/smp_lock.h>
 
 #include "vendorcmds.h"
 #include "pd-common.h"
@@ -485,15 +484,11 @@ static void poseidon_disconnect(struct usb_interface *interface)
        /*unregister v4l2 device */
        v4l2_device_unregister(&pd->v4l2_dev);
 
-       lock_kernel();
-       {
-               pd_dvb_usb_device_exit(pd);
-               poseidon_fm_exit(pd);
+       pd_dvb_usb_device_exit(pd);
+       poseidon_fm_exit(pd);
 
-               poseidon_audio_free(pd);
-               pd_video_exit(pd);
-       }
-       unlock_kernel();
+       poseidon_audio_free(pd);
+       pd_video_exit(pd);
 
        usb_set_intfdata(interface, NULL);
        kref_put(&pd->kref, poseidon_delete);
index 5d6fd01f918a4d5869edcf59eca93154794d38e3..dc17cce2fbb6d39104979b6e51260d8cf21fff07 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/firmware.h>
 #include <linux/ihex.h>
@@ -483,29 +482,28 @@ vicam_open(struct file *file)
                return -EINVAL;
        }
 
-       /* the videodev_lock held above us protects us from
-        * simultaneous opens...for now. we probably shouldn't
-        * rely on this fact forever.
+       /* cam_lock/open_count protects us from simultaneous opens
+        * ... for now. we probably shouldn't rely on this fact forever.
         */
 
-       lock_kernel();
+       mutex_lock(&cam->cam_lock);
        if (cam->open_count > 0) {
                printk(KERN_INFO
                       "vicam_open called on already opened camera");
-               unlock_kernel();
+               mutex_unlock(&cam->cam_lock);
                return -EBUSY;
        }
 
        cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
        if (!cam->raw_image) {
-               unlock_kernel();
+               mutex_unlock(&cam->cam_lock);
                return -ENOMEM;
        }
 
        cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
        if (!cam->framebuf) {
                kfree(cam->raw_image);
-               unlock_kernel();
+               mutex_unlock(&cam->cam_lock);
                return -ENOMEM;
        }
 
@@ -513,10 +511,17 @@ vicam_open(struct file *file)
        if (!cam->cntrlbuf) {
                kfree(cam->raw_image);
                rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
-               unlock_kernel();
+               mutex_unlock(&cam->cam_lock);
                return -ENOMEM;
        }
 
+       cam->needsDummyRead = 1;
+       cam->open_count++;
+
+       file->private_data = cam;
+       mutex_unlock(&cam->cam_lock);
+
+
        // First upload firmware, then turn the camera on
 
        if (!cam->is_initialized) {
@@ -527,12 +532,6 @@ vicam_open(struct file *file)
 
        set_camera_power(cam, 1);
 
-       cam->needsDummyRead = 1;
-       cam->open_count++;
-
-       file->private_data = cam;
-       unlock_kernel();
-
        return 0;
 }
 
index 0ca7978654b56699989a01222fdf9bcdd6fbd45b..03f7f4670e9badd4491f8cddb8e748a848c14119 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
@@ -247,10 +246,12 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                        mutex_unlock(vdev->lock);
        } else if (vdev->fops->ioctl) {
                /* TODO: convert all drivers to unlocked_ioctl */
-               lock_kernel();
+               static DEFINE_MUTEX(v4l2_ioctl_mutex);
+
+               mutex_lock(&v4l2_ioctl_mutex);
                if (video_is_registered(vdev))
                        ret = vdev->fops->ioctl(filp, cmd, arg);
-               unlock_kernel();
+               mutex_unlock(&v4l2_ioctl_mutex);
        } else
                ret = -ENOTTY;
 
index 37fe16181e3c7e13dbeb4e8a58706a3931172577..27f05551183f18ff6bbf739e63a9ff8ec00d1be7 100644 (file)
@@ -388,6 +388,7 @@ struct zoran {
        struct videocodec *vfe; /* video front end */
 
        struct mutex resource_lock;     /* prevent evil stuff */
+       struct mutex other_lock;        /* please merge with above */
 
        u8 initialized;         /* flag if zoran has been correctly initialized */
        int user;               /* number of current users */
index 0aac376c3f7a362e6c7b1345099ecf7ac224a44b..7e6d62467eaaa7bd1e913d5ce104608005ccbc58 100644 (file)
@@ -1227,6 +1227,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
        snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
        spin_lock_init(&zr->spinlock);
        mutex_init(&zr->resource_lock);
+       mutex_init(&zr->other_lock);
        if (pci_enable_device(pdev))
                goto zr_unreg;
        pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
index 401082b853f086bbe67046a561d810fe43e8b173..67a52e844ae613307665f338f67bd5d6ef69828c 100644 (file)
@@ -49,7 +49,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
@@ -913,7 +912,7 @@ static int zoran_open(struct file *file)
        dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n",
                ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1);
 
-       lock_kernel();
+       mutex_lock(&zr->other_lock);
 
        if (zr->user >= 2048) {
                dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
@@ -963,14 +962,14 @@ static int zoran_open(struct file *file)
        file->private_data = fh;
        fh->zr = zr;
        zoran_open_init_session(fh);
-       unlock_kernel();
+       mutex_unlock(&zr->other_lock);
 
        return 0;
 
 fail_fh:
        kfree(fh);
 fail_unlock:
-       unlock_kernel();
+       mutex_unlock(&zr->other_lock);
 
        dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n",
                ZR_DEVNAME(zr), res, zr->user);
@@ -989,7 +988,7 @@ zoran_close(struct file  *file)
 
        /* kernel locks (fs/device.c), so don't do that ourselves
         * (prevents deadlocks) */
-       /*mutex_lock(&zr->resource_lock);*/
+       mutex_lock(&zr->other_lock);
 
        zoran_close_end_session(fh);
 
@@ -1023,6 +1022,7 @@ zoran_close(struct file  *file)
                        encoder_call(zr, video, s_routing, 2, 0, 0);
                }
        }
+       mutex_unlock(&zr->other_lock);
 
        file->private_data = NULL;
        kfree(fh->overlay_mask);
@@ -3370,11 +3370,26 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
 #endif
 };
 
+/* please use zr->resource_lock consistently and kill this wrapper */
+static long zoran_ioctl(struct file *file, unsigned int cmd,
+                       unsigned long arg)
+{
+       struct zoran_fh *fh = file->private_data;
+       struct zoran *zr = fh->zr;
+       int ret;
+
+       mutex_lock(&zr->other_lock);
+       ret = video_ioctl2(file, cmd, arg);
+       mutex_unlock(&zr->other_lock);
+
+       return ret;
+}
+
 static const struct v4l2_file_operations zoran_fops = {
        .owner = THIS_MODULE,
        .open = zoran_open,
        .release = zoran_close,
-       .ioctl = video_ioctl2,
+       .unlocked_ioctl = zoran_ioctl,
        .read = zoran_read,
        .write = zoran_write,
        .mmap = zoran_mmap,
index f9b91ba8900c96f027a284185b97fc9dd1e755b0..644d4cd071cc58eb2afc02d09b53bab2f5a3ff38 100644 (file)
@@ -123,7 +123,7 @@ static ssize_t als_sensing_range_store(struct device *dev,
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct als_data *data = i2c_get_clientdata(client);
-       unsigned int ret_val;
+       int ret_val;
        unsigned long val;
 
        if (strict_strtoul(buf, 10, &val))
@@ -251,7 +251,6 @@ static int apds9802als_probe(struct i2c_client *client,
 
        return res;
 als_error1:
-       i2c_set_clientdata(client, NULL);
        kfree(data);
        return res;
 }
index cee632e645e1982fee9e99ef84e065daf0d17d39..d79a972f2c799c11b2aa4780efb86417eff13854 100644 (file)
@@ -649,7 +649,7 @@ static ssize_t bh1770_power_state_store(struct device *dev,
 {
        struct bh1770_chip *chip =  dev_get_drvdata(dev);
        unsigned long value;
-       size_t ret;
+       ssize_t ret;
 
        if (strict_strtoul(buf, 0, &value))
                return -EINVAL;
@@ -659,8 +659,12 @@ static ssize_t bh1770_power_state_store(struct device *dev,
                pm_runtime_get_sync(dev);
 
                ret = bh1770_lux_rate(chip, chip->lux_rate_index);
-               ret |= bh1770_lux_interrupt_control(chip, BH1770_ENABLE);
+               if (ret < 0) {
+                       pm_runtime_put(dev);
+                       goto leave;
+               }
 
+               ret = bh1770_lux_interrupt_control(chip, BH1770_ENABLE);
                if (ret < 0) {
                        pm_runtime_put(dev);
                        goto leave;
index 0a53500636c9d3f4c4d1f886d386f1b1b675f95d..d2d5d23416dda28bf6719649f0c1a84ff1ffcf8a 100644 (file)
@@ -91,11 +91,10 @@ static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root);
 static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent);
 
 
-static int ibmasmfs_get_super(struct file_system_type *fst,
-                       int flags, const char *name, void *data,
-                       struct vfsmount *mnt)
+static struct dentry *ibmasmfs_mount(struct file_system_type *fst,
+                       int flags, const char *name, void *data)
 {
-       return get_sb_single(fst, flags, data, ibmasmfs_fill_super, mnt);
+       return mount_single(fst, flags, data, ibmasmfs_fill_super);
 }
 
 static const struct super_operations ibmasmfs_s_ops = {
@@ -108,7 +107,7 @@ static const struct file_operations *ibmasmfs_dir_ops = &simple_dir_operations;
 static struct file_system_type ibmasmfs_type = {
        .owner          = THIS_MODULE,
        .name           = "ibmasmfs",
-       .get_sb         = ibmasmfs_get_super,
+       .mount          = ibmasmfs_mount,
        .kill_sb        = kill_litter_super,
 };
 
index 34fe835921c4b751beafaff119ca97fb352e63f6..ca47e62850752b80772bd3d77a246bfe1109b742 100644 (file)
@@ -87,7 +87,7 @@ static ssize_t als_sensing_range_store(struct device *dev,
                struct device_attribute *attr, const  char *buf, size_t count)
 {
        struct i2c_client *client = to_i2c_client(dev);
-       unsigned int ret_val;
+       int ret_val;
        unsigned long val;
 
        if (strict_strtoul(buf, 10, &val))
@@ -106,6 +106,8 @@ static ssize_t als_sensing_range_store(struct device *dev,
                val = 4;
 
        ret_val = i2c_smbus_read_byte_data(client, 0x00);
+       if (ret_val < 0)
+               return ret_val;
 
        ret_val &= 0xFC; /*reset the bit before setting them */
        ret_val |= val - 1;
index 72450237a0f418e0a41552cbdefd7943545add78..59c118c19a910e9950a04a069dacf62352a25e9a 100644 (file)
@@ -1044,12 +1044,6 @@ static int __init init_kgdbts(void)
        return configure_kgdbts();
 }
 
-static void cleanup_kgdbts(void)
-{
-       if (configured == 1)
-               kgdb_unregister_io_module(&kgdbts_io_ops);
-}
-
 static int kgdbts_get_char(void)
 {
        int val = 0;
@@ -1081,10 +1075,8 @@ static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp)
                return 0;
        }
 
-       if (kgdb_connected) {
-               printk(KERN_ERR
-              "kgdbts: Cannot reconfigure while KGDB is connected.\n");
-
+       if (configured == 1) {
+               printk(KERN_ERR "kgdbts: ERROR: Already configured and running.\n");
                return -EBUSY;
        }
 
@@ -1093,9 +1085,6 @@ static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp)
        if (config[len - 1] == '\n')
                config[len - 1] = '\0';
 
-       if (configured == 1)
-               cleanup_kgdbts();
-
        /* Go and configure with the new params. */
        return configure_kgdbts();
 }
@@ -1123,7 +1112,6 @@ static struct kgdb_io kgdbts_io_ops = {
 };
 
 module_init(init_kgdbts);
-module_exit(cleanup_kgdbts);
 module_param_call(kgdbts, param_set_kgdbts_var, param_get_string, &kps, 0644);
 MODULE_PARM_DESC(kgdbts, "<A|V1|V2>[F#|S#][N#]");
 MODULE_DESCRIPTION("KGDB Test Suite");
index 9e2b7e9e0ad91b4871423cf2f449c1b63329cb10..ad9268b444163e2df218b3ff5b3bee8bdfdca0a6 100644 (file)
@@ -1496,7 +1496,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
 
        switch (mode) {
        case FL_WRITING:
-               write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41);
+               write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0x40) : CMD(0x41);
                break;
        case FL_OTP_WRITE:
                write_cmd = CMD(0xc0);
@@ -1661,7 +1661,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
        cmd_adr = adr & ~(wbufsize-1);
 
        /* Let's determine this according to the interleave only once */
-       write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
+       write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0xe8) : CMD(0xe9);
 
        mutex_lock(&chip->mutex);
        ret = get_chip(map, chip, cmd_adr, FL_WRITING);
index ba29d2f0ffd77dc6b42bfa55acdcbf0bf97aacea..3b8e32d87977a3c5536e8af83e58795891adaa51 100644 (file)
@@ -291,6 +291,23 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param)
 
        cfi->addr_unlock1 = 0x555;
        cfi->addr_unlock2 = 0x2AA;
+
+       cfi->sector_erase_cmd = CMD(0x50);
+}
+
+static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd, void *param)
+{
+       struct map_info *map = mtd->priv;
+       struct cfi_private *cfi = map->fldrv_priv;
+
+       fixup_sst39vf_rev_b(mtd, param);
+
+       /*
+        * CFI reports 1024 sectors (0x03ff+1) of 64KBytes (0x0100*256) where
+        * it should report a size of 8KBytes (0x0020*256).
+        */
+       cfi->cfiq->EraseRegionInfo[0] = 0x002003ff;
+       pr_warning("%s: Bad 38VF640x CFI data; adjusting sector size from 64 to 8KiB\n", mtd->name);
 }
 
 static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param)
@@ -317,14 +334,14 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
 
 /* Used to fix CFI-Tables of chips without Extended Query Tables */
 static struct cfi_fixup cfi_nopri_fixup_table[] = {
-       { CFI_MFR_SST, 0x234A, fixup_sst39vf, NULL, }, // SST39VF1602
-       { CFI_MFR_SST, 0x234B, fixup_sst39vf, NULL, }, // SST39VF1601
-       { CFI_MFR_SST, 0x235A, fixup_sst39vf, NULL, }, // SST39VF3202
-       { CFI_MFR_SST, 0x235B, fixup_sst39vf, NULL, }, // SST39VF3201
-       { CFI_MFR_SST, 0x235C, fixup_sst39vf_rev_b, NULL, }, // SST39VF3202B
-       { CFI_MFR_SST, 0x235D, fixup_sst39vf_rev_b, NULL, }, // SST39VF3201B
-       { CFI_MFR_SST, 0x236C, fixup_sst39vf_rev_b, NULL, }, // SST39VF6402B
-       { CFI_MFR_SST, 0x236D, fixup_sst39vf_rev_b, NULL, }, // SST39VF6401B
+       { CFI_MFR_SST, 0x234A, fixup_sst39vf, NULL, }, /* SST39VF1602 */
+       { CFI_MFR_SST, 0x234B, fixup_sst39vf, NULL, }, /* SST39VF1601 */
+       { CFI_MFR_SST, 0x235A, fixup_sst39vf, NULL, }, /* SST39VF3202 */
+       { CFI_MFR_SST, 0x235B, fixup_sst39vf, NULL, }, /* SST39VF3201 */
+       { CFI_MFR_SST, 0x235C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3202B */
+       { CFI_MFR_SST, 0x235D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3201B */
+       { CFI_MFR_SST, 0x236C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6402B */
+       { CFI_MFR_SST, 0x236D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6401B */
        { 0, 0, NULL, NULL }
 };
 
@@ -344,6 +361,10 @@ static struct cfi_fixup cfi_fixup_table[] = {
        { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
        { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
        { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
+       { CFI_MFR_SST, 0x536A, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6402 */
+       { CFI_MFR_SST, 0x536B, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6401 */
+       { CFI_MFR_SST, 0x536C, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6404 */
+       { CFI_MFR_SST, 0x536D, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6403 */
 #if !FORCE_WORD_WRITE
        { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
 #endif
@@ -374,6 +395,13 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi,
        if (cfi->mfr == CFI_MFR_SAMSUNG && cfi->id == 0x257e &&
            extp->MajorVersion == '0')
                extp->MajorVersion = '1';
+       /*
+        * SST 38VF640x chips report major=0xFF / minor=0xFF.
+        */
+       if (cfi->mfr == CFI_MFR_SST && (cfi->id >> 4) == 0x0536) {
+               extp->MajorVersion = '1';
+               extp->MinorVersion = '0';
+       }
 }
 
 struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
@@ -545,15 +573,6 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
                printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
                goto setup_err;
        }
-#if 0
-       // debug
-       for (i=0; i<mtd->numeraseregions;i++){
-               printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
-                      i,mtd->eraseregions[i].offset,
-                      mtd->eraseregions[i].erasesize,
-                      mtd->eraseregions[i].numblocks);
-       }
-#endif
 
        __module_get(THIS_MODULE);
        register_reboot_notifier(&mtd->reboot_notifier);
@@ -674,7 +693,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                                 * there was an error (so leave the erase
                                 * routine to recover from it) or we trying to
                                 * use the erase-in-progress sector. */
-                               map_write(map, CMD(0x30), chip->in_progress_block_addr);
+                               map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr);
                                chip->state = FL_ERASING;
                                chip->oldstate = FL_READY;
                                printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
@@ -727,7 +746,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
        switch(chip->oldstate) {
        case FL_ERASING:
                chip->state = chip->oldstate;
-               map_write(map, CMD(0x30), chip->in_progress_block_addr);
+               map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr);
                chip->oldstate = FL_READY;
                chip->state = FL_ERASING;
                break;
@@ -870,7 +889,7 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
                        local_irq_disable();
 
                        /* Resume the write or erase operation */
-                       map_write(map, CMD(0x30), adr);
+                       map_write(map, cfi->sector_erase_cmd, adr);
                        chip->state = oldstate;
                        start = xip_currtime();
                } else if (usec >= 1000000/HZ) {
@@ -1025,9 +1044,6 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
        mutex_lock(&chip->mutex);
 
        if (chip->state != FL_READY){
-#if 0
-               printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state);
-#endif
                set_current_state(TASK_UNINTERRUPTIBLE);
                add_wait_queue(&chip->wq, &wait);
 
@@ -1035,10 +1051,6 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
 
                schedule();
                remove_wait_queue(&chip->wq, &wait);
-#if 0
-               if(signal_pending(current))
-                       return -EINTR;
-#endif
                timeo = jiffies + HZ;
 
                goto retry;
@@ -1246,9 +1258,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
                mutex_lock(&cfi->chips[chipnum].mutex);
 
                if (cfi->chips[chipnum].state != FL_READY) {
-#if 0
-                       printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
-#endif
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&cfi->chips[chipnum].wq, &wait);
 
@@ -1256,10 +1265,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
 
                        schedule();
                        remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
-#if 0
-                       if(signal_pending(current))
-                               return -EINTR;
-#endif
                        goto retry;
                }
 
@@ -1324,9 +1329,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
                mutex_lock(&cfi->chips[chipnum].mutex);
 
                if (cfi->chips[chipnum].state != FL_READY) {
-#if 0
-                       printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
-#endif
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&cfi->chips[chipnum].wq, &wait);
 
@@ -1334,10 +1336,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
 
                        schedule();
                        remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
-#if 0
-                       if(signal_pending(current))
-                               return -EINTR;
-#endif
                        goto retry1;
                }
 
@@ -1396,7 +1394,6 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
 
        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
-       //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
 
        /* Write Buffer Load */
        map_write(map, CMD(0x25), cmd_adr);
@@ -1675,7 +1672,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
        cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
-       map_write(map, CMD(0x30), adr);
+       map_write(map, cfi->sector_erase_cmd, adr);
 
        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
index 8f5b96aa87a0ae601f2ebeb2ea2e4353bcf5d65d..d25535279404a7b7d101692b3f5c3f262cd0626e 100644 (file)
@@ -177,6 +177,8 @@ static int __xipram cfi_chip_setup(struct map_info *map,
 
        cfi->cfi_mode = CFI_MODE_CFI;
 
+       cfi->sector_erase_cmd = CMD(0x30);
+
        /* Read the CFI info structure */
        xip_disable_qry(base, map, cfi);
        for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
index e503b2ca894de98687490d8b1806739dc9d61021..360525c637d2524cd984aadc1eb6b238846ec71f 100644 (file)
@@ -75,6 +75,13 @@ int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map,
        cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
        cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
        cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
+       if (cfi_qry_present(map, base, cfi))
+               return 1;
+       /* SST 39VF640xB */
+       cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0xAA, 0x555, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x55, 0x2AA, base, map, cfi, cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL);
        if (cfi_qry_present(map, base, cfi))
                return 1;
        /* QRY not found */
index 93651865ddbe6892891ce685698fe86153925807..2cf0cc6a418931897d7149978125041172522e9c 100644 (file)
@@ -91,7 +91,6 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
        } else
                instr->state = MTD_ERASE_DONE;
 
-       instr->state = MTD_ERASE_DONE;
        mtd_erase_callback(instr);
        return err;
 }
index ea22520c0406ed6a7c7a3537ee7ce64adf558481..bf5a002209bdb4603f7ecb811234a8223ea43bf1 100644 (file)
@@ -661,11 +661,14 @@ static const struct spi_device_id m25p_ids[] = {
        { "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
        { "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
        { "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
+       { "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SECT_4K) },
        { "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
        { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
        { "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
        { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
        { "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
+       { "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K) },
+       { "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
 
        /* SST -- large erase sizes are "overlays", "sectors" are 4K */
        { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K) },
@@ -714,6 +717,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
        { "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
        { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
+       { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
 
        /* Catalyst / On Semiconductor -- non-JEDEC */
        { "cat25c11", CAT25_INFO(  16, 8, 16, 1) },
@@ -924,7 +928,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
                        nr_parts = data->nr_parts;
                }
 
-#ifdef CONFIG_OF
+#ifdef CONFIG_MTD_OF_PARTS
                if (nr_parts <= 0 && spi->dev.of_node) {
                        nr_parts = of_mtd_parse_partitions(&spi->dev,
                                        spi->dev.of_node, &parts);
index 1696bbecaa7e0e86b31a2e7126b9bf77faf4d596..52393282eaf10ca813ed131565ce45951443542e 100644 (file)
@@ -15,7 +15,7 @@
  *     phram=swap,64Mi,128Mi phram=test,900Mi,1Mi
  */
 
-#define pr_fmt(fmt) "phram: " fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <asm/io.h>
 #include <linux/init.h>
index 962212628f6e3400ec171646c04139b6920cd9be..a0dd7bba9481ce1e3480ffe0ee55902994653731 100644 (file)
@@ -251,6 +251,15 @@ config MTD_NETtel
        help
          Support for flash chips on NETtel/SecureEdge/SnapGear boards.
 
+config MTD_BCM963XX
+        tristate "Map driver for Broadcom BCM963xx boards"
+        depends on BCM63XX
+       select MTD_MAP_BANK_WIDTH_2
+       select MTD_CFI_I1
+        help
+         Support for parsing CFE image tag and creating MTD partitions on
+         Broadcom BCM63xx boards.
+
 config MTD_DILNETPC
        tristate "CFI Flash device mapped on DIL/Net PC"
        depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
index f216bb573713a4edc99e7dbecb121541da76eb2b..c7869c7a6b18f1a2534976cb4388aa22efc2839b 100644 (file)
@@ -58,3 +58,4 @@ obj-$(CONFIG_MTD_BFIN_ASYNC)  += bfin-async-flash.o
 obj-$(CONFIG_MTD_RBTX4939)     += rbtx4939-flash.o
 obj-$(CONFIG_MTD_VMU)          += vmu-flash.o
 obj-$(CONFIG_MTD_GPIO_ADDR)    += gpio-addr-flash.o
+obj-$(CONFIG_MTD_BCM963XX)     += bcm963xx-flash.o
diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c
new file mode 100644 (file)
index 0000000..d175c12
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Copyright © 2006-2008  Florian Fainelli <florian@openwrt.org>
+ *                       Mike Albon <malbon@openwrt.org>
+ * Copyright © 2009-2010  Daniel Dickinson <openwrt@cshore.neomailbox.net>
+ *
+ * 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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/vmalloc.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach-bcm63xx/bcm963xx_tag.h>
+
+#define BCM63XX_BUSWIDTH       2               /* Buswidth */
+#define BCM63XX_EXTENDED_SIZE  0xBFC00000      /* Extended flash address */
+
+#define PFX KBUILD_MODNAME ": "
+
+static struct mtd_partition *parsed_parts;
+
+static struct mtd_info *bcm963xx_mtd_info;
+
+static struct map_info bcm963xx_map = {
+       .name           = "bcm963xx",
+       .bankwidth      = BCM63XX_BUSWIDTH,
+};
+
+static int parse_cfe_partitions(struct mtd_info *master,
+                                               struct mtd_partition **pparts)
+{
+       /* CFE, NVRAM and global Linux are always present */
+       int nrparts = 3, curpart = 0;
+       struct bcm_tag *buf;
+       struct mtd_partition *parts;
+       int ret;
+       size_t retlen;
+       unsigned int rootfsaddr, kerneladdr, spareaddr;
+       unsigned int rootfslen, kernellen, sparelen, totallen;
+       int namelen = 0;
+       int i;
+       char *boardid;
+       char *tagversion;
+
+       /* Allocate memory for buffer */
+       buf = vmalloc(sizeof(struct bcm_tag));
+       if (!buf)
+               return -ENOMEM;
+
+       /* Get the tag */
+       ret = master->read(master, master->erasesize, sizeof(struct bcm_tag),
+                                                       &retlen, (void *)buf);
+       if (retlen != sizeof(struct bcm_tag)) {
+               vfree(buf);
+               return -EIO;
+       }
+
+       sscanf(buf->kernel_address, "%u", &kerneladdr);
+       sscanf(buf->kernel_length, "%u", &kernellen);
+       sscanf(buf->total_length, "%u", &totallen);
+       tagversion = &(buf->tag_version[0]);
+       boardid = &(buf->board_id[0]);
+
+       printk(KERN_INFO PFX "CFE boot tag found with version %s "
+                               "and board type %s\n", tagversion, boardid);
+
+       kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
+       rootfsaddr = kerneladdr + kernellen;
+       spareaddr = roundup(totallen, master->erasesize) + master->erasesize;
+       sparelen = master->size - spareaddr - master->erasesize;
+       rootfslen = spareaddr - rootfsaddr;
+
+       /* Determine number of partitions */
+       namelen = 8;
+       if (rootfslen > 0) {
+               nrparts++;
+               namelen += 6;
+       };
+       if (kernellen > 0) {
+               nrparts++;
+               namelen += 6;
+       };
+
+       /* Ask kernel for more memory */
+       parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
+       if (!parts) {
+               vfree(buf);
+               return -ENOMEM;
+       };
+
+       /* Start building partition list */
+       parts[curpart].name = "CFE";
+       parts[curpart].offset = 0;
+       parts[curpart].size = master->erasesize;
+       curpart++;
+
+       if (kernellen > 0) {
+               parts[curpart].name = "kernel";
+               parts[curpart].offset = kerneladdr;
+               parts[curpart].size = kernellen;
+               curpart++;
+       };
+
+       if (rootfslen > 0) {
+               parts[curpart].name = "rootfs";
+               parts[curpart].offset = rootfsaddr;
+               parts[curpart].size = rootfslen;
+               if (sparelen > 0)
+                       parts[curpart].size += sparelen;
+               curpart++;
+       };
+
+       parts[curpart].name = "nvram";
+       parts[curpart].offset = master->size - master->erasesize;
+       parts[curpart].size = master->erasesize;
+
+       /* Global partition "linux" to make easy firmware upgrade */
+       curpart++;
+       parts[curpart].name = "linux";
+       parts[curpart].offset = parts[0].size;
+       parts[curpart].size = master->size - parts[0].size - parts[3].size;
+
+       for (i = 0; i < nrparts; i++)
+               printk(KERN_INFO PFX "Partition %d is %s offset %lx and "
+                                       "length %lx\n", i, parts[i].name,
+                                       (long unsigned int)(parts[i].offset),
+                                       (long unsigned int)(parts[i].size));
+
+       printk(KERN_INFO PFX "Spare partition is %x offset and length %x\n",
+                                                       spareaddr, sparelen);
+       *pparts = parts;
+       vfree(buf);
+
+       return nrparts;
+};
+
+static int bcm963xx_detect_cfe(struct mtd_info *master)
+{
+       int idoffset = 0x4e0;
+       static char idstring[8] = "CFE1CFE1";
+       char buf[9];
+       int ret;
+       size_t retlen;
+
+       ret = master->read(master, idoffset, 8, &retlen, (void *)buf);
+       buf[retlen] = 0;
+       printk(KERN_INFO PFX "Read Signature value of %s\n", buf);
+
+       return strncmp(idstring, buf, 8);
+}
+
+static int bcm963xx_probe(struct platform_device *pdev)
+{
+       int err = 0;
+       int parsed_nr_parts = 0;
+       char *part_type;
+       struct resource *r;
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!r) {
+               dev_err(&pdev->dev, "no resource supplied\n");
+               return -ENODEV;
+       }
+
+       bcm963xx_map.phys = r->start;
+       bcm963xx_map.size = resource_size(r);
+       bcm963xx_map.virt = ioremap(r->start, resource_size(r));
+       if (!bcm963xx_map.virt) {
+               dev_err(&pdev->dev, "failed to ioremap\n");
+               return -EIO;
+       }
+
+       dev_info(&pdev->dev, "0x%08lx at 0x%08x\n",
+                                       bcm963xx_map.size, bcm963xx_map.phys);
+
+       simple_map_init(&bcm963xx_map);
+
+       bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map);
+       if (!bcm963xx_mtd_info) {
+               dev_err(&pdev->dev, "failed to probe using CFI\n");
+               err = -EIO;
+               goto err_probe;
+       }
+
+       bcm963xx_mtd_info->owner = THIS_MODULE;
+
+       /* This is mutually exclusive */
+       if (bcm963xx_detect_cfe(bcm963xx_mtd_info) == 0) {
+               dev_info(&pdev->dev, "CFE bootloader detected\n");
+               if (parsed_nr_parts == 0) {
+                       int ret = parse_cfe_partitions(bcm963xx_mtd_info,
+                                                       &parsed_parts);
+                       if (ret > 0) {
+                               part_type = "CFE";
+                               parsed_nr_parts = ret;
+                       }
+               }
+       } else {
+               dev_info(&pdev->dev, "unsupported bootloader\n");
+               err = -ENODEV;
+               goto err_probe;
+       }
+
+       return add_mtd_partitions(bcm963xx_mtd_info, parsed_parts,
+                                               parsed_nr_parts);
+
+err_probe:
+       iounmap(bcm963xx_map.virt);
+       return err;
+}
+
+static int bcm963xx_remove(struct platform_device *pdev)
+{
+       if (bcm963xx_mtd_info) {
+               del_mtd_partitions(bcm963xx_mtd_info);
+               map_destroy(bcm963xx_mtd_info);
+       }
+
+       if (bcm963xx_map.virt) {
+               iounmap(bcm963xx_map.virt);
+               bcm963xx_map.virt = 0;
+       }
+
+       return 0;
+}
+
+static struct platform_driver bcm63xx_mtd_dev = {
+       .probe  = bcm963xx_probe,
+       .remove = bcm963xx_remove,
+       .driver = {
+               .name   = "bcm963xx-flash",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init bcm963xx_mtd_init(void)
+{
+       return platform_driver_register(&bcm63xx_mtd_dev);
+}
+
+static void __exit bcm963xx_mtd_exit(void)
+{
+       platform_driver_unregister(&bcm63xx_mtd_dev);
+}
+
+module_init(bcm963xx_mtd_init);
+module_exit(bcm963xx_mtd_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Broadcom BCM63xx MTD driver for CFE and RedBoot");
+MODULE_AUTHOR("Daniel Dickinson <openwrt@cshore.neomailbox.net>");
+MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
+MODULE_AUTHOR("Mike Albon <malbon@openwrt.org>");
index 32e89d773b4ead7dbaa6172e331fb6c9f11f17ec..af5707a80205c34985b2cba5cf2ceffce91cca76 100644 (file)
@@ -208,10 +208,14 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev)
        if (!state)
                return -ENOMEM;
 
+       /*
+        * We cast start/end to known types in the boards file, so cast
+        * away their pointer types here to the known types (gpios->xxx).
+        */
        state->gpio_count     = gpios->end;
-       state->gpio_addrs     = (void *)gpios->start;
+       state->gpio_addrs     = (void *)(unsigned long)gpios->start;
        state->gpio_values    = (void *)(state + 1);
-       state->win_size       = memory->end - memory->start + 1;
+       state->win_size       = resource_size(memory);
        memset(state->gpio_values, 0xff, arr_size);
 
        state->map.name       = DRIVER_NAME;
@@ -221,7 +225,7 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev)
        state->map.copy_to    = gf_copy_to;
        state->map.bankwidth  = pdata->width;
        state->map.size       = state->win_size * (1 << state->gpio_count);
-       state->map.virt       = (void __iomem *)memory->start;
+       state->map.virt       = ioremap_nocache(memory->start, state->map.size);
        state->map.phys       = NO_XIP;
        state->map.map_priv_1 = (unsigned long)state;
 
index 57a1acfe22c4a2df13903e42918b14ac47f875a4..91702294839942e8c225ed3f3176011a489d2d61 100644 (file)
@@ -640,10 +640,6 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        }
        dev_info(&dev->p_dev->dev, "mtd%d: %s\n", mtd->index, mtd->name);
        return 0;
-
-       dev_err(&dev->p_dev->dev, "CS Error, exiting\n");
-       pcmciamtd_release(link);
-       return -ENODEV;
 }
 
 
index ec3edf6e68b46175cd10ccff2e6d3dd3f72b8fd8..9861814aa027a3745b8e3112db3dd85370dd561a 100644 (file)
@@ -50,7 +50,7 @@ static int parse_obsolete_partitions(struct platform_device *dev,
 {
        int i, plen, nr_parts;
        const struct {
-               u32 offset, len;
+               __be32 offset, len;
        } *part;
        const char *names;
 
@@ -69,9 +69,9 @@ static int parse_obsolete_partitions(struct platform_device *dev,
        names = of_get_property(dp, "partition-names", &plen);
 
        for (i = 0; i < nr_parts; i++) {
-               info->parts[i].offset = part->offset;
-               info->parts[i].size   = part->len & ~1;
-               if (part->len & 1) /* bit 0 set signifies read only partition */
+               info->parts[i].offset = be32_to_cpu(part->offset);
+               info->parts[i].size   = be32_to_cpu(part->len) & ~1;
+               if (be32_to_cpu(part->len) & 1) /* bit 0 set signifies read only partition */
                        info->parts[i].mask_flags = MTD_WRITEABLE;
 
                if (names && (plen > 0)) {
@@ -226,11 +226,11 @@ static int __devinit of_flash_probe(struct platform_device *dev,
        struct resource res;
        struct of_flash *info;
        const char *probe_type = match->data;
-       const u32 *width;
+       const __be32 *width;
        int err;
        int i;
        int count;
-       const u32 *p;
+       const __be32 *p;
        int reg_tuple_size;
        struct mtd_info **mtd_list = NULL;
        resource_size_t res_size;
@@ -267,9 +267,11 @@ static int __devinit of_flash_probe(struct platform_device *dev,
        for (i = 0; i < count; i++) {
                err = -ENXIO;
                if (of_address_to_resource(dp, i, &res)) {
-                       dev_err(&dev->dev, "Can't get IO address from device"
-                               " tree\n");
-                       goto err_out;
+                       /*
+                        * Continue with next register tuple if this
+                        * one is not mappable
+                        */
+                       continue;
                }
 
                dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n",
index 50ab431b24ebafd456269061ac7a6873c152a57d..cb20c67995d8ba52652d8765b80dbceb82eba2b8 100644 (file)
@@ -37,7 +37,6 @@
 
 #include "mtdcore.h"
 
-static DEFINE_MUTEX(mtd_blkdevs_mutex);
 static LIST_HEAD(blktrans_majors);
 static DEFINE_MUTEX(blktrans_ref_mutex);
 
@@ -133,6 +132,10 @@ static int mtd_blktrans_thread(void *arg)
 
                if (!req && !(req = blk_fetch_request(rq))) {
                        set_current_state(TASK_INTERRUPTIBLE);
+
+                       if (kthread_should_stop())
+                               set_current_state(TASK_RUNNING);
+
                        spin_unlock_irq(rq->queue_lock);
                        schedule();
                        spin_lock_irq(rq->queue_lock);
@@ -176,54 +179,53 @@ static void mtd_blktrans_request(struct request_queue *rq)
 static int blktrans_open(struct block_device *bdev, fmode_t mode)
 {
        struct mtd_blktrans_dev *dev = blktrans_dev_get(bdev->bd_disk);
-       int ret;
+       int ret = 0;
 
        if (!dev)
                return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
 
-       mutex_lock(&mtd_blkdevs_mutex);
        mutex_lock(&dev->lock);
 
-       if (!dev->mtd) {
-               ret = -ENXIO;
+       if (dev->open++)
                goto unlock;
-       }
 
-       ret = !dev->open++ && dev->tr->open ? dev->tr->open(dev) : 0;
+       kref_get(&dev->ref);
+       __module_get(dev->tr->owner);
+
+       if (dev->mtd) {
+               ret = dev->tr->open ? dev->tr->open(dev) : 0;
+               __get_mtd_device(dev->mtd);
+       }
 
-       /* Take another reference on the device so it won't go away till
-               last release */
-       if (!ret)
-               kref_get(&dev->ref);
 unlock:
        mutex_unlock(&dev->lock);
        blktrans_dev_put(dev);
-       mutex_unlock(&mtd_blkdevs_mutex);
        return ret;
 }
 
 static int blktrans_release(struct gendisk *disk, fmode_t mode)
 {
        struct mtd_blktrans_dev *dev = blktrans_dev_get(disk);
-       int ret = -ENXIO;
+       int ret = 0;
 
        if (!dev)
                return ret;
 
-       mutex_lock(&mtd_blkdevs_mutex);
        mutex_lock(&dev->lock);
 
-       /* Release one reference, we sure its not the last one here*/
-       kref_put(&dev->ref, blktrans_dev_release);
-
-       if (!dev->mtd)
+       if (--dev->open)
                goto unlock;
 
-       ret = !--dev->open && dev->tr->release ? dev->tr->release(dev) : 0;
+       kref_put(&dev->ref, blktrans_dev_release);
+       module_put(dev->tr->owner);
+
+       if (dev->mtd) {
+               ret = dev->tr->release ? dev->tr->release(dev) : 0;
+               __put_mtd_device(dev->mtd);
+       }
 unlock:
        mutex_unlock(&dev->lock);
        blktrans_dev_put(dev);
-       mutex_unlock(&mtd_blkdevs_mutex);
        return ret;
 }
 
@@ -256,7 +258,6 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
        if (!dev)
                return ret;
 
-       mutex_lock(&mtd_blkdevs_mutex);
        mutex_lock(&dev->lock);
 
        if (!dev->mtd)
@@ -271,7 +272,6 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
        }
 unlock:
        mutex_unlock(&dev->lock);
-       mutex_unlock(&mtd_blkdevs_mutex);
        blktrans_dev_put(dev);
        return ret;
 }
@@ -385,9 +385,6 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 
        gd->queue = new->rq;
 
-       __get_mtd_device(new->mtd);
-       __module_get(tr->owner);
-
        /* Create processing thread */
        /* TODO: workqueue ? */
        new->thread = kthread_run(mtd_blktrans_thread, new,
@@ -410,8 +407,6 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
        }
        return 0;
 error4:
-       module_put(tr->owner);
-       __put_mtd_device(new->mtd);
        blk_cleanup_queue(new->rq);
 error3:
        put_disk(new->disk);
@@ -448,17 +443,15 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
        blk_start_queue(old->rq);
        spin_unlock_irqrestore(&old->queue_lock, flags);
 
-       /* Ask trans driver for release to the mtd device */
+       /* If the device is currently open, tell trans driver to close it,
+               then put mtd device, and don't touch it again */
        mutex_lock(&old->lock);
-       if (old->open && old->tr->release) {
-               old->tr->release(old);
-               old->open = 0;
+       if (old->open) {
+               if (old->tr->release)
+                       old->tr->release(old);
+               __put_mtd_device(old->mtd);
        }
 
-       __put_mtd_device(old->mtd);
-       module_put(old->tr->owner);
-
-       /* At that point, we don't touch the mtd anymore */
        old->mtd = NULL;
 
        mutex_unlock(&old->lock);
@@ -508,13 +501,16 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
        mutex_lock(&mtd_table_mutex);
 
        ret = register_blkdev(tr->major, tr->name);
-       if (ret) {
+       if (ret < 0) {
                printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
                       tr->name, tr->major, ret);
                mutex_unlock(&mtd_table_mutex);
                return ret;
        }
 
+       if (ret)
+               tr->major = ret;
+
        tr->blkshift = ffs(tr->blksize) - 1;
 
        INIT_LIST_HEAD(&tr->devs);
index 5ef45487b65f01c261222b35d5fd6ecc548bea7e..4759d827e8c78264b7ec54e1851eb9bdb6ed9c8c 100644 (file)
@@ -30,8 +30,9 @@
 #include <linux/backing-dev.h>
 #include <linux/compat.h>
 #include <linux/mount.h>
-
+#include <linux/blkpg.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
 #include <linux/mtd/map.h>
 
 #include <asm/uaccess.h>
@@ -478,6 +479,78 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
        return ret;
 }
 
+/*
+ * Copies (and truncates, if necessary) data from the larger struct,
+ * nand_ecclayout, to the smaller, deprecated layout struct,
+ * nand_ecclayout_user. This is necessary only to suppport the deprecated
+ * API ioctl ECCGETLAYOUT while allowing all new functionality to use
+ * nand_ecclayout flexibly (i.e. the struct may change size in new
+ * releases without requiring major rewrites).
+ */
+static int shrink_ecclayout(const struct nand_ecclayout *from,
+               struct nand_ecclayout_user *to)
+{
+       int i;
+
+       if (!from || !to)
+               return -EINVAL;
+
+       memset(to, 0, sizeof(*to));
+
+       to->eccbytes = min((int)from->eccbytes, MTD_MAX_ECCPOS_ENTRIES);
+       for (i = 0; i < to->eccbytes; i++)
+               to->eccpos[i] = from->eccpos[i];
+
+       for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
+               if (from->oobfree[i].length == 0 &&
+                               from->oobfree[i].offset == 0)
+                       break;
+               to->oobavail += from->oobfree[i].length;
+               to->oobfree[i] = from->oobfree[i];
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_MTD_PARTITIONS
+static int mtd_blkpg_ioctl(struct mtd_info *mtd,
+                          struct blkpg_ioctl_arg __user *arg)
+{
+       struct blkpg_ioctl_arg a;
+       struct blkpg_partition p;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       /* Only master mtd device must be used to control partitions */
+       if (!mtd_is_master(mtd))
+               return -EINVAL;
+
+       if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
+               return -EFAULT;
+
+       if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
+               return -EFAULT;
+
+       switch (a.op) {
+       case BLKPG_ADD_PARTITION:
+
+               return mtd_add_partition(mtd, p.devname, p.start, p.length);
+
+       case BLKPG_DEL_PARTITION:
+
+               if (p.pno < 0)
+                       return -EINVAL;
+
+               return mtd_del_partition(mtd, p.pno);
+
+       default:
+               return -EINVAL;
+       }
+}
+#endif
+
+
 static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
 {
        struct mtd_file_info *mfi = file->private_data;
@@ -514,6 +587,9 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
                if (get_user(ur_idx, &(ur->regionindex)))
                        return -EFAULT;
 
+               if (ur_idx >= mtd->numeraseregions)
+                       return -EINVAL;
+
                kr = &(mtd->eraseregions[ur_idx]);
 
                if (put_user(kr->offset, &(ur->offset))
@@ -813,14 +889,23 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
        }
 #endif
 
+       /* This ioctl is being deprecated - it truncates the ecc layout */
        case ECCGETLAYOUT:
        {
+               struct nand_ecclayout_user *usrlay;
+
                if (!mtd->ecclayout)
                        return -EOPNOTSUPP;
 
-               if (copy_to_user(argp, mtd->ecclayout,
-                                sizeof(struct nand_ecclayout)))
-                       return -EFAULT;
+               usrlay = kmalloc(sizeof(*usrlay), GFP_KERNEL);
+               if (!usrlay)
+                       return -ENOMEM;
+
+               shrink_ecclayout(mtd->ecclayout, usrlay);
+
+               if (copy_to_user(argp, usrlay, sizeof(*usrlay)))
+                       ret = -EFAULT;
+               kfree(usrlay);
                break;
        }
 
@@ -856,6 +941,22 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
                break;
        }
 
+#ifdef CONFIG_MTD_PARTITIONS
+       case BLKPG:
+       {
+               ret = mtd_blkpg_ioctl(mtd,
+                     (struct blkpg_ioctl_arg __user *)arg);
+               break;
+       }
+
+       case BLKRRPART:
+       {
+               /* No reread partition feature. Just return ok */
+               ret = 0;
+               break;
+       }
+#endif
+
        default:
                ret = -ENOTTY;
        }
@@ -1030,17 +1131,15 @@ static const struct file_operations mtd_fops = {
 #endif
 };
 
-static int mtd_inodefs_get_sb(struct file_system_type *fs_type, int flags,
-                               const char *dev_name, void *data,
-                               struct vfsmount *mnt)
+static struct dentry *mtd_inodefs_mount(struct file_system_type *fs_type,
+                               int flags, const char *dev_name, void *data)
 {
-        return get_sb_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC,
-                             mnt);
+       return mount_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC);
 }
 
 static struct file_system_type mtd_inodefs_type = {
        .name = "mtd_inodefs",
-       .get_sb = mtd_inodefs_get_sb,
+       .mount = mtd_inodefs_mount,
        .kill_sb = kill_anon_super,
 };
 
index dc65585688765c1f7e6e975b8c3c1fa8bc53429f..79e3689f1e16901f07e5ee770bcde218814d621d 100644 (file)
 #include <linux/kmod.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/err.h>
 
 /* Our partition linked list */
 static LIST_HEAD(mtd_partitions);
+static DEFINE_MUTEX(mtd_partitions_mutex);
 
 /* Our partition node structure */
 struct mtd_part {
@@ -326,6 +328,12 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
        return res;
 }
 
+static inline void free_partition(struct mtd_part *p)
+{
+       kfree(p->mtd.name);
+       kfree(p);
+}
+
 /*
  * This function unregisters and destroy all slave MTD objects which are
  * attached to the given master MTD object.
@@ -334,33 +342,42 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
 int del_mtd_partitions(struct mtd_info *master)
 {
        struct mtd_part *slave, *next;
+       int ret, err = 0;
 
+       mutex_lock(&mtd_partitions_mutex);
        list_for_each_entry_safe(slave, next, &mtd_partitions, list)
                if (slave->master == master) {
+                       ret = del_mtd_device(&slave->mtd);
+                       if (ret < 0) {
+                               err = ret;
+                               continue;
+                       }
                        list_del(&slave->list);
-                       del_mtd_device(&slave->mtd);
-                       kfree(slave);
+                       free_partition(slave);
                }
+       mutex_unlock(&mtd_partitions_mutex);
 
-       return 0;
+       return err;
 }
 EXPORT_SYMBOL(del_mtd_partitions);
 
-static struct mtd_part *add_one_partition(struct mtd_info *master,
-               const struct mtd_partition *part, int partno,
-               uint64_t cur_offset)
+static struct mtd_part *allocate_partition(struct mtd_info *master,
+                       const struct mtd_partition *part, int partno,
+                       uint64_t cur_offset)
 {
        struct mtd_part *slave;
+       char *name;
 
        /* allocate the partition structure */
        slave = kzalloc(sizeof(*slave), GFP_KERNEL);
-       if (!slave) {
+       name = kstrdup(part->name, GFP_KERNEL);
+       if (!name || !slave) {
                printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n",
-                       master->name);
-               del_mtd_partitions(master);
-               return NULL;
+                      master->name);
+               kfree(name);
+               kfree(slave);
+               return ERR_PTR(-ENOMEM);
        }
-       list_add(&slave->list, &mtd_partitions);
 
        /* set up the MTD object for this partition */
        slave->mtd.type = master->type;
@@ -371,7 +388,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
        slave->mtd.oobavail = master->oobavail;
        slave->mtd.subpage_sft = master->subpage_sft;
 
-       slave->mtd.name = part->name;
+       slave->mtd.name = name;
        slave->mtd.owner = master->owner;
        slave->mtd.backing_dev_info = master->backing_dev_info;
 
@@ -518,12 +535,89 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
        }
 
 out_register:
-       /* register our partition */
-       add_mtd_device(&slave->mtd);
-
        return slave;
 }
 
+int mtd_add_partition(struct mtd_info *master, char *name,
+                     long long offset, long long length)
+{
+       struct mtd_partition part;
+       struct mtd_part *p, *new;
+       uint64_t start, end;
+       int ret = 0;
+
+       /* the direct offset is expected */
+       if (offset == MTDPART_OFS_APPEND ||
+           offset == MTDPART_OFS_NXTBLK)
+               return -EINVAL;
+
+       if (length == MTDPART_SIZ_FULL)
+               length = master->size - offset;
+
+       if (length <= 0)
+               return -EINVAL;
+
+       part.name = name;
+       part.size = length;
+       part.offset = offset;
+       part.mask_flags = 0;
+       part.ecclayout = NULL;
+
+       new = allocate_partition(master, &part, -1, offset);
+       if (IS_ERR(new))
+               return PTR_ERR(new);
+
+       start = offset;
+       end = offset + length;
+
+       mutex_lock(&mtd_partitions_mutex);
+       list_for_each_entry(p, &mtd_partitions, list)
+               if (p->master == master) {
+                       if ((start >= p->offset) &&
+                           (start < (p->offset + p->mtd.size)))
+                               goto err_inv;
+
+                       if ((end >= p->offset) &&
+                           (end < (p->offset + p->mtd.size)))
+                               goto err_inv;
+               }
+
+       list_add(&new->list, &mtd_partitions);
+       mutex_unlock(&mtd_partitions_mutex);
+
+       add_mtd_device(&new->mtd);
+
+       return ret;
+err_inv:
+       mutex_unlock(&mtd_partitions_mutex);
+       free_partition(new);
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(mtd_add_partition);
+
+int mtd_del_partition(struct mtd_info *master, int partno)
+{
+       struct mtd_part *slave, *next;
+       int ret = -EINVAL;
+
+       mutex_lock(&mtd_partitions_mutex);
+       list_for_each_entry_safe(slave, next, &mtd_partitions, list)
+               if ((slave->master == master) &&
+                   (slave->mtd.index == partno)) {
+                       ret = del_mtd_device(&slave->mtd);
+                       if (ret < 0)
+                               break;
+
+                       list_del(&slave->list);
+                       free_partition(slave);
+                       break;
+               }
+       mutex_unlock(&mtd_partitions_mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(mtd_del_partition);
+
 /*
  * This function, given a master MTD object and a partition table, creates
  * and registers slave MTD objects which are bound to the master according to
@@ -544,9 +638,16 @@ int add_mtd_partitions(struct mtd_info *master,
        printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
 
        for (i = 0; i < nbparts; i++) {
-               slave = add_one_partition(master, parts + i, i, cur_offset);
-               if (!slave)
-                       return -ENOMEM;
+               slave = allocate_partition(master, parts + i, i, cur_offset);
+               if (IS_ERR(slave))
+                       return PTR_ERR(slave);
+
+               mutex_lock(&mtd_partitions_mutex);
+               list_add(&slave->list, &mtd_partitions);
+               mutex_unlock(&mtd_partitions_mutex);
+
+               add_mtd_device(&slave->mtd);
+
                cur_offset = slave->offset + slave->mtd.size;
        }
 
@@ -618,3 +719,20 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
        return ret;
 }
 EXPORT_SYMBOL_GPL(parse_mtd_partitions);
+
+int mtd_is_master(struct mtd_info *mtd)
+{
+       struct mtd_part *part;
+       int nopart = 0;
+
+       mutex_lock(&mtd_partitions_mutex);
+       list_for_each_entry(part, &mtd_partitions, list)
+               if (&part->mtd == mtd) {
+                       nopart = 1;
+                       break;
+               }
+       mutex_unlock(&mtd_partitions_mutex);
+
+       return nopart;
+}
+EXPORT_SYMBOL_GPL(mtd_is_master);
index 38e2ab07e7a3fc771f40d7a4448b52906d88c0d6..16b02a1fc100ce542bfdaad9bb6fdbf7f8b433fe 100644 (file)
@@ -54,11 +54,10 @@ static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
 /*
  * get a superblock on an MTD-backed filesystem
  */
-static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags,
+static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags,
                          const char *dev_name, void *data,
                          struct mtd_info *mtd,
-                         int (*fill_super)(struct super_block *, void *, int),
-                         struct vfsmount *mnt)
+                         int (*fill_super)(struct super_block *, void *, int))
 {
        struct super_block *sb;
        int ret;
@@ -79,57 +78,49 @@ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags,
        ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
        if (ret < 0) {
                deactivate_locked_super(sb);
-               return ret;
+               return ERR_PTR(ret);
        }
 
        /* go */
        sb->s_flags |= MS_ACTIVE;
-       simple_set_mnt(mnt, sb);
-
-       return 0;
+       return dget(sb->s_root);
 
        /* new mountpoint for an already mounted superblock */
 already_mounted:
        DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
              mtd->index, mtd->name);
-       simple_set_mnt(mnt, sb);
-       ret = 0;
-       goto out_put;
+       put_mtd_device(mtd);
+       return dget(sb->s_root);
 
 out_error:
-       ret = PTR_ERR(sb);
-out_put:
        put_mtd_device(mtd);
-       return ret;
+       return ERR_CAST(sb);
 }
 
 /*
  * get a superblock on an MTD-backed filesystem by MTD device number
  */
-static int get_sb_mtd_nr(struct file_system_type *fs_type, int flags,
+static struct dentry *mount_mtd_nr(struct file_system_type *fs_type, int flags,
                         const char *dev_name, void *data, int mtdnr,
-                        int (*fill_super)(struct super_block *, void *, int),
-                        struct vfsmount *mnt)
+                        int (*fill_super)(struct super_block *, void *, int))
 {
        struct mtd_info *mtd;
 
        mtd = get_mtd_device(NULL, mtdnr);
        if (IS_ERR(mtd)) {
                DEBUG(0, "MTDSB: Device #%u doesn't appear to exist\n", mtdnr);
-               return PTR_ERR(mtd);
+               return ERR_CAST(mtd);
        }
 
-       return get_sb_mtd_aux(fs_type, flags, dev_name, data, mtd, fill_super,
-                             mnt);
+       return mount_mtd_aux(fs_type, flags, dev_name, data, mtd, fill_super);
 }
 
 /*
  * set up an MTD-based superblock
  */
-int get_sb_mtd(struct file_system_type *fs_type, int flags,
+struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
               const char *dev_name, void *data,
-              int (*fill_super)(struct super_block *, void *, int),
-              struct vfsmount *mnt)
+              int (*fill_super)(struct super_block *, void *, int))
 {
 #ifdef CONFIG_BLOCK
        struct block_device *bdev;
@@ -138,7 +129,7 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags,
        int mtdnr;
 
        if (!dev_name)
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
 
        DEBUG(2, "MTDSB: dev_name \"%s\"\n", dev_name);
 
@@ -156,10 +147,10 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags,
 
                        mtd = get_mtd_device_nm(dev_name + 4);
                        if (!IS_ERR(mtd))
-                               return get_sb_mtd_aux(
+                               return mount_mtd_aux(
                                        fs_type, flags,
                                        dev_name, data, mtd,
-                                       fill_super, mnt);
+                                       fill_super);
 
                        printk(KERN_NOTICE "MTD:"
                               " MTD device with name \"%s\" not found.\n",
@@ -174,9 +165,9 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags,
                                /* It was a valid number */
                                DEBUG(1, "MTDSB: mtd%%d, mtdnr %d\n",
                                      mtdnr);
-                               return get_sb_mtd_nr(fs_type, flags,
+                               return mount_mtd_nr(fs_type, flags,
                                                     dev_name, data,
-                                                    mtdnr, fill_super, mnt);
+                                                    mtdnr, fill_super);
                        }
                }
        }
@@ -189,7 +180,7 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags,
        if (IS_ERR(bdev)) {
                ret = PTR_ERR(bdev);
                DEBUG(1, "MTDSB: lookup_bdev() returned %d\n", ret);
-               return ret;
+               return ERR_PTR(ret);
        }
        DEBUG(1, "MTDSB: lookup_bdev() returned 0\n");
 
@@ -202,8 +193,7 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags,
        if (major != MTD_BLOCK_MAJOR)
                goto not_an_MTD_device;
 
-       return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super,
-                            mnt);
+       return mount_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super);
 
 not_an_MTD_device:
 #endif /* CONFIG_BLOCK */
@@ -212,10 +202,10 @@ not_an_MTD_device:
                printk(KERN_NOTICE
                       "MTD: Attempt to mount non-MTD device \"%s\"\n",
                       dev_name);
-       return -EINVAL;
+       return ERR_PTR(-EINVAL);
 }
 
-EXPORT_SYMBOL_GPL(get_sb_mtd);
+EXPORT_SYMBOL_GPL(mount_mtd);
 
 /*
  * destroy an MTD-based superblock
index 8b4b67c8a391005bb530abc91ff61690546f2dfb..8229802b434629a533565aaeffc53db21319fbbb 100644 (file)
@@ -400,13 +400,6 @@ config MTD_NAND_PXA3xx
          This enables the driver for the NAND flash device found on
          PXA3xx processors
 
-config MTD_NAND_PXA3xx_BUILTIN
-       bool "Use builtin definitions for some NAND chips (deprecated)"
-       depends on MTD_NAND_PXA3xx
-       help
-         This enables builtin definitions for some NAND chips. This
-         is deprecated in favor of platform specific data.
-
 config MTD_NAND_CM_X270
        tristate "Support for NAND Flash on CM-X270 modules"
        depends on MACH_ARMCORE
@@ -458,6 +451,7 @@ config MTD_NAND_ORION
 config MTD_NAND_FSL_ELBC
        tristate "NAND support for Freescale eLBC controllers"
        depends on PPC_OF
+       select FSL_LBC
        help
          Various Freescale chips, including the 8313, include a NAND Flash
          Controller Module with built-in hardware ECC capabilities.
@@ -531,4 +525,11 @@ config MTD_NAND_JZ4740
        help
                Enables support for NAND Flash on JZ4740 SoC based boards.
 
+config MTD_NAND_FSMC
+       tristate "Support for NAND on ST Micros FSMC"
+       depends on PLAT_SPEAR || PLAT_NOMADIK || MACH_U300
+       help
+         Enables support for NAND Flash chips on the ST Microelectronics
+         Flexible Static Memory Controller (FSMC)
+
 endif # MTD_NAND
index ac83dcdac5d6182048e2279d24659126cd903a72..8ad6faec72cb315bacc6897616a35c4a5f7154fd 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
 obj-$(CONFIG_MTD_NAND_S3C2410)         += s3c2410.o
 obj-$(CONFIG_MTD_NAND_DAVINCI)         += davinci_nand.o
 obj-$(CONFIG_MTD_NAND_DISKONCHIP)      += diskonchip.o
+obj-$(CONFIG_MTD_NAND_FSMC)            += fsmc_nand.o
 obj-$(CONFIG_MTD_NAND_H1900)           += h1910.o
 obj-$(CONFIG_MTD_NAND_RTC_FROM4)       += rtc_from4.o
 obj-$(CONFIG_MTD_NAND_SHARPSL)         += sharpsl.o
index 6fbeefa3a7662fb5fb85e8bfdbb86e0c63307ab3..79947bea4d57aa7b075c766ab3038c9996cfb391 100644 (file)
@@ -110,15 +110,6 @@ static const unsigned short bfin_nfc_pin_req[] =
         0};
 
 #ifdef CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC
-static uint8_t bbt_pattern[] = { 0xff };
-
-static struct nand_bbt_descr bootrom_bbt = {
-       .options = 0,
-       .offs = 63,
-       .len = 1,
-       .pattern = bbt_pattern,
-};
-
 static struct nand_ecclayout bootrom_ecclayout = {
        .eccbytes = 24,
        .eccpos = {
@@ -809,7 +800,6 @@ static int __devinit bf5xx_nand_probe(struct platform_device *pdev)
        /* setup hardware ECC data struct */
        if (hardware_ecc) {
 #ifdef CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC
-               chip->badblock_pattern = &bootrom_bbt;
                chip->ecc.layout = &bootrom_ecclayout;
 #endif
                chip->read_buf      = bf5xx_nand_dma_read_buf;
@@ -830,6 +820,10 @@ static int __devinit bf5xx_nand_probe(struct platform_device *pdev)
                goto out_err_nand_scan;
        }
 
+#ifdef CONFIG_MTD_NAND_BF5XX_BOOTROM_ECC
+       chip->badblockpos = 63;
+#endif
+
        /* add NAND partition */
        bf5xx_nand_add_partition(info);
 
index 8beb0d0233b52bef86ed7f28060e051f5afed039..a90fde3ede28ca40d992432123cca7e08318e017 100644 (file)
@@ -316,7 +316,7 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd,
        u32 syndrome[4];
        u32 ecc_state;
        unsigned num_errors, corrected;
-       unsigned long timeo = jiffies + msecs_to_jiffies(100);
+       unsigned long timeo;
 
        /* All bytes 0xff?  It's an erased page; ignore its ECC. */
        for (i = 0; i < 10; i++) {
@@ -372,9 +372,11 @@ compare:
         * after setting the 4BITECC_ADD_CALC_START bit. So if you immediately
         * begin trying to poll for the state, you may fall right out of your
         * loop without any of the correction calculations having taken place.
-        * The recommendation from the hardware team is to wait till ECC_STATE
-        * reads less than 4, which means ECC HW has entered correction state.
+        * The recommendation from the hardware team is to initially delay as
+        * long as ECC_STATE reads less than 4. After that, ECC HW has entered
+        * correction state.
         */
+       timeo = jiffies + usecs_to_jiffies(100);
        do {
                ecc_state = (davinci_nand_readl(info,
                                NANDFSR_OFFSET) >> 8) & 0x0f;
@@ -733,6 +735,9 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
                 * breaks userspace ioctl interface with mtd-utils. Once we
                 * resolve this issue, NAND_ECC_HW_OOB_FIRST mode can be used
                 * for the 4KiB page chips.
+                *
+                * TODO: Note that nand_ecclayout has now been expanded and can
+                *  hold plenty of OOB entries.
                 */
                dev_warn(&pdev->dev, "no 4-bit ECC support yet "
                                "for 4KiB-page NAND\n");
index 532fe07cf886e9850dfeb03905a42eecb0635220..8c8d3c86c0e82a16d304362cc637d55b2e36a0b1 100644 (file)
@@ -1292,6 +1292,7 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
                read_status(denali);
                break;
        case NAND_CMD_READID:
+       case NAND_CMD_PARAM:
                reset_buf(denali);
                /*sometimes ManufactureId read from register is not right
                 * e.g. some of Micron MT29F32G08QAA MLC NAND chips
index 80de0bff6c3a0e7727a0fd1c35fcdaa0d0cea714..c141b07b25d119101987e96b0cefe379cae6e81f 100644 (file)
@@ -1,9 +1,11 @@
 /* Freescale Enhanced Local Bus Controller NAND driver
  *
- * Copyright (c) 2006-2007 Freescale Semiconductor
+ * Copyright © 2006-2007, 2010 Freescale Semiconductor
  *
  * Authors: Nick Spence <nick.spence@freescale.com>,
  *          Scott Wood <scottwood@freescale.com>
+ *          Jack Lan <jack.lan@freescale.com>
+ *          Roy Zang <tie-fei.zang@freescale.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
@@ -27,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/of_platform.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 
 #define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */
 #define FCM_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait for FCM */
 
-struct fsl_elbc_ctrl;
-
 /* mtd information per set */
 
 struct fsl_elbc_mtd {
        struct mtd_info mtd;
        struct nand_chip chip;
-       struct fsl_elbc_ctrl *ctrl;
+       struct fsl_lbc_ctrl *ctrl;
 
        struct device *dev;
        int bank;               /* Chip select bank number           */
@@ -58,18 +59,12 @@ struct fsl_elbc_mtd {
        unsigned int fmr;       /* FCM Flash Mode Register value     */
 };
 
-/* overview of the fsl elbc controller */
+/* Freescale eLBC FCM controller infomation */
 
-struct fsl_elbc_ctrl {
+struct fsl_elbc_fcm_ctrl {
        struct nand_hw_control controller;
        struct fsl_elbc_mtd *chips[MAX_BANKS];
 
-       /* device info */
-       struct device *dev;
-       struct fsl_lbc_regs __iomem *regs;
-       int irq;
-       wait_queue_head_t irq_wait;
-       unsigned int irq_status; /* status read from LTESR by irq handler */
        u8 __iomem *addr;        /* Address of assigned FCM buffer        */
        unsigned int page;       /* Last page written to / read from      */
        unsigned int read_bytes; /* Number of bytes read during command   */
@@ -79,6 +74,7 @@ struct fsl_elbc_ctrl {
        unsigned int mdr;        /* UPM/FCM Data Register value           */
        unsigned int use_mdr;    /* Non zero if the MDR is to be set      */
        unsigned int oob;        /* Non zero if operating on OOB data     */
+       unsigned int counter;    /* counter for the initializations       */
        char *oob_poi;           /* Place to write ECC after read back    */
 };
 
@@ -164,11 +160,12 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
 {
        struct nand_chip *chip = mtd->priv;
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_lbc_ctrl *ctrl = priv->ctrl;
        struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
        int buf_num;
 
-       ctrl->page = page_addr;
+       elbc_fcm_ctrl->page = page_addr;
 
        out_be32(&lbc->fbar,
                 page_addr >> (chip->phys_erase_shift - chip->page_shift));
@@ -185,16 +182,18 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
                buf_num = page_addr & 7;
        }
 
-       ctrl->addr = priv->vbase + buf_num * 1024;
-       ctrl->index = column;
+       elbc_fcm_ctrl->addr = priv->vbase + buf_num * 1024;
+       elbc_fcm_ctrl->index = column;
 
        /* for OOB data point to the second half of the buffer */
        if (oob)
-               ctrl->index += priv->page_size ? 2048 : 512;
+               elbc_fcm_ctrl->index += priv->page_size ? 2048 : 512;
 
-       dev_vdbg(ctrl->dev, "set_addr: bank=%d, ctrl->addr=0x%p (0x%p), "
+       dev_vdbg(priv->dev, "set_addr: bank=%d, "
+                           "elbc_fcm_ctrl->addr=0x%p (0x%p), "
                            "index %x, pes %d ps %d\n",
-                buf_num, ctrl->addr, priv->vbase, ctrl->index,
+                buf_num, elbc_fcm_ctrl->addr, priv->vbase,
+                elbc_fcm_ctrl->index,
                 chip->phys_erase_shift, chip->page_shift);
 }
 
@@ -205,18 +204,19 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_lbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
        struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
 
        /* Setup the FMR[OP] to execute without write protection */
        out_be32(&lbc->fmr, priv->fmr | 3);
-       if (ctrl->use_mdr)
-               out_be32(&lbc->mdr, ctrl->mdr);
+       if (elbc_fcm_ctrl->use_mdr)
+               out_be32(&lbc->mdr, elbc_fcm_ctrl->mdr);
 
-       dev_vdbg(ctrl->dev,
+       dev_vdbg(priv->dev,
                 "fsl_elbc_run_command: fmr=%08x fir=%08x fcr=%08x\n",
                 in_be32(&lbc->fmr), in_be32(&lbc->fir), in_be32(&lbc->fcr));
-       dev_vdbg(ctrl->dev,
+       dev_vdbg(priv->dev,
                 "fsl_elbc_run_command: fbar=%08x fpar=%08x "
                 "fbcr=%08x bank=%d\n",
                 in_be32(&lbc->fbar), in_be32(&lbc->fpar),
@@ -229,19 +229,18 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
        /* wait for FCM complete flag or timeout */
        wait_event_timeout(ctrl->irq_wait, ctrl->irq_status,
                           FCM_TIMEOUT_MSECS * HZ/1000);
-       ctrl->status = ctrl->irq_status;
-
+       elbc_fcm_ctrl->status = ctrl->irq_status;
        /* store mdr value in case it was needed */
-       if (ctrl->use_mdr)
-               ctrl->mdr = in_be32(&lbc->mdr);
+       if (elbc_fcm_ctrl->use_mdr)
+               elbc_fcm_ctrl->mdr = in_be32(&lbc->mdr);
 
-       ctrl->use_mdr = 0;
+       elbc_fcm_ctrl->use_mdr = 0;
 
-       if (ctrl->status != LTESR_CC) {
-               dev_info(ctrl->dev,
+       if (elbc_fcm_ctrl->status != LTESR_CC) {
+               dev_info(priv->dev,
                         "command failed: fir %x fcr %x status %x mdr %x\n",
                         in_be32(&lbc->fir), in_be32(&lbc->fcr),
-                        ctrl->status, ctrl->mdr);
+                        elbc_fcm_ctrl->status, elbc_fcm_ctrl->mdr);
                return -EIO;
        }
 
@@ -251,7 +250,7 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
 static void fsl_elbc_do_read(struct nand_chip *chip, int oob)
 {
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_lbc_ctrl *ctrl = priv->ctrl;
        struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
 
        if (priv->page_size) {
@@ -284,15 +283,16 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 {
        struct nand_chip *chip = mtd->priv;
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_lbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
        struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
 
-       ctrl->use_mdr = 0;
+       elbc_fcm_ctrl->use_mdr = 0;
 
        /* clear the read buffer */
-       ctrl->read_bytes = 0;
+       elbc_fcm_ctrl->read_bytes = 0;
        if (command != NAND_CMD_PAGEPROG)
-               ctrl->index = 0;
+               elbc_fcm_ctrl->index = 0;
 
        switch (command) {
        /* READ0 and READ1 read the entire buffer to use hardware ECC. */
@@ -301,7 +301,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
        /* fall-through */
        case NAND_CMD_READ0:
-               dev_dbg(ctrl->dev,
+               dev_dbg(priv->dev,
                        "fsl_elbc_cmdfunc: NAND_CMD_READ0, page_addr:"
                        " 0x%x, column: 0x%x.\n", page_addr, column);
 
@@ -309,8 +309,8 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                out_be32(&lbc->fbcr, 0); /* read entire page to enable ECC */
                set_addr(mtd, 0, page_addr, 0);
 
-               ctrl->read_bytes = mtd->writesize + mtd->oobsize;
-               ctrl->index += column;
+               elbc_fcm_ctrl->read_bytes = mtd->writesize + mtd->oobsize;
+               elbc_fcm_ctrl->index += column;
 
                fsl_elbc_do_read(chip, 0);
                fsl_elbc_run_command(mtd);
@@ -318,14 +318,14 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
        /* READOOB reads only the OOB because no ECC is performed. */
        case NAND_CMD_READOOB:
-               dev_vdbg(ctrl->dev,
+               dev_vdbg(priv->dev,
                         "fsl_elbc_cmdfunc: NAND_CMD_READOOB, page_addr:"
                         " 0x%x, column: 0x%x.\n", page_addr, column);
 
                out_be32(&lbc->fbcr, mtd->oobsize - column);
                set_addr(mtd, column, page_addr, 1);
 
-               ctrl->read_bytes = mtd->writesize + mtd->oobsize;
+               elbc_fcm_ctrl->read_bytes = mtd->writesize + mtd->oobsize;
 
                fsl_elbc_do_read(chip, 1);
                fsl_elbc_run_command(mtd);
@@ -333,7 +333,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
        /* READID must read all 5 possible bytes while CEB is active */
        case NAND_CMD_READID:
-               dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n");
+               dev_vdbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD_READID.\n");
 
                out_be32(&lbc->fir, (FIR_OP_CM0 << FIR_OP0_SHIFT) |
                                    (FIR_OP_UA  << FIR_OP1_SHIFT) |
@@ -341,9 +341,9 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT);
                /* 5 bytes for manuf, device and exts */
                out_be32(&lbc->fbcr, 5);
-               ctrl->read_bytes = 5;
-               ctrl->use_mdr = 1;
-               ctrl->mdr = 0;
+               elbc_fcm_ctrl->read_bytes = 5;
+               elbc_fcm_ctrl->use_mdr = 1;
+               elbc_fcm_ctrl->mdr = 0;
 
                set_addr(mtd, 0, 0, 0);
                fsl_elbc_run_command(mtd);
@@ -351,7 +351,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
        /* ERASE1 stores the block and page address */
        case NAND_CMD_ERASE1:
-               dev_vdbg(ctrl->dev,
+               dev_vdbg(priv->dev,
                         "fsl_elbc_cmdfunc: NAND_CMD_ERASE1, "
                         "page_addr: 0x%x.\n", page_addr);
                set_addr(mtd, 0, page_addr, 0);
@@ -359,7 +359,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 
        /* ERASE2 uses the block and page address from ERASE1 */
        case NAND_CMD_ERASE2:
-               dev_vdbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n");
+               dev_vdbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n");
 
                out_be32(&lbc->fir,
                         (FIR_OP_CM0 << FIR_OP0_SHIFT) |
@@ -374,8 +374,8 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                         (NAND_CMD_ERASE2 << FCR_CMD2_SHIFT));
 
                out_be32(&lbc->fbcr, 0);
-               ctrl->read_bytes = 0;
-               ctrl->use_mdr = 1;
+               elbc_fcm_ctrl->read_bytes = 0;
+               elbc_fcm_ctrl->use_mdr = 1;
 
                fsl_elbc_run_command(mtd);
                return;
@@ -383,14 +383,12 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
        /* SEQIN sets up the addr buffer and all registers except the length */
        case NAND_CMD_SEQIN: {
                __be32 fcr;
-               dev_vdbg(ctrl->dev,
-                        "fsl_elbc_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, "
+               dev_vdbg(priv->dev,
+                        "fsl_elbc_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, "
                         "page_addr: 0x%x, column: 0x%x.\n",
                         page_addr, column);
 
-               ctrl->column = column;
-               ctrl->oob = 0;
-               ctrl->use_mdr = 1;
+               elbc_fcm_ctrl->use_mdr = 1;
 
                fcr = (NAND_CMD_STATUS   << FCR_CMD1_SHIFT) |
                      (NAND_CMD_SEQIN    << FCR_CMD2_SHIFT) |
@@ -420,7 +418,7 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                                /* OOB area --> READOOB */
                                column -= mtd->writesize;
                                fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT;
-                               ctrl->oob = 1;
+                               elbc_fcm_ctrl->oob = 1;
                        } else {
                                WARN_ON(column != 0);
                                /* First 256 bytes --> READ0 */
@@ -429,24 +427,24 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                }
 
                out_be32(&lbc->fcr, fcr);
-               set_addr(mtd, column, page_addr, ctrl->oob);
+               set_addr(mtd, column, page_addr, elbc_fcm_ctrl->oob);
                return;
        }
 
        /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
        case NAND_CMD_PAGEPROG: {
                int full_page;
-               dev_vdbg(ctrl->dev,
+               dev_vdbg(priv->dev,
                         "fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG "
-                        "writing %d bytes.\n", ctrl->index);
+                        "writing %d bytes.\n", elbc_fcm_ctrl->index);
 
                /* if the write did not start at 0 or is not a full page
                 * then set the exact length, otherwise use a full page
                 * write so the HW generates the ECC.
                 */
-               if (ctrl->oob || ctrl->column != 0 ||
-                   ctrl->index != mtd->writesize + mtd->oobsize) {
-                       out_be32(&lbc->fbcr, ctrl->index);
+               if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 ||
+                   elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize) {
+                       out_be32(&lbc->fbcr, elbc_fcm_ctrl->index);
                        full_page = 0;
                } else {
                        out_be32(&lbc->fbcr, 0);
@@ -458,21 +456,21 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                /* Read back the page in order to fill in the ECC for the
                 * caller.  Is this really needed?
                 */
-               if (full_page && ctrl->oob_poi) {
+               if (full_page && elbc_fcm_ctrl->oob_poi) {
                        out_be32(&lbc->fbcr, 3);
                        set_addr(mtd, 6, page_addr, 1);
 
-                       ctrl->read_bytes = mtd->writesize + 9;
+                       elbc_fcm_ctrl->read_bytes = mtd->writesize + 9;
 
                        fsl_elbc_do_read(chip, 1);
                        fsl_elbc_run_command(mtd);
 
-                       memcpy_fromio(ctrl->oob_poi + 6,
-                                     &ctrl->addr[ctrl->index], 3);
-                       ctrl->index += 3;
+                       memcpy_fromio(elbc_fcm_ctrl->oob_poi + 6,
+                               &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], 3);
+                       elbc_fcm_ctrl->index += 3;
                }
 
-               ctrl->oob_poi = NULL;
+               elbc_fcm_ctrl->oob_poi = NULL;
                return;
        }
 
@@ -485,26 +483,26 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
                out_be32(&lbc->fcr, NAND_CMD_STATUS << FCR_CMD0_SHIFT);
                out_be32(&lbc->fbcr, 1);
                set_addr(mtd, 0, 0, 0);
-               ctrl->read_bytes = 1;
+               elbc_fcm_ctrl->read_bytes = 1;
 
                fsl_elbc_run_command(mtd);
 
                /* The chip always seems to report that it is
                 * write-protected, even when it is not.
                 */
-               setbits8(ctrl->addr, NAND_STATUS_WP);
+               setbits8(elbc_fcm_ctrl->addr, NAND_STATUS_WP);
                return;
 
        /* RESET without waiting for the ready line */
        case NAND_CMD_RESET:
-               dev_dbg(ctrl->dev, "fsl_elbc_cmdfunc: NAND_CMD_RESET.\n");
+               dev_dbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD_RESET.\n");
                out_be32(&lbc->fir, FIR_OP_CM0 << FIR_OP0_SHIFT);
                out_be32(&lbc->fcr, NAND_CMD_RESET << FCR_CMD0_SHIFT);
                fsl_elbc_run_command(mtd);
                return;
 
        default:
-               dev_err(ctrl->dev,
+               dev_err(priv->dev,
                        "fsl_elbc_cmdfunc: error, unsupported command 0x%x.\n",
                        command);
        }
@@ -524,24 +522,24 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 {
        struct nand_chip *chip = mtd->priv;
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
        unsigned int bufsize = mtd->writesize + mtd->oobsize;
 
        if (len <= 0) {
-               dev_err(ctrl->dev, "write_buf of %d bytes", len);
-               ctrl->status = 0;
+               dev_err(priv->dev, "write_buf of %d bytes", len);
+               elbc_fcm_ctrl->status = 0;
                return;
        }
 
-       if ((unsigned int)len > bufsize - ctrl->index) {
-               dev_err(ctrl->dev,
+       if ((unsigned int)len > bufsize - elbc_fcm_ctrl->index) {
+               dev_err(priv->dev,
                        "write_buf beyond end of buffer "
                        "(%d requested, %u available)\n",
-                       len, bufsize - ctrl->index);
-               len = bufsize - ctrl->index;
+                       len, bufsize - elbc_fcm_ctrl->index);
+               len = bufsize - elbc_fcm_ctrl->index;
        }
 
-       memcpy_toio(&ctrl->addr[ctrl->index], buf, len);
+       memcpy_toio(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], buf, len);
        /*
         * This is workaround for the weird elbc hangs during nand write,
         * Scott Wood says: "...perhaps difference in how long it takes a
@@ -549,9 +547,9 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
         * is causing problems, and sync isn't helping for some reason."
         * Reading back the last byte helps though.
         */
-       in_8(&ctrl->addr[ctrl->index] + len - 1);
+       in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index] + len - 1);
 
-       ctrl->index += len;
+       elbc_fcm_ctrl->index += len;
 }
 
 /*
@@ -562,13 +560,13 @@ static u8 fsl_elbc_read_byte(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
 
        /* If there are still bytes in the FCM, then use the next byte. */
-       if (ctrl->index < ctrl->read_bytes)
-               return in_8(&ctrl->addr[ctrl->index++]);
+       if (elbc_fcm_ctrl->index < elbc_fcm_ctrl->read_bytes)
+               return in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index++]);
 
-       dev_err(ctrl->dev, "read_byte beyond end of buffer\n");
+       dev_err(priv->dev, "read_byte beyond end of buffer\n");
        return ERR_BYTE;
 }
 
@@ -579,18 +577,19 @@ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
 {
        struct nand_chip *chip = mtd->priv;
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
        int avail;
 
        if (len < 0)
                return;
 
-       avail = min((unsigned int)len, ctrl->read_bytes - ctrl->index);
-       memcpy_fromio(buf, &ctrl->addr[ctrl->index], avail);
-       ctrl->index += avail;
+       avail = min((unsigned int)len,
+                       elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index);
+       memcpy_fromio(buf, &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], avail);
+       elbc_fcm_ctrl->index += avail;
 
        if (len > avail)
-               dev_err(ctrl->dev,
+               dev_err(priv->dev,
                        "read_buf beyond end of buffer "
                        "(%d requested, %d available)\n",
                        len, avail);
@@ -603,30 +602,32 @@ static int fsl_elbc_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
        struct nand_chip *chip = mtd->priv;
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
        int i;
 
        if (len < 0) {
-               dev_err(ctrl->dev, "write_buf of %d bytes", len);
+               dev_err(priv->dev, "write_buf of %d bytes", len);
                return -EINVAL;
        }
 
-       if ((unsigned int)len > ctrl->read_bytes - ctrl->index) {
-               dev_err(ctrl->dev,
-                       "verify_buf beyond end of buffer "
-                       "(%d requested, %u available)\n",
-                       len, ctrl->read_bytes - ctrl->index);
+       if ((unsigned int)len >
+                       elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index) {
+               dev_err(priv->dev,
+                       "verify_buf beyond end of buffer "
+                       "(%d requested, %u available)\n",
+                       len, elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index);
 
-               ctrl->index = ctrl->read_bytes;
+               elbc_fcm_ctrl->index = elbc_fcm_ctrl->read_bytes;
                return -EINVAL;
        }
 
        for (i = 0; i < len; i++)
-               if (in_8(&ctrl->addr[ctrl->index + i]) != buf[i])
+               if (in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index + i])
+                               != buf[i])
                        break;
 
-       ctrl->index += len;
-       return i == len && ctrl->status == LTESR_CC ? 0 : -EIO;
+       elbc_fcm_ctrl->index += len;
+       return i == len && elbc_fcm_ctrl->status == LTESR_CC ? 0 : -EIO;
 }
 
 /* This function is called after Program and Erase Operations to
@@ -635,22 +636,22 @@ static int fsl_elbc_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip)
 {
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
 
-       if (ctrl->status != LTESR_CC)
+       if (elbc_fcm_ctrl->status != LTESR_CC)
                return NAND_STATUS_FAIL;
 
        /* The chip always seems to report that it is
         * write-protected, even when it is not.
         */
-       return (ctrl->mdr & 0xff) | NAND_STATUS_WP;
+       return (elbc_fcm_ctrl->mdr & 0xff) | NAND_STATUS_WP;
 }
 
 static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_lbc_ctrl *ctrl = priv->ctrl;
        struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
        unsigned int al;
 
@@ -665,41 +666,41 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
        priv->fmr |= (12 << FMR_CWTO_SHIFT) |  /* Timeout > 12 ms */
                     (al << FMR_AL_SHIFT);
 
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->numchips = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n",
                chip->numchips);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
                chip->chipsize);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
                chip->pagemask);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chip_delay = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->chip_delay = %d\n",
                chip->chip_delay);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->badblockpos = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->badblockpos = %d\n",
                chip->badblockpos);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chip_shift = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->chip_shift = %d\n",
                chip->chip_shift);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->page_shift = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->page_shift = %d\n",
                chip->page_shift);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->phys_erase_shift = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->phys_erase_shift = %d\n",
                chip->phys_erase_shift);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecclayout = %p\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->ecclayout = %p\n",
                chip->ecclayout);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.mode = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.mode = %d\n",
                chip->ecc.mode);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.steps = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.steps = %d\n",
                chip->ecc.steps);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.bytes = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.bytes = %d\n",
                chip->ecc.bytes);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.total = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n",
                chip->ecc.total);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.layout = %p\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.layout = %p\n",
                chip->ecc.layout);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->erasesize = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags);
+       dev_dbg(priv->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size);
+       dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n",
                mtd->erasesize);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->writesize = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: mtd->writesize = %d\n",
                mtd->writesize);
-       dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->oobsize = %d\n",
+       dev_dbg(priv->dev, "fsl_elbc_init: mtd->oobsize = %d\n",
                mtd->oobsize);
 
        /* adjust Option Register and ECC to match Flash page size */
@@ -719,7 +720,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
                        chip->badblock_pattern = &largepage_memorybased;
                }
        } else {
-               dev_err(ctrl->dev,
+               dev_err(priv->dev,
                        "fsl_elbc_init: page size %d is not supported\n",
                        mtd->writesize);
                return -1;
@@ -750,18 +751,19 @@ static void fsl_elbc_write_page(struct mtd_info *mtd,
                                 const uint8_t *buf)
 {
        struct fsl_elbc_mtd *priv = chip->priv;
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
 
        fsl_elbc_write_buf(mtd, buf, mtd->writesize);
        fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-       ctrl->oob_poi = chip->oob_poi;
+       elbc_fcm_ctrl->oob_poi = chip->oob_poi;
 }
 
 static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
 {
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
+       struct fsl_lbc_ctrl *ctrl = priv->ctrl;
        struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand;
        struct nand_chip *chip = &priv->chip;
 
        dev_dbg(priv->dev, "eLBC Set Information for bank %d\n", priv->bank);
@@ -790,7 +792,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
        chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR |
                        NAND_USE_FLASH_BBT;
 
-       chip->controller = &ctrl->controller;
+       chip->controller = &elbc_fcm_ctrl->controller;
        chip->priv = priv;
 
        chip->ecc.read_page = fsl_elbc_read_page;
@@ -815,8 +817,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
 
 static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv)
 {
-       struct fsl_elbc_ctrl *ctrl = priv->ctrl;
-
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
        nand_release(&priv->mtd);
 
        kfree(priv->mtd.name);
@@ -824,18 +825,21 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv)
        if (priv->vbase)
                iounmap(priv->vbase);
 
-       ctrl->chips[priv->bank] = NULL;
+       elbc_fcm_ctrl->chips[priv->bank] = NULL;
        kfree(priv);
-
+       kfree(elbc_fcm_ctrl);
        return 0;
 }
 
-static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
-                                        struct device_node *node)
+static DEFINE_MUTEX(fsl_elbc_nand_mutex);
+
+static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev)
 {
-       struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+       struct fsl_lbc_regs __iomem *lbc;
        struct fsl_elbc_mtd *priv;
        struct resource res;
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl;
+
 #ifdef CONFIG_MTD_PARTITIONS
        static const char *part_probe_types[]
                = { "cmdlinepart", "RedBoot", NULL };
@@ -843,11 +847,18 @@ static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
 #endif
        int ret;
        int bank;
+       struct device *dev;
+       struct device_node *node = pdev->dev.of_node;
+
+       if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
+               return -ENODEV;
+       lbc = fsl_lbc_ctrl_dev->regs;
+       dev = fsl_lbc_ctrl_dev->dev;
 
        /* get, allocate and map the memory resource */
        ret = of_address_to_resource(node, 0, &res);
        if (ret) {
-               dev_err(ctrl->dev, "failed to get resource\n");
+               dev_err(dev, "failed to get resource\n");
                return ret;
        }
 
@@ -857,11 +868,11 @@ static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
                    (in_be32(&lbc->bank[bank].br) & BR_MSEL) == BR_MS_FCM &&
                    (in_be32(&lbc->bank[bank].br) &
                     in_be32(&lbc->bank[bank].or) & BR_BA)
-                    == res.start)
+                    == fsl_lbc_addr(res.start))
                        break;
 
        if (bank >= MAX_BANKS) {
-               dev_err(ctrl->dev, "address did not match any chip selects\n");
+               dev_err(dev, "address did not match any chip selects\n");
                return -ENODEV;
        }
 
@@ -869,14 +880,33 @@ static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
        if (!priv)
                return -ENOMEM;
 
-       ctrl->chips[bank] = priv;
+       mutex_lock(&fsl_elbc_nand_mutex);
+       if (!fsl_lbc_ctrl_dev->nand) {
+               elbc_fcm_ctrl = kzalloc(sizeof(*elbc_fcm_ctrl), GFP_KERNEL);
+               if (!elbc_fcm_ctrl) {
+                       dev_err(dev, "failed to allocate memory\n");
+                       mutex_unlock(&fsl_elbc_nand_mutex);
+                       ret = -ENOMEM;
+                       goto err;
+               }
+               elbc_fcm_ctrl->counter++;
+
+               spin_lock_init(&elbc_fcm_ctrl->controller.lock);
+               init_waitqueue_head(&elbc_fcm_ctrl->controller.wq);
+               fsl_lbc_ctrl_dev->nand = elbc_fcm_ctrl;
+       } else {
+               elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand;
+       }
+       mutex_unlock(&fsl_elbc_nand_mutex);
+
+       elbc_fcm_ctrl->chips[bank] = priv;
        priv->bank = bank;
-       priv->ctrl = ctrl;
-       priv->dev = ctrl->dev;
+       priv->ctrl = fsl_lbc_ctrl_dev;
+       priv->dev = dev;
 
        priv->vbase = ioremap(res.start, resource_size(&res));
        if (!priv->vbase) {
-               dev_err(ctrl->dev, "failed to map chip region\n");
+               dev_err(dev, "failed to map chip region\n");
                ret = -ENOMEM;
                goto err;
        }
@@ -933,171 +963,53 @@ err:
        return ret;
 }
 
-static int __devinit fsl_elbc_ctrl_init(struct fsl_elbc_ctrl *ctrl)
+static int fsl_elbc_nand_remove(struct platform_device *pdev)
 {
-       struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
-
-       /*
-        * NAND transactions can tie up the bus for a long time, so set the
-        * bus timeout to max by clearing LBCR[BMT] (highest base counter
-        * value) and setting LBCR[BMTPS] to the highest prescaler value.
-        */
-       clrsetbits_be32(&lbc->lbcr, LBCR_BMT, 15);
-
-       /* clear event registers */
-       setbits32(&lbc->ltesr, LTESR_NAND_MASK);
-       out_be32(&lbc->lteatr, 0);
-
-       /* Enable interrupts for any detected events */
-       out_be32(&lbc->lteir, LTESR_NAND_MASK);
-
-       ctrl->read_bytes = 0;
-       ctrl->index = 0;
-       ctrl->addr = NULL;
-
-       return 0;
-}
-
-static int fsl_elbc_ctrl_remove(struct platform_device *ofdev)
-{
-       struct fsl_elbc_ctrl *ctrl = dev_get_drvdata(&ofdev->dev);
        int i;
-
+       struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand;
        for (i = 0; i < MAX_BANKS; i++)
-               if (ctrl->chips[i])
-                       fsl_elbc_chip_remove(ctrl->chips[i]);
-
-       if (ctrl->irq)
-               free_irq(ctrl->irq, ctrl);
-
-       if (ctrl->regs)
-               iounmap(ctrl->regs);
-
-       dev_set_drvdata(&ofdev->dev, NULL);
-       kfree(ctrl);
-       return 0;
-}
-
-/* NOTE: This interrupt is also used to report other localbus events,
- * such as transaction errors on other chipselects.  If we want to
- * capture those, we'll need to move the IRQ code into a shared
- * LBC driver.
- */
-
-static irqreturn_t fsl_elbc_ctrl_irq(int irqno, void *data)
-{
-       struct fsl_elbc_ctrl *ctrl = data;
-       struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
-       __be32 status = in_be32(&lbc->ltesr) & LTESR_NAND_MASK;
-
-       if (status) {
-               out_be32(&lbc->ltesr, status);
-               out_be32(&lbc->lteatr, 0);
-
-               ctrl->irq_status = status;
-               smp_wmb();
-               wake_up(&ctrl->irq_wait);
-
-               return IRQ_HANDLED;
+               if (elbc_fcm_ctrl->chips[i])
+                       fsl_elbc_chip_remove(elbc_fcm_ctrl->chips[i]);
+
+       mutex_lock(&fsl_elbc_nand_mutex);
+       elbc_fcm_ctrl->counter--;
+       if (!elbc_fcm_ctrl->counter) {
+               fsl_lbc_ctrl_dev->nand = NULL;
+               kfree(elbc_fcm_ctrl);
        }
-
-       return IRQ_NONE;
-}
-
-/* fsl_elbc_ctrl_probe
- *
- * called by device layer when it finds a device matching
- * one our driver can handled. This code allocates all of
- * the resources needed for the controller only.  The
- * resources for the NAND banks themselves are allocated
- * in the chip probe function.
-*/
-
-static int __devinit fsl_elbc_ctrl_probe(struct platform_device *ofdev,
-                                         const struct of_device_id *match)
-{
-       struct device_node *child;
-       struct fsl_elbc_ctrl *ctrl;
-       int ret;
-
-       ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
-       if (!ctrl)
-               return -ENOMEM;
-
-       dev_set_drvdata(&ofdev->dev, ctrl);
-
-       spin_lock_init(&ctrl->controller.lock);
-       init_waitqueue_head(&ctrl->controller.wq);
-       init_waitqueue_head(&ctrl->irq_wait);
-
-       ctrl->regs = of_iomap(ofdev->dev.of_node, 0);
-       if (!ctrl->regs) {
-               dev_err(&ofdev->dev, "failed to get memory region\n");
-               ret = -ENODEV;
-               goto err;
-       }
-
-       ctrl->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL);
-       if (ctrl->irq == NO_IRQ) {
-               dev_err(&ofdev->dev, "failed to get irq resource\n");
-               ret = -ENODEV;
-               goto err;
-       }
-
-       ctrl->dev = &ofdev->dev;
-
-       ret = fsl_elbc_ctrl_init(ctrl);
-       if (ret < 0)
-               goto err;
-
-       ret = request_irq(ctrl->irq, fsl_elbc_ctrl_irq, 0, "fsl-elbc", ctrl);
-       if (ret != 0) {
-               dev_err(&ofdev->dev, "failed to install irq (%d)\n",
-                       ctrl->irq);
-               ret = ctrl->irq;
-               goto err;
-       }
-
-       for_each_child_of_node(ofdev->dev.of_node, child)
-               if (of_device_is_compatible(child, "fsl,elbc-fcm-nand"))
-                       fsl_elbc_chip_probe(ctrl, child);
+       mutex_unlock(&fsl_elbc_nand_mutex);
 
        return 0;
 
-err:
-       fsl_elbc_ctrl_remove(ofdev);
-       return ret;
 }
 
-static const struct of_device_id fsl_elbc_match[] = {
-       {
-               .compatible = "fsl,elbc",
-       },
+static const struct of_device_id fsl_elbc_nand_match[] = {
+       { .compatible = "fsl,elbc-fcm-nand", },
        {}
 };
 
-static struct of_platform_driver fsl_elbc_ctrl_driver = {
+static struct platform_driver fsl_elbc_nand_driver = {
        .driver = {
-               .name = "fsl-elbc",
+               .name = "fsl,elbc-fcm-nand",
                .owner = THIS_MODULE,
-               .of_match_table = fsl_elbc_match,
+               .of_match_table = fsl_elbc_nand_match,
        },
-       .probe = fsl_elbc_ctrl_probe,
-       .remove = fsl_elbc_ctrl_remove,
+       .probe = fsl_elbc_nand_probe,
+       .remove = fsl_elbc_nand_remove,
 };
 
-static int __init fsl_elbc_init(void)
+static int __init fsl_elbc_nand_init(void)
 {
-       return of_register_platform_driver(&fsl_elbc_ctrl_driver);
+       return platform_driver_register(&fsl_elbc_nand_driver);
 }
 
-static void __exit fsl_elbc_exit(void)
+static void __exit fsl_elbc_nand_exit(void)
 {
-       of_unregister_platform_driver(&fsl_elbc_ctrl_driver);
+       platform_driver_unregister(&fsl_elbc_nand_driver);
 }
 
-module_init(fsl_elbc_init);
-module_exit(fsl_elbc_exit);
+module_init(fsl_elbc_nand_init);
+module_exit(fsl_elbc_nand_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Freescale");
index 4eff8b25e5af2f8ca82fbaa50e2d6ae02bc6aa7e..efdcca94ce559f8aa6b6e7c9a2c3c994cc6bbb84 100644 (file)
@@ -186,7 +186,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
        if (!flash_np)
                return -ENODEV;
 
-       fun->mtd.name = kasprintf(GFP_KERNEL, "%x.%s", io_res->start,
+       fun->mtd.name = kasprintf(GFP_KERNEL, "0x%llx.%s", (u64)io_res->start,
                                  flash_np->name);
        if (!fun->mtd.name) {
                ret = -ENOMEM;
@@ -222,7 +222,7 @@ static int __devinit fun_probe(struct platform_device *ofdev,
 {
        struct fsl_upm_nand *fun;
        struct resource io_res;
-       const uint32_t *prop;
+       const __be32 *prop;
        int rnb_gpio;
        int ret;
        int size;
@@ -270,7 +270,7 @@ static int __devinit fun_probe(struct platform_device *ofdev,
                        goto err1;
                }
                for (i = 0; i < fun->mchip_count; i++)
-                       fun->mchip_offsets[i] = prop[i];
+                       fun->mchip_offsets[i] = be32_to_cpu(prop[i]);
        } else {
                fun->mchip_count = 1;
        }
@@ -295,13 +295,13 @@ static int __devinit fun_probe(struct platform_device *ofdev,
 
        prop = of_get_property(ofdev->dev.of_node, "chip-delay", NULL);
        if (prop)
-               fun->chip_delay = *prop;
+               fun->chip_delay = be32_to_cpup(prop);
        else
                fun->chip_delay = 50;
 
        prop = of_get_property(ofdev->dev.of_node, "fsl,upm-wait-flags", &size);
        if (prop && size == sizeof(uint32_t))
-               fun->wait_flags = *prop;
+               fun->wait_flags = be32_to_cpup(prop);
        else
                fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN |
                                  FSL_UPM_WAIT_WRITE_BYTE;
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
new file mode 100644 (file)
index 0000000..02edfba
--- /dev/null
@@ -0,0 +1,866 @@
+/*
+ * drivers/mtd/nand/fsmc_nand.c
+ *
+ * ST Microelectronics
+ * Flexible Static Memory Controller (FSMC)
+ * Driver for NAND portions
+ *
+ * Copyright © 2010 ST Microelectronics
+ * Vipin Kumar <vipin.kumar@st.com>
+ * Ashish Priyadarshi
+ *
+ * Based on drivers/mtd/nand/nomadik_nand.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/resource.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/mtd/fsmc.h>
+#include <mtd/mtd-abi.h>
+
+static struct nand_ecclayout fsmc_ecc1_layout = {
+       .eccbytes = 24,
+       .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
+               66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
+       .oobfree = {
+               {.offset = 8, .length = 8},
+               {.offset = 24, .length = 8},
+               {.offset = 40, .length = 8},
+               {.offset = 56, .length = 8},
+               {.offset = 72, .length = 8},
+               {.offset = 88, .length = 8},
+               {.offset = 104, .length = 8},
+               {.offset = 120, .length = 8}
+       }
+};
+
+static struct nand_ecclayout fsmc_ecc4_lp_layout = {
+       .eccbytes = 104,
+       .eccpos = {  2,   3,   4,   5,   6,   7,   8,
+               9,  10,  11,  12,  13,  14,
+               18,  19,  20,  21,  22,  23,  24,
+               25,  26,  27,  28,  29,  30,
+               34,  35,  36,  37,  38,  39,  40,
+               41,  42,  43,  44,  45,  46,
+               50,  51,  52,  53,  54,  55,  56,
+               57,  58,  59,  60,  61,  62,
+               66,  67,  68,  69,  70,  71,  72,
+               73,  74,  75,  76,  77,  78,
+               82,  83,  84,  85,  86,  87,  88,
+               89,  90,  91,  92,  93,  94,
+               98,  99, 100, 101, 102, 103, 104,
+               105, 106, 107, 108, 109, 110,
+               114, 115, 116, 117, 118, 119, 120,
+               121, 122, 123, 124, 125, 126
+       },
+       .oobfree = {
+               {.offset = 15, .length = 3},
+               {.offset = 31, .length = 3},
+               {.offset = 47, .length = 3},
+               {.offset = 63, .length = 3},
+               {.offset = 79, .length = 3},
+               {.offset = 95, .length = 3},
+               {.offset = 111, .length = 3},
+               {.offset = 127, .length = 1}
+       }
+};
+
+/*
+ * ECC placement definitions in oobfree type format.
+ * There are 13 bytes of ecc for every 512 byte block and it has to be read
+ * consecutively and immediately after the 512 byte data block for hardware to
+ * generate the error bit offsets in 512 byte data.
+ * Managing the ecc bytes in the following way makes it easier for software to
+ * read ecc bytes consecutive to data bytes. This way is similar to
+ * oobfree structure maintained already in generic nand driver
+ */
+static struct fsmc_eccplace fsmc_ecc4_lp_place = {
+       .eccplace = {
+               {.offset = 2, .length = 13},
+               {.offset = 18, .length = 13},
+               {.offset = 34, .length = 13},
+               {.offset = 50, .length = 13},
+               {.offset = 66, .length = 13},
+               {.offset = 82, .length = 13},
+               {.offset = 98, .length = 13},
+               {.offset = 114, .length = 13}
+       }
+};
+
+static struct nand_ecclayout fsmc_ecc4_sp_layout = {
+       .eccbytes = 13,
+       .eccpos = { 0,  1,  2,  3,  6,  7, 8,
+               9, 10, 11, 12, 13, 14
+       },
+       .oobfree = {
+               {.offset = 15, .length = 1},
+       }
+};
+
+static struct fsmc_eccplace fsmc_ecc4_sp_place = {
+       .eccplace = {
+               {.offset = 0, .length = 4},
+               {.offset = 6, .length = 9}
+       }
+};
+
+/*
+ * Default partition tables to be used if the partition information not
+ * provided through platform data
+ */
+#define PARTITION(n, off, sz)  {.name = n, .offset = off, .size = sz}
+
+/*
+ * Default partition layout for small page(= 512 bytes) devices
+ * Size for "Root file system" is updated in driver based on actual device size
+ */
+static struct mtd_partition partition_info_16KB_blk[] = {
+       PARTITION("X-loader", 0, 4 * 0x4000),
+       PARTITION("U-Boot", 0x10000, 20 * 0x4000),
+       PARTITION("Kernel", 0x60000, 256 * 0x4000),
+       PARTITION("Root File System", 0x460000, 0),
+};
+
+/*
+ * Default partition layout for large page(> 512 bytes) devices
+ * Size for "Root file system" is updated in driver based on actual device size
+ */
+static struct mtd_partition partition_info_128KB_blk[] = {
+       PARTITION("X-loader", 0, 4 * 0x20000),
+       PARTITION("U-Boot", 0x80000, 12 * 0x20000),
+       PARTITION("Kernel", 0x200000, 48 * 0x20000),
+       PARTITION("Root File System", 0x800000, 0),
+};
+
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+/**
+ * struct fsmc_nand_data - atructure for FSMC NAND device state
+ *
+ * @mtd:               MTD info for a NAND flash.
+ * @nand:              Chip related info for a NAND flash.
+ * @partitions:                Partition info for a NAND Flash.
+ * @nr_partitions:     Total number of partition of a NAND flash.
+ *
+ * @ecc_place:         ECC placing locations in oobfree type format.
+ * @bank:              Bank number for probed device.
+ * @clk:               Clock structure for FSMC.
+ *
+ * @data_va:           NAND port for Data.
+ * @cmd_va:            NAND port for Command.
+ * @addr_va:           NAND port for Address.
+ * @regs_va:           FSMC regs base address.
+ */
+struct fsmc_nand_data {
+       struct mtd_info         mtd;
+       struct nand_chip        nand;
+       struct mtd_partition    *partitions;
+       unsigned int            nr_partitions;
+
+       struct fsmc_eccplace    *ecc_place;
+       unsigned int            bank;
+       struct clk              *clk;
+
+       struct resource         *resregs;
+       struct resource         *rescmd;
+       struct resource         *resaddr;
+       struct resource         *resdata;
+
+       void __iomem            *data_va;
+       void __iomem            *cmd_va;
+       void __iomem            *addr_va;
+       void __iomem            *regs_va;
+
+       void                    (*select_chip)(uint32_t bank, uint32_t busw);
+};
+
+/* Assert CS signal based on chipnr */
+static void fsmc_select_chip(struct mtd_info *mtd, int chipnr)
+{
+       struct nand_chip *chip = mtd->priv;
+       struct fsmc_nand_data *host;
+
+       host = container_of(mtd, struct fsmc_nand_data, mtd);
+
+       switch (chipnr) {
+       case -1:
+               chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+               break;
+       case 0:
+       case 1:
+       case 2:
+       case 3:
+               if (host->select_chip)
+                       host->select_chip(chipnr,
+                                       chip->options & NAND_BUSWIDTH_16);
+               break;
+
+       default:
+               BUG();
+       }
+}
+
+/*
+ * fsmc_cmd_ctrl - For facilitaing Hardware access
+ * This routine allows hardware specific access to control-lines(ALE,CLE)
+ */
+static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+       struct nand_chip *this = mtd->priv;
+       struct fsmc_nand_data *host = container_of(mtd,
+                                       struct fsmc_nand_data, mtd);
+       struct fsmc_regs *regs = host->regs_va;
+       unsigned int bank = host->bank;
+
+       if (ctrl & NAND_CTRL_CHANGE) {
+               if (ctrl & NAND_CLE) {
+                       this->IO_ADDR_R = (void __iomem *)host->cmd_va;
+                       this->IO_ADDR_W = (void __iomem *)host->cmd_va;
+               } else if (ctrl & NAND_ALE) {
+                       this->IO_ADDR_R = (void __iomem *)host->addr_va;
+                       this->IO_ADDR_W = (void __iomem *)host->addr_va;
+               } else {
+                       this->IO_ADDR_R = (void __iomem *)host->data_va;
+                       this->IO_ADDR_W = (void __iomem *)host->data_va;
+               }
+
+               if (ctrl & NAND_NCE) {
+                       writel(readl(&regs->bank_regs[bank].pc) | FSMC_ENABLE,
+                                       &regs->bank_regs[bank].pc);
+               } else {
+                       writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ENABLE,
+                                      &regs->bank_regs[bank].pc);
+               }
+       }
+
+       mb();
+
+       if (cmd != NAND_CMD_NONE)
+               writeb(cmd, this->IO_ADDR_W);
+}
+
+/*
+ * fsmc_nand_setup - FSMC (Flexible Static Memory Controller) init routine
+ *
+ * This routine initializes timing parameters related to NAND memory access in
+ * FSMC registers
+ */
+static void __init fsmc_nand_setup(struct fsmc_regs *regs, uint32_t bank,
+                                  uint32_t busw)
+{
+       uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
+
+       if (busw)
+               writel(value | FSMC_DEVWID_16, &regs->bank_regs[bank].pc);
+       else
+               writel(value | FSMC_DEVWID_8, &regs->bank_regs[bank].pc);
+
+       writel(readl(&regs->bank_regs[bank].pc) | FSMC_TCLR_1 | FSMC_TAR_1,
+              &regs->bank_regs[bank].pc);
+       writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+              &regs->bank_regs[bank].comm);
+       writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0,
+              &regs->bank_regs[bank].attrib);
+}
+
+/*
+ * fsmc_enable_hwecc - Enables Hardware ECC through FSMC registers
+ */
+static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+       struct fsmc_nand_data *host = container_of(mtd,
+                                       struct fsmc_nand_data, mtd);
+       struct fsmc_regs *regs = host->regs_va;
+       uint32_t bank = host->bank;
+
+       writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ECCPLEN_256,
+                      &regs->bank_regs[bank].pc);
+       writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ECCEN,
+                       &regs->bank_regs[bank].pc);
+       writel(readl(&regs->bank_regs[bank].pc) | FSMC_ECCEN,
+                       &regs->bank_regs[bank].pc);
+}
+
+/*
+ * fsmc_read_hwecc_ecc4 - Hardware ECC calculator for ecc4 option supported by
+ * FSMC. ECC is 13 bytes for 512 bytes of data (supports error correction upto
+ * max of 8-bits)
+ */
+static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
+                               uint8_t *ecc)
+{
+       struct fsmc_nand_data *host = container_of(mtd,
+                                       struct fsmc_nand_data, mtd);
+       struct fsmc_regs *regs = host->regs_va;
+       uint32_t bank = host->bank;
+       uint32_t ecc_tmp;
+       unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;
+
+       do {
+               if (readl(&regs->bank_regs[bank].sts) & FSMC_CODE_RDY)
+                       break;
+               else
+                       cond_resched();
+       } while (!time_after_eq(jiffies, deadline));
+
+       ecc_tmp = readl(&regs->bank_regs[bank].ecc1);
+       ecc[0] = (uint8_t) (ecc_tmp >> 0);
+       ecc[1] = (uint8_t) (ecc_tmp >> 8);
+       ecc[2] = (uint8_t) (ecc_tmp >> 16);
+       ecc[3] = (uint8_t) (ecc_tmp >> 24);
+
+       ecc_tmp = readl(&regs->bank_regs[bank].ecc2);
+       ecc[4] = (uint8_t) (ecc_tmp >> 0);
+       ecc[5] = (uint8_t) (ecc_tmp >> 8);
+       ecc[6] = (uint8_t) (ecc_tmp >> 16);
+       ecc[7] = (uint8_t) (ecc_tmp >> 24);
+
+       ecc_tmp = readl(&regs->bank_regs[bank].ecc3);
+       ecc[8] = (uint8_t) (ecc_tmp >> 0);
+       ecc[9] = (uint8_t) (ecc_tmp >> 8);
+       ecc[10] = (uint8_t) (ecc_tmp >> 16);
+       ecc[11] = (uint8_t) (ecc_tmp >> 24);
+
+       ecc_tmp = readl(&regs->bank_regs[bank].sts);
+       ecc[12] = (uint8_t) (ecc_tmp >> 16);
+
+       return 0;
+}
+
+/*
+ * fsmc_read_hwecc_ecc1 - Hardware ECC calculator for ecc1 option supported by
+ * FSMC. ECC is 3 bytes for 512 bytes of data (supports error correction upto
+ * max of 1-bit)
+ */
+static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data,
+                               uint8_t *ecc)
+{
+       struct fsmc_nand_data *host = container_of(mtd,
+                                       struct fsmc_nand_data, mtd);
+       struct fsmc_regs *regs = host->regs_va;
+       uint32_t bank = host->bank;
+       uint32_t ecc_tmp;
+
+       ecc_tmp = readl(&regs->bank_regs[bank].ecc1);
+       ecc[0] = (uint8_t) (ecc_tmp >> 0);
+       ecc[1] = (uint8_t) (ecc_tmp >> 8);
+       ecc[2] = (uint8_t) (ecc_tmp >> 16);
+
+       return 0;
+}
+
+/*
+ * fsmc_read_page_hwecc
+ * @mtd:       mtd info structure
+ * @chip:      nand chip info structure
+ * @buf:       buffer to store read data
+ * @page:      page number to read
+ *
+ * This routine is needed for fsmc verison 8 as reading from NAND chip has to be
+ * performed in a strict sequence as follows:
+ * data(512 byte) -> ecc(13 byte)
+ * After this read, fsmc hardware generates and reports error data bits(upto a
+ * max of 8 bits)
+ */
+static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+                                uint8_t *buf, int page)
+{
+       struct fsmc_nand_data *host = container_of(mtd,
+                                       struct fsmc_nand_data, mtd);
+       struct fsmc_eccplace *ecc_place = host->ecc_place;
+       int i, j, s, stat, eccsize = chip->ecc.size;
+       int eccbytes = chip->ecc.bytes;
+       int eccsteps = chip->ecc.steps;
+       uint8_t *p = buf;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
+       uint8_t *ecc_code = chip->buffers->ecccode;
+       int off, len, group = 0;
+       /*
+        * ecc_oob is intentionally taken as uint16_t. In 16bit devices, we
+        * end up reading 14 bytes (7 words) from oob. The local array is
+        * to maintain word alignment
+        */
+       uint16_t ecc_oob[7];
+       uint8_t *oob = (uint8_t *)&ecc_oob[0];
+
+       for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
+
+               chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
+               chip->ecc.hwctl(mtd, NAND_ECC_READ);
+               chip->read_buf(mtd, p, eccsize);
+
+               for (j = 0; j < eccbytes;) {
+                       off = ecc_place->eccplace[group].offset;
+                       len = ecc_place->eccplace[group].length;
+                       group++;
+
+                       /*
+                       * length is intentionally kept a higher multiple of 2
+                       * to read at least 13 bytes even in case of 16 bit NAND
+                       * devices
+                       */
+                       len = roundup(len, 2);
+                       chip->cmdfunc(mtd, NAND_CMD_READOOB, off, page);
+                       chip->read_buf(mtd, oob + j, len);
+                       j += len;
+               }
+
+               memcpy(&ecc_code[i], oob, 13);
+               chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+               stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+               if (stat < 0)
+                       mtd->ecc_stats.failed++;
+               else
+                       mtd->ecc_stats.corrected += stat;
+       }
+
+       return 0;
+}
+
+/*
+ * fsmc_correct_data
+ * @mtd:       mtd info structure
+ * @dat:       buffer of read data
+ * @read_ecc:  ecc read from device spare area
+ * @calc_ecc:  ecc calculated from read data
+ *
+ * calc_ecc is a 104 bit information containing maximum of 8 error
+ * offset informations of 13 bits each in 512 bytes of read data.
+ */
+static int fsmc_correct_data(struct mtd_info *mtd, uint8_t *dat,
+                            uint8_t *read_ecc, uint8_t *calc_ecc)
+{
+       struct fsmc_nand_data *host = container_of(mtd,
+                                       struct fsmc_nand_data, mtd);
+       struct fsmc_regs *regs = host->regs_va;
+       unsigned int bank = host->bank;
+       uint16_t err_idx[8];
+       uint64_t ecc_data[2];
+       uint32_t num_err, i;
+
+       /* The calculated ecc is actually the correction index in data */
+       memcpy(ecc_data, calc_ecc, 13);
+
+       /*
+        * ------------------- calc_ecc[] bit wise -----------|--13 bits--|
+        * |---idx[7]--|--.....-----|---idx[2]--||---idx[1]--||---idx[0]--|
+        *
+        * calc_ecc is a 104 bit information containing maximum of 8 error
+        * offset informations of 13 bits each. calc_ecc is copied into a
+        * uint64_t array and error offset indexes are populated in err_idx
+        * array
+        */
+       for (i = 0; i < 8; i++) {
+               if (i == 4) {
+                       err_idx[4] = ((ecc_data[1] & 0x1) << 12) | ecc_data[0];
+                       ecc_data[1] >>= 1;
+                       continue;
+               }
+               err_idx[i] = (ecc_data[i/4] & 0x1FFF);
+               ecc_data[i/4] >>= 13;
+       }
+
+       num_err = (readl(&regs->bank_regs[bank].sts) >> 10) & 0xF;
+
+       if (num_err == 0xF)
+               return -EBADMSG;
+
+       i = 0;
+       while (num_err--) {
+               change_bit(0, (unsigned long *)&err_idx[i]);
+               change_bit(1, (unsigned long *)&err_idx[i]);
+
+               if (err_idx[i] <= 512 * 8) {
+                       change_bit(err_idx[i], (unsigned long *)dat);
+                       i++;
+               }
+       }
+       return i;
+}
+
+/*
+ * fsmc_nand_probe - Probe function
+ * @pdev:       platform device structure
+ */
+static int __init fsmc_nand_probe(struct platform_device *pdev)
+{
+       struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
+       struct fsmc_nand_data *host;
+       struct mtd_info *mtd;
+       struct nand_chip *nand;
+       struct fsmc_regs *regs;
+       struct resource *res;
+       int nr_parts, ret = 0;
+
+       if (!pdata) {
+               dev_err(&pdev->dev, "platform data is NULL\n");
+               return -EINVAL;
+       }
+
+       /* Allocate memory for the device structure (and zero it) */
+       host = kzalloc(sizeof(*host), GFP_KERNEL);
+       if (!host) {
+               dev_err(&pdev->dev, "failed to allocate device structure\n");
+               return -ENOMEM;
+       }
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
+       if (!res) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       host->resdata = request_mem_region(res->start, resource_size(res),
+                       pdev->name);
+       if (!host->resdata) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       host->data_va = ioremap(res->start, resource_size(res));
+       if (!host->data_va) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       host->resaddr = request_mem_region(res->start + PLAT_NAND_ALE,
+                       resource_size(res), pdev->name);
+       if (!host->resaddr) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       host->addr_va = ioremap(res->start + PLAT_NAND_ALE, resource_size(res));
+       if (!host->addr_va) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       host->rescmd = request_mem_region(res->start + PLAT_NAND_CLE,
+                       resource_size(res), pdev->name);
+       if (!host->rescmd) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       host->cmd_va = ioremap(res->start + PLAT_NAND_CLE, resource_size(res));
+       if (!host->cmd_va) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fsmc_regs");
+       if (!res) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       host->resregs = request_mem_region(res->start, resource_size(res),
+                       pdev->name);
+       if (!host->resregs) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       host->regs_va = ioremap(res->start, resource_size(res));
+       if (!host->regs_va) {
+               ret = -EIO;
+               goto err_probe1;
+       }
+
+       host->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(host->clk)) {
+               dev_err(&pdev->dev, "failed to fetch block clock\n");
+               ret = PTR_ERR(host->clk);
+               host->clk = NULL;
+               goto err_probe1;
+       }
+
+       ret = clk_enable(host->clk);
+       if (ret)
+               goto err_probe1;
+
+       host->bank = pdata->bank;
+       host->select_chip = pdata->select_bank;
+       regs = host->regs_va;
+
+       /* Link all private pointers */
+       mtd = &host->mtd;
+       nand = &host->nand;
+       mtd->priv = nand;
+       nand->priv = host;
+
+       host->mtd.owner = THIS_MODULE;
+       nand->IO_ADDR_R = host->data_va;
+       nand->IO_ADDR_W = host->data_va;
+       nand->cmd_ctrl = fsmc_cmd_ctrl;
+       nand->chip_delay = 30;
+
+       nand->ecc.mode = NAND_ECC_HW;
+       nand->ecc.hwctl = fsmc_enable_hwecc;
+       nand->ecc.size = 512;
+       nand->options = pdata->options;
+       nand->select_chip = fsmc_select_chip;
+
+       if (pdata->width == FSMC_NAND_BW16)
+               nand->options |= NAND_BUSWIDTH_16;
+
+       fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16);
+
+       if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+               nand->ecc.read_page = fsmc_read_page_hwecc;
+               nand->ecc.calculate = fsmc_read_hwecc_ecc4;
+               nand->ecc.correct = fsmc_correct_data;
+               nand->ecc.bytes = 13;
+       } else {
+               nand->ecc.calculate = fsmc_read_hwecc_ecc1;
+               nand->ecc.correct = nand_correct_data;
+               nand->ecc.bytes = 3;
+       }
+
+       /*
+        * Scan to find existance of the device
+        */
+       if (nand_scan_ident(&host->mtd, 1, NULL)) {
+               ret = -ENXIO;
+               dev_err(&pdev->dev, "No NAND Device found!\n");
+               goto err_probe;
+       }
+
+       if (get_fsmc_version(host->regs_va) == FSMC_VER8) {
+               if (host->mtd.writesize == 512) {
+                       nand->ecc.layout = &fsmc_ecc4_sp_layout;
+                       host->ecc_place = &fsmc_ecc4_sp_place;
+               } else {
+                       nand->ecc.layout = &fsmc_ecc4_lp_layout;
+                       host->ecc_place = &fsmc_ecc4_lp_place;
+               }
+       } else {
+               nand->ecc.layout = &fsmc_ecc1_layout;
+       }
+
+       /* Second stage of scan to fill MTD data-structures */
+       if (nand_scan_tail(&host->mtd)) {
+               ret = -ENXIO;
+               goto err_probe;
+       }
+
+       /*
+        * The partition information can is accessed by (in the same precedence)
+        *
+        * command line through Bootloader,
+        * platform data,
+        * default partition information present in driver.
+        */
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+       /*
+        * Check if partition info passed via command line
+        */
+       host->mtd.name = "nand";
+       nr_parts = parse_mtd_partitions(&host->mtd, part_probes,
+                       &host->partitions, 0);
+       if (nr_parts > 0) {
+               host->nr_partitions = nr_parts;
+       } else {
+#endif
+               /*
+                * Check if partition info passed via command line
+                */
+               if (pdata->partitions) {
+                       host->partitions = pdata->partitions;
+                       host->nr_partitions = pdata->nr_partitions;
+               } else {
+                       struct mtd_partition *partition;
+                       int i;
+
+                       /* Select the default partitions info */
+                       switch (host->mtd.size) {
+                       case 0x01000000:
+                       case 0x02000000:
+                       case 0x04000000:
+                               host->partitions = partition_info_16KB_blk;
+                               host->nr_partitions =
+                                       sizeof(partition_info_16KB_blk) /
+                                       sizeof(struct mtd_partition);
+                               break;
+                       case 0x08000000:
+                       case 0x10000000:
+                       case 0x20000000:
+                       case 0x40000000:
+                               host->partitions = partition_info_128KB_blk;
+                               host->nr_partitions =
+                                       sizeof(partition_info_128KB_blk) /
+                                       sizeof(struct mtd_partition);
+                               break;
+                       default:
+                               ret = -ENXIO;
+                               pr_err("Unsupported NAND size\n");
+                               goto err_probe;
+                       }
+
+                       partition = host->partitions;
+                       for (i = 0; i < host->nr_partitions; i++, partition++) {
+                               if (partition->size == 0) {
+                                       partition->size = host->mtd.size -
+                                               partition->offset;
+                                       break;
+                               }
+                       }
+               }
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+       }
+#endif
+
+       if (host->partitions) {
+               ret = add_mtd_partitions(&host->mtd, host->partitions,
+                               host->nr_partitions);
+               if (ret)
+                       goto err_probe;
+       }
+#else
+       dev_info(&pdev->dev, "Registering %s as whole device\n", mtd->name);
+       if (!add_mtd_device(mtd)) {
+               ret = -ENXIO;
+               goto err_probe;
+       }
+#endif
+
+       platform_set_drvdata(pdev, host);
+       dev_info(&pdev->dev, "FSMC NAND driver registration successful\n");
+       return 0;
+
+err_probe:
+       clk_disable(host->clk);
+err_probe1:
+       if (host->clk)
+               clk_put(host->clk);
+       if (host->regs_va)
+               iounmap(host->regs_va);
+       if (host->resregs)
+               release_mem_region(host->resregs->start,
+                               resource_size(host->resregs));
+       if (host->cmd_va)
+               iounmap(host->cmd_va);
+       if (host->rescmd)
+               release_mem_region(host->rescmd->start,
+                               resource_size(host->rescmd));
+       if (host->addr_va)
+               iounmap(host->addr_va);
+       if (host->resaddr)
+               release_mem_region(host->resaddr->start,
+                               resource_size(host->resaddr));
+       if (host->data_va)
+               iounmap(host->data_va);
+       if (host->resdata)
+               release_mem_region(host->resdata->start,
+                               resource_size(host->resdata));
+
+       kfree(host);
+       return ret;
+}
+
+/*
+ * Clean up routine
+ */
+static int fsmc_nand_remove(struct platform_device *pdev)
+{
+       struct fsmc_nand_data *host = platform_get_drvdata(pdev);
+
+       platform_set_drvdata(pdev, NULL);
+
+       if (host) {
+#ifdef CONFIG_MTD_PARTITIONS
+               del_mtd_partitions(&host->mtd);
+#else
+               del_mtd_device(&host->mtd);
+#endif
+               clk_disable(host->clk);
+               clk_put(host->clk);
+
+               iounmap(host->regs_va);
+               release_mem_region(host->resregs->start,
+                               resource_size(host->resregs));
+               iounmap(host->cmd_va);
+               release_mem_region(host->rescmd->start,
+                               resource_size(host->rescmd));
+               iounmap(host->addr_va);
+               release_mem_region(host->resaddr->start,
+                               resource_size(host->resaddr));
+               iounmap(host->data_va);
+               release_mem_region(host->resdata->start,
+                               resource_size(host->resdata));
+
+               kfree(host);
+       }
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsmc_nand_suspend(struct device *dev)
+{
+       struct fsmc_nand_data *host = dev_get_drvdata(dev);
+       if (host)
+               clk_disable(host->clk);
+       return 0;
+}
+
+static int fsmc_nand_resume(struct device *dev)
+{
+       struct fsmc_nand_data *host = dev_get_drvdata(dev);
+       if (host)
+               clk_enable(host->clk);
+       return 0;
+}
+
+static const struct dev_pm_ops fsmc_nand_pm_ops = {
+       .suspend = fsmc_nand_suspend,
+       .resume = fsmc_nand_resume,
+};
+#endif
+
+static struct platform_driver fsmc_nand_driver = {
+       .remove = fsmc_nand_remove,
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "fsmc-nand",
+#ifdef CONFIG_PM
+               .pm = &fsmc_nand_pm_ops,
+#endif
+       },
+};
+
+static int __init fsmc_nand_init(void)
+{
+       return platform_driver_probe(&fsmc_nand_driver,
+                                    fsmc_nand_probe);
+}
+module_init(fsmc_nand_init);
+
+static void __exit fsmc_nand_exit(void)
+{
+       platform_driver_unregister(&fsmc_nand_driver);
+}
+module_exit(fsmc_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>, Ashish Priyadarshi");
+MODULE_DESCRIPTION("NAND driver for SPEAr Platforms");
index df0c1da4ff49b5b36357bb8a6ccbea9c420728e5..469e649c911c83e1ac8d9c3d7f81be7ece2135fc 100644 (file)
@@ -568,6 +568,7 @@ static int mpc5121_nfc_read_hw_config(struct mtd_info *mtd)
        uint rcw_width;
        uint rcwh;
        uint romloc, ps;
+       int ret = 0;
 
        rmnode = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-reset");
        if (!rmnode) {
@@ -579,7 +580,8 @@ static int mpc5121_nfc_read_hw_config(struct mtd_info *mtd)
        rm = of_iomap(rmnode, 0);
        if (!rm) {
                dev_err(prv->dev, "Error mapping reset module node!\n");
-               return -EBUSY;
+               ret = -EBUSY;
+               goto out;
        }
 
        rcwh = in_be32(&rm->rcwhr);
@@ -628,8 +630,9 @@ static int mpc5121_nfc_read_hw_config(struct mtd_info *mtd)
                                rcw_width * 8, rcw_pagesize,
                                rcw_sparesize);
        iounmap(rm);
+out:
        of_node_put(rmnode);
-       return 0;
+       return ret;
 }
 
 /* Free driver resources */
@@ -660,7 +663,7 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op,
 #endif
        struct nand_chip *chip;
        unsigned long regs_paddr, regs_size;
-       const uint *chips_no;
+       const __be32 *chips_no;
        int resettime = 0;
        int retval = 0;
        int rev, len;
@@ -803,7 +806,7 @@ static int __devinit mpc5121_nfc_probe(struct platform_device *op,
        }
 
        /* Detect NAND chips */
-       if (nand_scan(mtd, *chips_no)) {
+       if (nand_scan(mtd, be32_to_cpup(chips_no))) {
                dev_err(dev, "NAND Flash not found !\n");
                devm_free_irq(dev, prv->irq, mtd);
                retval = -ENXIO;
index d551ddd9537a34d17fe3c13b7604855fc5c06f5b..1f75a1b1f7c3a6dc5fa0157d800e7c49fe483793 100644 (file)
@@ -45,7 +45,7 @@
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/leds.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #ifdef CONFIG_MTD_PARTITIONS
 #include <linux/mtd/partitions.h>
@@ -59,7 +59,7 @@ static struct nand_ecclayout nand_oob_8 = {
                {.offset = 3,
                 .length = 2},
                {.offset = 6,
-                .length = 2}}
+                .length = 2} }
 };
 
 static struct nand_ecclayout nand_oob_16 = {
@@ -67,7 +67,7 @@ static struct nand_ecclayout nand_oob_16 = {
        .eccpos = {0, 1, 2, 3, 6, 7},
        .oobfree = {
                {.offset = 8,
-                . length = 8}}
+                . length = 8} }
 };
 
 static struct nand_ecclayout nand_oob_64 = {
@@ -78,7 +78,7 @@ static struct nand_ecclayout nand_oob_64 = {
                   56, 57, 58, 59, 60, 61, 62, 63},
        .oobfree = {
                {.offset = 2,
-                .length = 38}}
+                .length = 38} }
 };
 
 static struct nand_ecclayout nand_oob_128 = {
@@ -92,7 +92,7 @@ static struct nand_ecclayout nand_oob_128 = {
                   120, 121, 122, 123, 124, 125, 126, 127},
        .oobfree = {
                {.offset = 2,
-                .length = 78}}
+                .length = 78} }
 };
 
 static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
@@ -612,7 +612,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
                               NAND_CTRL_CLE | NAND_CTRL_CHANGE);
                chip->cmd_ctrl(mtd,
                               NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
-               while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ;
+               while (!(chip->read_byte(mtd) & NAND_STATUS_READY))
+                               ;
                return;
 
                /* This applies to read commands */
@@ -718,7 +719,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                               NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
                chip->cmd_ctrl(mtd, NAND_CMD_NONE,
                               NAND_NCE | NAND_CTRL_CHANGE);
-               while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ;
+               while (!(chip->read_byte(mtd) & NAND_STATUS_READY))
+                               ;
                return;
 
        case NAND_CMD_RNDOUT:
@@ -784,7 +786,7 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
        spinlock_t *lock = &chip->controller->lock;
        wait_queue_head_t *wq = &chip->controller->wq;
        DECLARE_WAITQUEUE(wait, current);
- retry:
+retry:
        spin_lock(lock);
 
        /* Hardware controller shared among independent devices */
@@ -834,7 +836,7 @@ static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip,
                                break;
                }
                mdelay(1);
-        }
+       }
 }
 
 /**
@@ -980,6 +982,7 @@ out:
 
        return ret;
 }
+EXPORT_SYMBOL(nand_unlock);
 
 /**
  * nand_lock - [REPLACEABLE] locks all blocks present in the device
@@ -1049,6 +1052,7 @@ out:
 
        return ret;
 }
+EXPORT_SYMBOL(nand_lock);
 
 /**
  * nand_read_page_raw - [Intern] read raw page data without ecc
@@ -1076,8 +1080,9 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
  *
  * We need a special oob layout and handling even when OOB isn't used.
  */
-static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
-                             uint8_t *buf, int page)
+static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
+                                       struct nand_chip *chip,
+                                       uint8_t *buf, int page)
 {
        int eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1158,7 +1163,8 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @readlen:   data length
  * @bufpoi:    buffer to store read data
  */
-static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
+static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+                       uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
 {
        int start_step, end_step, num_steps;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
@@ -1166,6 +1172,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3
        int data_col_addr, i, gaps = 0;
        int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
        int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
+       int index = 0;
 
        /* Column address wihin the page aligned to ECC size (256bytes). */
        start_step = data_offs / chip->ecc.size;
@@ -1204,26 +1211,30 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3
        } else {
                /* send the command to read the particular ecc bytes */
                /* take care about buswidth alignment in read_buf */
-               aligned_pos = eccpos[start_step * chip->ecc.bytes] & ~(busw - 1);
+               index = start_step * chip->ecc.bytes;
+
+               aligned_pos = eccpos[index] & ~(busw - 1);
                aligned_len = eccfrag_len;
-               if (eccpos[start_step * chip->ecc.bytes] & (busw - 1))
+               if (eccpos[index] & (busw - 1))
                        aligned_len++;
-               if (eccpos[(start_step + num_steps) * chip->ecc.bytes] & (busw - 1))
+               if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
                        aligned_len++;
 
-               chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize + aligned_pos, -1);
+               chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
+                                       mtd->writesize + aligned_pos, -1);
                chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
        }
 
        for (i = 0; i < eccfrag_len; i++)
-               chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + start_step * chip->ecc.bytes]];
+               chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
 
        p = bufpoi + data_col_addr;
        for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
                int stat;
 
-               stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
-               if (stat == -1)
+               stat = chip->ecc.correct(mtd, p,
+                       &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
+               if (stat < 0)
                        mtd->ecc_stats.failed++;
                else
                        mtd->ecc_stats.corrected += stat;
@@ -1390,7 +1401,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
 static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
                                  struct mtd_oob_ops *ops, size_t len)
 {
-       switch(ops->mode) {
+       switch (ops->mode) {
 
        case MTD_OOB_PLACE:
        case MTD_OOB_RAW:
@@ -1402,7 +1413,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
                uint32_t boffs = 0, roffs = ops->ooboffs;
                size_t bytes = 0;
 
-               for(; free->length && len; free++, len -= bytes) {
+               for (; free->length && len; free++, len -= bytes) {
                        /* Read request not from offset 0 ? */
                        if (unlikely(roffs)) {
                                if (roffs >= free->length) {
@@ -1466,7 +1477,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
        buf = ops->datbuf;
        oob = ops->oobbuf;
 
-       while(1) {
+       while (1) {
                bytes = min(mtd->writesize - col, readlen);
                aligned = (bytes == mtd->writesize);
 
@@ -1484,7 +1495,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                                ret = chip->ecc.read_page_raw(mtd, chip,
                                                              bufpoi, page);
                        else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
-                               ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi);
+                               ret = chip->ecc.read_subpage(mtd, chip,
+                                                       col, bytes, bufpoi);
                        else
                                ret = chip->ecc.read_page(mtd, chip, bufpoi,
                                                          page);
@@ -1493,7 +1505,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 
                        /* Transfer not aligned data */
                        if (!aligned) {
-                               if (!NAND_SUBPAGE_READ(chip) && !oob)
+                               if (!NAND_SUBPAGE_READ(chip) && !oob &&
+                                   !(mtd->ecc_stats.failed - stats.failed))
                                        chip->pagebuf = realpage;
                                memcpy(buf, chip->buffers->databuf + col, bytes);
                        }
@@ -1791,7 +1804,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
        realpage = (int)(from >> chip->page_shift);
        page = realpage & chip->pagemask;
 
-       while(1) {
+       while (1) {
                sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
 
                len = min(len, readlen);
@@ -1861,7 +1874,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
 
        nand_get_device(chip, mtd, FL_READING);
 
-       switch(ops->mode) {
+       switch (ops->mode) {
        case MTD_OOB_PLACE:
        case MTD_OOB_AUTO:
        case MTD_OOB_RAW:
@@ -1876,7 +1889,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
        else
                ret = nand_do_read_ops(mtd, from, ops);
 
- out:
+out:
        nand_release_device(mtd);
        return ret;
 }
@@ -1905,8 +1918,9 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
  *
  * We need a special oob layout and handling even when ECC isn't checked.
  */
-static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
-                               const uint8_t *buf)
+static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
+                                       struct nand_chip *chip,
+                                       const uint8_t *buf)
 {
        int eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -2099,7 +2113,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
                                                struct mtd_oob_ops *ops)
 {
-       switch(ops->mode) {
+       switch (ops->mode) {
 
        case MTD_OOB_PLACE:
        case MTD_OOB_RAW:
@@ -2111,7 +2125,7 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
                uint32_t boffs = 0, woffs = ops->ooboffs;
                size_t bytes = 0;
 
-               for(; free->length && len; free++, len -= bytes) {
+               for (; free->length && len; free++, len -= bytes) {
                        /* Write request not from offset 0 ? */
                        if (unlikely(woffs)) {
                                if (woffs >= free->length) {
@@ -2137,7 +2151,7 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len,
        return NULL;
 }
 
-#define NOTALIGNED(x)  (x & (chip->subpagesize - 1)) != 0
+#define NOTALIGNED(x)  ((x & (chip->subpagesize - 1)) != 0)
 
 /**
  * nand_do_write_ops - [Internal] NAND write with ECC
@@ -2200,10 +2214,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                memset(chip->oob_poi, 0xff, mtd->oobsize);
 
        /* Don't allow multipage oob writes with offset */
-       if (ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
+       if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen))
                return -EINVAL;
 
-       while(1) {
+       while (1) {
                int bytes = mtd->writesize;
                int cached = writelen > bytes && page != blockmask;
                uint8_t *wbuf = buf;
@@ -2431,7 +2445,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
 
        nand_get_device(chip, mtd, FL_WRITING);
 
-       switch(ops->mode) {
+       switch (ops->mode) {
        case MTD_OOB_PLACE:
        case MTD_OOB_AUTO:
        case MTD_OOB_RAW:
@@ -2446,7 +2460,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
        else
                ret = nand_do_write_ops(mtd, to, ops);
 
- out:
+out:
        nand_release_device(mtd);
        return ret;
 }
@@ -2511,7 +2525,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 {
        int page, status, pages_per_block, ret, chipnr;
        struct nand_chip *chip = mtd->priv;
-       loff_t rewrite_bbt[NAND_MAX_CHIPS]={0};
+       loff_t rewrite_bbt[NAND_MAX_CHIPS] = {0};
        unsigned int bbt_masked_page = 0xffffffff;
        loff_t len;
 
@@ -2632,7 +2646,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
        }
        instr->state = MTD_ERASE_DONE;
 
- erase_exit:
+erase_exit:
 
        ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
 
@@ -2706,7 +2720,8 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
        struct nand_chip *chip = mtd->priv;
        int ret;
 
-       if ((ret = nand_block_isbad(mtd, ofs))) {
+       ret = nand_block_isbad(mtd, ofs);
+       if (ret) {
                /* If it was bad already, return success and do nothing. */
                if (ret > 0)
                        return 0;
@@ -2786,16 +2801,116 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
 
 }
 
+/*
+ * sanitize ONFI strings so we can safely print them
+ */
+static void sanitize_string(uint8_t *s, size_t len)
+{
+       ssize_t i;
+
+       /* null terminate */
+       s[len - 1] = 0;
+
+       /* remove non printable chars */
+       for (i = 0; i < len - 1; i++) {
+               if (s[i] < ' ' || s[i] > 127)
+                       s[i] = '?';
+       }
+
+       /* remove trailing spaces */
+       strim(s);
+}
+
+static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
+{
+       int i;
+       while (len--) {
+               crc ^= *p++ << 8;
+               for (i = 0; i < 8; i++)
+                       crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
+       }
+
+       return crc;
+}
+
+/*
+ * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise
+ */
+static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
+                                       int busw)
+{
+       struct nand_onfi_params *p = &chip->onfi_params;
+       int i;
+       int val;
+
+       /* try ONFI for unknow chip or LP */
+       chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
+       if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
+               chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I')
+               return 0;
+
+       printk(KERN_INFO "ONFI flash detected\n");
+       chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
+       for (i = 0; i < 3; i++) {
+               chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
+               if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
+                               le16_to_cpu(p->crc)) {
+                       printk(KERN_INFO "ONFI param page %d valid\n", i);
+                       break;
+               }
+       }
+
+       if (i == 3)
+               return 0;
+
+       /* check version */
+       val = le16_to_cpu(p->revision);
+       if (val == 1 || val > (1 << 4)) {
+               printk(KERN_INFO "%s: unsupported ONFI version: %d\n",
+                                                               __func__, val);
+               return 0;
+       }
+
+       if (val & (1 << 4))
+               chip->onfi_version = 22;
+       else if (val & (1 << 3))
+               chip->onfi_version = 21;
+       else if (val & (1 << 2))
+               chip->onfi_version = 20;
+       else
+               chip->onfi_version = 10;
+
+       sanitize_string(p->manufacturer, sizeof(p->manufacturer));
+       sanitize_string(p->model, sizeof(p->model));
+       if (!mtd->name)
+               mtd->name = p->model;
+       mtd->writesize = le32_to_cpu(p->byte_per_page);
+       mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
+       mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
+       chip->chipsize = le32_to_cpu(p->blocks_per_lun) * mtd->erasesize;
+       busw = 0;
+       if (le16_to_cpu(p->features) & 1)
+               busw = NAND_BUSWIDTH_16;
+
+       chip->options &= ~NAND_CHIPOPTIONS_MSK;
+       chip->options |= (NAND_NO_READRDY |
+                       NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK;
+
+       return 1;
+}
+
 /*
  * Get the flash and manufacturer id and lookup if the type is supported
  */
 static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                                                  struct nand_chip *chip,
-                                                 int busw, int *maf_id,
+                                                 int busw,
+                                                 int *maf_id, int *dev_id,
                                                  struct nand_flash_dev *type)
 {
-       int i, dev_id, maf_idx;
+       int i, maf_idx;
        u8 id_data[8];
+       int ret;
 
        /* Select the device */
        chip->select_chip(mtd, 0);
@@ -2811,7 +2926,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 
        /* Read manufacturer and device IDs */
        *maf_id = chip->read_byte(mtd);
-       dev_id = chip->read_byte(mtd);
+       *dev_id = chip->read_byte(mtd);
 
        /* Try again to make sure, as some systems the bus-hold or other
         * interface concerns can cause random data which looks like a
@@ -2821,15 +2936,13 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
 
-       /* Read entire ID string */
-
-       for (i = 0; i < 8; i++)
+       for (i = 0; i < 2; i++)
                id_data[i] = chip->read_byte(mtd);
 
-       if (id_data[0] != *maf_id || id_data[1] != dev_id) {
+       if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
                printk(KERN_INFO "%s: second ID read did not match "
                       "%02x,%02x against %02x,%02x\n", __func__,
-                      *maf_id, dev_id, id_data[0], id_data[1]);
+                      *maf_id, *dev_id, id_data[0], id_data[1]);
                return ERR_PTR(-ENODEV);
        }
 
@@ -2837,8 +2950,23 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                type = nand_flash_ids;
 
        for (; type->name != NULL; type++)
-               if (dev_id == type->id)
-                        break;
+               if (*dev_id == type->id)
+                       break;
+
+       chip->onfi_version = 0;
+       if (!type->name || !type->pagesize) {
+               /* Check is chip is ONFI compliant */
+               ret = nand_flash_detect_onfi(mtd, chip, busw);
+               if (ret)
+                       goto ident_done;
+       }
+
+       chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+
+       /* Read entire ID string */
+
+       for (i = 0; i < 8; i++)
+               id_data[i] = chip->read_byte(mtd);
 
        if (!type->name)
                return ERR_PTR(-ENODEV);
@@ -2848,8 +2976,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 
        chip->chipsize = (uint64_t)type->chipsize << 20;
 
-       /* Newer devices have all the information in additional id bytes */
-       if (!type->pagesize) {
+       if (!type->pagesize && chip->init_size) {
+               /* set the pagesize, oobsize, erasesize by the driver*/
+               busw = chip->init_size(mtd, chip, id_data);
+       } else if (!type->pagesize) {
                int extid;
                /* The 3rd id byte holds MLC / multichip data */
                chip->cellinfo = id_data[2];
@@ -2859,7 +2989,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                /*
                 * Field definitions are in the following datasheets:
                 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
-                * New style   (6 byte ID): Samsung K9GAG08U0D (p.40)
+                * New style   (6 byte ID): Samsung K9GBG08U0M (p.40)
                 *
                 * Check for wraparound + Samsung ID + nonzero 6th byte
                 * to decide what to do.
@@ -2872,7 +3002,20 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                        mtd->writesize = 2048 << (extid & 0x03);
                        extid >>= 2;
                        /* Calc oobsize */
-                       mtd->oobsize = (extid & 0x03) == 0x01 ? 128 : 218;
+                       switch (extid & 0x03) {
+                       case 1:
+                               mtd->oobsize = 128;
+                               break;
+                       case 2:
+                               mtd->oobsize = 218;
+                               break;
+                       case 3:
+                               mtd->oobsize = 400;
+                               break;
+                       default:
+                               mtd->oobsize = 436;
+                               break;
+                       }
                        extid >>= 2;
                        /* Calc blocksize */
                        mtd->erasesize = (128 * 1024) <<
@@ -2900,7 +3043,35 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                mtd->writesize = type->pagesize;
                mtd->oobsize = mtd->writesize / 32;
                busw = type->options & NAND_BUSWIDTH_16;
+
+               /*
+                * Check for Spansion/AMD ID + repeating 5th, 6th byte since
+                * some Spansion chips have erasesize that conflicts with size
+                * listed in nand_ids table
+                * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
+                */
+               if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 &&
+                               id_data[5] == 0x00 && id_data[6] == 0x00 &&
+                               id_data[7] == 0x00 && mtd->writesize == 512) {
+                       mtd->erasesize = 128 * 1024;
+                       mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
+               }
        }
+       /* Get chip options, preserve non chip based options */
+       chip->options &= ~NAND_CHIPOPTIONS_MSK;
+       chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
+
+       /* Check if chip is a not a samsung device. Do not clear the
+        * options for chips which are not having an extended id.
+        */
+       if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
+               chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
+ident_done:
+
+       /*
+        * Set chip as a default. Board drivers can override it, if necessary
+        */
+       chip->options |= NAND_NO_AUTOINCR;
 
        /* Try to identify manufacturer */
        for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
@@ -2915,7 +3086,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        if (busw != (chip->options & NAND_BUSWIDTH_16)) {
                printk(KERN_INFO "NAND device: Manufacturer ID:"
                       " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
-                      dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
+                      *dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
                printk(KERN_WARNING "NAND bus width %d instead %d bit\n",
                       (chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
                       busw ? 16 : 8);
@@ -2931,8 +3102,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                ffs(mtd->erasesize) - 1;
        if (chip->chipsize & 0xffffffff)
                chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
-       else
-               chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1;
+       else {
+               chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32));
+               chip->chip_shift += 32 - 1;
+       }
 
        /* Set the bad block position */
        if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
@@ -2940,27 +3113,12 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        else
                chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
 
-       /* Get chip options, preserve non chip based options */
-       chip->options &= ~NAND_CHIPOPTIONS_MSK;
-       chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
-
-       /*
-        * Set chip as a default. Board drivers can override it, if necessary
-        */
-       chip->options |= NAND_NO_AUTOINCR;
-
-       /* Check if chip is a not a samsung device. Do not clear the
-        * options for chips which are not having an extended id.
-        */
-       if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
-               chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
-
        /*
         * Bad block marker is stored in the last page of each block
         * on Samsung and Hynix MLC devices; stored in first two pages
         * of each block on Micron devices with 2KiB pages and on
-        * SLC Samsung, Hynix, and AMD/Spansion. All others scan only
-        * the first page.
+        * SLC Samsung, Hynix, Toshiba and AMD/Spansion. All others scan
+        * only the first page.
         */
        if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
                        (*maf_id == NAND_MFR_SAMSUNG ||
@@ -2969,6 +3127,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
                                (*maf_id == NAND_MFR_SAMSUNG ||
                                 *maf_id == NAND_MFR_HYNIX ||
+                                *maf_id == NAND_MFR_TOSHIBA ||
                                 *maf_id == NAND_MFR_AMD)) ||
                        (mtd->writesize == 2048 &&
                         *maf_id == NAND_MFR_MICRON))
@@ -2994,9 +3153,11 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
        if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
                chip->cmdfunc = nand_command_lp;
 
+       /* TODO onfi flash name */
        printk(KERN_INFO "NAND device: Manufacturer ID:"
-              " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id,
-              nand_manuf_ids[maf_idx].name, type->name);
+               " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,
+               nand_manuf_ids[maf_idx].name,
+       chip->onfi_version ? type->name : chip->onfi_params.model);
 
        return type;
 }
@@ -3015,7 +3176,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 int nand_scan_ident(struct mtd_info *mtd, int maxchips,
                    struct nand_flash_dev *table)
 {
-       int i, busw, nand_maf_id;
+       int i, busw, nand_maf_id, nand_dev_id;
        struct nand_chip *chip = mtd->priv;
        struct nand_flash_dev *type;
 
@@ -3025,7 +3186,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
        nand_set_defaults(chip, busw);
 
        /* Read the flash type */
-       type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, table);
+       type = nand_get_flash_type(mtd, chip, busw,
+                               &nand_maf_id, &nand_dev_id, table);
 
        if (IS_ERR(type)) {
                if (!(chip->options & NAND_SCAN_SILENT_NODEV))
@@ -3043,7 +3205,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
                chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
                /* Read manufacturer and device IDs */
                if (nand_maf_id != chip->read_byte(mtd) ||
-                   type->id != chip->read_byte(mtd))
+                   nand_dev_id != chip->read_byte(mtd))
                        break;
        }
        if (i > 1)
@@ -3055,6 +3217,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
 
        return 0;
 }
+EXPORT_SYMBOL(nand_scan_ident);
 
 
 /**
@@ -3219,7 +3382,7 @@ int nand_scan_tail(struct mtd_info *mtd)
         * mode
         */
        chip->ecc.steps = mtd->writesize / chip->ecc.size;
-       if(chip->ecc.steps * chip->ecc.size != mtd->writesize) {
+       if (chip->ecc.steps * chip->ecc.size != mtd->writesize) {
                printk(KERN_WARNING "Invalid ecc parameters\n");
                BUG();
        }
@@ -3231,7 +3394,7 @@ int nand_scan_tail(struct mtd_info *mtd)
         */
        if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
            !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
-               switch(chip->ecc.steps) {
+               switch (chip->ecc.steps) {
                case 2:
                        mtd->subpage_sft = 1;
                        break;
@@ -3283,10 +3446,11 @@ int nand_scan_tail(struct mtd_info *mtd)
        /* Build bad block table */
        return chip->scan_bbt(mtd);
 }
+EXPORT_SYMBOL(nand_scan_tail);
 
 /* is_module_text_address() isn't exported, and it's mostly a pointless
  test if this is a module _anyway_ -- they'd have to try _really_ hard
  to call us from in-kernel code if the core NAND support is modular. */
* test if this is a module _anyway_ -- they'd have to try _really_ hard
* to call us from in-kernel code if the core NAND support is modular. */
 #ifdef MODULE
 #define caller_is_module() (1)
 #else
@@ -3322,6 +3486,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
                ret = nand_scan_tail(mtd);
        return ret;
 }
+EXPORT_SYMBOL(nand_scan);
 
 /**
  * nand_release - [NAND Interface] Free resources held by the NAND device
@@ -3348,12 +3513,6 @@ void nand_release(struct mtd_info *mtd)
                        & NAND_BBT_DYNAMICSTRUCT)
                kfree(chip->badblock_pattern);
 }
-
-EXPORT_SYMBOL_GPL(nand_lock);
-EXPORT_SYMBOL_GPL(nand_unlock);
-EXPORT_SYMBOL_GPL(nand_scan);
-EXPORT_SYMBOL_GPL(nand_scan_ident);
-EXPORT_SYMBOL_GPL(nand_scan_tail);
 EXPORT_SYMBOL_GPL(nand_release);
 
 static int __init nand_base_init(void)
@@ -3371,5 +3530,6 @@ module_init(nand_base_init);
 module_exit(nand_base_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
+MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
+MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
 MODULE_DESCRIPTION("Generic NAND flash driver code");
index 5fedf4a74f16ca45bfc0c628ca03ae8dc60d53e4..586b981f0e61397f08e26ee71e1d63a9c39c0068 100644 (file)
  * Description:
  *
  * When nand_scan_bbt is called, then it tries to find the bad block table
- * depending on the options in the bbt descriptor(s). If a bbt is found
- * then the contents are read and the memory based bbt is created. If a
- * mirrored bbt is selected then the mirror is searched too and the
- * versions are compared. If the mirror has a greater version number
- * than the mirror bbt is used to build the memory based bbt.
+ * depending on the options in the BBT descriptor(s). If no flash based BBT
+ * (NAND_USE_FLASH_BBT) is specified then the device is scanned for factory
+ * marked good / bad blocks. This information is used to create a memory BBT.
+ * Once a new bad block is discovered then the "factory" information is updated
+ * on the device.
+ * If a flash based BBT is specified then the function first tries to find the
+ * BBT on flash. If a BBT is found then the contents are read and the memory
+ * based BBT is created. If a mirrored BBT is selected then the mirror is
+ * searched too and the versions are compared. If the mirror has a greater
+ * version number than the mirror BBT is used to build the memory based BBT.
  * If the tables are not versioned, then we "or" the bad block information.
- * If one of the bbt's is out of date or does not exist it is (re)created.
- * If no bbt exists at all then the device is scanned for factory marked
+ * If one of the BBTs is out of date or does not exist it is (re)created.
+ * If no BBT exists at all then the device is scanned for factory marked
  * good / bad blocks and the bad block tables are created.
  *
- * For manufacturer created bbts like the one found on M-SYS DOC devices
- * the bbt is searched and read but never created
+ * For manufacturer created BBTs like the one found on M-SYS DOC devices
+ * the BBT is searched and read but never created
  *
- * The autogenerated bad block table is located in the last good blocks
+ * The auto generated bad block table is located in the last good blocks
  * of the device. The table is mirrored, so it can be updated eventually.
- * The table is marked in the oob area with an ident pattern and a version
- * number which indicates which of both tables is more up to date.
+ * The table is marked in the OOB area with an ident pattern and a version
+ * number which indicates which of both tables is more up to date. If the NAND
+ * controller needs the complete OOB area for the ECC information then the
+ * option NAND_USE_FLASH_BBT_NO_OOB should be used: it moves the ident pattern
+ * and the version byte into the data area and the OOB area will remain
+ * untouched.
  *
  * The table uses 2 bits per block
- * 11b:        block is good
- * 00b:        block is factory marked bad
- * 01b, 10b:   block is marked bad due to wear
+ * 11b:                block is good
+ * 00b:                block is factory marked bad
+ * 01b, 10b:   block is marked bad due to wear
  *
  * The memory bad block table uses the following scheme:
  * 00b:                block is good
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
 
+static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
+{
+       int ret;
+
+       ret = memcmp(buf, td->pattern, td->len);
+       if (!ret)
+               return ret;
+       return -1;
+}
+
 /**
  * check_pattern - [GENERIC] check if a pattern is in the buffer
  * @buf:       the buffer to search
@@ -77,6 +96,9 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc
        int i, end = 0;
        uint8_t *p = buf;
 
+       if (td->options & NAND_BBT_NO_OOB)
+               return check_pattern_no_oob(buf, td);
+
        end = paglen + td->offs;
        if (td->options & NAND_BBT_SCANEMPTY) {
                for (i = 0; i < end; i++) {
@@ -155,33 +177,64 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
        return 0;
 }
 
+/**
+ * add_marker_len - compute the length of the marker in data area
+ * @td:                BBT descriptor used for computation
+ *
+ * The length will be 0 if the markeris located in OOB area.
+ */
+static u32 add_marker_len(struct nand_bbt_descr *td)
+{
+       u32 len;
+
+       if (!(td->options & NAND_BBT_NO_OOB))
+               return 0;
+
+       len = td->len;
+       if (td->options & NAND_BBT_VERSION)
+               len++;
+       return len;
+}
+
 /**
  * read_bbt - [GENERIC] Read the bad block table starting from page
  * @mtd:       MTD device structure
  * @buf:       temporary buffer
  * @page:      the starting page
  * @num:       the number of bbt descriptors to read
- * @bits:      number of bits per block
+ * @td:                the bbt describtion table
  * @offs:      offset in the memory table
- * @reserved_block_code:       Pattern to identify reserved blocks
  *
  * Read the bad block table starting from page.
  *
  */
 static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
-                   int bits, int offs, int reserved_block_code)
+               struct nand_bbt_descr *td, int offs)
 {
        int res, i, j, act = 0;
        struct nand_chip *this = mtd->priv;
        size_t retlen, len, totlen;
        loff_t from;
+       int bits = td->options & NAND_BBT_NRBITS_MSK;
        uint8_t msk = (uint8_t) ((1 << bits) - 1);
+       u32 marker_len;
+       int reserved_block_code = td->reserved_block_code;
 
        totlen = (num * bits) >> 3;
+       marker_len = add_marker_len(td);
        from = ((loff_t) page) << this->page_shift;
 
        while (totlen) {
                len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
+               if (marker_len) {
+                       /*
+                        * In case the BBT marker is not in the OOB area it
+                        * will be just in the first page.
+                        */
+                       len -= marker_len;
+                       from += marker_len;
+                       marker_len = 0;
+               }
                res = mtd->read(mtd, from, len, &retlen, buf);
                if (res < 0) {
                        if (retlen != len) {
@@ -238,30 +291,47 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 {
        struct nand_chip *this = mtd->priv;
        int res = 0, i;
-       int bits;
 
-       bits = td->options & NAND_BBT_NRBITS_MSK;
        if (td->options & NAND_BBT_PERCHIP) {
                int offs = 0;
                for (i = 0; i < this->numchips; i++) {
                        if (chip == -1 || chip == i)
-                               res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
+                               res = read_bbt(mtd, buf, td->pages[i],
+                                       this->chipsize >> this->bbt_erase_shift,
+                                       td, offs);
                        if (res)
                                return res;
                        offs += this->chipsize >> (this->bbt_erase_shift + 2);
                }
        } else {
-               res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
+               res = read_bbt(mtd, buf, td->pages[0],
+                               mtd->size >> this->bbt_erase_shift, td, 0);
                if (res)
                        return res;
        }
        return 0;
 }
 
+/*
+ * BBT marker is in the first page, no OOB.
+ */
+static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+                        struct nand_bbt_descr *td)
+{
+       size_t retlen;
+       size_t len;
+
+       len = td->len;
+       if (td->options & NAND_BBT_VERSION)
+               len++;
+
+       return mtd->read(mtd, offs, len, &retlen, buf);
+}
+
 /*
  * Scan read raw data from flash
  */
-static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
                         size_t len)
 {
        struct mtd_oob_ops ops;
@@ -294,6 +364,15 @@ static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
        return 0;
 }
 
+static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+                        size_t len, struct nand_bbt_descr *td)
+{
+       if (td->options & NAND_BBT_NO_OOB)
+               return scan_read_raw_data(mtd, buf, offs, td);
+       else
+               return scan_read_raw_oob(mtd, buf, offs, len);
+}
+
 /*
  * Scan write data with oob to flash
  */
@@ -312,6 +391,15 @@ static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
        return mtd->write_oob(mtd, offs, &ops);
 }
 
+static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
+{
+       u32 ver_offs = td->veroffs;
+
+       if (!(td->options & NAND_BBT_NO_OOB))
+               ver_offs += mtd->writesize;
+       return ver_offs;
+}
+
 /**
  * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
  * @mtd:       MTD device structure
@@ -331,8 +419,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
        /* Read the primary version, if available */
        if (td->options & NAND_BBT_VERSION) {
                scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
-                             mtd->writesize);
-               td->version[0] = buf[mtd->writesize + td->veroffs];
+                             mtd->writesize, td);
+               td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
                printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
                       td->pages[0], td->version[0]);
        }
@@ -340,8 +428,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
        /* Read the mirror version, if available */
        if (md && (md->options & NAND_BBT_VERSION)) {
                scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
-                             mtd->writesize);
-               md->version[0] = buf[mtd->writesize + md->veroffs];
+                             mtd->writesize, td);
+               md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
                printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
                       md->pages[0], md->version[0]);
        }
@@ -357,7 +445,7 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
 {
        int ret, j;
 
-       ret = scan_read_raw(mtd, buf, offs, readlen);
+       ret = scan_read_raw_oob(mtd, buf, offs, readlen);
        if (ret)
                return ret;
 
@@ -464,6 +552,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
        for (i = startblock; i < numblocks;) {
                int ret;
 
+               BUG_ON(bd->options & NAND_BBT_NO_OOB);
+
                if (bd->options & NAND_BBT_SCANALLPAGES)
                        ret = scan_block_full(mtd, bd, from, buf, readlen,
                                              scanlen, len);
@@ -545,11 +635,12 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
                        loff_t offs = (loff_t)actblock << this->bbt_erase_shift;
 
                        /* Read first page */
-                       scan_read_raw(mtd, buf, offs, mtd->writesize);
+                       scan_read_raw(mtd, buf, offs, mtd->writesize, td);
                        if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
                                td->pages[i] = actblock << blocktopage;
                                if (td->options & NAND_BBT_VERSION) {
-                                       td->version[i] = buf[mtd->writesize + td->veroffs];
+                                       offs = bbt_get_ver_offs(mtd, td);
+                                       td->version[i] = buf[offs];
                                }
                                break;
                        }
@@ -733,12 +824,26 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                        memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
                        ooboffs = len + (pageoffs * mtd->oobsize);
 
+               } else if (td->options & NAND_BBT_NO_OOB) {
+                       ooboffs = 0;
+                       offs = td->len;
+                       /* the version byte */
+                       if (td->options & NAND_BBT_VERSION)
+                               offs++;
+                       /* Calc length */
+                       len = (size_t) (numblocks >> sft);
+                       len += offs;
+                       /* Make it page aligned ! */
+                       len = ALIGN(len, mtd->writesize);
+                       /* Preset the buffer with 0xff */
+                       memset(buf, 0xff, len);
+                       /* Pattern is located at the begin of first page */
+                       memcpy(buf, td->pattern, td->len);
                } else {
                        /* Calc length */
                        len = (size_t) (numblocks >> sft);
                        /* Make it page aligned ! */
-                       len = (len + (mtd->writesize - 1)) &
-                               ~(mtd->writesize - 1);
+                       len = ALIGN(len, mtd->writesize);
                        /* Preset the buffer with 0xff */
                        memset(buf, 0xff, len +
                               (len >> this->page_shift)* mtd->oobsize);
@@ -772,7 +877,9 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
                if (res < 0)
                        goto outerr;
 
-               res = scan_write_bbt(mtd, to, len, buf, &buf[len]);
+               res = scan_write_bbt(mtd, to, len, buf,
+                               td->options & NAND_BBT_NO_OOB ? NULL :
+                               &buf[len]);
                if (res < 0)
                        goto outerr;
 
@@ -892,7 +999,8 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
                        continue;
 
                /* Create the table in memory by scanning the chip(s) */
-               create_bbt(mtd, buf, bd, chipsel);
+               if (!(this->options & NAND_CREATE_EMPTY_BBT))
+                       create_bbt(mtd, buf, bd, chipsel);
 
                td->version[i] = 1;
                if (md)
@@ -982,6 +1090,49 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
        }
 }
 
+/**
+ * verify_bbt_descr - verify the bad block description
+ * @bd:                        the table to verify
+ *
+ * This functions performs a few sanity checks on the bad block description
+ * table.
+ */
+static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+{
+       struct nand_chip *this = mtd->priv;
+       u32 pattern_len = bd->len;
+       u32 bits = bd->options & NAND_BBT_NRBITS_MSK;
+       u32 table_size;
+
+       if (!bd)
+               return;
+       BUG_ON((this->options & NAND_USE_FLASH_BBT_NO_OOB) &&
+                       !(this->options & NAND_USE_FLASH_BBT));
+       BUG_ON(!bits);
+
+       if (bd->options & NAND_BBT_VERSION)
+               pattern_len++;
+
+       if (bd->options & NAND_BBT_NO_OOB) {
+               BUG_ON(!(this->options & NAND_USE_FLASH_BBT));
+               BUG_ON(!(this->options & NAND_USE_FLASH_BBT_NO_OOB));
+               BUG_ON(bd->offs);
+               if (bd->options & NAND_BBT_VERSION)
+                       BUG_ON(bd->veroffs != bd->len);
+               BUG_ON(bd->options & NAND_BBT_SAVECONTENT);
+       }
+
+       if (bd->options & NAND_BBT_PERCHIP)
+               table_size = this->chipsize >> this->bbt_erase_shift;
+       else
+               table_size = mtd->size >> this->bbt_erase_shift;
+       table_size >>= 3;
+       table_size *= bits;
+       if (bd->options & NAND_BBT_NO_OOB)
+               table_size += pattern_len;
+       BUG_ON(table_size > (1 << this->bbt_erase_shift));
+}
+
 /**
  * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
  * @mtd:       MTD device structure
@@ -1023,6 +1174,8 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
                }
                return res;
        }
+       verify_bbt_descr(mtd, td);
+       verify_bbt_descr(mtd, md);
 
        /* Allocate a temporary buffer for one eraseblock incl. oob */
        len = (1 << this->bbt_erase_shift);
@@ -1166,6 +1319,26 @@ static struct nand_bbt_descr bbt_mirror_descr = {
        .pattern = mirror_pattern
 };
 
+static struct nand_bbt_descr bbt_main_no_bbt_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
+               | NAND_BBT_NO_OOB,
+       .len = 4,
+       .veroffs = 4,
+       .maxblocks = 4,
+       .pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_mirror_no_bbt_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+               | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
+               | NAND_BBT_NO_OOB,
+       .len = 4,
+       .veroffs = 4,
+       .maxblocks = 4,
+       .pattern = mirror_pattern
+};
+
 #define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \
                NAND_BBT_SCANBYTE1AND6)
 /**
@@ -1236,8 +1409,13 @@ int nand_default_bbt(struct mtd_info *mtd)
        if (this->options & NAND_USE_FLASH_BBT) {
                /* Use the default pattern descriptors */
                if (!this->bbt_td) {
-                       this->bbt_td = &bbt_main_descr;
-                       this->bbt_md = &bbt_mirror_descr;
+                       if (this->options & NAND_USE_FLASH_BBT_NO_OOB) {
+                               this->bbt_td = &bbt_main_no_bbt_descr;
+                               this->bbt_md = &bbt_mirror_no_bbt_descr;
+                       } else {
+                               this->bbt_td = &bbt_main_descr;
+                               this->bbt_md = &bbt_mirror_descr;
+                       }
                }
                if (!this->badblock_pattern) {
                        this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased;
index c65f19074bc83558f3bf6e5742b5299152224514..00cf1b0d60531a2699382fbdd5651ae11e956683 100644 (file)
@@ -75,9 +75,13 @@ struct nand_flash_dev nand_flash_ids[] = {
 
        /*512 Megabit */
        {"NAND 64MiB 1,8V 8-bit",       0xA2, 0,  64, 0, LP_OPTIONS},
+       {"NAND 64MiB 1,8V 8-bit",       0xA0, 0,  64, 0, LP_OPTIONS},
        {"NAND 64MiB 3,3V 8-bit",       0xF2, 0,  64, 0, LP_OPTIONS},
+       {"NAND 64MiB 3,3V 8-bit",       0xD0, 0,  64, 0, LP_OPTIONS},
        {"NAND 64MiB 1,8V 16-bit",      0xB2, 0,  64, 0, LP_OPTIONS16},
+       {"NAND 64MiB 1,8V 16-bit",      0xB0, 0,  64, 0, LP_OPTIONS16},
        {"NAND 64MiB 3,3V 16-bit",      0xC2, 0,  64, 0, LP_OPTIONS16},
+       {"NAND 64MiB 3,3V 16-bit",      0xC0, 0,  64, 0, LP_OPTIONS16},
 
        /* 1 Gigabit */
        {"NAND 128MiB 1,8V 8-bit",      0xA1, 0, 128, 0, LP_OPTIONS},
@@ -112,7 +116,34 @@ struct nand_flash_dev nand_flash_ids[] = {
        {"NAND 2GiB 3,3V 16-bit",       0xC5, 0, 2048, 0, LP_OPTIONS16},
 
        /* 32 Gigabit */
+       {"NAND 4GiB 1,8V 8-bit",        0xA7, 0, 4096, 0, LP_OPTIONS},
        {"NAND 4GiB 3,3V 8-bit",        0xD7, 0, 4096, 0, LP_OPTIONS},
+       {"NAND 4GiB 1,8V 16-bit",       0xB7, 0, 4096, 0, LP_OPTIONS16},
+       {"NAND 4GiB 3,3V 16-bit",       0xC7, 0, 4096, 0, LP_OPTIONS16},
+
+       /* 64 Gigabit */
+       {"NAND 8GiB 1,8V 8-bit",        0xAE, 0, 8192, 0, LP_OPTIONS},
+       {"NAND 8GiB 3,3V 8-bit",        0xDE, 0, 8192, 0, LP_OPTIONS},
+       {"NAND 8GiB 1,8V 16-bit",       0xBE, 0, 8192, 0, LP_OPTIONS16},
+       {"NAND 8GiB 3,3V 16-bit",       0xCE, 0, 8192, 0, LP_OPTIONS16},
+
+       /* 128 Gigabit */
+       {"NAND 16GiB 1,8V 8-bit",       0x1A, 0, 16384, 0, LP_OPTIONS},
+       {"NAND 16GiB 3,3V 8-bit",       0x3A, 0, 16384, 0, LP_OPTIONS},
+       {"NAND 16GiB 1,8V 16-bit",      0x2A, 0, 16384, 0, LP_OPTIONS16},
+       {"NAND 16GiB 3,3V 16-bit",      0x4A, 0, 16384, 0, LP_OPTIONS16},
+
+       /* 256 Gigabit */
+       {"NAND 32GiB 1,8V 8-bit",       0x1C, 0, 32768, 0, LP_OPTIONS},
+       {"NAND 32GiB 3,3V 8-bit",       0x3C, 0, 32768, 0, LP_OPTIONS},
+       {"NAND 32GiB 1,8V 16-bit",      0x2C, 0, 32768, 0, LP_OPTIONS16},
+       {"NAND 32GiB 3,3V 16-bit",      0x4C, 0, 32768, 0, LP_OPTIONS16},
+
+       /* 512 Gigabit */
+       {"NAND 64GiB 1,8V 8-bit",       0x1E, 0, 65536, 0, LP_OPTIONS},
+       {"NAND 64GiB 3,3V 8-bit",       0x3E, 0, 65536, 0, LP_OPTIONS},
+       {"NAND 64GiB 1,8V 16-bit",      0x2E, 0, 65536, 0, LP_OPTIONS16},
+       {"NAND 64GiB 3,3V 16-bit",      0x4E, 0, 65536, 0, LP_OPTIONS16},
 
        /*
         * Renesas AND 1 Gigabit. Those chips do not support extended id and
index c25648bb5793423ba0c6ce8378744b912715bdc9..a6a73aab12536222c53528155dc5dca2ab353f90 100644 (file)
@@ -107,6 +107,7 @@ static char *gravepages = NULL;
 static unsigned int rptwear = 0;
 static unsigned int overridesize = 0;
 static char *cache_file = NULL;
+static unsigned int bbt;
 
 module_param(first_id_byte,  uint, 0400);
 module_param(second_id_byte, uint, 0400);
@@ -130,6 +131,7 @@ module_param(gravepages,     charp, 0400);
 module_param(rptwear,        uint, 0400);
 module_param(overridesize,   uint, 0400);
 module_param(cache_file,     charp, 0400);
+module_param(bbt,           uint, 0400);
 
 MODULE_PARM_DESC(first_id_byte,  "The first byte returned by NAND Flash 'read ID' command (manufacturer ID)");
 MODULE_PARM_DESC(second_id_byte, "The second byte returned by NAND Flash 'read ID' command (chip ID)");
@@ -162,6 +164,7 @@ MODULE_PARM_DESC(overridesize,   "Specifies the NAND Flash size overriding the I
                                 "The size is specified in erase blocks and as the exponent of a power of two"
                                 " e.g. 5 means a size of 32 erase blocks");
 MODULE_PARM_DESC(cache_file,     "File to use to cache nand pages instead of memory");
+MODULE_PARM_DESC(bbt,           "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in data area");
 
 /* The largest possible page size */
 #define NS_LARGEST_PAGE_SIZE   4096
@@ -2264,6 +2267,18 @@ static int __init ns_init_module(void)
        /* and 'badblocks' parameters to work */
        chip->options   |= NAND_SKIP_BBTSCAN;
 
+       switch (bbt) {
+       case 2:
+                chip->options |= NAND_USE_FLASH_BBT_NO_OOB;
+       case 1:
+                chip->options |= NAND_USE_FLASH_BBT;
+       case 0:
+               break;
+       default:
+               NS_ERR("bbt has to be 0..2\n");
+               retval = -EINVAL;
+               goto error;
+       }
        /*
         * Perform minimum nandsim structure initialization to handle
         * the initial ID read command correctly
@@ -2321,10 +2336,10 @@ static int __init ns_init_module(void)
        if ((retval = init_nandsim(nsmtd)) != 0)
                goto err_exit;
 
-       if ((retval = parse_badblocks(nand, nsmtd)) != 0)
+       if ((retval = nand_default_bbt(nsmtd)) != 0)
                goto err_exit;
 
-       if ((retval = nand_default_bbt(nsmtd)) != 0)
+       if ((retval = parse_badblocks(nand, nsmtd)) != 0)
                goto err_exit;
 
        /* Register NAND partitions */
index 510554e6c115d9ad751a783bcb1e725dee7aba2a..c9ae0a5023b673e866716eaa58bbf02c368e7346 100644 (file)
@@ -229,7 +229,7 @@ static int __devinit ndfc_probe(struct platform_device *ofdev,
                                const struct of_device_id *match)
 {
        struct ndfc_controller *ndfc = &ndfc_ctrl;
-       const u32 *reg;
+       const __be32 *reg;
        u32 ccr;
        int err, len;
 
@@ -244,7 +244,7 @@ static int __devinit ndfc_probe(struct platform_device *ofdev,
                dev_err(&ofdev->dev, "unable read reg property (%d)\n", len);
                return -ENOENT;
        }
-       ndfc->chip_select = reg[0];
+       ndfc->chip_select = be32_to_cpu(reg[0]);
 
        ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0);
        if (!ndfc->ndfcbase) {
@@ -257,7 +257,7 @@ static int __devinit ndfc_probe(struct platform_device *ofdev,
        /* It is ok if ccr does not exist - just default to 0 */
        reg = of_get_property(ofdev->dev.of_node, "ccr", NULL);
        if (reg)
-               ccr |= *reg;
+               ccr |= be32_to_cpup(reg);
 
        out_be32(ndfc->ndfcbase + NDFC_CCR, ccr);
 
@@ -265,7 +265,7 @@ static int __devinit ndfc_probe(struct platform_device *ofdev,
        reg = of_get_property(ofdev->dev.of_node, "bank-settings", NULL);
        if (reg) {
                int offset = NDFC_BCFG0 + (ndfc->chip_select << 2);
-               out_be32(ndfc->ndfcbase + offset, *reg);
+               out_be32(ndfc->ndfcbase + offset, be32_to_cpup(reg));
        }
 
        err = ndfc_chip_init(ndfc, ofdev->dev.of_node);
index 513e0a76a4a73866d52bba8151e43556a3b30a54..cd41c58b5bbd50f8ed905a1a6da71dedc5cfca7e 100644 (file)
@@ -111,11 +111,11 @@ static int use_dma = 1;
 module_param(use_dma, bool, 0);
 MODULE_PARM_DESC(use_dma, "enable/disable use of DMA");
 #else
-const int use_dma;
+static const int use_dma;
 #endif
 #else
 const int use_prefetch;
-const int use_dma;
+static const int use_dma;
 #endif
 
 struct omap_nand_info {
index 4d01cda6884463daa844c02fde951970854e972a..17f8518cc5eba1d1138912d579731d6e6cb14c36 100644 (file)
@@ -117,7 +117,7 @@ struct pxa3xx_nand_info {
        struct nand_chip        nand_chip;
 
        struct platform_device   *pdev;
-       const struct pxa3xx_nand_flash *flash_info;
+       struct pxa3xx_nand_cmdset *cmdset;
 
        struct clk              *clk;
        void __iomem            *mmio_base;
@@ -131,6 +131,7 @@ struct pxa3xx_nand_info {
        int                     drcmr_cmd;
 
        unsigned char           *data_buff;
+       unsigned char           *oob_buff;
        dma_addr_t              data_buff_phys;
        size_t                  data_buff_size;
        int                     data_dma_ch;
@@ -149,7 +150,8 @@ struct pxa3xx_nand_info {
        int                     use_ecc;        /* use HW ECC ? */
        int                     use_dma;        /* use DMA ? */
 
-       size_t                  data_size;      /* data size in FIFO */
+       unsigned int            page_size;      /* page size of attached chip */
+       unsigned int            data_size;      /* data size in FIFO */
        int                     retcode;
        struct completion       cmd_complete;
 
@@ -158,6 +160,10 @@ struct pxa3xx_nand_info {
        uint32_t                ndcb1;
        uint32_t                ndcb2;
 
+       /* timing calcuted from setting */
+       uint32_t                ndtr0cs0;
+       uint32_t                ndtr1cs0;
+
        /* calculated from pxa3xx_nand_flash data */
        size_t          oob_size;
        size_t          read_id_bytes;
@@ -174,23 +180,7 @@ MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW");
  * Default NAND flash controller configuration setup by the
  * bootloader. This configuration is used only when pdata->keep_config is set
  */
-static struct pxa3xx_nand_timing default_timing;
-static struct pxa3xx_nand_flash default_flash;
-
-static struct pxa3xx_nand_cmdset smallpage_cmdset = {
-       .read1          = 0x0000,
-       .read2          = 0x0050,
-       .program        = 0x1080,
-       .read_status    = 0x0070,
-       .read_id        = 0x0090,
-       .erase          = 0xD060,
-       .reset          = 0x00FF,
-       .lock           = 0x002A,
-       .unlock         = 0x2423,
-       .lock_status    = 0x007A,
-};
-
-static struct pxa3xx_nand_cmdset largepage_cmdset = {
+static struct pxa3xx_nand_cmdset default_cmdset = {
        .read1          = 0x3000,
        .read2          = 0x0050,
        .program        = 0x1080,
@@ -203,142 +193,27 @@ static struct pxa3xx_nand_cmdset largepage_cmdset = {
        .lock_status    = 0x007A,
 };
 
-#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
-static struct pxa3xx_nand_timing samsung512MbX16_timing = {
-       .tCH    = 10,
-       .tCS    = 0,
-       .tWH    = 20,
-       .tWP    = 40,
-       .tRH    = 30,
-       .tRP    = 40,
-       .tR     = 11123,
-       .tWHR   = 110,
-       .tAR    = 10,
-};
-
-static struct pxa3xx_nand_flash samsung512MbX16 = {
-       .timing         = &samsung512MbX16_timing,
-       .cmdset         = &smallpage_cmdset,
-       .page_per_block = 32,
-       .page_size      = 512,
-       .flash_width    = 16,
-       .dfc_width      = 16,
-       .num_blocks     = 4096,
-       .chip_id        = 0x46ec,
-};
-
-static struct pxa3xx_nand_flash samsung2GbX8 = {
-       .timing         = &samsung512MbX16_timing,
-       .cmdset         = &smallpage_cmdset,
-       .page_per_block = 64,
-       .page_size      = 2048,
-       .flash_width    = 8,
-       .dfc_width      = 8,
-       .num_blocks     = 2048,
-       .chip_id        = 0xdaec,
+static struct pxa3xx_nand_timing timing[] = {
+       { 40, 80, 60, 100, 80, 100, 90000, 400, 40, },
+       { 10,  0, 20,  40, 30,  40, 11123, 110, 10, },
+       { 10, 25, 15,  25, 15,  30, 25000,  60, 10, },
+       { 10, 35, 15,  25, 15,  25, 25000,  60, 10, },
 };
 
-static struct pxa3xx_nand_flash samsung32GbX8 = {
-       .timing         = &samsung512MbX16_timing,
-       .cmdset         = &smallpage_cmdset,
-       .page_per_block = 128,
-       .page_size      = 4096,
-       .flash_width    = 8,
-       .dfc_width      = 8,
-       .num_blocks     = 8192,
-       .chip_id        = 0xd7ec,
+static struct pxa3xx_nand_flash builtin_flash_types[] = {
+       {      0,   0, 2048,  8,  8,    0, &default_cmdset, &timing[0] },
+       { 0x46ec,  32,  512, 16, 16, 4096, &default_cmdset, &timing[1] },
+       { 0xdaec,  64, 2048,  8,  8, 2048, &default_cmdset, &timing[1] },
+       { 0xd7ec, 128, 4096,  8,  8, 8192, &default_cmdset, &timing[1] },
+       { 0xa12c,  64, 2048,  8,  8, 1024, &default_cmdset, &timing[2] },
+       { 0xb12c,  64, 2048, 16, 16, 1024, &default_cmdset, &timing[2] },
+       { 0xdc2c,  64, 2048,  8,  8, 4096, &default_cmdset, &timing[2] },
+       { 0xcc2c,  64, 2048, 16, 16, 4096, &default_cmdset, &timing[2] },
+       { 0xba20,  64, 2048, 16, 16, 2048, &default_cmdset, &timing[3] },
 };
 
-static struct pxa3xx_nand_timing micron_timing = {
-       .tCH    = 10,
-       .tCS    = 25,
-       .tWH    = 15,
-       .tWP    = 25,
-       .tRH    = 15,
-       .tRP    = 30,
-       .tR     = 25000,
-       .tWHR   = 60,
-       .tAR    = 10,
-};
-
-static struct pxa3xx_nand_flash micron1GbX8 = {
-       .timing         = &micron_timing,
-       .cmdset         = &largepage_cmdset,
-       .page_per_block = 64,
-       .page_size      = 2048,
-       .flash_width    = 8,
-       .dfc_width      = 8,
-       .num_blocks     = 1024,
-       .chip_id        = 0xa12c,
-};
-
-static struct pxa3xx_nand_flash micron1GbX16 = {
-       .timing         = &micron_timing,
-       .cmdset         = &largepage_cmdset,
-       .page_per_block = 64,
-       .page_size      = 2048,
-       .flash_width    = 16,
-       .dfc_width      = 16,
-       .num_blocks     = 1024,
-       .chip_id        = 0xb12c,
-};
-
-static struct pxa3xx_nand_flash micron4GbX8 = {
-       .timing         = &micron_timing,
-       .cmdset         = &largepage_cmdset,
-       .page_per_block = 64,
-       .page_size      = 2048,
-       .flash_width    = 8,
-       .dfc_width      = 8,
-       .num_blocks     = 4096,
-       .chip_id        = 0xdc2c,
-};
-
-static struct pxa3xx_nand_flash micron4GbX16 = {
-       .timing         = &micron_timing,
-       .cmdset         = &largepage_cmdset,
-       .page_per_block = 64,
-       .page_size      = 2048,
-       .flash_width    = 16,
-       .dfc_width      = 16,
-       .num_blocks     = 4096,
-       .chip_id        = 0xcc2c,
-};
-
-static struct pxa3xx_nand_timing stm2GbX16_timing = {
-       .tCH = 10,
-       .tCS = 35,
-       .tWH = 15,
-       .tWP = 25,
-       .tRH = 15,
-       .tRP = 25,
-       .tR = 25000,
-       .tWHR = 60,
-       .tAR = 10,
-};
-
-static struct pxa3xx_nand_flash stm2GbX16 = {
-       .timing = &stm2GbX16_timing,
-       .cmdset = &largepage_cmdset,
-       .page_per_block = 64,
-       .page_size = 2048,
-       .flash_width = 16,
-       .dfc_width = 16,
-       .num_blocks = 2048,
-       .chip_id = 0xba20,
-};
-
-static struct pxa3xx_nand_flash *builtin_flash_types[] = {
-       &samsung512MbX16,
-       &samsung2GbX8,
-       &samsung32GbX8,
-       &micron1GbX8,
-       &micron1GbX16,
-       &micron4GbX8,
-       &micron4GbX16,
-       &stm2GbX16,
-};
-#endif /* CONFIG_MTD_NAND_PXA3xx_BUILTIN */
+/* Define a default flash type setting serve as flash detecting only */
+#define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
 
 #define NDTR0_tCH(c)   (min((c), 7) << 19)
 #define NDTR0_tCS(c)   (min((c), 7) << 16)
@@ -351,23 +226,9 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = {
 #define NDTR1_tWHR(c)  (min((c), 15) << 4)
 #define NDTR1_tAR(c)   (min((c), 15) << 0)
 
-#define tCH_NDTR0(r)   (((r) >> 19) & 0x7)
-#define tCS_NDTR0(r)   (((r) >> 16) & 0x7)
-#define tWH_NDTR0(r)   (((r) >> 11) & 0x7)
-#define tWP_NDTR0(r)   (((r) >> 8) & 0x7)
-#define tRH_NDTR0(r)   (((r) >> 3) & 0x7)
-#define tRP_NDTR0(r)   (((r) >> 0) & 0x7)
-
-#define tR_NDTR1(r)    (((r) >> 16) & 0xffff)
-#define tWHR_NDTR1(r)  (((r) >> 4) & 0xf)
-#define tAR_NDTR1(r)   (((r) >> 0) & 0xf)
-
 /* convert nano-seconds to nand flash controller clock cycles */
 #define ns2cycle(ns, clk)      (int)((ns) * (clk / 1000000) / 1000)
 
-/* convert nand flash controller clock cycles to nano-seconds */
-#define cycle2ns(c, clk)       ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000))
-
 static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
                                   const struct pxa3xx_nand_timing *t)
 {
@@ -385,6 +246,8 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
                NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) |
                NDTR1_tAR(ns2cycle(t->tAR, nand_clk));
 
+       info->ndtr0cs0 = ndtr0;
+       info->ndtr1cs0 = ndtr1;
        nand_writel(info, NDTR0CS0, ndtr0);
        nand_writel(info, NDTR1CS0, ndtr1);
 }
@@ -408,23 +271,31 @@ static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event)
        return -ETIMEDOUT;
 }
 
-static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info,
-                       uint16_t cmd, int column, int page_addr)
+static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
 {
-       const struct pxa3xx_nand_flash *f = info->flash_info;
-       const struct pxa3xx_nand_cmdset *cmdset = f->cmdset;
+       int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
 
-       /* calculate data size */
-       switch (f->page_size) {
+       info->data_size = info->page_size;
+       if (!oob_enable) {
+               info->oob_size = 0;
+               return;
+       }
+
+       switch (info->page_size) {
        case 2048:
-               info->data_size = (info->use_ecc) ? 2088 : 2112;
+               info->oob_size = (info->use_ecc) ? 40 : 64;
                break;
        case 512:
-               info->data_size = (info->use_ecc) ? 520 : 528;
+               info->oob_size = (info->use_ecc) ? 8 : 16;
                break;
-       default:
-               return -EINVAL;
        }
+}
+
+static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info,
+               uint16_t cmd, int column, int page_addr)
+{
+       const struct pxa3xx_nand_cmdset *cmdset = info->cmdset;
+       pxa3xx_set_datasize(info);
 
        /* generate values for NDCBx registers */
        info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0);
@@ -463,12 +334,13 @@ static int prepare_erase_cmd(struct pxa3xx_nand_info *info,
 
 static int prepare_other_cmd(struct pxa3xx_nand_info *info, uint16_t cmd)
 {
-       const struct pxa3xx_nand_cmdset *cmdset = info->flash_info->cmdset;
+       const struct pxa3xx_nand_cmdset *cmdset = info->cmdset;
 
        info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0);
        info->ndcb1 = 0;
        info->ndcb2 = 0;
 
+       info->oob_size = 0;
        if (cmd == cmdset->read_id) {
                info->ndcb0 |= NDCB0_CMD_TYPE(3);
                info->data_size = 8;
@@ -537,6 +409,9 @@ static int handle_data_pio(struct pxa3xx_nand_info *info)
        case STATE_PIO_WRITING:
                __raw_writesl(info->mmio_base + NDDB, info->data_buff,
                                DIV_ROUND_UP(info->data_size, 4));
+               if (info->oob_size > 0)
+                       __raw_writesl(info->mmio_base + NDDB, info->oob_buff,
+                                       DIV_ROUND_UP(info->oob_size, 4));
 
                enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD);
 
@@ -549,6 +424,9 @@ static int handle_data_pio(struct pxa3xx_nand_info *info)
        case STATE_PIO_READING:
                __raw_readsl(info->mmio_base + NDDB, info->data_buff,
                                DIV_ROUND_UP(info->data_size, 4));
+               if (info->oob_size > 0)
+                       __raw_readsl(info->mmio_base + NDDB, info->oob_buff,
+                                       DIV_ROUND_UP(info->oob_size, 4));
                break;
        default:
                printk(KERN_ERR "%s: invalid state %d\n", __func__,
@@ -563,7 +441,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info)
 static void start_data_dma(struct pxa3xx_nand_info *info, int dir_out)
 {
        struct pxa_dma_desc *desc = info->data_desc;
-       int dma_len = ALIGN(info->data_size, 32);
+       int dma_len = ALIGN(info->data_size + info->oob_size, 32);
 
        desc->ddadr = DDADR_STOP;
        desc->dcmd = DCMD_ENDIRQEN | DCMD_WIDTH4 | DCMD_BURST32 | dma_len;
@@ -700,8 +578,7 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
                                int column, int page_addr)
 {
        struct pxa3xx_nand_info *info = mtd->priv;
-       const struct pxa3xx_nand_flash *flash_info = info->flash_info;
-       const struct pxa3xx_nand_cmdset *cmdset = flash_info->cmdset;
+       const struct pxa3xx_nand_cmdset *cmdset = info->cmdset;
        int ret;
 
        info->use_dma = (use_dma) ? 1 : 0;
@@ -925,8 +802,7 @@ static int pxa3xx_nand_ecc_correct(struct mtd_info *mtd,
 
 static int __readid(struct pxa3xx_nand_info *info, uint32_t *id)
 {
-       const struct pxa3xx_nand_flash *f = info->flash_info;
-       const struct pxa3xx_nand_cmdset *cmdset = f->cmdset;
+       const struct pxa3xx_nand_cmdset *cmdset = info->cmdset;
        uint32_t ndcr;
        uint8_t  id_buff[8];
 
@@ -968,7 +844,9 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
                return -EINVAL;
 
        /* calculate flash information */
-       info->oob_size = (f->page_size == 2048) ? 64 : 16;
+       info->cmdset = f->cmdset;
+       info->page_size = f->page_size;
+       info->oob_buff = info->data_buff + f->page_size;
        info->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
 
        /* calculate addressing information */
@@ -992,49 +870,20 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
        info->reg_ndcr = ndcr;
 
        pxa3xx_nand_set_timing(info, f->timing);
-       info->flash_info = f;
        return 0;
 }
 
-static void pxa3xx_nand_detect_timing(struct pxa3xx_nand_info *info,
-                                     struct pxa3xx_nand_timing *t)
-{
-       unsigned long nand_clk = clk_get_rate(info->clk);
-       uint32_t ndtr0 = nand_readl(info, NDTR0CS0);
-       uint32_t ndtr1 = nand_readl(info, NDTR1CS0);
-
-       t->tCH = cycle2ns(tCH_NDTR0(ndtr0), nand_clk);
-       t->tCS = cycle2ns(tCS_NDTR0(ndtr0), nand_clk);
-       t->tWH = cycle2ns(tWH_NDTR0(ndtr0), nand_clk);
-       t->tWP = cycle2ns(tWP_NDTR0(ndtr0), nand_clk);
-       t->tRH = cycle2ns(tRH_NDTR0(ndtr0), nand_clk);
-       t->tRP = cycle2ns(tRP_NDTR0(ndtr0), nand_clk);
-
-       t->tR = cycle2ns(tR_NDTR1(ndtr1), nand_clk);
-       t->tWHR = cycle2ns(tWHR_NDTR1(ndtr1), nand_clk);
-       t->tAR = cycle2ns(tAR_NDTR1(ndtr1), nand_clk);
-}
-
 static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 {
        uint32_t ndcr = nand_readl(info, NDCR);
        struct nand_flash_dev *type = NULL;
-       uint32_t id = -1;
+       uint32_t id = -1, page_per_block, num_blocks;
        int i;
 
-       default_flash.page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
-       default_flash.page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
-       default_flash.flash_width = ndcr & NDCR_DWIDTH_M ? 16 : 8;
-       default_flash.dfc_width = ndcr & NDCR_DWIDTH_C ? 16 : 8;
-
-       if (default_flash.page_size == 2048)
-               default_flash.cmdset = &largepage_cmdset;
-       else
-               default_flash.cmdset = &smallpage_cmdset;
-
+       page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
+       info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
        /* set info fields needed to __readid */
-       info->flash_info = &default_flash;
-       info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2;
+       info->read_id_bytes = (info->page_size == 2048) ? 4 : 2;
        info->reg_ndcr = ndcr;
 
        if (__readid(info, &id))
@@ -1053,21 +902,20 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
                return -ENODEV;
 
        /* fill the missing flash information */
-       i = __ffs(default_flash.page_per_block * default_flash.page_size);
-       default_flash.num_blocks = type->chipsize << (20 - i);
-
-       info->oob_size = (default_flash.page_size == 2048) ? 64 : 16;
+       i = __ffs(page_per_block * info->page_size);
+       num_blocks = type->chipsize << (20 - i);
 
        /* calculate addressing information */
-       info->col_addr_cycles = (default_flash.page_size == 2048) ? 2 : 1;
+       info->col_addr_cycles = (info->page_size == 2048) ? 2 : 1;
 
-       if (default_flash.num_blocks * default_flash.page_per_block > 65536)
+       if (num_blocks * page_per_block > 65536)
                info->row_addr_cycles = 3;
        else
                info->row_addr_cycles = 2;
 
-       pxa3xx_nand_detect_timing(info, &default_timing);
-       default_flash.timing = &default_timing;
+       info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
+       info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
+       info->cmdset = &default_cmdset;
 
        return 0;
 }
@@ -1083,38 +931,29 @@ static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
                if (pxa3xx_nand_detect_config(info) == 0)
                        return 0;
 
-       for (i = 0; i<pdata->num_flash; ++i) {
-               f = pdata->flash + i;
-
-               if (pxa3xx_nand_config_flash(info, f))
-                       continue;
-
-               if (__readid(info, &id))
-                       continue;
-
-               if (id == f->chip_id)
-                       return 0;
-       }
-
-#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
-       for (i = 0; i < ARRAY_SIZE(builtin_flash_types); i++) {
-
-               f = builtin_flash_types[i];
-
-               if (pxa3xx_nand_config_flash(info, f))
-                       continue;
-
-               if (__readid(info, &id))
-                       continue;
-
-               if (id == f->chip_id)
+       /* we use default timing to detect id */
+       f = DEFAULT_FLASH_TYPE;
+       pxa3xx_nand_config_flash(info, f);
+       if (__readid(info, &id))
+               goto fail_detect;
+
+       for (i=0; i<ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1; i++) {
+               /* we first choose the flash definition from platfrom */
+               if (i < pdata->num_flash)
+                       f = pdata->flash + i;
+               else
+                       f = &builtin_flash_types[i - pdata->num_flash + 1];
+               if (f->chip_id == id) {
+                       dev_info(&info->pdev->dev, "detect chip id: 0x%x\n", id);
+                       pxa3xx_nand_config_flash(info, f);
                        return 0;
+               }
        }
-#endif
 
        dev_warn(&info->pdev->dev,
                 "failed to detect configured nand flash; found %04x instead of\n",
                 id);
+fail_detect:
        return -ENODEV;
 }
 
@@ -1177,10 +1016,9 @@ static struct nand_ecclayout hw_largepage_ecclayout = {
 static void pxa3xx_nand_init_mtd(struct mtd_info *mtd,
                                 struct pxa3xx_nand_info *info)
 {
-       const struct pxa3xx_nand_flash *f = info->flash_info;
        struct nand_chip *this = &info->nand_chip;
 
-       this->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16: 0;
+       this->options = (info->reg_ndcr & NDCR_DWIDTH_C) ? NAND_BUSWIDTH_16: 0;
 
        this->waitfunc          = pxa3xx_nand_waitfunc;
        this->select_chip       = pxa3xx_nand_select_chip;
@@ -1196,9 +1034,9 @@ static void pxa3xx_nand_init_mtd(struct mtd_info *mtd,
        this->ecc.hwctl         = pxa3xx_nand_ecc_hwctl;
        this->ecc.calculate     = pxa3xx_nand_ecc_calculate;
        this->ecc.correct       = pxa3xx_nand_ecc_correct;
-       this->ecc.size          = f->page_size;
+       this->ecc.size          = info->page_size;
 
-       if (f->page_size == 2048)
+       if (info->page_size == 2048)
                this->ecc.layout = &hw_largepage_ecclayout;
        else
                this->ecc.layout = &hw_smallpage_ecclayout;
@@ -1411,9 +1249,11 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
        struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev);
        struct pxa3xx_nand_info *info = mtd->priv;
 
+       nand_writel(info, NDTR0CS0, info->ndtr0cs0);
+       nand_writel(info, NDTR1CS0, info->ndtr1cs0);
        clk_enable(info->clk);
 
-       return pxa3xx_nand_config_flash(info, info->flash_info);
+       return 0;
 }
 #else
 #define pxa3xx_nand_suspend    NULL
index 5169ca6a66bcdf55df5033c1868b17964df83888..d9d7efbc77cc496bc49c4da371d78c69c2e10b51 100644 (file)
@@ -757,11 +757,6 @@ static irqreturn_t r852_irq(int irq, void *data)
 
        spin_lock_irqsave(&dev->irqlock, flags);
 
-       /* We can recieve shared interrupt while pci is suspended
-               in that case reads will return 0xFFFFFFFF.... */
-       if (dev->insuspend)
-               goto out;
-
        /* handle card detection interrupts first */
        card_status = r852_read_reg(dev, R852_CARD_IRQ_STA);
        r852_write_reg(dev, R852_CARD_IRQ_STA, card_status);
@@ -1035,7 +1030,6 @@ void r852_shutdown(struct pci_dev *pci_dev)
 int r852_suspend(struct device *device)
 {
        struct r852_device *dev = pci_get_drvdata(to_pci_dev(device));
-       unsigned long flags;
 
        if (dev->ctlreg & R852_CTL_CARDENABLE)
                return -EBUSY;
@@ -1047,43 +1041,22 @@ int r852_suspend(struct device *device)
        r852_disable_irqs(dev);
        r852_engine_disable(dev);
 
-       spin_lock_irqsave(&dev->irqlock, flags);
-       dev->insuspend = 1;
-       spin_unlock_irqrestore(&dev->irqlock, flags);
-
-       /* At that point, even if interrupt handler is running, it will quit */
-       /* So wait for this to happen explictly */
-       synchronize_irq(dev->irq);
-
        /* If card was pulled off just during the suspend, which is very
                unlikely, we will remove it on resume, it too late now
                anyway... */
        dev->card_unstable = 0;
-
-       pci_save_state(to_pci_dev(device));
-       return pci_prepare_to_sleep(to_pci_dev(device));
+       return 0;
 }
 
 int r852_resume(struct device *device)
 {
        struct r852_device *dev = pci_get_drvdata(to_pci_dev(device));
-       unsigned long flags;
-
-       /* Turn on the hardware */
-       pci_back_from_sleep(to_pci_dev(device));
-       pci_restore_state(to_pci_dev(device));
 
        r852_disable_irqs(dev);
        r852_card_update_present(dev);
        r852_engine_disable(dev);
 
 
-       /* Now its safe for IRQ to run */
-       spin_lock_irqsave(&dev->irqlock, flags);
-       dev->insuspend = 0;
-       spin_unlock_irqrestore(&dev->irqlock, flags);
-
-
        /* If card status changed, just do the work */
        if (dev->card_detected != dev->card_registred) {
                dbg("card was %s during low power state",
@@ -1121,7 +1094,6 @@ MODULE_DEVICE_TABLE(pci, r852_pci_id_tbl);
 
 SIMPLE_DEV_PM_OPS(r852_pm_ops, r852_suspend, r852_resume);
 
-
 static struct pci_driver r852_pci_driver = {
        .name           = DRV_NAME,
        .id_table       = r852_pci_id_tbl,
index 8096cc280c73a835170e542c9ce1a097002aca85..e6a21d9d22c60f6829f088a882eff096d7069bff 100644 (file)
@@ -140,8 +140,6 @@ struct r852_device {
        /* interrupt handling */
        spinlock_t irqlock;             /* IRQ protecting lock */
        int irq;                        /* irq num */
-       int insuspend;                  /* device is suspended */
-
        /* misc */
        void *tmp_buffer;               /* temporary buffer */
        uint8_t ctlreg;                 /* cached contents of control reg */
index 7bd171eefd216071cc06a2ba4d844013003dd53d..a996718fa6b06e05607dae1f86bf01a8ff024dd5 100644 (file)
@@ -44,7 +44,7 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
        pp = NULL;
        i = 0;
        while ((pp = of_get_next_child(node, pp))) {
-               const u32 *reg;
+               const __be32 *reg;
                int len;
 
                reg = of_get_property(pp, "reg", &len);
index 3f32289fdbb596e2e7d20f69e6cf92ecf6e492ec..4dbd0f58eebf0e259a4fa23c04d11f1d004ea5d8 100644 (file)
@@ -32,10 +32,11 @@ config MTD_ONENAND_OMAP2
 
 config MTD_ONENAND_SAMSUNG
         tristate "OneNAND on Samsung SOC controller support"
-        depends on ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
+        depends on ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310
         help
-          Support for a OneNAND flash device connected to an Samsung SOC
-          S3C64XX/S5PC1XX controller.
+          Support for a OneNAND flash device connected to an Samsung SOC.
+          S3C64XX/S5PC100 use command mapping method.
+          S5PC110/S5PC210 use generic OneNAND method.
 
 config MTD_ONENAND_OTP
        bool "OneNAND OTP Support"
index a2bb520286f8f995a909527931cebdfbf63d6210..6b3a875647c9ed63e21c6b801416a3e8d7f8a152 100644 (file)
@@ -3365,18 +3365,19 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
 static void onenand_check_features(struct mtd_info *mtd)
 {
        struct onenand_chip *this = mtd->priv;
-       unsigned int density, process;
+       unsigned int density, process, numbufs;
 
        /* Lock scheme depends on density and process */
        density = onenand_get_density(this->device_id);
        process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
+       numbufs = this->read_word(this->base + ONENAND_REG_NUM_BUFFERS) >> 8;
 
        /* Lock scheme */
        switch (density) {
        case ONENAND_DEVICE_DENSITY_4Gb:
                if (ONENAND_IS_DDP(this))
                        this->options |= ONENAND_HAS_2PLANE;
-               else
+               else if (numbufs == 1)
                        this->options |= ONENAND_HAS_4KB_PAGE;
 
        case ONENAND_DEVICE_DENSITY_2Gb:
@@ -4027,7 +4028,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
        mtd->ecclayout = this->ecclayout;
 
        /* Fill in remaining MTD driver data */
-       mtd->type = MTD_NANDFLASH;
+       mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH;
        mtd->flags = MTD_CAP_NANDFLASH;
        mtd->erase = onenand_erase;
        mtd->point = NULL;
index a460f1b748c20fbcb29982925820b79e6a7bbd78..0de7a05e6de065ecfd90cd465939374c11b12090 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
 
 #include <asm/mach/flash.h>
 #include <plat/regs-onenand.h>
@@ -58,7 +59,7 @@ enum soc_type {
 #define MAP_11                         (0x3)
 
 #define S3C64XX_CMD_MAP_SHIFT          24
-#define S5PC1XX_CMD_MAP_SHIFT          26
+#define S5PC100_CMD_MAP_SHIFT          26
 
 #define S3C6400_FBA_SHIFT              10
 #define S3C6400_FPA_SHIFT              4
@@ -81,6 +82,17 @@ enum soc_type {
 #define S5PC110_DMA_TRANS_CMD          0x418
 #define S5PC110_DMA_TRANS_STATUS       0x41C
 #define S5PC110_DMA_TRANS_DIR          0x420
+#define S5PC110_INTC_DMA_CLR           0x1004
+#define S5PC110_INTC_ONENAND_CLR       0x1008
+#define S5PC110_INTC_DMA_MASK          0x1024
+#define S5PC110_INTC_ONENAND_MASK      0x1028
+#define S5PC110_INTC_DMA_PEND          0x1044
+#define S5PC110_INTC_ONENAND_PEND      0x1048
+#define S5PC110_INTC_DMA_STATUS                0x1064
+#define S5PC110_INTC_ONENAND_STATUS    0x1068
+
+#define S5PC110_INTC_DMA_TD            (1 << 24)
+#define S5PC110_INTC_DMA_TE            (1 << 16)
 
 #define S5PC110_DMA_CFG_SINGLE         (0x0 << 16)
 #define S5PC110_DMA_CFG_4BURST         (0x2 << 16)
@@ -134,6 +146,7 @@ struct s3c_onenand {
        void __iomem    *dma_addr;
        struct resource *dma_res;
        unsigned long   phys_base;
+       struct completion       complete;
 #ifdef CONFIG_MTD_PARTITIONS
        struct mtd_partition *parts;
 #endif
@@ -191,7 +204,7 @@ static unsigned int s3c64xx_cmd_map(unsigned type, unsigned val)
 
 static unsigned int s5pc1xx_cmd_map(unsigned type, unsigned val)
 {
-       return (type << S5PC1XX_CMD_MAP_SHIFT) | val;
+       return (type << S5PC100_CMD_MAP_SHIFT) | val;
 }
 
 static unsigned int s3c6400_mem_addr(int fba, int fpa, int fsa)
@@ -531,10 +544,13 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
        return 0;
 }
 
-static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction)
+static int (*s5pc110_dma_ops)(void *dst, void *src, size_t count, int direction);
+
+static int s5pc110_dma_poll(void *dst, void *src, size_t count, int direction)
 {
        void __iomem *base = onenand->dma_addr;
        int status;
+       unsigned long timeout;
 
        writel(src, base + S5PC110_DMA_SRC_ADDR);
        writel(dst, base + S5PC110_DMA_DST_ADDR);
@@ -552,6 +568,13 @@ static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction)
 
        writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD);
 
+       /*
+        * There's no exact timeout values at Spec.
+        * In real case it takes under 1 msec.
+        * So 20 msecs are enough.
+        */
+       timeout = jiffies + msecs_to_jiffies(20);
+
        do {
                status = readl(base + S5PC110_DMA_TRANS_STATUS);
                if (status & S5PC110_DMA_TRANS_STATUS_TE) {
@@ -559,13 +582,68 @@ static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction)
                                        base + S5PC110_DMA_TRANS_CMD);
                        return -EIO;
                }
-       } while (!(status & S5PC110_DMA_TRANS_STATUS_TD));
+       } while (!(status & S5PC110_DMA_TRANS_STATUS_TD) &&
+               time_before(jiffies, timeout));
 
        writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD);
 
        return 0;
 }
 
+static irqreturn_t s5pc110_onenand_irq(int irq, void *data)
+{
+       void __iomem *base = onenand->dma_addr;
+       int status, cmd = 0;
+
+       status = readl(base + S5PC110_INTC_DMA_STATUS);
+
+       if (likely(status & S5PC110_INTC_DMA_TD))
+               cmd = S5PC110_DMA_TRANS_CMD_TDC;
+
+       if (unlikely(status & S5PC110_INTC_DMA_TE))
+               cmd = S5PC110_DMA_TRANS_CMD_TEC;
+
+       writel(cmd, base + S5PC110_DMA_TRANS_CMD);
+       writel(status, base + S5PC110_INTC_DMA_CLR);
+
+       if (!onenand->complete.done)
+               complete(&onenand->complete);
+
+       return IRQ_HANDLED;
+}
+
+static int s5pc110_dma_irq(void *dst, void *src, size_t count, int direction)
+{
+       void __iomem *base = onenand->dma_addr;
+       int status;
+
+       status = readl(base + S5PC110_INTC_DMA_MASK);
+       if (status) {
+               status &= ~(S5PC110_INTC_DMA_TD | S5PC110_INTC_DMA_TE);
+               writel(status, base + S5PC110_INTC_DMA_MASK);
+       }
+
+       writel(src, base + S5PC110_DMA_SRC_ADDR);
+       writel(dst, base + S5PC110_DMA_DST_ADDR);
+
+       if (direction == S5PC110_DMA_DIR_READ) {
+               writel(S5PC110_DMA_SRC_CFG_READ, base + S5PC110_DMA_SRC_CFG);
+               writel(S5PC110_DMA_DST_CFG_READ, base + S5PC110_DMA_DST_CFG);
+       } else {
+               writel(S5PC110_DMA_SRC_CFG_WRITE, base + S5PC110_DMA_SRC_CFG);
+               writel(S5PC110_DMA_DST_CFG_WRITE, base + S5PC110_DMA_DST_CFG);
+       }
+
+       writel(count, base + S5PC110_DMA_TRANS_SIZE);
+       writel(direction, base + S5PC110_DMA_TRANS_DIR);
+
+       writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD);
+
+       wait_for_completion_timeout(&onenand->complete, msecs_to_jiffies(20));
+
+       return 0;
+}
+
 static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
                unsigned char *buffer, int offset, size_t count)
 {
@@ -573,7 +651,8 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
        void __iomem *p;
        void *buf = (void *) buffer;
        dma_addr_t dma_src, dma_dst;
-       int err;
+       int err, page_dma = 0;
+       struct device *dev = &onenand->pdev->dev;
 
        p = this->base + area;
        if (ONENAND_CURRENT_BUFFERRAM(this)) {
@@ -597,21 +676,27 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
                page = vmalloc_to_page(buf);
                if (!page)
                        goto normal;
-               buf = page_address(page) + ((size_t) buf & ~PAGE_MASK);
-       }
 
-       /* DMA routine */
-       dma_src = onenand->phys_base + (p - this->base);
-       dma_dst = dma_map_single(&onenand->pdev->dev,
-                       buf, count, DMA_FROM_DEVICE);
-       if (dma_mapping_error(&onenand->pdev->dev, dma_dst)) {
-               dev_err(&onenand->pdev->dev,
-                       "Couldn't map a %d byte buffer for DMA\n", count);
+               page_dma = 1;
+               /* DMA routine */
+               dma_src = onenand->phys_base + (p - this->base);
+               dma_dst = dma_map_page(dev, page, 0, count, DMA_FROM_DEVICE);
+       } else {
+               /* DMA routine */
+               dma_src = onenand->phys_base + (p - this->base);
+               dma_dst = dma_map_single(dev, buf, count, DMA_FROM_DEVICE);
+       }
+       if (dma_mapping_error(dev, dma_dst)) {
+               dev_err(dev, "Couldn't map a %d byte buffer for DMA\n", count);
                goto normal;
        }
        err = s5pc110_dma_ops((void *) dma_dst, (void *) dma_src,
                        count, S5PC110_DMA_DIR_READ);
-       dma_unmap_single(&onenand->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
+
+       if (page_dma)
+               dma_unmap_page(dev, dma_dst, count, DMA_FROM_DEVICE);
+       else
+               dma_unmap_single(dev, dma_dst, count, DMA_FROM_DEVICE);
 
        if (!err)
                return 0;
@@ -759,7 +844,6 @@ static void s3c_onenand_setup(struct mtd_info *mtd)
                onenand->cmd_map = s5pc1xx_cmd_map;
        } else if (onenand->type == TYPE_S5PC110) {
                /* Use generic onenand functions */
-               onenand->cmd_map = s5pc1xx_cmd_map;
                this->read_bufferram = s5pc110_read_bufferram;
                this->chip_probe = s5pc110_chip_probe;
                return;
@@ -904,6 +988,20 @@ static int s3c_onenand_probe(struct platform_device *pdev)
                }
 
                onenand->phys_base = onenand->base_res->start;
+
+               s5pc110_dma_ops = s5pc110_dma_poll;
+               /* Interrupt support */
+               r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+               if (r) {
+                       init_completion(&onenand->complete);
+                       s5pc110_dma_ops = s5pc110_dma_irq;
+                       err = request_irq(r->start, s5pc110_onenand_irq,
+                                       IRQF_SHARED, "onenand", &onenand);
+                       if (err) {
+                               dev_err(&pdev->dev, "failed to get irq\n");
+                               goto scan_failed;
+                       }
+               }
        }
 
        if (onenand_scan(mtd, 1)) {
@@ -1000,7 +1098,7 @@ static int s3c_pm_ops_suspend(struct device *dev)
        struct onenand_chip *this = mtd->priv;
 
        this->wait(mtd, FL_PM_SUSPENDED);
-       return mtd->suspend(mtd);
+       return 0;
 }
 
 static  int s3c_pm_ops_resume(struct device *dev)
@@ -1009,7 +1107,6 @@ static  int s3c_pm_ops_resume(struct device *dev)
        struct mtd_info *mtd = platform_get_drvdata(pdev);
        struct onenand_chip *this = mtd->priv;
 
-       mtd->resume(mtd);
        this->unlock_all(mtd);
        return 0;
 }
index e30e48e7f63d016975ed7bbcc54bb26e07c68c57..43bb7300785be49cf6b6043f56bd5d2914204658 100644 (file)
@@ -20,7 +20,7 @@
 
 
 struct ftl_zone {
-       int initialized;
+       bool initialized;
        int16_t *lba_to_phys_table;             /* LBA to physical table */
        struct kfifo free_sectors;      /* queue of free sectors */
 };
@@ -37,8 +37,8 @@ struct sm_ftl {
        int zone_count;                 /* number of zones */
        int max_lba;                    /* maximum lba in a zone */
        int smallpagenand;              /* 256 bytes/page nand */
-       int readonly;                   /* is FS readonly */
-       int unstable;
+       bool readonly;                  /* is FS readonly */
+       bool unstable;
        int cis_block;                  /* CIS block location */
        int cis_boffset;                /* CIS offset in the block */
        int cis_page_offset;            /* CIS offset in the page */
@@ -49,7 +49,7 @@ struct sm_ftl {
        int cache_zone;                 /* zone of cached block */
        unsigned char *cache_data;      /* cached block data */
        long unsigned int cache_data_invalid_bitmap;
-       int cache_clean;
+       bool cache_clean;
        struct work_struct flush_work;
        struct timer_list timer;
 
index 9334539ebf75bcb01b91b088bedd7aca9199a03d..f6668cdaac85487b3c621b881af0c9afd975595b 100644 (file)
@@ -2541,6 +2541,7 @@ source "drivers/net/stmmac/Kconfig"
 config PCH_GBE
        tristate "PCH Gigabit Ethernet"
        depends on PCI
+       select MII
        ---help---
          This is a gigabit ethernet driver for Topcliff PCH.
          Topcliff PCH is the platform controller hub that is used in Intel's
index 3134e53262314e7551910ea98fa488115ebaa7e7..8cb27cb7bca1b347c0b072d25e98ef5b58acdb5a 100644 (file)
@@ -407,7 +407,7 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag,
                                           int writeflag)
 {
        int             ret;
-       long    flags;
+       unsigned long   flags;
        long    *vbr, save_berr;
 
        local_irq_save(flags);
index 43579b3b24acce4e23caac9e9ce1d2f2f811af44..53363108994ee93bed670940b0eb91170a389456 100644 (file)
@@ -3043,7 +3043,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
        atl1_pcie_patch(adapter);
        /* assume we have no link for now */
        netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
 
        setup_timer(&adapter->phy_config_timer, atl1_phy_config,
                    (unsigned long)adapter);
index 9eea225decaf724e7d88243fc8c462c62020f81e..863e73a85fbe0ef4cd48ebac5cd5e95846397ebc 100644 (file)
@@ -20,8 +20,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.60.00-3"
-#define DRV_MODULE_RELDATE      "2010/10/19"
+#define DRV_MODULE_VERSION      "1.60.00-4"
+#define DRV_MODULE_RELDATE      "2010/11/01"
 #define BNX2X_BC_VER            0x040200
 
 #define BNX2X_MULTI_QUEUE
index 459614d2d7bcfff471f08f2866a1cc667a272a76..94d5f59d5a6f0a1de6dd8cc5ad44fc2083649b98 100644 (file)
@@ -1680,7 +1680,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
                rc = XMIT_PLAIN;
 
        else {
-               if (skb->protocol == htons(ETH_P_IPV6)) {
+               if (vlan_get_protocol(skb) == htons(ETH_P_IPV6)) {
                        rc = XMIT_CSUM_V6;
                        if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
                                rc |= XMIT_CSUM_TCP;
index 18c8e23a0e82fafaabe0183700960a194c9524af..4cfd4e9b5586f1740d547b02aa8f86e756c86033 100644 (file)
@@ -244,7 +244,14 @@ struct port_hw_cfg {                           /* port 0: 0x12c  port 1: 0x2bc */
 
        u16 xgxs_config_tx[4];                              /* 0x1A0 */
 
-       u32 Reserved1[57];                                  /* 0x1A8 */
+       u32 Reserved1[56];                                  /* 0x1A8 */
+       u32 default_cfg;                                    /* 0x288 */
+       /*  Enable BAM on KR */
+#define PORT_HW_CFG_ENABLE_BAM_ON_KR_MASK                    0x00100000
+#define PORT_HW_CFG_ENABLE_BAM_ON_KR_SHIFT                   20
+#define PORT_HW_CFG_ENABLE_BAM_ON_KR_DISABLED                0x00000000
+#define PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED                 0x00100000
+
        u32 speed_capability_mask2;                         /* 0x28C */
 #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK                0x0000FFFF
 #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT               0
index 2326774df843841315d783dfa6c53a073a2ef4b5..580919619252e3d0594f5365226bc295a8efcba9 100644 (file)
@@ -610,7 +610,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params,
        /* reset and unreset the BigMac */
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
                     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-       udelay(10);
+       msleep(1);
 
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
                     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
@@ -3525,13 +3525,19 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
        DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
 
        /* Enable CL37 BAM */
-       bnx2x_cl45_read(bp, phy,
-                       MDIO_AN_DEVAD,
-                       MDIO_AN_REG_8073_BAM, &val);
-       bnx2x_cl45_write(bp, phy,
-                        MDIO_AN_DEVAD,
-                        MDIO_AN_REG_8073_BAM, val | 1);
+       if (REG_RD(bp, params->shmem_base +
+                        offsetof(struct shmem_region, dev_info.
+                                 port_hw_config[params->port].default_cfg)) &
+           PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
 
+               bnx2x_cl45_read(bp, phy,
+                               MDIO_AN_DEVAD,
+                               MDIO_AN_REG_8073_BAM, &val);
+               bnx2x_cl45_write(bp, phy,
+                                MDIO_AN_DEVAD,
+                                MDIO_AN_REG_8073_BAM, val | 1);
+               DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
+       }
        if (params->loopback_mode == LOOPBACK_EXT) {
                bnx2x_807x_force_10G(bp, phy);
                DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
@@ -5302,7 +5308,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
 {
        struct bnx2x *bp = params->bp;
        u16 autoneg_val, an_1000_val, an_10_100_val;
-       bnx2x_wait_reset_complete(bp, phy);
+
        bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
                      1 << NIG_LATCH_BC_ENABLE_MI_INT);
 
@@ -5431,6 +5437,7 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
 
        /* HW reset */
        bnx2x_ext_phy_hw_reset(bp, params->port);
+       bnx2x_wait_reset_complete(bp, phy);
 
        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
        return bnx2x_848xx_cmn_config_init(phy, params, vars);
@@ -5441,7 +5448,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
                                  struct link_vars *vars)
 {
        struct bnx2x *bp = params->bp;
-       u8 port = params->port, initialize = 1;
+       u8 port, initialize = 1;
        u16 val;
        u16 temp;
        u32 actual_phy_selection;
@@ -5450,11 +5457,16 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
        /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
 
        msleep(1);
+       if (CHIP_IS_E2(bp))
+               port = BP_PATH(bp);
+       else
+               port = params->port;
        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
                       port);
-       msleep(200); /* 100 is not enough */
-
+       bnx2x_wait_reset_complete(bp, phy);
+       /* Wait for GPHY to come out of reset */
+       msleep(50);
        /* BCM84823 requires that XGXS links up first @ 10G for normal
        behavior */
        temp = vars->line_speed;
@@ -5625,7 +5637,11 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
                                   struct link_params *params)
 {
        struct bnx2x *bp = params->bp;
-       u8 port = params->port;
+       u8 port;
+       if (CHIP_IS_E2(bp))
+               port = BP_PATH(bp);
+       else
+               port = params->port;
        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
                            MISC_REGISTERS_GPIO_OUTPUT_LOW,
                            port);
@@ -6928,7 +6944,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
                  u8 reset_ext_phy)
 {
        struct bnx2x *bp = params->bp;
-       u8 phy_index, port = params->port;
+       u8 phy_index, port = params->port, clear_latch_ind = 0;
        DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
        /* disable attentions */
        vars->link_status = 0;
@@ -6966,9 +6982,18 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
                                params->phy[phy_index].link_reset(
                                        &params->phy[phy_index],
                                        params);
+                       if (params->phy[phy_index].flags &
+                           FLAGS_REARM_LATCH_SIGNAL)
+                               clear_latch_ind = 1;
                }
        }
 
+       if (clear_latch_ind) {
+               /* Clear latching indication */
+               bnx2x_rearm_latch_signal(bp, port, 0);
+               bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
+                              1 << NIG_LATCH_BC_ENABLE_MI_INT);
+       }
        if (params->phy[INT_PHY].link_reset)
                params->phy[INT_PHY].link_reset(
                        &params->phy[INT_PHY], params);
@@ -6999,6 +7024,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
        s8 port;
        s8 port_of_path = 0;
 
+       bnx2x_ext_phy_hw_reset(bp, 0);
        /* PART1 - Reset both phys */
        for (port = PORT_MAX - 1; port >= PORT_0; port--) {
                u32 shmem_base, shmem2_base;
@@ -7021,7 +7047,8 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
                        return -EINVAL;
                }
                /* disable attentions */
-               bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+               bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
+                              port_of_path*4,
                             (NIG_MASK_XGXS0_LINK_STATUS |
                              NIG_MASK_XGXS0_LINK10G |
                              NIG_MASK_SERDES0_LINK_STATUS |
@@ -7132,7 +7159,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
                (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
        REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
 
-       bnx2x_ext_phy_hw_reset(bp, 1);
+       bnx2x_ext_phy_hw_reset(bp, 0);
        msleep(5);
        for (port = 0; port < PORT_MAX; port++) {
                u32 shmem_base, shmem2_base;
index 8427533fe313c35cb38727e533cd77dd35cdb4af..8b4cea57a6c5c47f585f5fcae935771e575dcd18 100644 (file)
@@ -33,6 +33,9 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Daniel Martensson<daniel.martensson@stericsson.com>");
 MODULE_DESCRIPTION("CAIF SPI driver");
 
+/* Returns the number of padding bytes for alignment. */
+#define PAD_POW2(x, pow) ((((x)&((pow)-1))==0) ? 0 : (((pow)-((x)&((pow)-1)))))
+
 static int spi_loop;
 module_param(spi_loop, bool, S_IRUGO);
 MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode.");
@@ -41,7 +44,10 @@ MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode.");
 module_param(spi_frm_align, int, S_IRUGO);
 MODULE_PARM_DESC(spi_frm_align, "SPI frame alignment.");
 
-/* SPI padding options. */
+/*
+ * SPI padding options.
+ * Warning: must be a base of 2 (& operation used) and can not be zero !
+ */
 module_param(spi_up_head_align, int, S_IRUGO);
 MODULE_PARM_DESC(spi_up_head_align, "SPI uplink head alignment.");
 
@@ -240,15 +246,13 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf,
 static const struct file_operations dbgfs_state_fops = {
        .open = dbgfs_open,
        .read = dbgfs_state,
-       .owner = THIS_MODULE,
-       .llseek = default_llseek,
+       .owner = THIS_MODULE
 };
 
 static const struct file_operations dbgfs_frame_fops = {
        .open = dbgfs_open,
        .read = dbgfs_frame,
-       .owner = THIS_MODULE,
-       .llseek = default_llseek,
+       .owner = THIS_MODULE
 };
 
 static inline void dev_debugfs_add(struct cfspi *cfspi)
@@ -337,6 +341,9 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len)
        u8 *dst = buf;
        caif_assert(buf);
 
+       if (cfspi->slave && !cfspi->slave_talked)
+               cfspi->slave_talked = true;
+
        do {
                struct sk_buff *skb;
                struct caif_payload_info *info;
@@ -357,8 +364,8 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len)
                 * Compute head offset i.e. number of bytes to add to
                 * get the start of the payload aligned.
                 */
-               if (spi_up_head_align) {
-                       spad = 1 + ((info->hdr_len + 1) & spi_up_head_align);
+               if (spi_up_head_align > 1) {
+                       spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align);
                        *dst = (u8)(spad - 1);
                        dst += spad;
                }
@@ -373,7 +380,7 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len)
                 * Compute tail offset i.e. number of bytes to add to
                 * get the complete CAIF frame aligned.
                 */
-               epad = (skb->len + spad) & spi_up_tail_align;
+               epad = PAD_POW2((skb->len + spad), spi_up_tail_align);
                dst += epad;
 
                dev_kfree_skb(skb);
@@ -417,14 +424,14 @@ int cfspi_xmitlen(struct cfspi *cfspi)
                 * Compute head offset i.e. number of bytes to add to
                 * get the start of the payload aligned.
                 */
-               if (spi_up_head_align)
-                       spad = 1 + ((info->hdr_len + 1) & spi_up_head_align);
+               if (spi_up_head_align > 1)
+                       spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align);
 
                /*
                 * Compute tail offset i.e. number of bytes to add to
                 * get the complete CAIF frame aligned.
                 */
-               epad = (skb->len + spad) & spi_up_tail_align;
+               epad = PAD_POW2((skb->len + spad), spi_up_tail_align);
 
                if ((skb->len + spad + epad + frm_len) <= CAIF_MAX_SPI_FRAME) {
                        skb_queue_tail(&cfspi->chead, skb);
@@ -433,6 +440,7 @@ int cfspi_xmitlen(struct cfspi *cfspi)
                } else {
                        /* Put back packet. */
                        skb_queue_head(&cfspi->qhead, skb);
+                       break;
                }
        } while (pkts <= CAIF_MAX_SPI_PKTS);
 
@@ -453,6 +461,15 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc)
 {
        struct cfspi *cfspi = (struct cfspi *)ifc->priv;
 
+       /*
+        * The slave device is the master on the link. Interrupts before the
+        * slave has transmitted are considered spurious.
+        */
+       if (cfspi->slave && !cfspi->slave_talked) {
+               printk(KERN_WARNING "CFSPI: Spurious SS interrupt.\n");
+               return;
+       }
+
        if (!in_interrupt())
                spin_lock(&cfspi->lock);
        if (assert) {
@@ -465,7 +482,8 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc)
                spin_unlock(&cfspi->lock);
 
        /* Wake up the xfer thread. */
-       wake_up_interruptible(&cfspi->wait);
+       if (assert)
+               wake_up_interruptible(&cfspi->wait);
 }
 
 static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc)
@@ -523,7 +541,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len)
                 * Compute head offset i.e. number of bytes added to
                 * get the start of the payload aligned.
                 */
-               if (spi_down_head_align) {
+               if (spi_down_head_align > 1) {
                        spad = 1 + *src;
                        src += spad;
                }
@@ -564,7 +582,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len)
                 * Compute tail offset i.e. number of bytes added to
                 * get the complete CAIF frame aligned.
                 */
-               epad = (pkt_len + spad) & spi_down_tail_align;
+               epad = PAD_POW2((pkt_len + spad), spi_down_tail_align);
                src += epad;
        } while ((src - buf) < len);
 
@@ -625,11 +643,20 @@ int cfspi_spi_probe(struct platform_device *pdev)
        cfspi->ndev = ndev;
        cfspi->pdev = pdev;
 
-       /* Set flow info */
+       /* Set flow info. */
        cfspi->flow_off_sent = 0;
        cfspi->qd_low_mark = LOW_WATER_MARK;
        cfspi->qd_high_mark = HIGH_WATER_MARK;
 
+       /* Set slave info. */
+       if (!strncmp(cfspi_spi_driver.driver.name, "cfspi_sspi", 10)) {
+               cfspi->slave = true;
+               cfspi->slave_talked = false;
+       } else {
+               cfspi->slave = false;
+               cfspi->slave_talked = false;
+       }
+
        /* Assign the SPI device. */
        cfspi->dev = dev;
        /* Assign the device ifc to this SPI interface. */
index 2111dbfea6feb8b53f56e73567e54fd4d11a818b..1b9943a4edabb8f48678d7384ac2141d47264908 100644 (file)
@@ -36,10 +36,15 @@ static inline int forward_to_spi_cmd(struct cfspi *cfspi)
 #endif
 
 int spi_frm_align = 2;
-int spi_up_head_align = 1;
-int spi_up_tail_align;
-int spi_down_head_align = 3;
-int spi_down_tail_align = 1;
+
+/*
+ * SPI padding options.
+ * Warning: must be a base of 2 (& operation used) and can not be zero !
+ */
+int spi_up_head_align   = 1 << 1;
+int spi_up_tail_align   = 1 << 0;
+int spi_down_head_align = 1 << 2;
+int spi_down_tail_align = 1 << 1;
 
 #ifdef CONFIG_DEBUG_FS
 static inline void debugfs_store_prev(struct cfspi *cfspi)
index cee98fa668bd703c9e34356acb9e6350c0ad80f5..7ef83d06f7eddce14ef7a4cff8cc866a0a6bc572 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * at91_can.c - CAN network driver for AT91 SoC CAN controller
  *
- * (C) 2007 by Hans J. Koch <hjk@linutronix.de>
+ * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
  * (C) 2008, 2009, 2010 by Marc Kleine-Budde <kernel@pengutronix.de>
  *
  * This software may be distributed under the terms of the GNU General
index 55ec324caaf4395b12c2d0dd7ec185ed43921e64..672718261c6872d7fb62578788bd90d54a359789 100644 (file)
@@ -213,12 +213,12 @@ static DEFINE_PCI_DEVICE_TABLE(pch_pci_tbl) = {
 };
 MODULE_DEVICE_TABLE(pci, pch_pci_tbl);
 
-static inline void pch_can_bit_set(u32 *addr, u32 mask)
+static inline void pch_can_bit_set(void __iomem *addr, u32 mask)
 {
        iowrite32(ioread32(addr) | mask, addr);
 }
 
-static inline void pch_can_bit_clear(u32 *addr, u32 mask)
+static inline void pch_can_bit_clear(void __iomem *addr, u32 mask)
 {
        iowrite32(ioread32(addr) & ~mask, addr);
 }
@@ -1437,7 +1437,7 @@ probe_exit_endev:
        return rc;
 }
 
-static struct pci_driver pch_can_pcidev = {
+static struct pci_driver pch_can_pci_driver = {
        .name = "pch_can",
        .id_table = pch_pci_tbl,
        .probe = pch_can_probe,
@@ -1448,13 +1448,13 @@ static struct pci_driver pch_can_pcidev = {
 
 static int __init pch_can_pci_init(void)
 {
-       return pci_register_driver(&pch_can_pcidev);
+       return pci_register_driver(&pch_can_pci_driver);
 }
 module_init(pch_can_pci_init);
 
 static void __exit pch_can_pci_exit(void)
 {
-       pci_unregister_driver(&pch_can_pcidev);
+       pci_unregister_driver(&pch_can_pci_driver);
 }
 module_exit(pch_can_pci_exit);
 
index 4e3c12371aaecea6de7e3057b6f8b4713387355f..046d846c652dc4c807bb79b9ee5ffe343368919d 100644 (file)
@@ -3301,7 +3301,6 @@ static int __devinit init_one(struct pci_dev *pdev,
                pi->rx_offload = T3_RX_CSUM | T3_LRO;
                pi->port_id = i;
                netif_carrier_off(netdev);
-               netif_tx_stop_all_queues(netdev);
                netdev->irq = pdev->irq;
                netdev->mem_start = mmio_start;
                netdev->mem_end = mmio_start + mmio_len - 1;
index 5d72bda543894c3a990d959c8f7bcff17f270d08..f9f6645b2e61341af8b3c2c37dd438c024c3b0c4 100644 (file)
@@ -296,8 +296,10 @@ static void free_tx_desc(struct adapter *adapter, struct sge_txq *q,
                if (d->skb) {   /* an SGL is present */
                        if (need_unmap)
                                unmap_skb(d->skb, q, cidx, pdev);
-                       if (d->eop)
+                       if (d->eop) {
                                kfree_skb(d->skb);
+                               d->skb = NULL;
+                       }
                }
                ++d;
                if (++cidx == q->size) {
index f17703f410b3673a096aec05f9085329650c5c52..f50bc98310f8b319cf8cdfe1f1b63a23fff19e72 100644 (file)
@@ -3736,7 +3736,6 @@ static int __devinit init_one(struct pci_dev *pdev,
 
                        __set_bit(i, &adapter->registered_device_map);
                        adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i;
-                       netif_tx_stop_all_queues(adapter->port[i]);
                }
        }
        if (!adapter->registered_device_map) {
index 555ecc5a2e939b25028ac6a61cf2792da379caa7..c3449bbc585a682b57a39b306f251f9691e27e0b 100644 (file)
@@ -753,7 +753,9 @@ static int cxgb4vf_open(struct net_device *dev)
        if (err)
                return err;
        set_bit(pi->port_id, &adapter->open_device_map);
-       link_start(dev);
+       err = link_start(dev);
+       if (err)
+               return err;
        netif_tx_start_all_queues(dev);
        return 0;
 }
@@ -1103,18 +1105,6 @@ static int cxgb4vf_set_mac_addr(struct net_device *dev, void *_addr)
        return 0;
 }
 
-/*
- * Return a TX Queue on which to send the specified skb.
- */
-static u16 cxgb4vf_select_queue(struct net_device *dev, struct sk_buff *skb)
-{
-       /*
-        * XXX For now just use the default hash but we probably want to
-        * XXX look at other possibilities ...
-        */
-       return skb_tx_hash(dev, skb);
-}
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /*
  * Poll all of our receive queues.  This is called outside of normal interrupt
@@ -2074,6 +2064,22 @@ static int adap_init0(struct adapter *adapter)
                return err;
        }
 
+       /*
+        * Some environments do not properly handle PCIE FLRs -- e.g. in Linux
+        * 2.6.31 and later we can't call pci_reset_function() in order to
+        * issue an FLR because of a self- deadlock on the device semaphore.
+        * Meanwhile, the OS infrastructure doesn't issue FLRs in all the
+        * cases where they're needed -- for instance, some versions of KVM
+        * fail to reset "Assigned Devices" when the VM reboots.  Therefore we
+        * use the firmware based reset in order to reset any per function
+        * state.
+        */
+       err = t4vf_fw_reset(adapter);
+       if (err < 0) {
+               dev_err(adapter->pdev_dev, "FW reset failed: err=%d\n", err);
+               return err;
+       }
+
        /*
         * Grab basic operational parameters.  These will predominantly have
         * been set up by the Physical Function Driver or will be hard coded
@@ -2417,7 +2423,6 @@ static const struct net_device_ops cxgb4vf_netdev_ops     = {
        .ndo_get_stats          = cxgb4vf_get_stats,
        .ndo_set_rx_mode        = cxgb4vf_set_rxmode,
        .ndo_set_mac_address    = cxgb4vf_set_mac_addr,
-       .ndo_select_queue       = cxgb4vf_select_queue,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = cxgb4vf_do_ioctl,
        .ndo_change_mtu         = cxgb4vf_change_mtu,
@@ -2600,7 +2605,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
                pi->xact_addr_filt = -1;
                pi->rx_offload = RX_CSO;
                netif_carrier_off(netdev);
-               netif_tx_stop_all_queues(netdev);
                netdev->irq = pdev->irq;
 
                netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
@@ -2625,7 +2629,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
                netdev->do_ioctl = cxgb4vf_do_ioctl;
                netdev->change_mtu = cxgb4vf_change_mtu;
                netdev->set_mac_address = cxgb4vf_set_mac_addr;
-               netdev->select_queue = cxgb4vf_select_queue;
 #ifdef CONFIG_NET_POLL_CONTROLLER
                netdev->poll_controller = cxgb4vf_poll_controller;
 #endif
@@ -2844,6 +2847,14 @@ static struct pci_device_id cxgb4vf_pci_tbl[] = {
        CH_DEVICE(0x4800, 0),   /* T440-dbg */
        CH_DEVICE(0x4801, 0),   /* T420-cr */
        CH_DEVICE(0x4802, 0),   /* T422-cr */
+       CH_DEVICE(0x4803, 0),   /* T440-cr */
+       CH_DEVICE(0x4804, 0),   /* T420-bch */
+       CH_DEVICE(0x4805, 0),   /* T440-bch */
+       CH_DEVICE(0x4806, 0),   /* T460-ch */
+       CH_DEVICE(0x4807, 0),   /* T420-so */
+       CH_DEVICE(0x4808, 0),   /* T420-cx */
+       CH_DEVICE(0x4809, 0),   /* T420-bt */
+       CH_DEVICE(0x480a, 0),   /* T404-bt */
        { 0, }
 };
 
index f10864ddafbef62492fc95608e0d0f7b8737c561..ecf0770bf0ff60bde745ff12c00e337a4aa54982 100644 (file)
@@ -154,13 +154,14 @@ enum {
         */
        RX_COPY_THRES = 256,
        RX_PULL_LEN = 128,
-};
 
-/*
- * Can't define this in the above enum because PKTSHIFT isn't a constant in
- * the VF Driver ...
- */
-#define RX_PKT_PULL_LEN (RX_PULL_LEN + PKTSHIFT)
+       /*
+        * Main body length for sk_buffs used for RX Ethernet packets with
+        * fragments.  Should be >= RX_PULL_LEN but possibly bigger to give
+        * pskb_may_pull() some room.
+        */
+       RX_SKB_LEN = 512,
+};
 
 /*
  * Software state per TX descriptor.
@@ -1354,6 +1355,67 @@ out_free:
        return NETDEV_TX_OK;
 }
 
+/**
+ *     t4vf_pktgl_to_skb - build an sk_buff from a packet gather list
+ *     @gl: the gather list
+ *     @skb_len: size of sk_buff main body if it carries fragments
+ *     @pull_len: amount of data to move to the sk_buff's main body
+ *
+ *     Builds an sk_buff from the given packet gather list.  Returns the
+ *     sk_buff or %NULL if sk_buff allocation failed.
+ */
+struct sk_buff *t4vf_pktgl_to_skb(const struct pkt_gl *gl,
+                                 unsigned int skb_len, unsigned int pull_len)
+{
+       struct sk_buff *skb;
+       struct skb_shared_info *ssi;
+
+       /*
+        * If the ingress packet is small enough, allocate an skb large enough
+        * for all of the data and copy it inline.  Otherwise, allocate an skb
+        * with enough room to pull in the header and reference the rest of
+        * the data via the skb fragment list.
+        *
+        * Below we rely on RX_COPY_THRES being less than the smallest Rx
+        * buff!  size, which is expected since buffers are at least
+        * PAGE_SIZEd.  In this case packets up to RX_COPY_THRES have only one
+        * fragment.
+        */
+       if (gl->tot_len <= RX_COPY_THRES) {
+               /* small packets have only one fragment */
+               skb = alloc_skb(gl->tot_len, GFP_ATOMIC);
+               if (unlikely(!skb))
+                       goto out;
+               __skb_put(skb, gl->tot_len);
+               skb_copy_to_linear_data(skb, gl->va, gl->tot_len);
+       } else {
+               skb = alloc_skb(skb_len, GFP_ATOMIC);
+               if (unlikely(!skb))
+                       goto out;
+               __skb_put(skb, pull_len);
+               skb_copy_to_linear_data(skb, gl->va, pull_len);
+
+               ssi = skb_shinfo(skb);
+               ssi->frags[0].page = gl->frags[0].page;
+               ssi->frags[0].page_offset = gl->frags[0].page_offset + pull_len;
+               ssi->frags[0].size = gl->frags[0].size - pull_len;
+               if (gl->nfrags > 1)
+                       memcpy(&ssi->frags[1], &gl->frags[1],
+                              (gl->nfrags-1) * sizeof(skb_frag_t));
+               ssi->nr_frags = gl->nfrags;
+
+               skb->len = gl->tot_len;
+               skb->data_len = skb->len - pull_len;
+               skb->truesize += skb->data_len;
+
+               /* Get a reference for the last page, we don't own it */
+               get_page(gl->frags[gl->nfrags - 1].page);
+       }
+
+out:
+       return skb;
+}
+
 /**
  *     t4vf_pktgl_free - free a packet gather list
  *     @gl: the gather list
@@ -1463,10 +1525,8 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
 {
        struct sk_buff *skb;
        struct port_info *pi;
-       struct skb_shared_info *ssi;
        const struct cpl_rx_pkt *pkt = (void *)&rsp[1];
        bool csum_ok = pkt->csum_calc && !pkt->err_vec;
-       unsigned int len = be16_to_cpu(pkt->len);
        struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq);
 
        /*
@@ -1481,42 +1541,14 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
        }
 
        /*
-        * If the ingress packet is small enough, allocate an skb large enough
-        * for all of the data and copy it inline.  Otherwise, allocate an skb
-        * with enough room to pull in the header and reference the rest of
-        * the data via the skb fragment list.
+        * Convert the Packet Gather List into an skb.
         */
-       if (len <= RX_COPY_THRES) {
-               /* small packets have only one fragment */
-               skb = alloc_skb(gl->frags[0].size, GFP_ATOMIC);
-               if (!skb)
-                       goto nomem;
-               __skb_put(skb, gl->frags[0].size);
-               skb_copy_to_linear_data(skb, gl->va, gl->frags[0].size);
-       } else {
-               skb = alloc_skb(RX_PKT_PULL_LEN, GFP_ATOMIC);
-               if (!skb)
-                       goto nomem;
-               __skb_put(skb, RX_PKT_PULL_LEN);
-               skb_copy_to_linear_data(skb, gl->va, RX_PKT_PULL_LEN);
-
-               ssi = skb_shinfo(skb);
-               ssi->frags[0].page = gl->frags[0].page;
-               ssi->frags[0].page_offset = (gl->frags[0].page_offset +
-                                            RX_PKT_PULL_LEN);
-               ssi->frags[0].size = gl->frags[0].size - RX_PKT_PULL_LEN;
-               if (gl->nfrags > 1)
-                       memcpy(&ssi->frags[1], &gl->frags[1],
-                              (gl->nfrags-1) * sizeof(skb_frag_t));
-               ssi->nr_frags = gl->nfrags;
-               skb->len = len + PKTSHIFT;
-               skb->data_len = skb->len - RX_PKT_PULL_LEN;
-               skb->truesize += skb->data_len;
-
-               /* Get a reference for the last page, we don't own it */
-               get_page(gl->frags[gl->nfrags - 1].page);
+       skb = t4vf_pktgl_to_skb(gl, RX_SKB_LEN, RX_PULL_LEN);
+       if (unlikely(!skb)) {
+               t4vf_pktgl_free(gl);
+               rxq->stats.rx_drops++;
+               return 0;
        }
-
        __skb_pull(skb, PKTSHIFT);
        skb->protocol = eth_type_trans(skb, rspq->netdev);
        skb_record_rx_queue(skb, rspq->idx);
@@ -1549,11 +1581,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
                netif_receive_skb(skb);
 
        return 0;
-
-nomem:
-       t4vf_pktgl_free(gl);
-       rxq->stats.rx_drops++;
-       return 0;
 }
 
 /**
@@ -1679,6 +1706,7 @@ int process_responses(struct sge_rspq *rspq, int budget)
                                }
                                len = RSPD_LEN(len);
                        }
+                       gl.tot_len = len;
 
                        /*
                         * Gather packet fragments.
index 873cb7d86c57fc50ae3c71d6638c5e2b58e2ca07..a65c80aed1f2a214d99e520a2125755e2c16ecec 100644 (file)
@@ -235,6 +235,7 @@ static inline int t4vf_wr_mbox_ns(struct adapter *adapter, const void *cmd,
 int __devinit t4vf_wait_dev_ready(struct adapter *);
 int __devinit t4vf_port_init(struct adapter *, int);
 
+int t4vf_fw_reset(struct adapter *);
 int t4vf_query_params(struct adapter *, unsigned int, const u32 *, u32 *);
 int t4vf_set_params(struct adapter *, unsigned int, const u32 *, const u32 *);
 
index ea1c123f0cb4b9e44eeac857920622aa9d51e8b5..e306c20dfaee3fd2c54a7d4e3497ddd8ba787d19 100644 (file)
@@ -325,6 +325,25 @@ int __devinit t4vf_port_init(struct adapter *adapter, int pidx)
        return 0;
 }
 
+/**
+ *      t4vf_fw_reset - issue a reset to FW
+ *      @adapter: the adapter
+ *
+ *     Issues a reset command to FW.  For a Physical Function this would
+ *     result in the Firmware reseting all of its state.  For a Virtual
+ *     Function this just resets the state associated with the VF.
+ */
+int t4vf_fw_reset(struct adapter *adapter)
+{
+       struct fw_reset_cmd cmd;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RESET_CMD) |
+                                     FW_CMD_WRITE);
+       cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
+       return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
+}
+
 /**
  *     t4vf_query_params - query FW or device parameters
  *     @adapter: the adapter
index ca663f19d7df97563dec1ac9192e30042cef8cc6..7236f1a53ba0997da7ba66a218db4b56091faedf 100644 (file)
                              (ID_LED_DEF1_DEF2))
 
 #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
+#define E1000_BASE1000T_STATUS          10
+#define E1000_IDLE_ERROR_COUNT_MASK     0xFF
+#define E1000_RECEIVE_ERROR_COUNTER     21
+#define E1000_RECEIVE_ERROR_MAX         0xFFFF
 
 #define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */
 
@@ -1242,6 +1246,39 @@ static s32 e1000_led_on_82574(struct e1000_hw *hw)
        return 0;
 }
 
+/**
+ *  e1000_check_phy_82574 - check 82574 phy hung state
+ *  @hw: pointer to the HW structure
+ *
+ *  Returns whether phy is hung or not
+ **/
+bool e1000_check_phy_82574(struct e1000_hw *hw)
+{
+       u16 status_1kbt = 0;
+       u16 receive_errors = 0;
+       bool phy_hung = false;
+       s32 ret_val = 0;
+
+       /*
+        * Read PHY Receive Error counter first, if its is max - all F's then
+        * read the Base1000T status register If both are max then PHY is hung.
+        */
+       ret_val = e1e_rphy(hw, E1000_RECEIVE_ERROR_COUNTER, &receive_errors);
+
+       if (ret_val)
+               goto out;
+       if (receive_errors == E1000_RECEIVE_ERROR_MAX)  {
+               ret_val = e1e_rphy(hw, E1000_BASE1000T_STATUS, &status_1kbt);
+               if (ret_val)
+                       goto out;
+               if ((status_1kbt & E1000_IDLE_ERROR_COUNT_MASK) ==
+                   E1000_IDLE_ERROR_COUNT_MASK)
+                       phy_hung = true;
+       }
+out:
+       return phy_hung;
+}
+
 /**
  *  e1000_setup_link_82571 - Setup flow control and link settings
  *  @hw: pointer to the HW structure
@@ -1859,6 +1896,7 @@ struct e1000_info e1000_82574_info = {
                                  | FLAG_HAS_SMART_POWER_DOWN
                                  | FLAG_HAS_AMT
                                  | FLAG_HAS_CTRLEXT_ON_LOAD,
+       .flags2                   = FLAG2_CHECK_PHY_HANG,
        .pba                    = 36,
        .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_82571,
index cee882dd67bf74c3601259e1fc6a3e87d605d6ee..fdc67fead4ea529e3574f38252273deaec456bca 100644 (file)
@@ -397,6 +397,7 @@ struct e1000_adapter {
        struct work_struct print_hang_task;
 
        bool idle_check;
+       int phy_hang_count;
 };
 
 struct e1000_info {
@@ -454,6 +455,7 @@ struct e1000_info {
 #define FLAG2_HAS_EEE                     (1 << 5)
 #define FLAG2_DMA_BURST                   (1 << 6)
 #define FLAG2_DISABLE_AIM                 (1 << 8)
+#define FLAG2_CHECK_PHY_HANG              (1 << 9)
 
 #define E1000_RX_DESC_PS(R, i)     \
        (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@ -631,6 +633,7 @@ extern s32 e1000_get_phy_info_ife(struct e1000_hw *hw);
 extern s32 e1000_check_polarity_ife(struct e1000_hw *hw);
 extern s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
 extern s32 e1000_check_polarity_igp(struct e1000_hw *hw);
+extern bool e1000_check_phy_82574(struct e1000_hw *hw);
 
 static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
 {
index ec8cf3f51423fbf12fbdb9794ce1684f314b5140..c4ca1629f532e49b502c78b76e0e99226c728379 100644 (file)
@@ -4098,6 +4098,25 @@ static void e1000e_enable_receives(struct e1000_adapter *adapter)
        }
 }
 
+static void e1000e_check_82574_phy_workaround(struct e1000_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+
+       /*
+        * With 82574 controllers, PHY needs to be checked periodically
+        * for hung state and reset, if two calls return true
+        */
+       if (e1000_check_phy_82574(hw))
+               adapter->phy_hang_count++;
+       else
+               adapter->phy_hang_count = 0;
+
+       if (adapter->phy_hang_count > 1) {
+               adapter->phy_hang_count = 0;
+               schedule_work(&adapter->reset_task);
+       }
+}
+
 /**
  * e1000_watchdog - Timer Call-back
  * @data: pointer to adapter cast into an unsigned long
@@ -4333,6 +4352,9 @@ link_up:
        if (e1000e_get_laa_state_82571(hw))
                e1000e_rar_set(hw, adapter->hw.mac.addr, 0);
 
+       if (adapter->flags2 & FLAG2_CHECK_PHY_HANG)
+               e1000e_check_82574_phy_workaround(adapter);
+
        /* Reset the timer */
        if (!test_bit(__E1000_DOWN, &adapter->state))
                mod_timer(&adapter->watchdog_timer,
@@ -4860,8 +4882,11 @@ static void e1000_reset_task(struct work_struct *work)
        struct e1000_adapter *adapter;
        adapter = container_of(work, struct e1000_adapter, reset_task);
 
-       e1000e_dump(adapter);
-       e_err("Reset adapter\n");
+       if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
+             (adapter->flags & FLAG_RX_RESTART_NOW))) {
+               e1000e_dump(adapter);
+               e_err("Reset adapter\n");
+       }
        e1000e_reinit_locked(adapter);
 }
 
index 5c566ebc54b80f7da56a4cdf71b68368065c864f..3bc8e276ba4d713370f86af90d7b4b1b22209dfb 100644 (file)
@@ -635,9 +635,10 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        if (wol->wolopts & ~WAKE_MAGIC)
                return -EINVAL;
 
+       device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC);
+
        spin_lock_irqsave(&priv->bflock, flags);
-       priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0;
-       device_set_wakeup_enable(&dev->dev, priv->wol_en);
+       priv->wol_en =  !!device_may_wakeup(&dev->dev);
        spin_unlock_irqrestore(&priv->bflock, flags);
 
        return 0;
index 385dc3204cb7eefbbaa184f0601267abe7c392ee..06bb9b7994585318bb723046a0804a39a4a4a5e8 100644 (file)
@@ -2871,7 +2871,6 @@ static int __devinit emac_probe(struct platform_device *ofdev,
        SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
 
        netif_carrier_off(ndev);
-       netif_stop_queue(ndev);
 
        err = register_netdev(ndev);
        if (err) {
index 14db09e2fa8b1cde0759eb19fd9c4544899168ee..892d196f17accfffc4996f830e02ea74d777c415 100644 (file)
@@ -4107,7 +4107,6 @@ static inline int igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
 netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
                                    struct igb_ring *tx_ring)
 {
-       struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
        int tso = 0, count;
        u32 tx_flags = 0;
        u16 first;
index ebfaa68ee630404addca4607b4dffa2e3fe6bc33..28af019c97bb8bdd7bc413bd494a0cac6aef03dc 100644 (file)
@@ -2783,15 +2783,15 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
        /* reset the hardware with the new settings */
        igbvf_reset(adapter);
 
-       /* tell the stack to leave us alone until igbvf_open() is called */
-       netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
-
        strcpy(netdev->name, "eth%d");
        err = register_netdev(netdev);
        if (err)
                goto err_hw_init;
 
+       /* tell the stack to leave us alone until igbvf_open() is called */
+       netif_carrier_off(netdev);
+       netif_stop_queue(netdev);
+
        igbvf_print_device_info(adapter);
 
        igbvf_initialize_last_counter_stats(adapter);
index 666207a9c039ee2875aa92a553f5f9e321573df7..caa8192fff2a5a3751fc96fd84af1ec6ed7a5cb7 100644 (file)
@@ -533,6 +533,7 @@ ixgb_remove(struct pci_dev *pdev)
        pci_release_regions(pdev);
 
        free_netdev(netdev);
+       pci_disable_device(pdev);
 }
 
 /**
index 8bb9ddb6dffeaff7fbdb7d8b3c0a4eacb87a797f..0d44c6470ca36429ca020a0c81105fecbf6e0cdd 100644 (file)
  * ixgbe_dcb_check_config().
  */
 s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config,
-                                   u8 direction)
+                                  int max_frame, u8 direction)
 {
        struct tc_bw_alloc *p;
+       int min_credit;
+       int min_multiplier;
+       int min_percent = 100;
        s32 ret_val = 0;
        /* Initialization values default for Tx settings */
        u32 credit_refill       = 0;
@@ -59,6 +62,31 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config,
                goto out;
        }
 
+       min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
+                       DCB_CREDIT_QUANTUM;
+
+       /* Find smallest link percentage */
+       for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+               p = &dcb_config->tc_config[i].path[direction];
+               bw_percent = dcb_config->bw_percentage[direction][p->bwg_id];
+               link_percentage = p->bwg_percent;
+
+               link_percentage = (link_percentage * bw_percent) / 100;
+
+               if (link_percentage && link_percentage < min_percent)
+                       min_percent = link_percentage;
+       }
+
+       /*
+        * The ratio between traffic classes will control the bandwidth
+        * percentages seen on the wire. To calculate this ratio we use
+        * a multiplier. It is required that the refill credits must be
+        * larger than the max frame size so here we find the smallest
+        * multiplier that will allow all bandwidth percentages to be
+        * greater than the max frame size.
+        */
+       min_multiplier = (min_credit / min_percent) + 1;
+
        /* Find out the link percentage for each TC first */
        for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
                p = &dcb_config->tc_config[i].path[direction];
@@ -73,8 +101,9 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config,
                /* Save link_percentage for reference */
                p->link_percent = (u8)link_percentage;
 
-               /* Calculate credit refill and save it */
-               credit_refill = link_percentage * MINIMUM_CREDIT_REFILL;
+               /* Calculate credit refill ratio using multiplier */
+               credit_refill = min(link_percentage * min_multiplier,
+                                   MAX_CREDIT_REFILL);
                p->data_credits_refill = (u16)credit_refill;
 
                /* Calculate maximum credit for the TC */
@@ -85,8 +114,8 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config,
                 * of a TC is too small, the maximum credit may not be
                 * enough to send out a jumbo frame in data plane arbitration.
                 */
-               if (credit_max && (credit_max < MINIMUM_CREDIT_FOR_JUMBO))
-                       credit_max = MINIMUM_CREDIT_FOR_JUMBO;
+               if (credit_max && (credit_max < min_credit))
+                       credit_max = min_credit;
 
                if (direction == DCB_TX_CONFIG) {
                        /*
index eb1059f09da0d590a98e0356c552986f576e004b..0208a87b129e3d6d0bc1c64045964c661ed7e319 100644 (file)
@@ -150,15 +150,14 @@ struct ixgbe_dcb_config {
 /* DCB driver APIs */
 
 /* DCB credits calculation */
-s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, u8);
+s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, int, u8);
 
 /* DCB hw initialization */
 s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *);
 
 /* DCB definitions for credit calculation */
+#define DCB_CREDIT_QUANTUM     64   /* DCB Quantum */
 #define MAX_CREDIT_REFILL       511  /* 0x1FF * 64B = 32704B */
-#define MINIMUM_CREDIT_REFILL   5    /* 5*64B = 320B */
-#define MINIMUM_CREDIT_FOR_JUMBO 145  /* 145= UpperBound((9*1024+54)/64B) for 9KB jumbo frame */
 #define DCB_MAX_TSO_SIZE        (32*1024) /* MAX TSO packet size supported in DCB mode */
 #define MINIMUM_CREDIT_FOR_TSO  (DCB_MAX_TSO_SIZE/64 + 1) /* 513 for 32KB TSO packet */
 #define MAX_CREDIT              4095 /* Maximum credit supported: 256KB * 1204 / 64B */
index 67c219f86c3a09d06e1f51abc05bde1bc29a2345..05f224715073cf46e42e52db91a1b57fca226ddc 100644 (file)
@@ -397,6 +397,11 @@ static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw)
        reg &= ~IXGBE_RTTDCS_ARBDIS;
        IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
 
+       /* Enable Security TX Buffer IFG for DCB */
+       reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
+       reg |= IXGBE_SECTX_DCB;
+       IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);
+
        return 0;
 }
 
index 18d7fbf6c292f92d065c9434866aaedaf737623b..3841649fb9545235756a8f647a6a6c260e58c9ab 100644 (file)
@@ -95,6 +95,9 @@
 
 #define IXGBE_TXPBTHRESH_DCB    0xA        /* THRESH value for DCB mode */
 
+/* SECTXMINIFG DCB */
+#define IXGBE_SECTX_DCB                0x00001F00 /* DCB TX Buffer IFG */
+
 
 /* DCB hardware-specific driver APIs */
 
index f85631263af8573f7f0ea96ac63e961abebe225b..fbad4d819608f234d0eff25175bccf9a8545c20b 100644 (file)
@@ -764,8 +764,9 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 #ifdef IXGBE_FCOE
                                /* adjust for FCoE Sequence Offload */
                                if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
-                                   && (skb->protocol == htons(ETH_P_FCOE)) &&
-                                   skb_is_gso(skb)) {
+                                   && skb_is_gso(skb)
+                                   && vlan_get_protocol(skb) ==
+                                   htons(ETH_P_FCOE)) {
                                        hlen = skb_transport_offset(skb) +
                                                sizeof(struct fc_frame_header) +
                                                sizeof(struct fcoe_crc_eof);
@@ -3347,6 +3348,7 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
 static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
 {
        struct ixgbe_hw *hw = &adapter->hw;
+       int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
        u32 txdctl;
        int i, j;
 
@@ -3359,8 +3361,15 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
        if (hw->mac.type == ixgbe_mac_82598EB)
                netif_set_gso_max_size(adapter->netdev, 32768);
 
-       ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG);
-       ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG);
+#ifdef CONFIG_FCOE
+       if (adapter->netdev->features & NETIF_F_FCOE_MTU)
+               max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
+#endif
+
+       ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame,
+                                       DCB_TX_CONFIG);
+       ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame,
+                                       DCB_RX_CONFIG);
 
        /* reconfigure the hardware */
        ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg);
@@ -5815,7 +5824,7 @@ static void ixgbe_watchdog_task(struct work_struct *work)
 
 static int ixgbe_tso(struct ixgbe_adapter *adapter,
                     struct ixgbe_ring *tx_ring, struct sk_buff *skb,
-                    u32 tx_flags, u8 *hdr_len)
+                    u32 tx_flags, u8 *hdr_len, __be16 protocol)
 {
        struct ixgbe_adv_tx_context_desc *context_desc;
        unsigned int i;
@@ -5833,7 +5842,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
                l4len = tcp_hdrlen(skb);
                *hdr_len += l4len;
 
-               if (skb->protocol == htons(ETH_P_IP)) {
+               if (protocol == htons(ETH_P_IP)) {
                        struct iphdr *iph = ip_hdr(skb);
                        iph->tot_len = 0;
                        iph->check = 0;
@@ -5872,7 +5881,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
                type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT |
                                   IXGBE_ADVTXD_DTYP_CTXT);
 
-               if (skb->protocol == htons(ETH_P_IP))
+               if (protocol == htons(ETH_P_IP))
                        type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
                type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
                context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
@@ -5898,16 +5907,10 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
        return false;
 }
 
-static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb)
+static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb,
+                     __be16 protocol)
 {
        u32 rtn = 0;
-       __be16 protocol;
-
-       if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
-               protocol = ((const struct vlan_ethhdr *)skb->data)->
-                                       h_vlan_encapsulated_proto;
-       else
-               protocol = skb->protocol;
 
        switch (protocol) {
        case cpu_to_be16(ETH_P_IP):
@@ -5935,7 +5938,7 @@ static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb)
        default:
                if (unlikely(net_ratelimit()))
                        e_warn(probe, "partial checksum but proto=%x!\n",
-                              skb->protocol);
+                              protocol);
                break;
        }
 
@@ -5944,7 +5947,8 @@ static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb)
 
 static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
                          struct ixgbe_ring *tx_ring,
-                         struct sk_buff *skb, u32 tx_flags)
+                         struct sk_buff *skb, u32 tx_flags,
+                         __be16 protocol)
 {
        struct ixgbe_adv_tx_context_desc *context_desc;
        unsigned int i;
@@ -5973,7 +5977,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
                                    IXGBE_ADVTXD_DTYP_CTXT);
 
                if (skb->ip_summed == CHECKSUM_PARTIAL)
-                       type_tucmd_mlhl |= ixgbe_psum(adapter, skb);
+                       type_tucmd_mlhl |= ixgbe_psum(adapter, skb, protocol);
 
                context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
                /* use index zero for tx checksum offload */
@@ -6171,7 +6175,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
 }
 
 static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
-                     int queue, u32 tx_flags)
+                     int queue, u32 tx_flags, __be16 protocol)
 {
        struct ixgbe_atr_input atr_input;
        struct tcphdr *th;
@@ -6182,7 +6186,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
        u8 l4type = 0;
 
        /* Right now, we support IPv4 only */
-       if (skb->protocol != htons(ETH_P_IP))
+       if (protocol != htons(ETH_P_IP))
                return;
        /* check if we're UDP or TCP */
        if (iph->protocol == IPPROTO_TCP) {
@@ -6249,10 +6253,13 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
        int txq = smp_processor_id();
-
 #ifdef IXGBE_FCOE
-       if ((skb->protocol == htons(ETH_P_FCOE)) ||
-           (skb->protocol == htons(ETH_P_FIP))) {
+       __be16 protocol;
+
+       protocol = vlan_get_protocol(skb);
+
+       if ((protocol == htons(ETH_P_FCOE)) ||
+           (protocol == htons(ETH_P_FIP))) {
                if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
                        txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
                        txq += adapter->ring_feature[RING_F_FCOE].mask;
@@ -6295,6 +6302,9 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
        int tso;
        int count = 0;
        unsigned int f;
+       __be16 protocol;
+
+       protocol = vlan_get_protocol(skb);
 
        if (vlan_tx_tag_present(skb)) {
                tx_flags |= vlan_tx_tag_get(skb);
@@ -6315,8 +6325,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
        /* for FCoE with DCB, we force the priority to what
         * was specified by the switch */
        if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED &&
-           (skb->protocol == htons(ETH_P_FCOE) ||
-            skb->protocol == htons(ETH_P_FIP))) {
+           (protocol == htons(ETH_P_FCOE) ||
+            protocol == htons(ETH_P_FIP))) {
 #ifdef CONFIG_IXGBE_DCB
                if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
                        tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
@@ -6326,7 +6336,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
                }
 #endif
                /* flag for FCoE offloads */
-               if (skb->protocol == htons(ETH_P_FCOE))
+               if (protocol == htons(ETH_P_FCOE))
                        tx_flags |= IXGBE_TX_FLAGS_FCOE;
        }
 #endif
@@ -6360,9 +6370,10 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
                        tx_flags |= IXGBE_TX_FLAGS_FSO;
 #endif /* IXGBE_FCOE */
        } else {
-               if (skb->protocol == htons(ETH_P_IP))
+               if (protocol == htons(ETH_P_IP))
                        tx_flags |= IXGBE_TX_FLAGS_IPV4;
-               tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len);
+               tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len,
+                               protocol);
                if (tso < 0) {
                        dev_kfree_skb_any(skb);
                        return NETDEV_TX_OK;
@@ -6370,7 +6381,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
 
                if (tso)
                        tx_flags |= IXGBE_TX_FLAGS_TSO;
-               else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) &&
+               else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags,
+                                      protocol) &&
                         (skb->ip_summed == CHECKSUM_PARTIAL))
                        tx_flags |= IXGBE_TX_FLAGS_CSUM;
        }
@@ -6384,7 +6396,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
                             test_bit(__IXGBE_FDIR_INIT_DONE,
                                      &tx_ring->reinit_state)) {
                                ixgbe_atr(adapter, skb, tx_ring->queue_index,
-                                         tx_flags);
+                                         tx_flags, protocol);
                                tx_ring->atr_count = 0;
                        }
                }
index d85edf3119c2625d999b22a41b6159ba9ebf7a24..c57d9a43cecacbf8a668a0c4b1cca5e7b93c3521 100644 (file)
@@ -2955,11 +2955,7 @@ jme_init_one(struct pci_dev *pdev,
         * Tell stack that we are not ready to work until open()
         */
        netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
 
-       /*
-        * Register netdev
-        */
        rc = register_netdev(netdev);
        if (rc) {
                pr_err("Cannot register net device\n");
index 316bb70775b111a11853f783791b265e9a6bc598..e7030ceb178b6c3f109c5c355cbec7b55e0bae75 100644 (file)
@@ -1077,7 +1077,6 @@ static void __NS8390_init(struct net_device *dev, int startp)
        ei_outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG);
        ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
 
-       netif_start_queue(dev);
        ei_local->tx1 = ei_local->tx2 = 0;
        ei_local->txing = 0;
 
index 12612127a08718e71b0c6ca07881fedd9eb4e31d..f7d06cbc70ae5780b4fb85db1211d4f8f9726859 100644 (file)
@@ -254,19 +254,6 @@ out_free_rq:
        return err;
 }
 
-static void
-nx_fw_cmd_reset_ctx(struct netxen_adapter *adapter)
-{
-
-       netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION,
-                       adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0,
-                       NX_CDRP_CMD_DESTROY_RX_CTX);
-
-       netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION,
-                       adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0,
-                       NX_CDRP_CMD_DESTROY_TX_CTX);
-}
-
 static void
 nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
 {
@@ -698,8 +685,6 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
        if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
                if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state))
                        goto done;
-               if (reset_devices)
-                       nx_fw_cmd_reset_ctx(adapter);
                err = nx_fw_cmd_create_rx_ctx(adapter);
                if (err)
                        goto err_out_free;
index 50820beac3aa7c20ec8775e6886b419678bf4b04..e1d30d7f207121a5de4636fd85b8bf7d9b76acb5 100644 (file)
@@ -41,9 +41,6 @@
 MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
-MODULE_FIRMWARE(NX_P2_MN_ROMIMAGE_NAME);
-MODULE_FIRMWARE(NX_P3_CT_ROMIMAGE_NAME);
-MODULE_FIRMWARE(NX_P3_MN_ROMIMAGE_NAME);
 MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME);
 
 char netxen_nic_driver_name[] = "netxen_nic";
@@ -1240,7 +1237,6 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
                dev_warn(&pdev->dev, "failed to read mac addr\n");
 
        netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
 
        err = register_netdev(netdev);
        if (err) {
@@ -1356,6 +1352,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                break;
        }
 
+       if (reset_devices) {
+               if (adapter->portnum == 0) {
+                       NXWR32(adapter, NX_CRB_DEV_REF_COUNT, 0);
+                       adapter->need_fw_reset = 1;
+               }
+       }
+
        err = netxen_start_firmware(adapter);
        if (err)
                goto err_out_decr_ref;
index d2e166e29dda2ea5e972526a89af60097221fa0a..8a4d19e5de064bd3fbbb11a2d2e916a28cf593b0 100644 (file)
@@ -111,13 +111,14 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id);
 
 typedef struct axnet_dev_t {
        struct pcmcia_device    *p_dev;
-    caddr_t            base;
-    struct timer_list  watchdog;
-    int                        stale, fast_poll;
-    u_short            link_status;
-    u_char             duplex_flag;
-    int                        phy_id;
-    int                        flags;
+       caddr_t base;
+       struct timer_list       watchdog;
+       int     stale, fast_poll;
+       u_short link_status;
+       u_char  duplex_flag;
+       int     phy_id;
+       int     flags;
+       int     active_low;
 } axnet_dev_t;
 
 static inline axnet_dev_t *PRIV(struct net_device *dev)
@@ -322,6 +323,8 @@ static int axnet_config(struct pcmcia_device *link)
     if (info->flags & IS_AX88790)
        outb(0x10, dev->base_addr + AXNET_GPIO);  /* select Internal PHY */
 
+    info->active_low = 0;
+
     for (i = 0; i < 32; i++) {
        j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
        j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
@@ -329,15 +332,18 @@ static int axnet_config(struct pcmcia_device *link)
        if ((j != 0) && (j != 0xffff)) break;
     }
 
-    /* Maybe PHY is in power down mode. (PPD_SET = 1) 
-       Bit 2 of CCSR is active low. */ 
     if (i == 32) {
+       /* Maybe PHY is in power down mode. (PPD_SET = 1)
+          Bit 2 of CCSR is active low. */
        pcmcia_write_config_byte(link, CISREG_CCSR, 0x04);
        for (i = 0; i < 32; i++) {
            j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
            j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
            if (j == j2) continue;
-           if ((j != 0) && (j != 0xffff)) break;
+           if ((j != 0) && (j != 0xffff)) {
+               info->active_low = 1;
+               break;
+           }
        }
     }
 
@@ -383,8 +389,12 @@ static int axnet_suspend(struct pcmcia_device *link)
 static int axnet_resume(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
+       axnet_dev_t *info = PRIV(dev);
 
        if (link->open) {
+               if (info->active_low == 1)
+                       pcmcia_write_config_byte(link, CISREG_CCSR, 0x04);
+
                axnet_reset_8390(dev);
                AX88190_init(dev, 1);
                netif_device_attach(dev);
index 03096c80103d5c0fc98a52990aa18ec2d9af3804..d05c44692f08306f4dc04dbbb30098c46fd8e362 100644 (file)
@@ -1536,6 +1536,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "FASTline PCMCIA 10/100 Fast-Ethernet", 0xfa2e424d, 0x3953d9b9),
        PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722),
        PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2),
+       PCMCIA_DEVICE_PROD_ID12("corega", "Ether CF-TD", 0x0a21501a, 0x6589340a),
        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd),
        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d),
        PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d),
index e2afdce0a43781a7dc6876e20eecbb9df8f38f93..f0bd1a1aba3ab3413a16eab296b4881d99ea1145 100644 (file)
@@ -74,8 +74,8 @@
 #define MII_88E1121_PHY_MSCR_TX_DELAY  BIT(4)
 #define MII_88E1121_PHY_MSCR_DELAY_MASK        (~(0x3 << 4))
 
-#define MII_88EC048_PHY_MSCR1_REG      16
-#define MII_88EC048_PHY_MSCR1_PAD_ODD  BIT(6)
+#define MII_88E1318S_PHY_MSCR1_REG     16
+#define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6)
 
 #define MII_88E1121_PHY_LED_CTRL       16
 #define MII_88E1121_PHY_LED_PAGE       3
@@ -240,7 +240,7 @@ static int m88e1121_config_aneg(struct phy_device *phydev)
        return err;
 }
 
-static int m88ec048_config_aneg(struct phy_device *phydev)
+static int m88e1318_config_aneg(struct phy_device *phydev)
 {
        int err, oldpage, mscr;
 
@@ -251,10 +251,10 @@ static int m88ec048_config_aneg(struct phy_device *phydev)
        if (err < 0)
                return err;
 
-       mscr = phy_read(phydev, MII_88EC048_PHY_MSCR1_REG);
-       mscr |= MII_88EC048_PHY_MSCR1_PAD_ODD;
+       mscr = phy_read(phydev, MII_88E1318S_PHY_MSCR1_REG);
+       mscr |= MII_88E1318S_PHY_MSCR1_PAD_ODD;
 
-       err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr);
+       err = phy_write(phydev, MII_88E1318S_PHY_MSCR1_REG, mscr);
        if (err < 0)
                return err;
 
@@ -659,12 +659,12 @@ static struct phy_driver marvell_drivers[] = {
                .driver = { .owner = THIS_MODULE },
        },
        {
-               .phy_id = MARVELL_PHY_ID_88EC048,
+               .phy_id = MARVELL_PHY_ID_88E1318S,
                .phy_id_mask = MARVELL_PHY_ID_MASK,
-               .name = "Marvell 88EC048",
+               .name = "Marvell 88E1318S",
                .features = PHY_GBIT_FEATURES,
                .flags = PHY_HAS_INTERRUPT,
-               .config_aneg = &m88ec048_config_aneg,
+               .config_aneg = &m88e1318_config_aneg,
                .read_status = &marvell_read_status,
                .ack_interrupt = &marvell_ack_interrupt,
                .config_intr = &marvell_config_intr,
index 7a298cdf9ab398135b2f59df9c7ad642c8f8840b..a3dcd04be22f6291e2546f84e474cef31e7fae34 100644 (file)
@@ -1450,7 +1450,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
        netdev->irq = adapter->msix_entries[0].vector;
 
        netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
 
        err = register_netdev(netdev);
        if (err) {
index d88ce9fb1cbdacd4c04e802369f504af15e17d37..4c4d16905efb7253a055978e736edc93381cdd69 100644 (file)
@@ -846,10 +846,10 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        else
                tp->features &= ~RTL_FEATURE_WOL;
        __rtl8169_set_wol(tp, wol->wolopts);
-       device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts);
-
        spin_unlock_irq(&tp->lock);
 
+       device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts);
+
        return 0;
 }
 
@@ -2931,7 +2931,7 @@ static const struct rtl_cfg_info {
                .hw_start       = rtl_hw_start_8168,
                .region         = 2,
                .align          = 8,
-               .intr_event     = SYSErr | RxFIFOOver | LinkChg | RxOverflow |
+               .intr_event     = SYSErr | LinkChg | RxOverflow |
                                  TxErr | TxOK | RxOK | RxErr,
                .napi_event     = TxErr | TxOK | RxOK | RxOverflow,
                .features       = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
@@ -4588,7 +4588,8 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                }
 
                /* Work around for rx fifo overflow */
-               if (unlikely(status & RxFIFOOver)) {
+               if (unlikely(status & RxFIFOOver) &&
+               (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
                        netif_stop_queue(dev);
                        rtl8169_tx_timeout(dev);
                        break;
index bfec2e0f52757bdb1097d158b813aaecd7164d66..220e0398f1d519130c63628b3e0461c45227fa7c 100644 (file)
@@ -3858,7 +3858,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
 
        /* device is off until link detection */
        netif_carrier_off(dev);
-       netif_stop_queue(dev);
 
        return dev;
 }
index 52f38e12a879db9d344fb80f169f05eba31fa860..50f712e99e9634d2a348ba497a146b3d86c9dfde 100644 (file)
@@ -22,7 +22,7 @@
 #define __SMSC911X_H__
 
 #define TX_FIFO_LOW_THRESHOLD  ((u32)1600)
-#define SMSC911X_EEPROM_SIZE   ((u32)7)
+#define SMSC911X_EEPROM_SIZE   ((u32)128)
 #define USE_DEBUG              0
 
 /* This is the maximum number of packets to be received every
index 823b9e6431d5f29a3b23a45be8bdbda962a61565..06bc6034ce810f49a67a698af524bec91e1eee5f 100644 (file)
@@ -337,33 +337,19 @@ static int stmmac_init_phy(struct net_device *dev)
        return 0;
 }
 
-static inline void stmmac_mac_enable_rx(void __iomem *ioaddr)
+static inline void stmmac_enable_mac(void __iomem *ioaddr)
 {
        u32 value = readl(ioaddr + MAC_CTRL_REG);
-       value |= MAC_RNABLE_RX;
-       /* Set the RE (receive enable bit into the MAC CTRL register).  */
-       writel(value, ioaddr + MAC_CTRL_REG);
-}
 
-static inline void stmmac_mac_enable_tx(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + MAC_CTRL_REG);
-       value |= MAC_ENABLE_TX;
-       /* Set the TE (transmit enable bit into the MAC CTRL register).  */
+       value |= MAC_RNABLE_RX | MAC_ENABLE_TX;
        writel(value, ioaddr + MAC_CTRL_REG);
 }
 
-static inline void stmmac_mac_disable_rx(void __iomem *ioaddr)
+static inline void stmmac_disable_mac(void __iomem *ioaddr)
 {
        u32 value = readl(ioaddr + MAC_CTRL_REG);
-       value &= ~MAC_RNABLE_RX;
-       writel(value, ioaddr + MAC_CTRL_REG);
-}
 
-static inline void stmmac_mac_disable_tx(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + MAC_CTRL_REG);
-       value &= ~MAC_ENABLE_TX;
+       value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX);
        writel(value, ioaddr + MAC_CTRL_REG);
 }
 
@@ -857,8 +843,7 @@ static int stmmac_open(struct net_device *dev)
        writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK);
 
        /* Enable the MAC Rx/Tx */
-       stmmac_mac_enable_rx(priv->ioaddr);
-       stmmac_mac_enable_tx(priv->ioaddr);
+       stmmac_enable_mac(priv->ioaddr);
 
        /* Set the HW DMA mode and the COE */
        stmmac_dma_operation_mode(priv);
@@ -928,9 +913,8 @@ static int stmmac_release(struct net_device *dev)
        /* Release and free the Rx/Tx resources */
        free_dma_desc_resources(priv);
 
-       /* Disable the MAC core */
-       stmmac_mac_disable_tx(priv->ioaddr);
-       stmmac_mac_disable_rx(priv->ioaddr);
+       /* Disable the MAC Rx/Tx */
+       stmmac_disable_mac(priv->ioaddr);
 
        netif_carrier_off(dev);
 
@@ -1787,8 +1771,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
        priv->hw->dma->stop_rx(priv->ioaddr);
        priv->hw->dma->stop_tx(priv->ioaddr);
 
-       stmmac_mac_disable_rx(priv->ioaddr);
-       stmmac_mac_disable_tx(priv->ioaddr);
+       stmmac_disable_mac(priv->ioaddr);
 
        netif_carrier_off(ndev);
 
@@ -1839,13 +1822,11 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
                                             dis_ic);
                priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
 
-               stmmac_mac_disable_tx(priv->ioaddr);
-
                /* Enable Power down mode by programming the PMT regs */
                if (device_can_wakeup(priv->device))
                        priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
                else
-                       stmmac_mac_disable_rx(priv->ioaddr);
+                       stmmac_disable_mac(priv->ioaddr);
        } else {
                priv->shutdown = 1;
                /* Although this can appear slightly redundant it actually
@@ -1886,8 +1867,7 @@ static int stmmac_resume(struct platform_device *pdev)
        netif_device_attach(dev);
 
        /* Enable the MAC and DMA */
-       stmmac_mac_enable_rx(priv->ioaddr);
-       stmmac_mac_enable_tx(priv->ioaddr);
+       stmmac_enable_mac(priv->ioaddr);
        priv->hw->dma->start_tx(priv->ioaddr);
        priv->hw->dma->start_rx(priv->ioaddr);
 
index 28e1ffb13db99df5b0537a7426b2af3c03980feb..c78a50586c1d86a0fffa9a59ab461a1996da8122 100644 (file)
@@ -2021,7 +2021,6 @@ static int __devinit de_init_one (struct pci_dev *pdev,
        de->media_timer.data = (unsigned long) de;
 
        netif_carrier_off(dev);
-       netif_stop_queue(dev);
 
        /* wake up device, assign resources */
        rc = pci_enable_device(pdev);
index a4c3f5708246e9038ac716c4b8e9b7b06abeb28e..acbdab3d66caa70081e30b87f41e5e82c7d88b33 100644 (file)
@@ -2050,12 +2050,16 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
 
        ugeth_vdbg("%s: IN", __func__);
 
+       /*
+        * Tell the kernel the link is down.
+        * Must be done before disabling the controller
+        * or deadlock may happen.
+        */
+       phy_stop(phydev);
+
        /* Disable the controller */
        ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
 
-       /* Tell the kernel the link is down */
-       phy_stop(phydev);
-
        /* Mask all interrupts */
        out_be32(ugeth->uccf->p_uccm, 0x00000000);
 
@@ -2065,9 +2069,6 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
        /* Disable Rx and Tx */
        clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
 
-       phy_disconnect(ugeth->phydev);
-       ugeth->phydev = NULL;
-
        ucc_geth_memclean(ugeth);
 }
 
@@ -3550,7 +3551,10 @@ static int ucc_geth_close(struct net_device *dev)
 
        napi_disable(&ugeth->napi);
 
+       cancel_work_sync(&ugeth->timeout_work);
        ucc_geth_stop(ugeth);
+       phy_disconnect(ugeth->phydev);
+       ugeth->phydev = NULL;
 
        free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev);
 
@@ -3579,8 +3583,12 @@ static void ucc_geth_timeout_work(struct work_struct *work)
                 * Must reset MAC *and* PHY. This is done by reopening
                 * the device.
                 */
-               ucc_geth_close(dev);
-               ucc_geth_open(dev);
+               netif_tx_stop_all_queues(dev);
+               ucc_geth_stop(ugeth);
+               ucc_geth_init_mac(ugeth);
+               /* Must start PHY here */
+               phy_start(ugeth->phydev);
+               netif_tx_start_all_queues(dev);
        }
 
        netif_tx_schedule_all(dev);
@@ -3594,7 +3602,6 @@ static void ucc_geth_timeout(struct net_device *dev)
 {
        struct ucc_geth_private *ugeth = netdev_priv(dev);
 
-       netif_carrier_off(dev);
        schedule_work(&ugeth->timeout_work);
 }
 
index ca7fc9df1ccf900533d56c35326b360316283af2..c04d49e31f814fe11d2f1b730dcba014afeb324c 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/usb/usbnet.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/pm_runtime.h>
 
 #define DRIVER_VERSION         "22-Aug-2005"
 
@@ -1273,6 +1274,16 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        struct usb_device               *xdev;
        int                             status;
        const char                      *name;
+       struct usb_driver       *driver = to_usb_driver(udev->dev.driver);
+
+       /* usbnet already took usb runtime pm, so have to enable the feature
+        * for usb interface, otherwise usb_autopm_get_interface may return
+        * failure if USB_SUSPEND(RUNTIME_PM) is enabled.
+        */
+       if (!driver->supports_autosuspend) {
+               driver->supports_autosuspend = 1;
+               pm_runtime_enable(&udev->dev);
+       }
 
        name = udev->dev.driver->name;
        info = (struct driver_info *) prod->driver_info;
index bb6b67f6b0cc731df707cbfc06006a2c8c39b198..b6d402806ae67253d2c12ff902ea79d40be5fe87 100644 (file)
@@ -986,9 +986,15 @@ static int virtnet_probe(struct virtio_device *vdev)
                goto unregister;
        }
 
-       vi->status = VIRTIO_NET_S_LINK_UP;
-       virtnet_update_status(vi);
-       netif_carrier_on(dev);
+       /* Assume link up if device can't report link status,
+          otherwise get link status from config. */
+       if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
+               netif_carrier_off(dev);
+               virtnet_update_status(vi);
+       } else {
+               vi->status = VIRTIO_NET_S_LINK_UP;
+               netif_carrier_on(dev);
+       }
 
        pr_debug("virtnet: registered device %s\n", dev->name);
        return 0;
index e3658e10db390dd2ef74d62bd9c34004abe2d4dd..21314e06e6d7da4722bb9fc0d9306a916da7f551 100644 (file)
@@ -873,7 +873,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
        count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) +
                skb_shinfo(skb)->nr_frags + 1;
 
-       ctx.ipv4 = (skb->protocol == __constant_ntohs(ETH_P_IP));
+       ctx.ipv4 = (skb->protocol == cpu_to_be16(ETH_P_IP));
 
        ctx.mss = skb_shinfo(skb)->gso_size;
        if (ctx.mss) {
index 8a2f4712284cfcbf0f2851547e43a2ef5f0fd595..edf228843afc6adc9112419a913cdd2e515072c4 100644 (file)
@@ -330,14 +330,14 @@ struct vmxnet3_adapter {
 };
 
 #define VMXNET3_WRITE_BAR0_REG(adapter, reg, val)  \
-       writel(cpu_to_le32(val), (adapter)->hw_addr0 + (reg))
+       writel((val), (adapter)->hw_addr0 + (reg))
 #define VMXNET3_READ_BAR0_REG(adapter, reg)        \
-       le32_to_cpu(readl((adapter)->hw_addr0 + (reg)))
+       readl((adapter)->hw_addr0 + (reg))
 
 #define VMXNET3_WRITE_BAR1_REG(adapter, reg, val)  \
-       writel(cpu_to_le32(val), (adapter)->hw_addr1 + (reg))
+       writel((val), (adapter)->hw_addr1 + (reg))
 #define VMXNET3_READ_BAR1_REG(adapter, reg)        \
-       le32_to_cpu(readl((adapter)->hw_addr1 + (reg)))
+       readl((adapter)->hw_addr1 + (reg))
 
 #define VMXNET3_WAKE_QUEUE_THRESHOLD(tq)  (5)
 #define VMXNET3_RX_ALLOC_THRESHOLD(rq, ring_idx, adapter) \
index cd0b14a0a93abc3e0bf320c065cac21b30cc0a4d..fbe8aca975d85d940e4ee0f60b1283eb2357a339 100644 (file)
@@ -139,12 +139,12 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
        /* Fill the ath5k_hw struct with the needed functions */
        ret = ath5k_hw_init_desc_functions(ah);
        if (ret)
-               goto err_free;
+               goto err;
 
        /* Bring device out of sleep and reset its units */
        ret = ath5k_hw_nic_wakeup(ah, 0, true);
        if (ret)
-               goto err_free;
+               goto err;
 
        /* Get MAC, PHY and RADIO revisions */
        ah->ah_mac_srev = srev;
@@ -234,7 +234,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
                } else {
                        ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
                        ret = -ENODEV;
-                       goto err_free;
+                       goto err;
                }
        }
 
@@ -244,7 +244,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
        (srev < AR5K_SREV_AR2425)) {
                ATH5K_ERR(sc, "Device not yet supported.\n");
                ret = -ENODEV;
-               goto err_free;
+               goto err;
        }
 
        /*
@@ -252,7 +252,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
         */
        ret = ath5k_hw_post(ah);
        if (ret)
-               goto err_free;
+               goto err;
 
        /* Enable pci core retry fix on Hainan (5213A) and later chips */
        if (srev >= AR5K_SREV_AR5213A)
@@ -265,7 +265,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
        ret = ath5k_eeprom_init(ah);
        if (ret) {
                ATH5K_ERR(sc, "unable to init EEPROM\n");
-               goto err_free;
+               goto err;
        }
 
        ee = &ah->ah_capabilities.cap_eeprom;
@@ -307,7 +307,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
        if (ret) {
                ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
                        sc->pdev->device);
-               goto err_free;
+               goto err;
        }
 
        /* Crypto settings */
@@ -341,8 +341,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
        ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
 
        return 0;
-err_free:
-       kfree(ah);
+err:
        return ret;
 }
 
index a0471f2e1c7a0e8cadb92adb09aa06d3b0b7a1ef..48261b7252d0061e5932c16a98dc3c1caf6e6245 100644 (file)
@@ -410,6 +410,9 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
                        val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
                }
 
+               if (AR_SREV_9280(ah))
+                       val |= AR_WA_BIT22;
+
                if (AR_SREV_9285E_20(ah))
                        val |= AR_WA_BIT23;
 
index 973c919fdd27f5ece00c29a023c598f9054d4f2f..170d44a35ccbd2ca06886be2be2ed8c1cd5dcf25 100644 (file)
@@ -310,7 +310,7 @@ struct ath_rx {
        u8 rxotherant;
        u32 *rxlink;
        unsigned int rxfilter;
-       spinlock_t rxflushlock;
+       spinlock_t pcu_lock;
        spinlock_t rxbuflock;
        struct list_head rxbuf;
        struct ath_descdma rxdma;
@@ -675,6 +675,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
 }
 
 extern struct ieee80211_ops ath9k_ops;
+extern struct pm_qos_request_list ath9k_pm_qos_req;
 extern int modparam_nohwcrypt;
 extern int led_blink;
 
index 728d904c74d7d30408231c90b46a2cfe95f3e2a9..f7ec31b4ddd3a9af801dcb8211763f21e6ab7e09 100644 (file)
@@ -35,6 +35,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
        { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */
        { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
        { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
+       { USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */
        { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
        { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */
        { },
@@ -540,11 +541,11 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
                        return;
                }
 
-               usb_fill_int_urb(urb, hif_dev->udev,
+               usb_fill_bulk_urb(urb, hif_dev->udev,
                                 usb_rcvbulkpipe(hif_dev->udev,
                                                 USB_REG_IN_PIPE),
                                 nskb->data, MAX_REG_IN_BUF_SIZE,
-                                ath9k_hif_usb_reg_in_cb, nskb, 1);
+                                ath9k_hif_usb_reg_in_cb, nskb);
 
                ret = usb_submit_urb(urb, GFP_ATOMIC);
                if (ret) {
@@ -720,11 +721,11 @@ static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
        if (!skb)
                goto err;
 
-       usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev,
+       usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev,
                         usb_rcvbulkpipe(hif_dev->udev,
                                         USB_REG_IN_PIPE),
                         skb->data, MAX_REG_IN_BUF_SIZE,
-                        ath9k_hif_usb_reg_in_cb, skb, 1);
+                        ath9k_hif_usb_reg_in_cb, skb);
 
        if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
                goto err;
@@ -801,10 +802,16 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
        }
        kfree(buf);
 
-       if ((hif_dev->device_id == 0x7010) || (hif_dev->device_id == 0x7015))
+       switch (hif_dev->device_id) {
+       case 0x7010:
+       case 0x7015:
+       case 0x9018:
                firm_offset = AR7010_FIRMWARE_TEXT;
-       else
+               break;
+       default:
                firm_offset = AR9271_FIRMWARE_TEXT;
+               break;
+       }
 
        /*
         * Issue FW download complete command to firmware.
@@ -837,14 +844,6 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
                goto err_fw_req;
        }
 
-       /* Alloc URBs */
-       ret = ath9k_hif_usb_alloc_urbs(hif_dev);
-       if (ret) {
-               dev_err(&hif_dev->udev->dev,
-                       "ath9k_htc: Unable to allocate URBs\n");
-               goto err_urb;
-       }
-
        /* Download firmware */
        ret = ath9k_hif_usb_download_fw(hif_dev);
        if (ret) {
@@ -860,16 +859,22 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
         */
        for (idx = 0; idx < alt->desc.bNumEndpoints; idx++) {
                endp = &alt->endpoint[idx].desc;
-               if (((endp->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
-                               == 0x04) &&
-                   ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-                               == USB_ENDPOINT_XFER_INT)) {
+               if ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+                               == USB_ENDPOINT_XFER_INT) {
                        endp->bmAttributes &= ~USB_ENDPOINT_XFERTYPE_MASK;
                        endp->bmAttributes |= USB_ENDPOINT_XFER_BULK;
                        endp->bInterval = 0;
                }
        }
 
+       /* Alloc URBs */
+       ret = ath9k_hif_usb_alloc_urbs(hif_dev);
+       if (ret) {
+               dev_err(&hif_dev->udev->dev,
+                       "ath9k_htc: Unable to allocate URBs\n");
+               goto err_urb;
+       }
+
        return 0;
 
 err_fw_download:
index cc13ee1178237da72617f92bf7b3a103c82e772b..6ebc68bca91f0a999614572b38f69452df49645d 100644 (file)
@@ -484,6 +484,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
                ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
                          "Failed allocating banks for "
                          "external radio\n");
+               ath9k_hw_rf_free_ext_banks(ah);
                return ecode;
        }
 
@@ -952,9 +953,12 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
                REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
                break;
        case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_MONITOR:
                REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
                break;
+       default:
+               if (ah->is_monitoring)
+                       REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
+               break;
        }
 }
 
@@ -1634,7 +1638,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
 
        switch (ah->opmode) {
        case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_MONITOR:
                REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
                REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
                REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
@@ -1663,6 +1666,14 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
                        AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
                break;
        default:
+               if (ah->is_monitoring) {
+                       REG_WRITE(ah, AR_NEXT_TBTT_TIMER,
+                                       TU_TO_USEC(next_beacon));
+                       REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
+                       REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
+                       flags |= AR_TBTT_TIMER_EN;
+                       break;
+               }
                ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON,
                          "%s: unsupported opmode: %d\n",
                          __func__, ah->opmode);
index d032939768b073aa80e672641f805ac416e1ce22..d47d1b4b6002f2650cba8c80401cd52089800cc6 100644 (file)
@@ -622,6 +622,7 @@ struct ath_hw {
 
        bool sw_mgmt_crypto;
        bool is_pciexpress;
+       bool is_monitoring;
        bool need_an_top2_fixup;
        u16 tx_trig_level;
 
index 95b41db0d86b5b945189ba2c6fd1034043c26811..6a0d99eff404b77417856c7f1b7c035eb079359e 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/pm_qos_params.h>
 
 #include "ath9k.h"
 
@@ -179,6 +180,8 @@ static const struct ath_ops ath9k_common_ops = {
        .write = ath9k_iowrite32,
 };
 
+struct pm_qos_request_list ath9k_pm_qos_req;
+
 /**************************/
 /*     Initialization     */
 /**************************/
@@ -756,6 +759,9 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
        ath_init_leds(sc);
        ath_start_rfkill_poll(sc);
 
+       pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+                          PM_QOS_DEFAULT_VALUE);
+
        return 0;
 
 error_world:
@@ -811,6 +817,8 @@ void ath9k_deinit_device(struct ath_softc *sc)
 
        ath9k_ps_wakeup(sc);
 
+       pm_qos_remove_request(&ath9k_pm_qos_req);
+
        wiphy_rfkill_stop_polling(sc->hw->wiphy);
        ath_deinit_leds(sc);
 
index c6ec800d7a6b6ef4fe91cc00ccffdb543d3504d0..25d3ef4c338e1eb45800b45fec112fc064c095af 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/nl80211.h>
+#include <linux/pm_qos_params.h>
 #include "ath9k.h"
 #include "btcoex.h"
 
@@ -93,11 +94,13 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        unsigned long flags;
+       enum ath9k_power_mode power_mode;
 
        spin_lock_irqsave(&sc->sc_pm_lock, flags);
        if (++sc->ps_usecount != 1)
                goto unlock;
 
+       power_mode = sc->sc_ah->power_mode;
        ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
 
        /*
@@ -105,10 +108,12 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
         * useful data. Better clear them now so that they don't mess up
         * survey data results.
         */
-       spin_lock(&common->cc_lock);
-       ath_hw_cycle_counters_update(common);
-       memset(&common->cc_survey, 0, sizeof(common->cc_survey));
-       spin_unlock(&common->cc_lock);
+       if (power_mode != ATH9K_PM_AWAKE) {
+               spin_lock(&common->cc_lock);
+               ath_hw_cycle_counters_update(common);
+               memset(&common->cc_survey, 0, sizeof(common->cc_survey));
+               spin_unlock(&common->cc_lock);
+       }
 
  unlock:
        spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
@@ -241,6 +246,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
         */
        ath9k_hw_set_interrupts(ah, 0);
        ath_drain_all_txq(sc, false);
+
+       spin_lock_bh(&sc->rx.pcu_lock);
+
        stopped = ath_stoprecv(sc);
 
        /* XXX: do not flush receive queue here. We don't want
@@ -268,6 +276,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
                          "reset status %d\n",
                          channel->center_freq, r);
                spin_unlock_bh(&sc->sc_resetlock);
+               spin_unlock_bh(&sc->rx.pcu_lock);
                goto ps_restore;
        }
        spin_unlock_bh(&sc->sc_resetlock);
@@ -276,9 +285,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to restart recv logic\n");
                r = -EIO;
+               spin_unlock_bh(&sc->rx.pcu_lock);
                goto ps_restore;
        }
 
+       spin_unlock_bh(&sc->rx.pcu_lock);
+
        ath_update_txpow(sc);
        ath9k_hw_set_interrupts(ah, ah->imask);
 
@@ -613,7 +625,7 @@ void ath9k_tasklet(unsigned long data)
                rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
 
        if (status & rxmask) {
-               spin_lock_bh(&sc->rx.rxflushlock);
+               spin_lock_bh(&sc->rx.pcu_lock);
 
                /* Check for high priority Rx first */
                if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
@@ -621,7 +633,7 @@ void ath9k_tasklet(unsigned long data)
                        ath_rx_tasklet(sc, 0, true);
 
                ath_rx_tasklet(sc, 0, false);
-               spin_unlock_bh(&sc->rx.rxflushlock);
+               spin_unlock_bh(&sc->rx.pcu_lock);
        }
 
        if (status & ATH9K_INT_TX) {
@@ -876,6 +888,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
        if (!ah->curchan)
                ah->curchan = ath_get_curchannel(sc, sc->hw);
 
+       spin_lock_bh(&sc->rx.pcu_lock);
        spin_lock_bh(&sc->sc_resetlock);
        r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
        if (r) {
@@ -890,8 +903,10 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
        if (ath_startrecv(sc) != 0) {
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to restart recv logic\n");
+               spin_unlock_bh(&sc->rx.pcu_lock);
                return;
        }
+       spin_unlock_bh(&sc->rx.pcu_lock);
 
        if (sc->sc_flags & SC_OP_BEACONS)
                ath_beacon_config(sc, NULL);    /* restart beacons */
@@ -930,6 +945,9 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
        ath9k_hw_set_interrupts(ah, 0);
 
        ath_drain_all_txq(sc, false);   /* clear pending tx frames */
+
+       spin_lock_bh(&sc->rx.pcu_lock);
+
        ath_stoprecv(sc);               /* turn off frame recv */
        ath_flushrecv(sc);              /* flush recv queue */
 
@@ -947,6 +965,9 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
        spin_unlock_bh(&sc->sc_resetlock);
 
        ath9k_hw_phy_disable(ah);
+
+       spin_unlock_bh(&sc->rx.pcu_lock);
+
        ath9k_hw_configpcipowersave(ah, 1, 1);
        ath9k_ps_restore(sc);
        ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
@@ -966,6 +987,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
 
        ath9k_hw_set_interrupts(ah, 0);
        ath_drain_all_txq(sc, retry_tx);
+
+       spin_lock_bh(&sc->rx.pcu_lock);
+
        ath_stoprecv(sc);
        ath_flushrecv(sc);
 
@@ -980,6 +1004,8 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to start recv logic\n");
 
+       spin_unlock_bh(&sc->rx.pcu_lock);
+
        /*
         * We may be doing a reset in response to a request
         * that changes the channel so update any state that
@@ -1142,6 +1168,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
         * be followed by initialization of the appropriate bits
         * and then setup of the interrupt mask.
         */
+       spin_lock_bh(&sc->rx.pcu_lock);
        spin_lock_bh(&sc->sc_resetlock);
        r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
        if (r) {
@@ -1150,6 +1177,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
                          "(freq %u MHz)\n", r,
                          curchan->center_freq);
                spin_unlock_bh(&sc->sc_resetlock);
+               spin_unlock_bh(&sc->rx.pcu_lock);
                goto mutex_unlock;
        }
        spin_unlock_bh(&sc->sc_resetlock);
@@ -1171,8 +1199,10 @@ static int ath9k_start(struct ieee80211_hw *hw)
                ath_print(common, ATH_DBG_FATAL,
                          "Unable to start recv logic\n");
                r = -EIO;
+               spin_unlock_bh(&sc->rx.pcu_lock);
                goto mutex_unlock;
        }
+       spin_unlock_bh(&sc->rx.pcu_lock);
 
        /* Setup our intr mask. */
        ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
@@ -1192,6 +1222,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
                ah->imask |= ATH9K_INT_CST;
 
        sc->sc_flags &= ~SC_OP_INVALID;
+       sc->sc_ah->is_monitoring = false;
 
        /* Disable BMISS interrupt when we're not associated */
        ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
@@ -1213,6 +1244,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
                        ath9k_btcoex_timer_resume(sc);
        }
 
+       pm_qos_update_request(&ath9k_pm_qos_req, 55);
+
 mutex_unlock:
        mutex_unlock(&sc->mutex);
 
@@ -1371,12 +1404,14 @@ static void ath9k_stop(struct ieee80211_hw *hw)
         * before setting the invalid flag. */
        ath9k_hw_set_interrupts(ah, 0);
 
+       spin_lock_bh(&sc->rx.pcu_lock);
        if (!(sc->sc_flags & SC_OP_INVALID)) {
                ath_drain_all_txq(sc, false);
                ath_stoprecv(sc);
                ath9k_hw_phy_disable(ah);
        } else
                sc->rx.rxlink = NULL;
+       spin_unlock_bh(&sc->rx.pcu_lock);
 
        /* disable HAL and put h/w to sleep */
        ath9k_hw_disable(ah);
@@ -1388,6 +1423,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
        sc->sc_flags |= SC_OP_INVALID;
 
+       pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE);
+
        mutex_unlock(&sc->mutex);
 
        ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
@@ -1466,8 +1503,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
        ath9k_hw_set_interrupts(ah, ah->imask);
 
        if (vif->type == NL80211_IFTYPE_AP    ||
-           vif->type == NL80211_IFTYPE_ADHOC ||
-           vif->type == NL80211_IFTYPE_MONITOR) {
+           vif->type == NL80211_IFTYPE_ADHOC) {
                sc->sc_flags |= SC_OP_ANI_RUN;
                ath_start_ani(common);
        }
@@ -1617,8 +1653,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
        if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
                if (conf->flags & IEEE80211_CONF_MONITOR) {
                        ath_print(common, ATH_DBG_CONFIG,
-                                 "HW opmode set to Monitor mode\n");
-                       sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
+                                 "Monitor mode is enabled\n");
+                       sc->sc_ah->is_monitoring = true;
+               } else {
+                       ath_print(common, ATH_DBG_CONFIG,
+                                 "Monitor mode is disabled\n");
+                       sc->sc_ah->is_monitoring = false;
                }
        }
 
index 0cee90cf8dc9dcb4529db6e783a10f2cc819161a..89978d71617fdaf89a70be70f28a77b199b18d98 100644 (file)
@@ -527,7 +527,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
        for (i = 0; i < rateset->rs_nrates; i++) {
                for (j = 0; j < rate_table->rate_cnt; j++) {
                        u32 phy = rate_table->info[j].phy;
-                       u16 rate_flags = rate_table->info[i].rate_flags;
+                       u16 rate_flags = rate_table->info[j].rate_flags;
                        u8 rate = rateset->rs_rates[i];
                        u8 dot11rate = rate_table->info[j].dot11rate;
 
index fe73fc50082a2c4d681dab51058615a66ceacdfd..c76ea53c20ce7dbe41863c00930853a59ccc6cf8 100644 (file)
@@ -297,19 +297,17 @@ static void ath_edma_start_recv(struct ath_softc *sc)
        ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP,
                              sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize);
 
-       spin_unlock_bh(&sc->rx.rxbuflock);
-
        ath_opmode_init(sc);
 
        ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
+
+       spin_unlock_bh(&sc->rx.rxbuflock);
 }
 
 static void ath_edma_stop_recv(struct ath_softc *sc)
 {
-       spin_lock_bh(&sc->rx.rxbuflock);
        ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
        ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
-       spin_unlock_bh(&sc->rx.rxbuflock);
 }
 
 int ath_rx_init(struct ath_softc *sc, int nbufs)
@@ -319,7 +317,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
        struct ath_buf *bf;
        int error = 0;
 
-       spin_lock_init(&sc->rx.rxflushlock);
+       spin_lock_init(&sc->rx.pcu_lock);
        sc->sc_flags &= ~SC_OP_RXFLUSH;
        spin_lock_init(&sc->rx.rxbuflock);
 
@@ -443,7 +441,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
         */
        if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
             (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
+           (sc->sc_ah->is_monitoring))
                rfilt |= ATH9K_RX_FILTER_PROM;
 
        if (sc->rx.rxfilter & FIF_CONTROL)
@@ -506,10 +504,11 @@ int ath_startrecv(struct ath_softc *sc)
        ath9k_hw_rxena(ah);
 
 start_recv:
-       spin_unlock_bh(&sc->rx.rxbuflock);
        ath_opmode_init(sc);
        ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
 
+       spin_unlock_bh(&sc->rx.rxbuflock);
+
        return 0;
 }
 
@@ -518,6 +517,7 @@ bool ath_stoprecv(struct ath_softc *sc)
        struct ath_hw *ah = sc->sc_ah;
        bool stopped;
 
+       spin_lock_bh(&sc->rx.rxbuflock);
        ath9k_hw_stoppcurecv(ah);
        ath9k_hw_setrxfilter(ah, 0);
        stopped = ath9k_hw_stopdmarecv(ah);
@@ -526,19 +526,18 @@ bool ath_stoprecv(struct ath_softc *sc)
                ath_edma_stop_recv(sc);
        else
                sc->rx.rxlink = NULL;
+       spin_unlock_bh(&sc->rx.rxbuflock);
 
        return stopped;
 }
 
 void ath_flushrecv(struct ath_softc *sc)
 {
-       spin_lock_bh(&sc->rx.rxflushlock);
        sc->sc_flags |= SC_OP_RXFLUSH;
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
                ath_rx_tasklet(sc, 1, true);
        ath_rx_tasklet(sc, 1, false);
        sc->sc_flags &= ~SC_OP_RXFLUSH;
-       spin_unlock_bh(&sc->rx.rxflushlock);
 }
 
 static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
@@ -898,7 +897,7 @@ static bool ath9k_rx_accept(struct ath_common *common,
                 * decryption and MIC failures. For monitor mode,
                 * we also ignore the CRC error.
                 */
-               if (ah->opmode == NL80211_IFTYPE_MONITOR) {
+               if (ah->is_monitoring) {
                        if (rx_stats->rs_status &
                            ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
                              ATH9K_RXERR_CRC))
index 42976b0a01c115692566fe0f7f416c5aa9949b9f..fa05b711e5cdfb7657f94ac420bc87a3f443c1ef 100644 (file)
 #define AR_WA_RESET_EN                  (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */
 #define AR_WA_ANALOG_SHIFT              (1 << 20)
 #define AR_WA_POR_SHORT                 (1 << 21) /* PCI-E Phy reset control */
+#define AR_WA_BIT22                    (1 << 22)
 #define AR9285_WA_DEFAULT              0x004a050b
 #define AR9280_WA_DEFAULT              0x0040073b
 #define AR_WA_DEFAULT                  0x0000073f
index 30ef2dfc1ed2037ee63c54ec0a16223732194ac4..f2ade2402ce27709e1da385941b9adbaece96b1e 100644 (file)
@@ -1089,15 +1089,6 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
        txq->axq_tx_inprogress = false;
        spin_unlock_bh(&txq->axq_lock);
 
-       /* flush any pending frames if aggregation is enabled */
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               if (!retry_tx) {
-                       spin_lock_bh(&txq->axq_lock);
-                       ath_txq_drain_pending_buffers(sc, txq);
-                       spin_unlock_bh(&txq->axq_lock);
-               }
-       }
-
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
                spin_lock_bh(&txq->axq_lock);
                while (!list_empty(&txq->txq_fifo_pending)) {
@@ -1118,6 +1109,15 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
                }
                spin_unlock_bh(&txq->axq_lock);
        }
+
+       /* flush any pending frames if aggregation is enabled */
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               if (!retry_tx) {
+                       spin_lock_bh(&txq->axq_lock);
+                       ath_txq_drain_pending_buffers(sc, txq);
+                       spin_unlock_bh(&txq->axq_lock);
+               }
+       }
 }
 
 void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
index d8607f4c144d80741f26eb133323aff5cebe936c..3317039cd28fe5ae6b1e38ff0029bf345fd78d50 100644 (file)
@@ -82,9 +82,11 @@ static struct usb_device_id carl9170_usb_ids[] = {
        { USB_DEVICE(0x07d1, 0x3c10) },
        /* D-Link DWA 160 A2 */
        { USB_DEVICE(0x07d1, 0x3a09) },
+       /* D-Link DWA 130 D */
+       { USB_DEVICE(0x07d1, 0x3a0f) },
        /* Netgear WNA1000 */
        { USB_DEVICE(0x0846, 0x9040) },
-       /* Netgear WNDA3100 */
+       /* Netgear WNDA3100 (v1) */
        { USB_DEVICE(0x0846, 0x9010) },
        /* Netgear WN111 v2 */
        { USB_DEVICE(0x0846, 0x9001), .driver_info = CARL9170_ONE_LED },
index 45933cf8e8c2297e67728992ebab8891d03b8f16..9a55338d957f1768aed1121b393cca2ef862d640 100644 (file)
@@ -175,7 +175,9 @@ static void b43_sdio_remove(struct sdio_func *func)
        struct b43_sdio *sdio = sdio_get_drvdata(func);
 
        ssb_bus_unregister(&sdio->ssb);
+       sdio_claim_host(func);
        sdio_disable_func(func);
+       sdio_release_host(func);
        kfree(sdio);
        sdio_set_drvdata(func, NULL);
 }
index 32dee2ce5d3177706f8bc7394794952a87389324..d5ef696298eed37db811f55e60c0b7f3c0ded6f6 100644 (file)
@@ -54,6 +54,7 @@
 
 #define DRV_DESCRIPTION "802.11 data/management/control stack"
 #define DRV_NAME        "libipw"
+#define DRV_PROCNAME   "ieee80211"
 #define DRV_VERSION    LIBIPW_VERSION
 #define DRV_COPYRIGHT   "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
 
@@ -293,16 +294,16 @@ static int __init libipw_init(void)
        struct proc_dir_entry *e;
 
        libipw_debug_level = debug;
-       libipw_proc = proc_mkdir("ieee80211", init_net.proc_net);
+       libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net);
        if (libipw_proc == NULL) {
-               LIBIPW_ERROR("Unable to create " DRV_NAME
+               LIBIPW_ERROR("Unable to create " DRV_PROCNAME
                                " proc directory\n");
                return -EIO;
        }
        e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc,
                        &debug_level_proc_fops);
        if (!e) {
-               remove_proc_entry(DRV_NAME, init_net.proc_net);
+               remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
                libipw_proc = NULL;
                return -EIO;
        }
@@ -319,7 +320,7 @@ static void __exit libipw_exit(void)
 #ifdef CONFIG_LIBIPW_DEBUG
        if (libipw_proc) {
                remove_proc_entry("debug_level", libipw_proc);
-               remove_proc_entry(DRV_NAME, init_net.proc_net);
+               remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
                libipw_proc = NULL;
        }
 #endif                         /* CONFIG_LIBIPW_DEBUG */
index 8f8c4b73f8b9667a245f764360058be740f38b03..7edf8c2fb8c7c6072294854281ba40f416f1423a 100644 (file)
@@ -4000,7 +4000,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
         * "the hard way", rather than using device's scan.
         */
        if (iwl3945_mod_params.disable_hw_scan) {
-               IWL_ERR(priv, "sw scan support is deprecated\n");
+               dev_printk(KERN_DEBUG, &(pdev->dev),
+                       "sw scan support is deprecated\n");
                iwl3945_hw_ops.hw_scan = NULL;
        }
 
index 5046a00050348cc03fa4d10a566144449542bf36..373930afc26b50f2d7cddeb9027b07f8e5ad7775 100644 (file)
@@ -700,8 +700,9 @@ static void lbs_scan_worker(struct work_struct *work)
 
        if (priv->scan_channel < priv->scan_req->n_channels) {
                cancel_delayed_work(&priv->scan_work);
-               queue_delayed_work(priv->work_thread, &priv->scan_work,
-                       msecs_to_jiffies(300));
+               if (!priv->stopping)
+                       queue_delayed_work(priv->work_thread, &priv->scan_work,
+                               msecs_to_jiffies(300));
        }
 
        /* This is the final data we are about to send */
index f062ed5839016c4752d3f30922e27c7aa6dca2f8..cb14c38caf3aac8dc5dfc03fe6d77b0cd40bd42c 100644 (file)
@@ -36,6 +36,7 @@ struct lbs_private {
        /* CFG80211 */
        struct wireless_dev *wdev;
        bool wiphy_registered;
+       bool stopping;
        struct cfg80211_scan_request *scan_req;
        u8 assoc_bss[ETH_ALEN];
        u8 disassoc_reason;
index 296fd00a5129f2bb9f47e3475bf25d35c67e7f20..e5685dc317a80423a7acb6a68694bba4043d3897 100644 (file)
@@ -684,18 +684,40 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
 
        lbs_deb_enter(LBS_DEB_SDIO);
 
+       /*
+        * Disable interrupts
+        */
+       sdio_claim_host(card->func);
+       sdio_writeb(card->func, 0x00, IF_SDIO_H_INT_MASK, &ret);
+       sdio_release_host(card->func);
+
        sdio_claim_host(card->func);
        scratch = if_sdio_read_scratch(card, &ret);
        sdio_release_host(card->func);
 
+       lbs_deb_sdio("firmware status = %#x\n", scratch);
+       lbs_deb_sdio("scratch ret = %d\n", ret);
+
        if (ret)
                goto out;
 
-       lbs_deb_sdio("firmware status = %#x\n", scratch);
 
+       /*
+        * The manual clearly describes that FEDC is the right code to use
+        * to detect firmware presence, but for SD8686 it is not that simple.
+        * Scratch is also used to store the RX packet length, so we lose
+        * the FEDC value early on. So we use a non-zero check in order
+        * to validate firmware presence.
+        * Additionally, the SD8686 in the Gumstix always has the high scratch
+        * bit set, even when the firmware is not loaded. So we have to
+        * exclude that from the test.
+        */
        if (scratch == IF_SDIO_FIRMWARE_OK) {
                lbs_deb_sdio("firmware already loaded\n");
                goto success;
+       } else if ((card->model == MODEL_8686) && (scratch & 0x7fff)) {
+               lbs_deb_sdio("firmware may be running\n");
+               goto success;
        }
 
        ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name,
@@ -709,10 +731,14 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
        if (ret)
                goto out;
 
+       lbs_deb_sdio("Helper firmware loaded\n");
+
        ret = if_sdio_prog_real(card, mainfw);
        if (ret)
                goto out;
 
+       lbs_deb_sdio("Firmware loaded\n");
+
 success:
        sdio_claim_host(card->func);
        sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
@@ -1042,8 +1068,6 @@ static int if_sdio_probe(struct sdio_func *func,
        priv->exit_deep_sleep = if_sdio_exit_deep_sleep;
        priv->reset_deep_sleep_wakeup = if_sdio_reset_deep_sleep_wakeup;
 
-       priv->fw_ready = 1;
-
        sdio_claim_host(func);
 
        /*
@@ -1064,6 +1088,8 @@ static int if_sdio_probe(struct sdio_func *func,
        if (ret)
                goto reclaim;
 
+       priv->fw_ready = 1;
+
        /*
         * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
         */
index 47ce5a6ba120e9b9d707c56e93a79d35c1b5a3ea..46b88b118c992c12764084233f8633a62a01a629 100644 (file)
@@ -104,6 +104,7 @@ static int lbs_dev_open(struct net_device *dev)
        lbs_deb_enter(LBS_DEB_NET);
 
        spin_lock_irq(&priv->driver_lock);
+       priv->stopping = false;
 
        if (priv->connect_status == LBS_CONNECTED)
                netif_carrier_on(dev);
@@ -131,10 +132,16 @@ static int lbs_eth_stop(struct net_device *dev)
        lbs_deb_enter(LBS_DEB_NET);
 
        spin_lock_irq(&priv->driver_lock);
+       priv->stopping = true;
        netif_stop_queue(dev);
        spin_unlock_irq(&priv->driver_lock);
 
        schedule_work(&priv->mcast_work);
+       cancel_delayed_work_sync(&priv->scan_work);
+       if (priv->scan_req) {
+               cfg80211_scan_done(priv->scan_req, false);
+               priv->scan_req = NULL;
+       }
 
        lbs_deb_leave(LBS_DEB_NET);
        return 0;
index eea1ef2f502bd3c926599b2308901277e35250ef..4396d4b9bfb9a68ed3c0d7b41a96a80963d30c9f 100644 (file)
@@ -221,9 +221,6 @@ config RT2X00_LIB_LEDS
        boolean
        default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n)
 
-comment "rt2x00 leds support disabled due to modularized LEDS_CLASS and built-in rt2x00"
-       depends on RT2X00_LIB=y && LEDS_CLASS=m
-
 config RT2X00_LIB_DEBUGFS
        bool "Ralink debugfs support"
        depends on RT2X00_LIB && MAC80211_DEBUGFS
index b7e755f4178ad885332ccaaeeb5eda492e6dfcfd..a3984f4ef192a1807ed4714d70babb6702a175d8 100644 (file)
@@ -190,7 +190,7 @@ void sync_stop(void)
        profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
        task_handoff_unregister(&task_free_nb);
        mutex_unlock(&buffer_mutex);
-       flush_scheduled_work();
+       flush_cpu_work();
 
        /* make sure we don't leak task structs */
        process_task_mortuary();
index f179ac2ea80149423034d66a90b1e81251c5069b..59f55441e075fb2c0e6a448f611d7c9c6f115bd3 100644 (file)
@@ -111,14 +111,18 @@ void start_cpu_work(void)
 
 void end_cpu_work(void)
 {
-       int i;
-
        work_enabled = 0;
+}
+
+void flush_cpu_work(void)
+{
+       int i;
 
        for_each_online_cpu(i) {
                struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i);
 
-               cancel_delayed_work(&b->work);
+               /* these works are per-cpu, no need for flush_sync */
+               flush_delayed_work(&b->work);
        }
 }
 
index 68ea16ab645f3e3e134b56db9269df2044234b92..e1d097e250ae6690d077c104fcd2833ab6a24e58 100644 (file)
@@ -25,6 +25,7 @@ void free_cpu_buffers(void);
 
 void start_cpu_work(void);
 void end_cpu_work(void);
+void flush_cpu_work(void);
 
 /* CPU buffer is composed of such entries (which are
  * also used for context switch notes)
index 449de59bf35bb8a255d73b1a77eff0d040f953be..e9ff6f7770be23a046cd5ce22b8fd504794b3907 100644 (file)
@@ -259,17 +259,17 @@ static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent)
 }
 
 
-static int oprofilefs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *oprofilefs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, oprofilefs_fill_super, mnt);
+       return mount_single(fs_type, flags, data, oprofilefs_fill_super);
 }
 
 
 static struct file_system_type oprofilefs_type = {
        .owner          = THIS_MODULE,
        .name           = "oprofilefs",
-       .get_sb         = oprofilefs_get_sb,
+       .mount          = oprofilefs_mount,
        .kill_sb        = kill_litter_super,
 };
 
index dc0ae4d14dffe25ab067f337907b77815121cfd3..010725117dbb0c81d042c7257a94724554425491 100644 (file)
@@ -21,6 +21,7 @@
 #include "oprof.h"
 
 static DEFINE_PER_CPU(struct hrtimer, oprofile_hrtimer);
+static int ctr_running;
 
 static enum hrtimer_restart oprofile_hrtimer_notify(struct hrtimer *hrtimer)
 {
@@ -33,6 +34,9 @@ static void __oprofile_hrtimer_start(void *unused)
 {
        struct hrtimer *hrtimer = &__get_cpu_var(oprofile_hrtimer);
 
+       if (!ctr_running)
+               return;
+
        hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        hrtimer->function = oprofile_hrtimer_notify;
 
@@ -42,7 +46,10 @@ static void __oprofile_hrtimer_start(void *unused)
 
 static int oprofile_hrtimer_start(void)
 {
+       get_online_cpus();
+       ctr_running = 1;
        on_each_cpu(__oprofile_hrtimer_start, NULL, 1);
+       put_online_cpus();
        return 0;
 }
 
@@ -50,6 +57,9 @@ static void __oprofile_hrtimer_stop(int cpu)
 {
        struct hrtimer *hrtimer = &per_cpu(oprofile_hrtimer, cpu);
 
+       if (!ctr_running)
+               return;
+
        hrtimer_cancel(hrtimer);
 }
 
@@ -57,8 +67,11 @@ static void oprofile_hrtimer_stop(void)
 {
        int cpu;
 
+       get_online_cpus();
        for_each_online_cpu(cpu)
                __oprofile_hrtimer_stop(cpu);
+       ctr_running = 0;
+       put_online_cpus();
 }
 
 static int __cpuinit oprofile_cpu_notify(struct notifier_block *self,
index 5624db8c9ad0c511880ca16daf99f4dfb26c3769..003170ea2e394193bdcb7af4033a98bca9d46127 100644 (file)
@@ -64,17 +64,57 @@ void pci_bus_remove_resources(struct pci_bus *bus)
        }
 }
 
+static bool pci_bus_resource_better(struct resource *res1, bool pos1,
+                                   struct resource *res2, bool pos2)
+{
+       /* If exactly one is positive decode, always prefer that one */
+       if (pos1 != pos2)
+               return pos1 ? true : false;
+
+       /* Prefer the one that contains the highest address */
+       if (res1->end != res2->end)
+               return (res1->end > res2->end) ? true : false;
+
+       /* Otherwise, prefer the one with highest "center of gravity" */
+       if (res1->start != res2->start)
+               return (res1->start > res2->start) ? true : false;
+
+       /* Otherwise, choose one arbitrarily (but consistently) */
+       return (res1 > res2) ? true : false;
+}
+
+static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res)
+{
+       struct pci_bus_resource *bus_res;
+
+       /*
+        * This relies on the fact that pci_bus.resource[] refers to P2P or
+        * CardBus bridge base/limit registers, which are always positively
+        * decoded.  The pci_bus.resources list contains host bridge or
+        * subtractively decoded resources.
+        */
+       list_for_each_entry(bus_res, &bus->resources, list) {
+               if (bus_res->res == res)
+                       return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ?
+                               false : true;
+       }
+       return true;
+}
+
 /*
- * Find the highest-address bus resource below the cursor "res".  If the
- * cursor is NULL, return the highest resource.
+ * Find the next-best bus resource after the cursor "res".  If the cursor is
+ * NULL, return the best resource.  "Best" means that we prefer positive
+ * decode regions over subtractive decode, then those at higher addresses.
  */
 static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus,
                                                   unsigned int type,
                                                   struct resource *res)
 {
+       bool res_pos, r_pos, prev_pos = false;
        struct resource *r, *prev = NULL;
        int i;
 
+       res_pos = pci_bus_resource_positive(bus, res);
        pci_bus_for_each_resource(bus, r, i) {
                if (!r)
                        continue;
@@ -82,26 +122,14 @@ static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus,
                if ((r->flags & IORESOURCE_TYPE_BITS) != type)
                        continue;
 
-               /* If this resource is at or past the cursor, skip it */
-               if (res) {
-                       if (r == res)
-                               continue;
-                       if (r->end > res->end)
-                               continue;
-                       if (r->end == res->end && r->start > res->start)
-                               continue;
+               r_pos = pci_bus_resource_positive(bus, r);
+               if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) {
+                       if (!prev || pci_bus_resource_better(r, r_pos,
+                                                            prev, prev_pos)) {
+                               prev = r;
+                               prev_pos = r_pos;
+                       }
                }
-
-               if (!prev)
-                       prev = r;
-
-               /*
-                * A small resource is higher than a large one that ends at
-                * the same address.
-                */
-               if (r->end > prev->end ||
-                   (r->end == prev->end && r->start > prev->start))
-                       prev = r;
        }
 
        return prev;
index 5becbdee4027019a5c584df5ff5fb3cc99b04cc3..2850e64dedae3e0cb9e258d113b75156aff891d3 100644 (file)
@@ -276,6 +276,12 @@ int __init ibmphp_access_ebda (void)
 
        for (;;) {
                offset = next_offset;
+
+               /* Make sure what we read is still in the mapped section */
+               if (WARN(offset > (ebda_sz * 1024 - 4),
+                        "ibmphp_ebda: next read is beyond ebda_sz\n"))
+                       break;
+
                next_offset = readw (io_mem + offset);  /* offset of next blk */
 
                offset += 2;
index b5a7d9bfcb24a70523a33793e60d217475fc9a91..95712a375cd521954f2a1f130a7ddf73704703cf 100644 (file)
@@ -705,17 +705,21 @@ void pci_remove_legacy_files(struct pci_bus *b)
 
 #ifdef HAVE_PCI_MMAP
 
-int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma)
+int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
+                 enum pci_mmap_api mmap_api)
 {
-       unsigned long nr, start, size;
+       unsigned long nr, start, size, pci_start;
 
+       if (pci_resource_len(pdev, resno) == 0)
+               return 0;
        nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
        start = vma->vm_pgoff;
        size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
-       if (start < size && size - start >= nr)
+       pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
+                       pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
+       if (start >= pci_start && start < pci_start + size &&
+                       start + nr <= pci_start + size)
                return 1;
-       WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n",
-               current->comm, start, start+nr, pci_name(pdev), resno, size);
        return 0;
 }
 
@@ -745,8 +749,15 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
        if (i >= PCI_ROM_RESOURCE)
                return -ENODEV;
 
-       if (!pci_mmap_fits(pdev, i, vma))
+       if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) {
+               WARN(1, "process \"%s\" tried to map 0x%08lx bytes "
+                       "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
+                       current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
+                       pci_name(pdev), i,
+                       (u64)pci_resource_start(pdev, i),
+                       (u64)pci_resource_len(pdev, i));
                return -EINVAL;
+       }
 
        /* pci_mmap_page_range() expects the same kind of entry as coming
         * from /proc/bus/pci/ which is a "user visible" value. If this is
index e98c8104297b6c25eb130b01af6c8f00f14008de..710c8a29be0d5b8028eafb239bde42ae5d5934b6 100644 (file)
@@ -1007,6 +1007,18 @@ static int __pci_enable_device_flags(struct pci_dev *dev,
        int err;
        int i, bars = 0;
 
+       /*
+        * Power state could be unknown at this point, either due to a fresh
+        * boot or a device removal call.  So get the current power state
+        * so that things like MSI message writing will behave as expected
+        * (e.g. if the device really is in D0 at enable time).
+        */
+       if (dev->pm_cap) {
+               u16 pmcsr;
+               pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
+               dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
+       }
+
        if (atomic_add_return(1, &dev->enable_cnt) > 1)
                return 0;               /* already enabled */
 
index f5c7c382765f4192345c94cbd4ca0204cc041ebd..7d33f6673868ff5b3254e136770dae4edc635faf 100644 (file)
@@ -22,8 +22,13 @@ extern void pci_remove_firmware_label_files(struct pci_dev *pdev);
 #endif
 extern void pci_cleanup_rom(struct pci_dev *dev);
 #ifdef HAVE_PCI_MMAP
+enum pci_mmap_api {
+       PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */
+       PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */
+};
 extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
-                        struct vm_area_struct *vma);
+                        struct vm_area_struct *vmai,
+                        enum pci_mmap_api mmap_api);
 #endif
 int pci_probe_reset_function(struct pci_dev *dev);
 
index 297b72c880a1f3a84fab6ed277fbabffc90f22ff..ea00647f4732fcb83f60db140265e1b1465a3548 100644 (file)
@@ -257,7 +257,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
 
        /* Make sure the caller is mapping a real resource for this device */
        for (i = 0; i < PCI_ROM_RESOURCE; i++) {
-               if (pci_mmap_fits(dev, i, vma))
+               if (pci_mmap_fits(dev, i, vma,  PCI_MMAP_PROCFS))
                        break;
        }
 
index a87c4985326ebb3f39533946ee31cb839f585cbe..3a5a6fcc0eada9305be0acd3e0a67e8348c85a62 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/msi.h>
-#include <xen/xenbus.h>
 #include <xen/interface/io/pciif.h>
 #include <asm/xen/pci.h>
 #include <linux/interrupt.h>
@@ -576,8 +575,9 @@ static pci_ers_result_t pcifront_common_process(int cmd,
 
        pcidev = pci_get_bus_and_slot(bus, devfn);
        if (!pcidev || !pcidev->driver) {
-               dev_err(&pcidev->dev,
-                       "device or driver is NULL\n");
+               dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
+               if (pcidev)
+                       pci_dev_put(pcidev);
                return result;
        }
        pdrv = pcidev->driver;
index 8cbfa067171f8a1264dbc95b195928bd24833982..96c72e90b79c4c1ff26bcc0e754dbb1c34350017 100644 (file)
@@ -725,17 +725,17 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
 
        return 0;
 
- err_out_free_res2:
+err_out_free_res2:
        if (irq_mode == 1)
                free_irq(dev->irq, socket);
        else
                del_timer_sync(&socket->poll_timer);
- err_out_free_res:
+err_out_free_res:
        pci_release_regions(dev);
- err_out_disable:
+err_out_disable:
        pci_disable_device(dev);
 
- err_out_free_mem:
+err_out_free_mem:
        kfree(socket);
        return ret;
 }
index 41418d394c55bf2c31dab3a12f3b1bc0d2b42913..c8e84bdece386c501e4039fce9f983f1f6b246fa 100644 (file)
@@ -15,7 +15,7 @@
 struct pd6729_socket {
        int     number;
        int     card_irq;
-       unsigned long io_base;  /* base io address of the socket */
+       unsigned long io_base;  /* base io address of the socket */
        struct pcmcia_socket socket;
        struct timer_list poll_timer;
 };
index 0ea3b29440e6b394a5608f41f749610f62b45091..81af2b3bcc005ae90a77d349edd7212b093b29a1 100644 (file)
@@ -237,7 +237,7 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = {
 #ifdef CONFIG_SA1100_COLLIE
 #include "sa11xx_base.h"
 
-int __init pcmcia_collie_init(struct device *dev)
+int __devinit pcmcia_collie_init(struct device *dev)
 {
        int ret = -ENODEV;
 
index fd013a1ef47abcdd5746f4fa7f9885670fc2a9cd..f1e882272ab0e7f2c2c83dce6e271ce04f12c911 100644 (file)
@@ -130,7 +130,7 @@ static struct pcmcia_low_level assabet_pcmcia_ops = {
        .socket_suspend         = assabet_pcmcia_socket_suspend,
 };
 
-int pcmcia_assabet_init(struct device *dev)
+int __devinit pcmcia_assabet_init(struct device *dev)
 {
        int ret = -ENODEV;
 
index 9bf088b1727592b256c5bafcc3bb6188310d2e0c..30560df8c76b6893151ae1f22654492177bdb78f 100644 (file)
@@ -97,7 +97,7 @@ static struct pcmcia_low_level cerf_pcmcia_ops = {
        .socket_suspend         = cerf_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_cerf_init(struct device *dev)
+int __devinit pcmcia_cerf_init(struct device *dev)
 {
        int ret = -ENODEV;
 
index 945857f8c2843d6d258769f54629562395fc088a..6b228590b3fddb5bbd044acd561a029f99bb328d 100644 (file)
@@ -64,7 +64,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
 #endif
 };
 
-static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
+static int __devinit sa11x0_drv_pcmcia_probe(struct platform_device *dev)
 {
        int i, ret = -ENODEV;
 
index 56329ad575a90cdbb78c8d9720b6f1ccb1687359..edf8f00288987c539595ed5fa5522f8e0d196953 100644 (file)
@@ -219,7 +219,7 @@ struct pcmcia_low_level h3600_pcmcia_ops = {
        .socket_suspend         = h3600_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_h3600_init(struct device *dev)
+int __devinit pcmcia_h3600_init(struct device *dev)
 {
        int ret = -ENODEV;
 
index c4d51867a050fa09703b469424d10d3a604c4971..7ff1b43540b809b2a970638bdbf45dff292d0af3 100644 (file)
@@ -113,7 +113,7 @@ static struct pcmcia_low_level shannon_pcmcia_ops = {
        .socket_suspend         = shannon_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_shannon_init(struct device *dev)
+int __devinit pcmcia_shannon_init(struct device *dev)
 {
        int ret = -ENODEV;
 
index 05bd504e6f18a47ff43c24d7bbba27c185ebe822..c998f7aaadbcec38448896be62ece98d16061afa 100644 (file)
@@ -123,7 +123,7 @@ static struct pcmcia_low_level simpad_pcmcia_ops = {
        .socket_suspend         = simpad_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_simpad_init(struct device *dev)
+int __devinit pcmcia_simpad_init(struct device *dev)
 {
        int ret = -ENODEV;
 
index 689e3c02edb819e7c41190787d30d55e06de1131..3753fd0722e72383137d57e839b377721ad86c7a 100644 (file)
@@ -57,11 +57,16 @@ module_param(pc_debug, int, 0644);
 void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
                      int lvl, const char *fmt, ...)
 {
+       struct va_format vaf;
        va_list args;
        if (pc_debug > lvl) {
-               printk(KERN_DEBUG "skt%u: %s: ", skt->nr, func);
                va_start(args, fmt);
-               vprintk(fmt, args);
+
+               vaf.fmt = fmt;
+               vaf.va = &args;
+
+               printk(KERN_DEBUG "skt%u: %s: %pV", skt->nr, func, &vaf);
+
                va_end(args);
        }
 }
index 68cf0c99138a94517f3f2e9dae03de4149049092..7b5080c455690941a97294f03583b64e109927ce 100644 (file)
@@ -1159,11 +1159,11 @@ int __devinit rio_init_mports(void)
 
        list_for_each_entry(port, &rio_mports, node) {
                if (!request_mem_region(port->iores.start,
-                                       port->iores.end - port->iores.start,
+                                       resource_size(&port->iores),
                                        port->name)) {
                        printk(KERN_ERR
                               "RIO: Error requesting master port region 0x%016llx-0x%016llx\n",
-                              (u64)port->iores.start, (u64)port->iores.end - 1);
+                              (u64)port->iores.start, (u64)port->iores.end);
                        rc = -ENOMEM;
                        goto out;
                }
index 359d1e04626cb938784290a5700058a3115d7b34..f0d63892264410b23e19753885868cca81071eda 100644 (file)
@@ -35,7 +35,7 @@
 
 #ifdef CONFIG_SH_SECUREEDGE5410
 #include <asm/rtc.h>
-#include <mach/snapgear.h>
+#include <mach/secureedge5410.h>
 
 #define        RTC_RESET       0x1000
 #define        RTC_IODATA      0x0800
index 5efbd5990ff8dee1ea6431540405082303fd3119..06e41ed9323080475a5639eed3dde6b589c84fc1 100644 (file)
@@ -761,7 +761,7 @@ err_unmap:
        clk_put(rtc->clk);
        iounmap(rtc->regbase);
 err_badmap:
-       release_resource(rtc->res);
+       release_mem_region(rtc->res->start, rtc->regsize);
 err_badres:
        kfree(rtc);
 
@@ -786,7 +786,7 @@ static int __exit sh_rtc_remove(struct platform_device *pdev)
        }
 
        iounmap(rtc->regbase);
-       release_resource(rtc->res);
+       release_mem_region(rtc->res->start, rtc->regsize);
 
        clk_disable(rtc->clk);
        clk_put(rtc->clk);
index 50cf96389d2c319c3d67d95a039e00157adc0078..bf61274af3bb1a0290f6bfbf897205c079da9b5f 100644 (file)
@@ -2801,6 +2801,73 @@ dasd_eckd_steal_lock(struct dasd_device *device)
        return rc;
 }
 
+/*
+ * SNID - Sense Path Group ID
+ * This ioctl may be used in situations where I/O is stalled due to
+ * a reserve, so if the normal dasd_smalloc_request fails, we use the
+ * preallocated dasd_reserve_req.
+ */
+static int dasd_eckd_snid(struct dasd_device *device,
+                         void __user *argp)
+{
+       struct dasd_ccw_req *cqr;
+       int rc;
+       struct ccw1 *ccw;
+       int useglobal;
+       struct dasd_snid_ioctl_data usrparm;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+
+       if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
+               return -EFAULT;
+
+       useglobal = 0;
+       cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1,
+                                  sizeof(struct dasd_snid_data), device);
+       if (IS_ERR(cqr)) {
+               mutex_lock(&dasd_reserve_mutex);
+               useglobal = 1;
+               cqr = &dasd_reserve_req->cqr;
+               memset(cqr, 0, sizeof(*cqr));
+               memset(&dasd_reserve_req->ccw, 0,
+                      sizeof(dasd_reserve_req->ccw));
+               cqr->cpaddr = &dasd_reserve_req->ccw;
+               cqr->data = &dasd_reserve_req->data;
+               cqr->magic = DASD_ECKD_MAGIC;
+       }
+       ccw = cqr->cpaddr;
+       ccw->cmd_code = DASD_ECKD_CCW_SNID;
+       ccw->flags |= CCW_FLAG_SLI;
+       ccw->count = 12;
+       ccw->cda = (__u32)(addr_t) cqr->data;
+       cqr->startdev = device;
+       cqr->memdev = device;
+       clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
+       set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+       cqr->retries = 5;
+       cqr->expires = 10 * HZ;
+       cqr->buildclk = get_clock();
+       cqr->status = DASD_CQR_FILLED;
+       cqr->lpm = usrparm.path_mask;
+
+       rc = dasd_sleep_on_immediatly(cqr);
+       /* verify that I/O processing didn't modify the path mask */
+       if (!rc && usrparm.path_mask && (cqr->lpm != usrparm.path_mask))
+               rc = -EIO;
+       if (!rc) {
+               usrparm.data = *((struct dasd_snid_data *)cqr->data);
+               if (copy_to_user(argp, &usrparm, sizeof(usrparm)))
+                       rc = -EFAULT;
+       }
+
+       if (useglobal)
+               mutex_unlock(&dasd_reserve_mutex);
+       else
+               dasd_sfree_request(cqr, cqr->memdev);
+       return rc;
+}
+
 /*
  * Read performance statistics
  */
@@ -3036,6 +3103,8 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
                return dasd_eckd_reserve(device);
        case BIODASDSLCK:
                return dasd_eckd_steal_lock(device);
+       case BIODASDSNID:
+               return dasd_eckd_snid(device, argp);
        case BIODASDSYMMIO:
                return dasd_symm_io(device, argp);
        default:
index 0eb49655a6cd06ee10256811fcc1da3e3cb3d7f8..12097c24f2f50c2826f8913e43f1a8cb7c0cda15 100644 (file)
@@ -27,6 +27,7 @@
 #define DASD_ECKD_CCW_WRITE_CKD                 0x1d
 #define DASD_ECKD_CCW_READ_CKD          0x1e
 #define DASD_ECKD_CCW_PSF               0x27
+#define DASD_ECKD_CCW_SNID              0x34
 #define DASD_ECKD_CCW_RSSD              0x3e
 #define DASD_ECKD_CCW_LOCATE_RECORD     0x47
 #define DASD_ECKD_CCW_SNSS              0x54
index 29c2d73d719db55ab963660efdbfe6b9db55c030..6c408670e08d72336ecfe1e3298a6db285740787 100644 (file)
@@ -1077,15 +1077,14 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                /* FIXME: What to do with the request? */
                switch (PTR_ERR(irb)) {
                        case -ETIMEDOUT:
-                               DBF_LH(1, "(%s): Request timed out\n",
-                                       dev_name(&cdev->dev));
+                               DBF_LH(1, "(%08x): Request timed out\n",
+                                      device->cdev_id);
                        case -EIO:
                                __tape_end_request(device, request, -EIO);
                                break;
                        default:
-                               DBF_LH(1, "(%s): Unexpected i/o error %li\n",
-                                       dev_name(&cdev->dev),
-                                       PTR_ERR(irb));
+                               DBF_LH(1, "(%08x): Unexpected i/o error %li\n",
+                                      device->cdev_id, PTR_ERR(irb));
                }
                return;
        }
index 03f07e5dd6e9ebe9699ae7306d585101f0db38ec..3c3f342149ecd09d7b48334550047425fe42105c 100644 (file)
@@ -47,8 +47,8 @@ tape_std_assign_timeout(unsigned long data)
                        device->cdev_id);
        rc = tape_cancel_io(device, request);
        if(rc)
-               DBF_EVENT(3, "(%s): Assign timeout: Cancel failed with rc = %i\n",
-                       dev_name(&device->cdev->dev), rc);
+               DBF_EVENT(3, "(%08x): Assign timeout: Cancel failed with rc = "
+                         "%i\n", device->cdev_id, rc);
 }
 
 int
index 6be43eb126b40077ab4bc0298ef7179bea0c9496..f47a714538db187e209d82a2acda81a91d7fd0de 100644 (file)
@@ -440,7 +440,6 @@ struct qeth_qdio_out_q {
         * index of buffer to be filled by driver; state EMPTY or PACKING
         */
        int next_buf_to_fill;
-       int sync_iqdio_error;
        /*
         * number of buffers that are currently filled (PRIMED)
         * -> these buffers are hardware-owned
@@ -695,14 +694,6 @@ struct qeth_mc_mac {
        int is_vmac;
 };
 
-struct qeth_skb_data {
-       __u32 magic;
-       int count;
-};
-
-#define QETH_SKB_MAGIC 0x71657468
-#define QETH_SIGA_CC2_RETRIES 3
-
 struct qeth_rx {
        int b_count;
        int b_index;
index 764267062601b8812017f9552350b0ad6480ba23..e6b2df0e73f56a4b143365be8302875c600c49bc 100644 (file)
@@ -877,8 +877,8 @@ out:
        return;
 }
 
-static void __qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
-                struct qeth_qdio_out_buffer *buf, unsigned int qeth_skip_skb)
+static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
+               struct qeth_qdio_out_buffer *buf)
 {
        int i;
        struct sk_buff *skb;
@@ -887,13 +887,11 @@ static void __qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
        if (buf->buffer->element[0].flags & 0x40)
                atomic_dec(&queue->set_pci_flags_count);
 
-       if (!qeth_skip_skb) {
+       skb = skb_dequeue(&buf->skb_list);
+       while (skb) {
+               atomic_dec(&skb->users);
+               dev_kfree_skb_any(skb);
                skb = skb_dequeue(&buf->skb_list);
-               while (skb) {
-                       atomic_dec(&skb->users);
-                       dev_kfree_skb_any(skb);
-                       skb = skb_dequeue(&buf->skb_list);
-               }
        }
        for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) {
                if (buf->buffer->element[i].addr && buf->is_header[i])
@@ -909,12 +907,6 @@ static void __qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
        atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
 }
 
-static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
-               struct qeth_qdio_out_buffer *buf)
-{
-       __qeth_clear_output_buffer(queue, buf, 0);
-}
-
 void qeth_clear_qdio_buffers(struct qeth_card *card)
 {
        int i, j;
@@ -2833,7 +2825,6 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
                }
        }
 
-       queue->sync_iqdio_error = 0;
        queue->card->dev->trans_start = jiffies;
        if (queue->card->options.performance_stats) {
                queue->card->perf_stats.outbound_do_qdio_cnt++;
@@ -2849,10 +2840,6 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
                queue->card->perf_stats.outbound_do_qdio_time +=
                        qeth_get_micros() -
                        queue->card->perf_stats.outbound_do_qdio_start_time;
-       if (rc > 0) {
-               if (!(rc & QDIO_ERROR_SIGA_BUSY))
-                       queue->sync_iqdio_error = rc & 3;
-       }
        if (rc) {
                queue->card->stats.tx_errors += count;
                /* ignore temporary SIGA errors without busy condition */
@@ -2916,7 +2903,7 @@ void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
 {
        struct qeth_card *card = (struct qeth_card *)card_ptr;
 
-       if (card->dev)
+       if (card->dev && (card->dev->flags & IFF_UP))
                napi_schedule(&card->napi);
 }
 EXPORT_SYMBOL_GPL(qeth_qdio_start_poll);
@@ -2940,7 +2927,6 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
        struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue];
        struct qeth_qdio_out_buffer *buffer;
        int i;
-       unsigned qeth_send_err;
 
        QETH_CARD_TEXT(card, 6, "qdouhdl");
        if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
@@ -2956,9 +2942,8 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
        }
        for (i = first_element; i < (first_element + count); ++i) {
                buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
-               qeth_send_err = qeth_handle_send_error(card, buffer, qdio_error);
-               __qeth_clear_output_buffer(queue, buffer,
-                       (qeth_send_err == QETH_SEND_ERROR_RETRY) ? 1 : 0);
+               qeth_handle_send_error(card, buffer, qdio_error);
+               qeth_clear_output_buffer(queue, buffer);
        }
        atomic_sub(count, &queue->used_buffers);
        /* check if we need to do something on this outbound queue */
@@ -3183,10 +3168,7 @@ int qeth_do_send_packet_fast(struct qeth_card *card,
                int offset, int hd_len)
 {
        struct qeth_qdio_out_buffer *buffer;
-       struct sk_buff *skb1;
-       struct qeth_skb_data *retry_ctrl;
        int index;
-       int rc;
 
        /* spin until we get the queue ... */
        while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
@@ -3205,25 +3187,6 @@ int qeth_do_send_packet_fast(struct qeth_card *card,
        atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
        qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
        qeth_flush_buffers(queue, index, 1);
-       if (queue->sync_iqdio_error == 2) {
-               skb1 = skb_dequeue(&buffer->skb_list);
-               while (skb1) {
-                       atomic_dec(&skb1->users);
-                       skb1 = skb_dequeue(&buffer->skb_list);
-               }
-               retry_ctrl = (struct qeth_skb_data *) &skb->cb[16];
-               if (retry_ctrl->magic != QETH_SKB_MAGIC) {
-                       retry_ctrl->magic = QETH_SKB_MAGIC;
-                       retry_ctrl->count = 0;
-               }
-               if (retry_ctrl->count < QETH_SIGA_CC2_RETRIES) {
-                       retry_ctrl->count++;
-                       rc = dev_queue_xmit(skb);
-               } else {
-                       dev_kfree_skb_any(skb);
-                       QETH_CARD_TEXT(card, 2, "qrdrop");
-               }
-       }
        return 0;
 out:
        atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
index 938d5036016687d06267d3fab991eb841e122e20..b464ae01086cfef7773814c765418f81863e695e 100644 (file)
@@ -270,7 +270,7 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
        if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) {
                sense = (char *) &fcp_rsp[1];
                if (rsp_flags & FCP_RSP_LEN_VAL)
-                       sense += fcp_rsp->ext.fr_sns_len;
+                       sense += fcp_rsp->ext.fr_rsp_len;
                sense_len = min(fcp_rsp->ext.fr_sns_len,
                                (u32) SCSI_SENSE_BUFFERSIZE);
                memcpy(scsi->sense_buffer, sense, sense_len);
index beaf0916ceab73e627c95931aa6186ab3df7dd55..be0317457147fc4a891f4b0be67c8116b98526b1 100644 (file)
@@ -532,9 +532,6 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
                fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
                adapter->hydra_version = 0;
 
-               atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
-                               &adapter->status);
-
                zfcp_fsf_link_down_info_eval(req,
                        &qtcb->header.fsf_status_qual.link_down_info);
                break;
index 1119c535a667318381409eee3626bc2dcb85f1fa..20796ebc33cec3435cb5b2a2de297580e534fb8c 100644 (file)
@@ -142,6 +142,8 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
                return -ENOMEM;
        }
 
+       get_device(&port->dev);
+
        if (device_register(&unit->dev)) {
                put_device(&unit->dev);
                return -ENOMEM;
@@ -152,8 +154,6 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun)
                return -EINVAL;
        }
 
-       get_device(&port->dev);
-
        write_lock_irq(&port->unit_list_lock);
        list_add_tail(&unit->list, &port->unit_list);
        write_unlock_irq(&port->unit_list_lock);
index ceaac65a91ff4f9cae03ea55197c2266948b5d21..ff2bd07161f746a1c3dee089807628b6fe90a840 100644 (file)
@@ -29,13 +29,13 @@ struct bfa_s;
 typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m);
 typedef void    (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
 
-/**
+/*
  * Interrupt message handlers
  */
 void bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m);
 void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func);
 
-/**
+/*
  * Request and response queue related defines
  */
 #define BFA_REQQ_NELEMS_MIN    (4)
@@ -58,9 +58,9 @@ void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func);
 #define bfa_reqq_produce(__bfa, __reqq)        do {                            \
                (__bfa)->iocfc.req_cq_pi[__reqq]++;                     \
                (__bfa)->iocfc.req_cq_pi[__reqq] &=                     \
-                       ((__bfa)->iocfc.cfg.drvcfg.num_reqq_elems - 1);      \
-               bfa_reg_write((__bfa)->iocfc.bfa_regs.cpe_q_pi[__reqq], \
-                             (__bfa)->iocfc.req_cq_pi[__reqq]);      \
+                       ((__bfa)->iocfc.cfg.drvcfg.num_reqq_elems - 1); \
+               writel((__bfa)->iocfc.req_cq_pi[__reqq],                \
+                       (__bfa)->iocfc.bfa_regs.cpe_q_pi[__reqq]);      \
                mmiowb();      \
        } while (0)
 
@@ -76,7 +76,7 @@ void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func);
        (__index) &= ((__size) - 1);                    \
 } while (0)
 
-/**
+/*
  * Queue element to wait for room in request queue. FIFO order is
  * maintained when fullfilling requests.
  */
@@ -86,7 +86,7 @@ struct bfa_reqq_wait_s {
        void            *cbarg;
 };
 
-/**
+/*
  * Circular queue usage assignments
  */
 enum {
@@ -113,7 +113,7 @@ bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg),
 
 #define bfa_reqq(__bfa, __reqq)        (&(__bfa)->reqq_waitq[__reqq])
 
-/**
+/*
  * static inline void
  * bfa_reqq_wait(struct bfa_s *bfa, int reqq, struct bfa_reqq_wait_s *wqe)
  */
@@ -130,7 +130,7 @@ bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg),
 #define bfa_reqq_wcancel(__wqe)        list_del(&(__wqe)->qe)
 
 
-/**
+/*
  * Generic BFA callback element.
  */
 struct bfa_cb_qe_s {
@@ -163,7 +163,7 @@ struct bfa_cb_qe_s {
        } while (0)
 
 
-/**
+/*
  * PCI devices supported by the current BFA
  */
 struct bfa_pciid_s {
@@ -173,7 +173,7 @@ struct bfa_pciid_s {
 
 extern char     bfa_version[];
 
-/**
+/*
  * BFA memory resources
  */
 enum bfa_mem_type {
@@ -202,19 +202,19 @@ struct bfa_meminfo_s {
        ((_m)->meminfo[BFA_MEM_TYPE_DMA - 1].dma_curp)
 
 struct bfa_iocfc_regs_s {
-       bfa_os_addr_t   intr_status;
-       bfa_os_addr_t   intr_mask;
-       bfa_os_addr_t   cpe_q_pi[BFI_IOC_MAX_CQS];
-       bfa_os_addr_t   cpe_q_ci[BFI_IOC_MAX_CQS];
-       bfa_os_addr_t   cpe_q_depth[BFI_IOC_MAX_CQS];
-       bfa_os_addr_t   cpe_q_ctrl[BFI_IOC_MAX_CQS];
-       bfa_os_addr_t   rme_q_ci[BFI_IOC_MAX_CQS];
-       bfa_os_addr_t   rme_q_pi[BFI_IOC_MAX_CQS];
-       bfa_os_addr_t   rme_q_depth[BFI_IOC_MAX_CQS];
-       bfa_os_addr_t   rme_q_ctrl[BFI_IOC_MAX_CQS];
+       void __iomem    *intr_status;
+       void __iomem    *intr_mask;
+       void __iomem    *cpe_q_pi[BFI_IOC_MAX_CQS];
+       void __iomem    *cpe_q_ci[BFI_IOC_MAX_CQS];
+       void __iomem    *cpe_q_depth[BFI_IOC_MAX_CQS];
+       void __iomem    *cpe_q_ctrl[BFI_IOC_MAX_CQS];
+       void __iomem    *rme_q_ci[BFI_IOC_MAX_CQS];
+       void __iomem    *rme_q_pi[BFI_IOC_MAX_CQS];
+       void __iomem    *rme_q_depth[BFI_IOC_MAX_CQS];
+       void __iomem    *rme_q_ctrl[BFI_IOC_MAX_CQS];
 };
 
-/**
+/*
  * MSIX vector handlers
  */
 #define BFA_MSIX_MAX_VECTORS   22
@@ -224,7 +224,7 @@ struct bfa_msix_s {
        bfa_msix_handler_t handler[BFA_MSIX_MAX_VECTORS];
 };
 
-/**
+/*
  * Chip specific interfaces
  */
 struct bfa_hwif_s {
@@ -343,7 +343,7 @@ int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa,
                                struct bfi_pbc_vport_s *pbc_vport);
 
 
-/**
+/*
  *----------------------------------------------------------------------
  *             BFA public interfaces
  *----------------------------------------------------------------------
index a989a94c38da3f43238bbb875d65c22b9dec2629..6f021015f1f67c14fd400b38a2669683db73661b 100644 (file)
@@ -37,18 +37,18 @@ bfad_int_to_lun(u32 luno)
        } lun;
 
        lun.bfa_lun     = 0;
-       lun.scsi_lun[0] = bfa_os_htons(luno);
+       lun.scsi_lun[0] = cpu_to_be16(luno);
 
        return lun.bfa_lun;
 }
 
-/**
+/*
  * Get LUN for the I/O request
  */
 #define bfa_cb_ioim_get_lun(__dio)     \
        bfad_int_to_lun(((struct scsi_cmnd *)__dio)->device->lun)
 
-/**
+/*
  * Get CDB for the I/O request
  */
 static inline u8 *
@@ -59,7 +59,7 @@ bfa_cb_ioim_get_cdb(struct bfad_ioim_s *dio)
        return (u8 *) cmnd->cmnd;
 }
 
-/**
+/*
  * Get I/O direction (read/write) for the I/O request
  */
 static inline enum fcp_iodir
@@ -77,7 +77,7 @@ bfa_cb_ioim_get_iodir(struct bfad_ioim_s *dio)
                return FCP_IODIR_NONE;
 }
 
-/**
+/*
  * Get IO size in bytes for the I/O request
  */
 static inline u32
@@ -88,7 +88,7 @@ bfa_cb_ioim_get_size(struct bfad_ioim_s *dio)
        return scsi_bufflen(cmnd);
 }
 
-/**
+/*
  * Get timeout for the I/O request
  */
 static inline u8
@@ -104,7 +104,7 @@ bfa_cb_ioim_get_timeout(struct bfad_ioim_s *dio)
        return 0;
 }
 
-/**
+/*
  * Get Command Reference Number for the I/O request. 0 if none.
  */
 static inline u8
@@ -113,7 +113,7 @@ bfa_cb_ioim_get_crn(struct bfad_ioim_s *dio)
        return 0;
 }
 
-/**
+/*
  * Get SAM-3 priority for the I/O request. 0 is default.
  */
 static inline u8
@@ -122,7 +122,7 @@ bfa_cb_ioim_get_priority(struct bfad_ioim_s *dio)
        return 0;
 }
 
-/**
+/*
  * Get task attributes for the I/O request. Default is FCP_TASK_ATTR_SIMPLE(0).
  */
 static inline u8
@@ -148,7 +148,7 @@ bfa_cb_ioim_get_taskattr(struct bfad_ioim_s *dio)
        return task_attr;
 }
 
-/**
+/*
  * Get CDB length in bytes for the I/O request. Default is FCP_CMND_CDB_LEN(16).
  */
 static inline u8
@@ -159,7 +159,7 @@ bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio)
        return cmnd->cmd_len;
 }
 
-/**
+/*
  * Assign queue to be used for the I/O request. This value depends on whether
  * the driver wants to use the queues via any specific algorithm. Currently,
  * this is not supported.
index c2fa07f2485dc909bc7910efa925ee8c01bcb877..2345f48dc57fc9a3940665d75b11a3a205f22b16 100644 (file)
 
 BFA_TRC_FILE(HAL, CORE);
 
-/**
+/*
  * BFA IOC FC related definitions
  */
 
-/**
+/*
  * IOC local definitions
  */
 #define BFA_IOCFC_TOV          5000    /* msecs */
@@ -54,7 +54,7 @@ enum {
 #define DEF_CFG_NUM_SBOOT_TGTS         16
 #define DEF_CFG_NUM_SBOOT_LUNS         16
 
-/**
+/*
  * forward declaration for IOC FC functions
  */
 static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status);
@@ -63,7 +63,7 @@ static void bfa_iocfc_hbfail_cbfn(void *bfa_arg);
 static void bfa_iocfc_reset_cbfn(void *bfa_arg);
 static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn;
 
-/**
+/*
  * BFA Interrupt handling functions
  */
 static void
@@ -86,7 +86,7 @@ bfa_reqq_resume(struct bfa_s *bfa, int qid)
 
        waitq = bfa_reqq(bfa, qid);
        list_for_each_safe(qe, qen, waitq) {
-               /**
+               /*
                 * Callback only as long as there is room in request queue
                 */
                if (bfa_reqq_full(bfa, qid))
@@ -104,7 +104,7 @@ bfa_msix_all(struct bfa_s *bfa, int vec)
        bfa_intx(bfa);
 }
 
-/**
+/*
  *  hal_intr_api
  */
 bfa_boolean_t
@@ -113,15 +113,15 @@ bfa_intx(struct bfa_s *bfa)
        u32 intr, qintr;
        int queue;
 
-       intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
+       intr = readl(bfa->iocfc.bfa_regs.intr_status);
        if (!intr)
                return BFA_FALSE;
 
-       /**
+       /*
         * RME completion queue interrupt
         */
        qintr = intr & __HFN_INT_RME_MASK;
-       bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr);
+       writel(qintr, bfa->iocfc.bfa_regs.intr_status);
 
        for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
                if (intr & (__HFN_INT_RME_Q0 << queue))
@@ -131,11 +131,11 @@ bfa_intx(struct bfa_s *bfa)
        if (!intr)
                return BFA_TRUE;
 
-       /**
+       /*
         * CPE completion queue interrupt
         */
        qintr = intr & __HFN_INT_CPE_MASK;
-       bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr);
+       writel(qintr, bfa->iocfc.bfa_regs.intr_status);
 
        for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
                if (intr & (__HFN_INT_CPE_Q0 << queue))
@@ -153,13 +153,13 @@ bfa_intx(struct bfa_s *bfa)
 void
 bfa_intx_enable(struct bfa_s *bfa)
 {
-       bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, bfa->iocfc.intr_mask);
+       writel(bfa->iocfc.intr_mask, bfa->iocfc.bfa_regs.intr_mask);
 }
 
 void
 bfa_intx_disable(struct bfa_s *bfa)
 {
-       bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, -1L);
+       writel(-1L, bfa->iocfc.bfa_regs.intr_mask);
 }
 
 void
@@ -188,8 +188,8 @@ bfa_isr_enable(struct bfa_s *bfa)
                                __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 |
                                __HFN_INT_MBOX_LPU1);
 
-       bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr_unmask);
-       bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, ~intr_unmask);
+       writel(intr_unmask, bfa->iocfc.bfa_regs.intr_status);
+       writel(~intr_unmask, bfa->iocfc.bfa_regs.intr_mask);
        bfa->iocfc.intr_mask = ~intr_unmask;
        bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0);
 }
@@ -198,7 +198,7 @@ void
 bfa_isr_disable(struct bfa_s *bfa)
 {
        bfa_isr_mode_set(bfa, BFA_FALSE);
-       bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, -1L);
+       writel(-1L, bfa->iocfc.bfa_regs.intr_mask);
        bfa_msix_uninstall(bfa);
 }
 
@@ -211,7 +211,7 @@ bfa_msix_reqq(struct bfa_s *bfa, int qid)
 
        bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
 
-       /**
+       /*
         * Resume any pending requests in the corresponding reqq.
         */
        waitq = bfa_reqq(bfa, qid);
@@ -259,14 +259,14 @@ bfa_msix_rspq(struct bfa_s *bfa, int qid)
                }
        }
 
-       /**
+       /*
         * update CI
         */
        bfa_rspq_ci(bfa, qid) = pi;
-       bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi);
+       writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]);
        mmiowb();
 
-       /**
+       /*
         * Resume any pending requests in the corresponding reqq.
         */
        waitq = bfa_reqq(bfa, qid);
@@ -279,7 +279,7 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
 {
        u32 intr, curr_value;
 
-       intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
+       intr = readl(bfa->iocfc.bfa_regs.intr_status);
 
        if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
                bfa_msix_lpu(bfa);
@@ -289,30 +289,30 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
 
        if (intr) {
                if (intr & __HFN_INT_LL_HALT) {
-                       /**
+                       /*
                         * If LL_HALT bit is set then FW Init Halt LL Port
                         * Register needs to be cleared as well so Interrupt
                         * Status Register will be cleared.
                         */
-                       curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt);
+                       curr_value = readl(bfa->ioc.ioc_regs.ll_halt);
                        curr_value &= ~__FW_INIT_HALT_P;
-                       bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value);
+                       writel(curr_value, bfa->ioc.ioc_regs.ll_halt);
                }
 
                if (intr & __HFN_INT_ERR_PSS) {
-                       /**
+                       /*
                         * ERR_PSS bit needs to be cleared as well in case
                         * interrups are shared so driver's interrupt handler is
                         * still called eventhough it is already masked out.
                         */
-                       curr_value = bfa_reg_read(
+                       curr_value = readl(
                                        bfa->ioc.ioc_regs.pss_err_status_reg);
                        curr_value &= __PSS_ERR_STATUS_SET;
-                       bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg,
-                                       curr_value);
+                       writel(curr_value,
+                               bfa->ioc.ioc_regs.pss_err_status_reg);
                }
 
-               bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr);
+               writel(intr, bfa->iocfc.bfa_regs.intr_status);
                bfa_msix_errint(bfa, intr);
        }
 }
@@ -323,11 +323,11 @@ bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func)
        bfa_isrs[mc] = isr_func;
 }
 
-/**
+/*
  * BFA IOC FC related functions
  */
 
-/**
+/*
  *  hal_ioc_pvt BFA IOC private functions
  */
 
@@ -366,7 +366,7 @@ bfa_iocfc_fw_cfg_sz(struct bfa_iocfc_cfg_s *cfg, u32 *dm_len)
                            BFA_CACHELINE_SZ);
 }
 
-/**
+/*
  * Use the Mailbox interface to send BFI_IOCFC_H2I_CFG_REQ
  */
 static void
@@ -384,14 +384,14 @@ bfa_iocfc_send_cfg(void *bfa_arg)
 
        bfa_iocfc_reset_queues(bfa);
 
-       /**
+       /*
         * initialize IOC configuration info
         */
        cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG;
        cfg_info->num_cqs = cfg->fwcfg.num_cqs;
 
        bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa);
-       /**
+       /*
         * dma map REQ and RSP circular queues and shadow pointers
         */
        for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
@@ -400,17 +400,17 @@ bfa_iocfc_send_cfg(void *bfa_arg)
                bfa_dma_be_addr_set(cfg_info->req_shadow_ci[i],
                                    iocfc->req_cq_shadow_ci[i].pa);
                cfg_info->req_cq_elems[i] =
-                       bfa_os_htons(cfg->drvcfg.num_reqq_elems);
+                       cpu_to_be16(cfg->drvcfg.num_reqq_elems);
 
                bfa_dma_be_addr_set(cfg_info->rsp_cq_ba[i],
                                    iocfc->rsp_cq_ba[i].pa);
                bfa_dma_be_addr_set(cfg_info->rsp_shadow_pi[i],
                                    iocfc->rsp_cq_shadow_pi[i].pa);
                cfg_info->rsp_cq_elems[i] =
-                       bfa_os_htons(cfg->drvcfg.num_rspq_elems);
+                       cpu_to_be16(cfg->drvcfg.num_rspq_elems);
        }
 
-       /**
+       /*
         * Enable interrupt coalescing if it is driver init path
         * and not ioc disable/enable path.
         */
@@ -419,7 +419,7 @@ bfa_iocfc_send_cfg(void *bfa_arg)
 
        iocfc->cfgdone = BFA_FALSE;
 
-       /**
+       /*
         * dma map IOC configuration itself
         */
        bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ,
@@ -440,9 +440,9 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        iocfc->bfa = bfa;
        iocfc->action = BFA_IOCFC_ACT_NONE;
 
-       bfa_os_assign(iocfc->cfg, *cfg);
+       iocfc->cfg = *cfg;
 
-       /**
+       /*
         * Initialize chip specific handlers.
         */
        if (bfa_asic_id_ct(bfa_ioc_devid(&bfa->ioc))) {
@@ -503,13 +503,13 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
        for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
                iocfc->req_cq_ba[i].kva = dm_kva;
                iocfc->req_cq_ba[i].pa = dm_pa;
-               bfa_os_memset(dm_kva, 0, per_reqq_sz);
+               memset(dm_kva, 0, per_reqq_sz);
                dm_kva += per_reqq_sz;
                dm_pa += per_reqq_sz;
 
                iocfc->rsp_cq_ba[i].kva = dm_kva;
                iocfc->rsp_cq_ba[i].pa = dm_pa;
-               bfa_os_memset(dm_kva, 0, per_rspq_sz);
+               memset(dm_kva, 0, per_rspq_sz);
                dm_kva += per_rspq_sz;
                dm_pa += per_rspq_sz;
        }
@@ -559,7 +559,7 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
        }
 }
 
-/**
+/*
  * Start BFA submodules.
  */
 static void
@@ -573,7 +573,7 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)
                hal_mods[i]->start(bfa);
 }
 
-/**
+/*
  * Disable BFA submodules.
  */
 static void
@@ -623,7 +623,7 @@ bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl)
                complete(&bfad->disable_comp);
 }
 
-/**
+/*
  * Update BFA configuration from firmware configuration.
  */
 static void
@@ -634,15 +634,15 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
        struct bfa_iocfc_fwcfg_s        *fwcfg   = &cfgrsp->fwcfg;
 
        fwcfg->num_cqs        = fwcfg->num_cqs;
-       fwcfg->num_ioim_reqs  = bfa_os_ntohs(fwcfg->num_ioim_reqs);
-       fwcfg->num_tskim_reqs = bfa_os_ntohs(fwcfg->num_tskim_reqs);
-       fwcfg->num_fcxp_reqs  = bfa_os_ntohs(fwcfg->num_fcxp_reqs);
-       fwcfg->num_uf_bufs    = bfa_os_ntohs(fwcfg->num_uf_bufs);
-       fwcfg->num_rports     = bfa_os_ntohs(fwcfg->num_rports);
+       fwcfg->num_ioim_reqs  = be16_to_cpu(fwcfg->num_ioim_reqs);
+       fwcfg->num_tskim_reqs = be16_to_cpu(fwcfg->num_tskim_reqs);
+       fwcfg->num_fcxp_reqs  = be16_to_cpu(fwcfg->num_fcxp_reqs);
+       fwcfg->num_uf_bufs    = be16_to_cpu(fwcfg->num_uf_bufs);
+       fwcfg->num_rports     = be16_to_cpu(fwcfg->num_rports);
 
        iocfc->cfgdone = BFA_TRUE;
 
-       /**
+       /*
         * Configuration is complete - initialize/start submodules
         */
        bfa_fcport_init(bfa);
@@ -665,7 +665,7 @@ bfa_iocfc_reset_queues(struct bfa_s *bfa)
        }
 }
 
-/**
+/*
  * IOC enable request is complete
  */
 static void
@@ -684,7 +684,7 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
        bfa_iocfc_send_cfg(bfa);
 }
 
-/**
+/*
  * IOC disable request is complete
  */
 static void
@@ -705,7 +705,7 @@ bfa_iocfc_disable_cbfn(void *bfa_arg)
        }
 }
 
-/**
+/*
  * Notify sub-modules of hardware failure.
  */
 static void
@@ -723,7 +723,7 @@ bfa_iocfc_hbfail_cbfn(void *bfa_arg)
                             bfa);
 }
 
-/**
+/*
  * Actions on chip-reset completion.
  */
 static void
@@ -735,11 +735,11 @@ bfa_iocfc_reset_cbfn(void *bfa_arg)
        bfa_isr_enable(bfa);
 }
 
-/**
+/*
  *  hal_ioc_public
  */
 
-/**
+/*
  * Query IOC memory requirement information.
  */
 void
@@ -754,7 +754,7 @@ bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
        *km_len += bfa_ioc_debug_trcsz(bfa_auto_recover);
 }
 
-/**
+/*
  * Query IOC memory requirement information.
  */
 void
@@ -772,7 +772,7 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        ioc->trcmod = bfa->trcmod;
        bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod);
 
-       /**
+       /*
         * Set FC mode for BFA_PCI_DEVICE_ID_CT_FC.
         */
        if (pcidev->device_id == BFA_PCI_DEVICE_ID_CT_FC)
@@ -790,7 +790,7 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
                INIT_LIST_HEAD(&bfa->reqq_waitq[i]);
 }
 
-/**
+/*
  * Query IOC memory requirement information.
  */
 void
@@ -799,7 +799,7 @@ bfa_iocfc_detach(struct bfa_s *bfa)
        bfa_ioc_detach(&bfa->ioc);
 }
 
-/**
+/*
  * Query IOC memory requirement information.
  */
 void
@@ -809,7 +809,7 @@ bfa_iocfc_init(struct bfa_s *bfa)
        bfa_ioc_enable(&bfa->ioc);
 }
 
-/**
+/*
  * IOC start called from bfa_start(). Called to start IOC operations
  * at driver instantiation for this instance.
  */
@@ -820,7 +820,7 @@ bfa_iocfc_start(struct bfa_s *bfa)
                bfa_iocfc_start_submod(bfa);
 }
 
-/**
+/*
  * IOC stop called from bfa_stop(). Called only when driver is unloaded
  * for this instance.
  */
@@ -876,12 +876,12 @@ bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)
        attr->intr_attr.coalesce = iocfc->cfginfo->intr_attr.coalesce;
 
        attr->intr_attr.delay = iocfc->cfginfo->intr_attr.delay ?
-                               bfa_os_ntohs(iocfc->cfginfo->intr_attr.delay) :
-                               bfa_os_ntohs(iocfc->cfgrsp->intr_attr.delay);
+                               be16_to_cpu(iocfc->cfginfo->intr_attr.delay) :
+                               be16_to_cpu(iocfc->cfgrsp->intr_attr.delay);
 
        attr->intr_attr.latency = iocfc->cfginfo->intr_attr.latency ?
-                       bfa_os_ntohs(iocfc->cfginfo->intr_attr.latency) :
-                       bfa_os_ntohs(iocfc->cfgrsp->intr_attr.latency);
+                       be16_to_cpu(iocfc->cfginfo->intr_attr.latency) :
+                       be16_to_cpu(iocfc->cfgrsp->intr_attr.latency);
 
        attr->config    = iocfc->cfg;
 }
@@ -893,8 +893,8 @@ bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
        struct bfi_iocfc_set_intr_req_s *m;
 
        iocfc->cfginfo->intr_attr.coalesce = attr->coalesce;
-       iocfc->cfginfo->intr_attr.delay = bfa_os_htons(attr->delay);
-       iocfc->cfginfo->intr_attr.latency = bfa_os_htons(attr->latency);
+       iocfc->cfginfo->intr_attr.delay = cpu_to_be16(attr->delay);
+       iocfc->cfginfo->intr_attr.latency = cpu_to_be16(attr->latency);
 
        if (!bfa_iocfc_is_operational(bfa))
                return BFA_STATUS_OK;
@@ -924,7 +924,7 @@ bfa_iocfc_set_snsbase(struct bfa_s *bfa, u64 snsbase_pa)
        iocfc->cfginfo->sense_buf_len = (BFI_IOIM_SNSLEN - 1);
        bfa_dma_be_addr_set(iocfc->cfginfo->ioim_snsbase, snsbase_pa);
 }
-/**
+/*
  * Enable IOC after it is disabled.
  */
 void
@@ -953,7 +953,7 @@ bfa_iocfc_is_operational(struct bfa_s *bfa)
        return bfa_ioc_is_operational(&bfa->ioc) && bfa->iocfc.cfgdone;
 }
 
-/**
+/*
  * Return boot target port wwns -- read from boot information in flash.
  */
 void
@@ -998,11 +998,11 @@ bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
        return cfgrsp->pbc_cfg.nvports;
 }
 
-/**
+/*
  *  hal_api
  */
 
-/**
+/*
  * Use this function query the memory requirement of the BFA library.
  * This function needs to be called before bfa_attach() to get the
  * memory required of the BFA layer for a given driver configuration.
@@ -1038,7 +1038,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo)
 
        bfa_assert((cfg != NULL) && (meminfo != NULL));
 
-       bfa_os_memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
+       memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
        meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type =
                BFA_MEM_TYPE_KVA;
        meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type =
@@ -1055,7 +1055,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo)
        meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len;
 }
 
-/**
+/*
  * Use this function to do attach the driver instance with the BFA
  * library. This function will not trigger any HW initialization
  * process (which will be done in bfa_init() call)
@@ -1092,7 +1092,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 
        bfa_assert((cfg != NULL) && (meminfo != NULL));
 
-       /**
+       /*
         * initialize all memory pointers for iterative allocation
         */
        for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
@@ -1109,7 +1109,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        bfa_com_port_attach(bfa, meminfo);
 }
 
-/**
+/*
  * Use this function to delete a BFA IOC. IOC should be stopped (by
  * calling bfa_stop()) before this function call.
  *
@@ -1146,7 +1146,7 @@ bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog)
        bfa->plog = plog;
 }
 
-/**
+/*
  * Initialize IOC.
  *
  * This function will return immediately, when the IOC initialization is
@@ -1169,7 +1169,7 @@ bfa_init(struct bfa_s *bfa)
        bfa_iocfc_init(bfa);
 }
 
-/**
+/*
  * Use this function initiate the IOC configuration setup. This function
  * will return immediately.
  *
@@ -1183,7 +1183,7 @@ bfa_start(struct bfa_s *bfa)
        bfa_iocfc_start(bfa);
 }
 
-/**
+/*
  * Use this function quiese the IOC. This function will return immediately,
  * when the IOC is actually stopped, the bfad->comp will be set.
  *
@@ -1243,7 +1243,7 @@ bfa_attach_fcs(struct bfa_s *bfa)
        bfa->fcs = BFA_TRUE;
 }
 
-/**
+/*
  * Periodic timer heart beat from driver
  */
 void
@@ -1252,7 +1252,7 @@ bfa_timer_tick(struct bfa_s *bfa)
        bfa_timer_beat(&bfa->timer_mod);
 }
 
-/**
+/*
  * Return the list of PCI vendor/device id lists supported by this
  * BFA instance.
  */
@@ -1270,7 +1270,7 @@ bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
        *pciids = __pciids;
 }
 
-/**
+/*
  * Use this function query the default struct bfa_iocfc_cfg_s value (compiled
  * into BFA layer). The OS driver can then turn back and overwrite entries that
  * have been configured by the user.
@@ -1328,7 +1328,7 @@ bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr)
        bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
 }
 
-/**
+/*
  * Retrieve firmware trace information on IOC failure.
  */
 bfa_status_t
@@ -1337,7 +1337,7 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
        return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen);
 }
 
-/**
+/*
  * Clear the saved firmware trace information of an IOC.
  */
 void
@@ -1346,7 +1346,7 @@ bfa_debug_fwsave_clear(struct bfa_s *bfa)
        bfa_ioc_debug_fwsave_clear(&bfa->ioc);
 }
 
-/**
+/*
  * Fetch firmware trace data.
  *
  * @param[in]          bfa                     BFA instance
@@ -1362,7 +1362,7 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
        return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
 }
 
-/**
+/*
  * Dump firmware memory.
  *
  * @param[in]          bfa             BFA instance
@@ -1378,7 +1378,7 @@ bfa_debug_fwcore(struct bfa_s *bfa, void *buf, u32 *offset, int *buflen)
 {
        return bfa_ioc_debug_fwcore(&bfa->ioc, buf, offset, buflen);
 }
-/**
+/*
  * Reset hw semaphore & usage cnt regs and initialize.
  */
 void
@@ -1388,7 +1388,7 @@ bfa_chip_reset(struct bfa_s *bfa)
        bfa_ioc_pll_init(&bfa->ioc);
 }
 
-/**
+/*
  * Fetch firmware statistics data.
  *
  * @param[in]          bfa             BFA instance
index 7260c74620f8fa5f2fd4cbe0060d1e87a326d6b4..99f242b9aa3110216fb93915338a86d8c22f7955 100644 (file)
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 
-/**
+/*
  *  bfa_cs.h BFA common services
  */
 
@@ -24,7 +24,7 @@
 
 #include "bfa_os_inc.h"
 
-/**
+/*
  * BFA TRC
  */
 
@@ -73,7 +73,7 @@ enum {
 #define BFA_TRC_MOD_SH 10
 #define BFA_TRC_MOD(__mod)     ((BFA_TRC_ ## __mod) << BFA_TRC_MOD_SH)
 
-/**
+/*
  * Define a new tracing file (module). Module should match one defined above.
  */
 #define BFA_TRC_FILE(__mod, __submod)                                  \
@@ -155,7 +155,7 @@ __bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
 #define bfa_trc_fp(_trcp, _data)
 #endif
 
-/**
+/*
  * @ BFA LOG interfaces
  */
 #define bfa_assert(__cond)     do {                                    \
@@ -249,13 +249,13 @@ bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe)
 #define bfa_q_is_on_q(_q, _qe)      \
        bfa_q_is_on_q_func(_q, (struct list_head *)(_qe))
 
-/**
+/*
  * @ BFA state machine interfaces
  */
 
 typedef void (*bfa_sm_t)(void *sm, int event);
 
-/**
+/*
  * oc - object class eg. bfa_ioc
  * st - state, eg. reset
  * otype - object type, eg. struct bfa_ioc_s
@@ -269,7 +269,7 @@ typedef void (*bfa_sm_t)(void *sm, int event);
 #define bfa_sm_get_state(_sm)          ((_sm)->sm)
 #define bfa_sm_cmp_state(_sm, _state)  ((_sm)->sm == (bfa_sm_t)(_state))
 
-/**
+/*
  * For converting from state machine function to state encoding.
  */
 struct bfa_sm_table_s {
@@ -279,12 +279,12 @@ struct bfa_sm_table_s {
 };
 #define BFA_SM(_sm)    ((bfa_sm_t)(_sm))
 
-/**
+/*
  * State machine with entry actions.
  */
 typedef void (*bfa_fsm_t)(void *fsm, int event);
 
-/**
+/*
  * oc - object class eg. bfa_ioc
  * st - state, eg. reset
  * otype - object type, eg. struct bfa_ioc_s
@@ -314,7 +314,7 @@ bfa_sm_to_state(struct bfa_sm_table_s *smt, bfa_sm_t sm)
        return smt[i].state;
 }
 
-/**
+/*
  * @ Generic wait counter.
  */
 
@@ -340,7 +340,7 @@ bfa_wc_down(struct bfa_wc_s *wc)
                wc->wc_resume(wc->wc_cbarg);
 }
 
-/**
+/*
  * Initialize a waiting counter.
  */
 static inline void
@@ -352,7 +352,7 @@ bfa_wc_init(struct bfa_wc_s *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg)
        bfa_wc_up(wc);
 }
 
-/**
+/*
  * Wait for counter to reach zero
  */
 static inline void
index d49877ff5140a6856620a8d45831f4104d806d57..4b5b9e35abb9889e72824d01f5ddf361817fc7dd 100644 (file)
@@ -24,7 +24,7 @@
 #define BFA_MFG_SERIALNUM_SIZE                  11
 #define STRSZ(_n)                               (((_n) + 4) & ~3)
 
-/**
+/*
  * Manufacturing card type
  */
 enum {
@@ -45,7 +45,7 @@ enum {
 
 #pragma pack(1)
 
-/**
+/*
  * Check if Mezz card
  */
 #define bfa_mfg_is_mezz(type) (( \
@@ -55,7 +55,7 @@ enum {
        (type) == BFA_MFG_TYPE_LIGHTNING_P0 || \
        (type) == BFA_MFG_TYPE_LIGHTNING))
 
-/**
+/*
  * Check if the card having old wwn/mac handling
  */
 #define bfa_mfg_is_old_wwn_mac_model(type) (( \
@@ -78,12 +78,12 @@ do {                                                            \
        (m)[2] = t & 0xFF;                                      \
 } while (0)
 
-/**
+/*
  * VPD data length
  */
 #define BFA_MFG_VPD_LEN                 512
 
-/**
+/*
  * VPD vendor tag
  */
 enum {
@@ -97,7 +97,7 @@ enum {
        BFA_MFG_VPD_PCI_BRCD    = 0xf8,  /*  PCI VPD Brocade            */
 };
 
-/**
+/*
  * All numerical fields are in big-endian format.
  */
 struct bfa_mfg_vpd_s {
@@ -112,7 +112,7 @@ struct bfa_mfg_vpd_s {
 
 #pragma pack()
 
-/**
+/*
  * Status return values
  */
 enum bfa_status {
@@ -167,11 +167,11 @@ enum bfa_boolean {
 #define BFA_STRING_32  32
 #define BFA_VERSION_LEN 64
 
-/**
+/*
  * ---------------------- adapter definitions ------------
  */
 
-/**
+/*
  * BFA adapter level attributes.
  */
 enum {
@@ -215,7 +215,7 @@ struct bfa_adapter_attr_s {
        u8              trunk_capable;
 };
 
-/**
+/*
  * ---------------------- IOC definitions ------------
  */
 
@@ -224,7 +224,7 @@ enum {
        BFA_IOC_CHIP_REV_LEN    = 8,
 };
 
-/**
+/*
  * Driver and firmware versions.
  */
 struct bfa_ioc_driver_attr_s {
@@ -236,7 +236,7 @@ struct bfa_ioc_driver_attr_s {
        char            ob_ver[BFA_VERSION_LEN];        /*  openboot version */
 };
 
-/**
+/*
  * IOC PCI device attributes
  */
 struct bfa_ioc_pci_attr_s {
@@ -249,7 +249,7 @@ struct bfa_ioc_pci_attr_s {
        char            chip_rev[BFA_IOC_CHIP_REV_LEN];  /*  chip revision */
 };
 
-/**
+/*
  * IOC states
  */
 enum bfa_ioc_state {
@@ -267,7 +267,7 @@ enum bfa_ioc_state {
        BFA_IOC_ENABLING        = 12,   /*  IOC is being enabled */
 };
 
-/**
+/*
  * IOC firmware stats
  */
 struct bfa_fw_ioc_stats_s {
@@ -279,7 +279,7 @@ struct bfa_fw_ioc_stats_s {
        u32     unknown_reqs;
 };
 
-/**
+/*
  * IOC driver stats
  */
 struct bfa_ioc_drv_stats_s {
@@ -296,7 +296,7 @@ struct bfa_ioc_drv_stats_s {
        u32     enable_replies;
 };
 
-/**
+/*
  * IOC statistics
  */
 struct bfa_ioc_stats_s {
@@ -310,7 +310,7 @@ enum bfa_ioc_type_e {
        BFA_IOC_TYPE_LL         = 3,
 };
 
-/**
+/*
  * IOC attributes returned in queries
  */
 struct bfa_ioc_attr_s {
@@ -323,11 +323,11 @@ struct bfa_ioc_attr_s {
        u8                              rsvd[7];        /*  64bit align    */
 };
 
-/**
+/*
  * ---------------------- mfg definitions ------------
  */
 
-/**
+/*
  * Checksum size
  */
 #define BFA_MFG_CHKSUM_SIZE                    16
@@ -340,7 +340,7 @@ struct bfa_ioc_attr_s {
 
 #pragma pack(1)
 
-/**
+/*
  * All numerical fields are in big-endian format.
  */
 struct bfa_mfg_block_s {
@@ -373,11 +373,11 @@ struct bfa_mfg_block_s {
 
 #pragma pack()
 
-/**
+/*
  * ---------------------- pci definitions ------------
  */
 
-/**
+/*
  * PCI device and vendor ID information
  */
 enum {
@@ -392,14 +392,14 @@ enum {
        ((devid) == BFA_PCI_DEVICE_ID_CT ||     \
         (devid) == BFA_PCI_DEVICE_ID_CT_FC)
 
-/**
+/*
  * PCI sub-system device and vendor ID information
  */
 enum {
        BFA_PCI_FCOE_SSDEVICE_ID        = 0x14,
 };
 
-/**
+/*
  * Maximum number of device address ranges mapped through different BAR(s)
  */
 #define BFA_PCI_ACCESS_RANGES 1
@@ -430,7 +430,7 @@ enum {
 #define BOOT_CFG_REV1   1
 #define BOOT_CFG_VLAN   1
 
-/**
+/*
  *      Boot options setting. Boot options setting determines from where
  *      to get the boot lun information
  */
@@ -442,7 +442,7 @@ enum bfa_boot_bootopt {
 };
 
 #pragma pack(1)
-/**
+/*
  * Boot lun information.
  */
 struct bfa_boot_bootlun_s {
@@ -451,7 +451,7 @@ struct bfa_boot_bootlun_s {
 };
 #pragma pack()
 
-/**
+/*
  * BOOT boot configuraton
  */
 struct bfa_boot_pbc_s {
index 96905d301828f90b3060752661e5d247c54fa18a..191d34a58b9cf15e5167b419832fc287b0201779 100644 (file)
@@ -21,7 +21,7 @@
 #include "bfa_fc.h"
 #include "bfa_defs_svc.h"
 
-/**
+/*
  * VF states
  */
 enum bfa_vf_state {
@@ -35,7 +35,7 @@ enum bfa_vf_state {
        BFA_VF_ISOLATED  = 7,   /*  port isolated due to vf_id mismatch */
 };
 
-/**
+/*
  * VF statistics
  */
 struct bfa_vf_stats_s {
@@ -55,7 +55,7 @@ struct bfa_vf_stats_s {
        u32     resvd; /*  padding for 64 bit alignment */
 };
 
-/**
+/*
  * VF attributes returned in queries
  */
 struct bfa_vf_attr_s {
@@ -67,7 +67,7 @@ struct bfa_vf_attr_s {
 #define BFA_FCS_MAX_LPORTS 256
 #define BFA_FCS_FABRIC_IPADDR_SZ  16
 
-/**
+/*
  * symbolic names for base port/virtual port
  */
 #define BFA_SYMNAME_MAXLEN     128     /* 128 bytes */
@@ -75,7 +75,7 @@ struct bfa_lport_symname_s {
        char        symname[BFA_SYMNAME_MAXLEN];
 };
 
-/**
+/*
 * Roles of FCS port:
  *     - FCP IM and FCP TM roles cannot be enabled together for a FCS port
  *     - Create multiple ports if both IM and TM functions required.
@@ -86,19 +86,19 @@ enum bfa_lport_role {
        BFA_LPORT_ROLE_FCP_MAX  = BFA_LPORT_ROLE_FCP_IM,
 };
 
-/**
+/*
  * FCS port configuration.
  */
 struct bfa_lport_cfg_s {
     wwn_t             pwwn;       /*  port wwn */
     wwn_t             nwwn;       /*  node wwn */
     struct bfa_lport_symname_s  sym_name;   /*  vm port symbolic name */
-       bfa_boolean_t       preboot_vp;  /*  vport created from PBC */
+    bfa_boolean_t       preboot_vp;  /*  vport created from PBC */
     enum bfa_lport_role     roles;      /*  FCS port roles */
     u8      tag[16];   /*  opaque tag from application */
 };
 
-/**
+/*
  * FCS port states
  */
 enum bfa_lport_state {
@@ -108,7 +108,7 @@ enum bfa_lport_state {
        BFA_LPORT_OFFLINE = 3,  /*  No login to fabric */
 };
 
-/**
+/*
  * FCS port type.
  */
 enum bfa_lport_type {
@@ -116,7 +116,7 @@ enum bfa_lport_type {
        BFA_LPORT_TYPE_VIRTUAL,
 };
 
-/**
+/*
  * FCS port offline reason.
  */
 enum bfa_lport_offline_reason {
@@ -128,7 +128,7 @@ enum bfa_lport_offline_reason {
        BFA_LPORT_OFFLINE_FAB_LOGOUT,
 };
 
-/**
+/*
  * FCS lport info.
  */
 struct bfa_lport_info_s {
@@ -150,7 +150,7 @@ struct bfa_lport_info_s {
 
 };
 
-/**
+/*
  * FCS port statistics
  */
 struct bfa_lport_stats_s {
@@ -222,7 +222,7 @@ struct bfa_lport_stats_s {
                                            * (max retry of plogi) */
 };
 
-/**
+/*
  * BFA port attribute returned in queries
  */
 struct bfa_lport_attr_s {
@@ -239,7 +239,7 @@ struct bfa_lport_attr_s {
 };
 
 
-/**
+/*
  * VPORT states
  */
 enum bfa_vport_state {
@@ -258,7 +258,7 @@ enum bfa_vport_state {
        BFA_FCS_VPORT_MAX_STATE,
 };
 
-/**
+/*
  * vport statistics
  */
 struct bfa_vport_stats_s {
@@ -296,7 +296,7 @@ struct bfa_vport_stats_s {
        u32        rsvd;
 };
 
-/**
+/*
  * BFA vport attribute returned in queries
  */
 struct bfa_vport_attr_s {
@@ -305,7 +305,7 @@ struct bfa_vport_attr_s {
        u32          rsvd;
 };
 
-/**
+/*
  * FCS remote port states
  */
 enum bfa_rport_state {
@@ -321,7 +321,7 @@ enum bfa_rport_state {
        BFA_RPORT_NSDISC        = 9,    /*  re-discover rport */
 };
 
-/**
+/*
  *  Rport Scsi Function : Initiator/Target.
  */
 enum bfa_rport_function {
@@ -329,7 +329,7 @@ enum bfa_rport_function {
        BFA_RPORT_TARGET        = 0x02, /*  SCSI Target */
 };
 
-/**
+/*
  * port/node symbolic names for rport
  */
 #define BFA_RPORT_SYMNAME_MAXLEN       255
@@ -337,7 +337,7 @@ struct bfa_rport_symname_s {
        char            symname[BFA_RPORT_SYMNAME_MAXLEN];
 };
 
-/**
+/*
  * FCS remote port statistics
  */
 struct bfa_rport_stats_s {
@@ -374,7 +374,7 @@ struct bfa_rport_stats_s {
        struct bfa_rport_hal_stats_s    hal_stats;  /*  BFA rport stats    */
 };
 
-/**
+/*
  * FCS remote port attributes returned in queries
  */
 struct bfa_rport_attr_s {
@@ -411,7 +411,7 @@ struct bfa_rport_remote_link_stats_s {
 #define BFA_MAX_IO_INDEX 7
 #define BFA_NO_IO_INDEX 9
 
-/**
+/*
  * FCS itnim states
  */
 enum bfa_itnim_state {
@@ -425,7 +425,7 @@ enum bfa_itnim_state {
        BFA_ITNIM_INITIATIOR    = 7,    /*  initiator */
 };
 
-/**
+/*
  * FCS remote port statistics
  */
 struct bfa_itnim_stats_s {
@@ -443,7 +443,7 @@ struct bfa_itnim_stats_s {
        u32     rsvd;           /* padding for 64 bit alignment */
 };
 
-/**
+/*
  * FCS itnim attributes returned in queries
  */
 struct bfa_itnim_attr_s {
index 56226fcf9470e167b71eb3f9cc5b8136d8bfb6db..e24e9f7ca81ff0b68f0b6ea2383f374a73d47165 100644 (file)
@@ -27,7 +27,7 @@
 #define BFA_IOCFCOE_INTR_DELAY 25
 #define BFA_IOCFCOE_INTR_LATENCY 5
 
-/**
+/*
  * Interrupt coalescing configuration.
  */
 #pragma pack(1)
@@ -38,7 +38,7 @@ struct bfa_iocfc_intr_attr_s {
        u16     delay;          /*  delay in microseconds     */
 };
 
-/**
+/*
  * IOC firmware configuraton
  */
 struct bfa_iocfc_fwcfg_s {
@@ -71,7 +71,7 @@ struct bfa_iocfc_drvcfg_s {
        u32             rsvd;
 };
 
-/**
+/*
  * IOC configuration
  */
 struct bfa_iocfc_cfg_s {
@@ -79,7 +79,7 @@ struct bfa_iocfc_cfg_s {
        struct bfa_iocfc_drvcfg_s       drvcfg; /*  driver side config    */
 };
 
-/**
+/*
  * IOC firmware IO stats
  */
 struct bfa_fw_io_stats_s {
@@ -152,7 +152,7 @@ struct bfa_fw_io_stats_s {
                                                 */
 };
 
-/**
+/*
  * IOC port firmware stats
  */
 
@@ -262,7 +262,7 @@ struct bfa_fw_fcoe_stats_s {
     u32    mac_invalids;       /*  Invalid mac assigned                */
 };
 
-/**
+/*
  * IOC firmware FCoE port stats
  */
 struct bfa_fw_fcoe_port_stats_s {
@@ -270,7 +270,7 @@ struct bfa_fw_fcoe_port_stats_s {
     struct bfa_fw_fip_stats_s   fip_stats;
 };
 
-/**
+/*
  * IOC firmware FC uport stats
  */
 struct bfa_fw_fc_uport_stats_s {
@@ -278,7 +278,7 @@ struct bfa_fw_fc_uport_stats_s {
        struct bfa_fw_port_lksm_stats_s         lksm_stats;
 };
 
-/**
+/*
  * IOC firmware FC port stats
  */
 union bfa_fw_fc_port_stats_s {
@@ -286,7 +286,7 @@ union bfa_fw_fc_port_stats_s {
        struct bfa_fw_fcoe_port_stats_s fcoe_stats;
 };
 
-/**
+/*
  * IOC firmware port stats
  */
 struct bfa_fw_port_stats_s {
@@ -295,7 +295,7 @@ struct bfa_fw_port_stats_s {
        union  bfa_fw_fc_port_stats_s           fc_port;
 };
 
-/**
+/*
  * fcxchg module statistics
  */
 struct bfa_fw_fcxchg_stats_s {
@@ -308,7 +308,7 @@ struct bfa_fw_lpsm_stats_s {
        u32     cls_tx;
 };
 
-/**
+/*
  *  Trunk statistics
  */
 struct bfa_fw_trunk_stats_s {
@@ -334,7 +334,7 @@ struct bfa_fw_advsm_stats_s {
        u32 elp_dropped;                /*  ELP dropped         */
 };
 
-/**
+/*
  * IOCFC firmware stats
  */
 struct bfa_fw_iocfc_stats_s {
@@ -345,7 +345,7 @@ struct bfa_fw_iocfc_stats_s {
        u32     set_intr_reqs;  /*  set interrupt reqs */
 };
 
-/**
+/*
  * IOC attributes returned in queries
  */
 struct bfa_iocfc_attr_s {
@@ -353,7 +353,7 @@ struct bfa_iocfc_attr_s {
        struct bfa_iocfc_intr_attr_s    intr_attr;      /*  interrupt attr */
 };
 
-/**
+/*
  * Eth_sndrcv mod stats
  */
 struct bfa_fw_eth_sndrcv_stats_s {
@@ -361,7 +361,7 @@ struct bfa_fw_eth_sndrcv_stats_s {
        u32     rsvd;           /*  64bit align    */
 };
 
-/**
+/*
  * CT MAC mod stats
  */
 struct bfa_fw_mac_mod_stats_s {
@@ -379,7 +379,7 @@ struct bfa_fw_mac_mod_stats_s {
        u32     rsvd;           /*  64bit align    */
 };
 
-/**
+/*
  * CT MOD stats
  */
 struct bfa_fw_ct_mod_stats_s {
@@ -391,7 +391,7 @@ struct bfa_fw_ct_mod_stats_s {
        u32     rsvd;           /*  64bit align    */
 };
 
-/**
+/*
  * IOC firmware stats
  */
 struct bfa_fw_stats_s {
@@ -412,7 +412,7 @@ struct bfa_fw_stats_s {
 #define BFA_IOCFC_PATHTOV_MAX  60
 #define BFA_IOCFC_QDEPTH_MAX   2000
 
-/**
+/*
  * QoS states
  */
 enum bfa_qos_state {
@@ -420,7 +420,7 @@ enum bfa_qos_state {
        BFA_QOS_OFFLINE = 2,            /*  QoS is offline */
 };
 
-/**
+/*
  * QoS  Priority levels.
  */
 enum bfa_qos_priority {
@@ -430,7 +430,7 @@ enum bfa_qos_priority {
        BFA_QOS_LOW  =  3,      /*  QoS Priority Level Low */
 };
 
-/**
+/*
  * QoS  bandwidth allocation for each priority level
  */
 enum bfa_qos_bw_alloc {
@@ -439,7 +439,7 @@ enum bfa_qos_bw_alloc {
        BFA_QOS_BW_LOW  =  10,  /*  bandwidth allocation for Low */
 };
 #pragma pack(1)
-/**
+/*
  * QoS attribute returned in QoS Query
  */
 struct bfa_qos_attr_s {
@@ -448,7 +448,7 @@ struct bfa_qos_attr_s {
        u32  total_bb_cr;               /*  Total BB Credits */
 };
 
-/**
+/*
  * These fields should be displayed only from the CLI.
  * There will be a separate BFAL API (get_qos_vc_attr ?)
  * to retrieve this.
@@ -471,7 +471,7 @@ struct bfa_qos_vc_attr_s {
                                                            * total_vc_count */
 };
 
-/**
+/*
  * QoS statistics
  */
 struct bfa_qos_stats_s {
@@ -489,7 +489,7 @@ struct bfa_qos_stats_s {
        u32     rsvd;               /* padding for 64 bit alignment */
 };
 
-/**
+/*
  * FCoE statistics
  */
 struct bfa_fcoe_stats_s {
@@ -540,7 +540,7 @@ struct bfa_fcoe_stats_s {
        u64     rxf_bcast_vlan; /*  Rx FCoE broadcast vlan frames   */
 };
 
-/**
+/*
  * QoS or FCoE stats (fcport stats excluding physical FC port stats)
  */
 union bfa_fcport_stats_u {
@@ -639,7 +639,7 @@ enum bfa_port_states {
        BFA_PORT_ST_MAX_STATE,
 };
 
-/**
+/*
  *     Port operational type (in sync with SNIA port type).
  */
 enum bfa_port_type {
@@ -651,7 +651,7 @@ enum bfa_port_type {
        BFA_PORT_TYPE_VPORT     = 22,   /*  NPIV - virtual port */
 };
 
-/**
+/*
  *     Port topology setting. A port's topology and fabric login status
  *     determine its operational type.
  */
@@ -662,7 +662,7 @@ enum bfa_port_topology {
        BFA_PORT_TOPOLOGY_AUTO = 3,     /*  auto topology selection */
 };
 
-/**
+/*
  *     Physical port loopback types.
  */
 enum bfa_port_opmode {
@@ -679,7 +679,7 @@ enum bfa_port_opmode {
        (_mode == BFA_PORT_OPMODE_LB_SLW) ||            \
        (_mode == BFA_PORT_OPMODE_LB_EXT))
 
-/**
+/*
  *     Port link state
  */
 enum bfa_port_linkstate {
@@ -687,7 +687,7 @@ enum bfa_port_linkstate {
        BFA_PORT_LINKDOWN       = 2,    /*  Physical port/Trunk link down */
 };
 
-/**
+/*
  *     Port link state reason code
  */
 enum bfa_port_linkstate_rsn {
@@ -733,7 +733,7 @@ enum bfa_port_linkstate_rsn {
        CEE_ISCSI_PRI_OVERLAP_FCOE_PRI          = 43
 };
 #pragma pack(1)
-/**
+/*
  *      Physical port configuration
  */
 struct bfa_port_cfg_s {
@@ -753,7 +753,7 @@ struct bfa_port_cfg_s {
 };
 #pragma pack()
 
-/**
+/*
  *     Port attribute values.
  */
 struct bfa_port_attr_s {
@@ -800,7 +800,7 @@ struct bfa_port_attr_s {
        u8                      rsvd1[6];
 };
 
-/**
+/*
  *           Port FCP mappings.
  */
 struct bfa_port_fcpmap_s {
@@ -815,7 +815,7 @@ struct bfa_port_fcpmap_s {
        char            luid[256];
 };
 
-/**
+/*
  *           Port RNID info.
  */
 struct bfa_port_rnid_s {
@@ -848,7 +848,7 @@ struct bfa_fcport_fcf_s {
        mac_t      mac;     /*  FCF mac           */
 };
 
-/**
+/*
  *     Trunk states for BCU/BFAL
  */
 enum bfa_trunk_state {
@@ -857,7 +857,7 @@ enum bfa_trunk_state {
        BFA_TRUNK_OFFLINE       = 2,    /*  Trunk is offline            */
 };
 
-/**
+/*
  *     VC attributes for trunked link
  */
 struct bfa_trunk_vc_attr_s {
@@ -867,7 +867,7 @@ struct bfa_trunk_vc_attr_s {
        u16 vc_credits[8];
 };
 
-/**
+/*
  *     Link state information
  */
 struct bfa_port_link_s {
@@ -959,7 +959,7 @@ struct bfa_rport_hal_stats_s {
        u32        rsvd;
 };
 #pragma pack(1)
-/**
+/*
  *  Rport's QoS attributes
  */
 struct bfa_rport_qos_attr_s {
@@ -987,7 +987,7 @@ struct bfa_itnim_ioprofile_s {
        struct bfa_itnim_latency_s io_latency;
 };
 
-/**
+/*
  * FC physical port statistics.
  */
 struct bfa_port_fc_stats_s {
@@ -1022,7 +1022,7 @@ struct bfa_port_fc_stats_s {
        u64     err_enc;        /*  Encoding err frame_8b10b    */
 };
 
-/**
+/*
  * Eth Physical Port statistics.
  */
 struct bfa_port_eth_stats_s {
@@ -1070,7 +1070,7 @@ struct bfa_port_eth_stats_s {
        u64     tx_iscsi_zero_pause; /*  Tx iSCSI zero pause    */
 };
 
-/**
+/*
  *              Port statistics.
  */
 union bfa_port_stats_u {
index 14127646dc54cdb811ff944b7bea9dc0c838d4ed..0222d7c88a9a269812e520037d1d81d1f39070bd 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "bfa_modules.h"
 
-/**
+/*
  * BFA module list terminated by NULL
  */
 struct bfa_module_s *hal_mods[] = {
@@ -31,7 +31,7 @@ struct bfa_module_s *hal_mods[] = {
        NULL
 };
 
-/**
+/*
  * Message handlers for various modules.
  */
 bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
@@ -70,7 +70,7 @@ bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
 };
 
 
-/**
+/*
  * Message handlers for mailbox command classes
  */
 bfa_ioc_mbox_mcfunc_t  bfa_mbox_isrs[BFI_MC_MAX] = {
index 6eff705564eb5310d015e1e54a2b82db760a1c3b..e929d25b09e3083d3a095c974d48f4faa464d199 100644 (file)
@@ -1029,7 +1029,7 @@ struct link_e2e_beacon_req_s {
        struct link_e2e_beacon_param_s beacon_parm;
 };
 
-/**
+/*
  * If RPSC request is sent to the Domain Controller, the request is for
  * all the ports within that domain (TODO - I don't think FOS implements
  * this...).
@@ -1049,7 +1049,7 @@ struct fc_rpsc_acc_s {
        struct fc_rpsc_speed_info_s speed_info[1];
 };
 
-/**
+/*
  * If RPSC2 request is sent to the Domain Controller,
  */
 #define FC_BRCD_TOKEN    0x42524344
@@ -1094,7 +1094,7 @@ struct fc_rpsc2_acc_s {
     struct fc_rpsc2_port_info_s port_info[1];    /* port information */
 };
 
-/**
+/*
  * bit fields so that multiple classes can be specified
  */
 enum fc_cos {
@@ -1131,7 +1131,7 @@ struct fc_alpabm_s {
 #define FC_VF_ID_MAX     0xEFF
 #define FC_VF_ID_CTL     0xFEF /*  control VF_ID */
 
-/**
+/*
  * Virtual Fabric Tagging header format
  * @caution This is defined only in BIG ENDIAN format.
  */
@@ -1463,7 +1463,7 @@ struct fcgs_gidpn_resp_s {
        u32     dap:24; /* port identifier */
 };
 
-/**
+/*
  * RFT_ID
  */
 struct fcgs_rftid_req_s {
@@ -1472,7 +1472,7 @@ struct fcgs_rftid_req_s {
        u32     fc4_type[8];    /* fc4 types */
 };
 
-/**
+/*
  * RFF_ID : Register FC4 features.
  */
 
@@ -1487,7 +1487,7 @@ struct fcgs_rffid_req_s {
     u32    fc4_type:8;         /* corresponding FC4 Type */
 };
 
-/**
+/*
  * GID_FT Request
  */
 struct fcgs_gidft_req_s {
@@ -1497,7 +1497,7 @@ struct fcgs_gidft_req_s {
        u8      fc4_type;       /* FC_TYPE_FCP for SCSI devices */
 };             /* GID_FT Request */
 
-/**
+/*
  * GID_FT Response
  */
 struct fcgs_gidft_resp_s {
@@ -1506,7 +1506,7 @@ struct fcgs_gidft_resp_s {
        u32     pid:24; /* port identifier */
 };             /* GID_FT Response */
 
-/**
+/*
  * RSPN_ID
  */
 struct fcgs_rspnid_req_s {
@@ -1516,7 +1516,7 @@ struct fcgs_rspnid_req_s {
        u8              spn[256];       /* symbolic port name */
 };
 
-/**
+/*
  * RPN_ID
  */
 struct fcgs_rpnid_req_s {
@@ -1525,7 +1525,7 @@ struct fcgs_rpnid_req_s {
        wwn_t           port_name;
 };
 
-/**
+/*
  * RNN_ID
  */
 struct fcgs_rnnid_req_s {
@@ -1534,7 +1534,7 @@ struct fcgs_rnnid_req_s {
        wwn_t           node_name;
 };
 
-/**
+/*
  * RCS_ID
  */
 struct fcgs_rcsid_req_s {
@@ -1543,7 +1543,7 @@ struct fcgs_rcsid_req_s {
        u32     cos;
 };
 
-/**
+/*
  * RPT_ID
  */
 struct fcgs_rptid_req_s {
@@ -1553,7 +1553,7 @@ struct fcgs_rptid_req_s {
        u32     rsvd1:24;
 };
 
-/**
+/*
  * GA_NXT Request
  */
 struct fcgs_ganxt_req_s {
@@ -1561,7 +1561,7 @@ struct fcgs_ganxt_req_s {
        u32     port_id:24;
 };
 
-/**
+/*
  * GA_NXT Response
  */
 struct fcgs_ganxt_rsp_s {
index b7d2657ca82a2086d4b6ac492c94e3c7835b36c8..9c725314b513f203fc3d4cfbe667f6850568564c 100644 (file)
@@ -94,13 +94,13 @@ fcbuild_init(void)
         */
        plogi_tmpl.csp.verhi = FC_PH_VER_PH_3;
        plogi_tmpl.csp.verlo = FC_PH_VER_4_3;
-       plogi_tmpl.csp.bbcred = bfa_os_htons(0x0004);
+       plogi_tmpl.csp.bbcred = cpu_to_be16(0x0004);
        plogi_tmpl.csp.ciro = 0x1;
        plogi_tmpl.csp.cisc = 0x0;
        plogi_tmpl.csp.altbbcred = 0x0;
-       plogi_tmpl.csp.conseq = bfa_os_htons(0x00FF);
-       plogi_tmpl.csp.ro_bitmap = bfa_os_htons(0x0002);
-       plogi_tmpl.csp.e_d_tov = bfa_os_htonl(2000);
+       plogi_tmpl.csp.conseq = cpu_to_be16(0x00FF);
+       plogi_tmpl.csp.ro_bitmap = cpu_to_be16(0x0002);
+       plogi_tmpl.csp.e_d_tov = cpu_to_be32(2000);
 
        plogi_tmpl.class3.class_valid = 1;
        plogi_tmpl.class3.sequential = 1;
@@ -112,7 +112,7 @@ fcbuild_init(void)
         */
        prli_tmpl.command = FC_ELS_PRLI;
        prli_tmpl.pglen = 0x10;
-       prli_tmpl.pagebytes = bfa_os_htons(0x0014);
+       prli_tmpl.pagebytes = cpu_to_be16(0x0014);
        prli_tmpl.parampage.type = FC_TYPE_FCP;
        prli_tmpl.parampage.imagepair = 1;
        prli_tmpl.parampage.servparams.rxrdisab = 1;
@@ -137,7 +137,7 @@ fcbuild_init(void)
 static void
 fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
 {
-       bfa_os_memset(fchs, 0, sizeof(struct fchs_s));
+       memset(fchs, 0, sizeof(struct fchs_s));
 
        fchs->routing = FC_RTG_FC4_DEV_DATA;
        fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
@@ -148,9 +148,9 @@ fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
        fchs->rx_id = FC_RXID_ANY;
        fchs->d_id = (d_id);
        fchs->s_id = (s_id);
-       fchs->ox_id = bfa_os_htons(ox_id);
+       fchs->ox_id = cpu_to_be16(ox_id);
 
-       /**
+       /*
         * @todo no need to set ox_id for request
         *       no need to set rx_id for response
         */
@@ -159,16 +159,16 @@ fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
 void
 fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
 {
-       bfa_os_memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
+       memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
        fchs->d_id = (d_id);
        fchs->s_id = (s_id);
-       fchs->ox_id = bfa_os_htons(ox_id);
+       fchs->ox_id = cpu_to_be16(ox_id);
 }
 
 static void
 fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
 {
-       bfa_os_memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
+       memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
        fchs->d_id = d_id;
        fchs->s_id = s_id;
        fchs->ox_id = ox_id;
@@ -198,7 +198,7 @@ fc_els_rsp_parse(struct fchs_s *fchs, int len)
 static void
 fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
 {
-       bfa_os_memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
+       memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
        fchs->d_id = d_id;
        fchs->s_id = s_id;
        fchs->ox_id = ox_id;
@@ -211,7 +211,7 @@ fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 {
        struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
 
-       bfa_os_memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
+       memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 
        plogi->els_cmd.els_code = els_code;
        if (els_code == FC_ELS_PLOGI)
@@ -219,10 +219,10 @@ fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
        else
                fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 
-       plogi->csp.rxsz = plogi->class3.rxsz = bfa_os_htons(pdu_size);
+       plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size);
 
-       bfa_os_memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
-       bfa_os_memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
+       memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
+       memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
 
        return sizeof(struct fc_logi_s);
 }
@@ -235,12 +235,12 @@ fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
        u32        d_id = bfa_os_hton3b(FC_FABRIC_PORT);
        u32     *vvl_info;
 
-       bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
+       memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 
        flogi->els_cmd.els_code = FC_ELS_FLOGI;
        fc_els_req_build(fchs, d_id, s_id, ox_id);
 
-       flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size);
+       flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
        flogi->port_name = port_name;
        flogi->node_name = node_name;
 
@@ -253,14 +253,14 @@ fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
        /* set AUTH capability */
        flogi->csp.security = set_auth;
 
-       flogi->csp.bbcred = bfa_os_htons(local_bb_credits);
+       flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
 
        /* Set brcd token in VVL */
        vvl_info = (u32 *)&flogi->vvl[0];
 
        /* set the flag to indicate the presence of VVL */
        flogi->csp.npiv_supp    = 1; /* @todo. field name is not correct */
-       vvl_info[0]     = bfa_os_htonl(FLOGI_VVL_BRCD);
+       vvl_info[0]     = cpu_to_be32(FLOGI_VVL_BRCD);
 
        return sizeof(struct fc_logi_s);
 }
@@ -272,15 +272,15 @@ fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
 {
        u32        d_id = 0;
 
-       bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
+       memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 
        flogi->els_cmd.els_code = FC_ELS_ACC;
-       flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size);
+       flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
        flogi->port_name = port_name;
        flogi->node_name = node_name;
 
-       flogi->csp.bbcred = bfa_os_htons(local_bb_credits);
+       flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
 
        return sizeof(struct fc_logi_s);
 }
@@ -291,12 +291,12 @@ fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
 {
        u32        d_id = bfa_os_hton3b(FC_FABRIC_PORT);
 
-       bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
+       memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 
        flogi->els_cmd.els_code = FC_ELS_FDISC;
        fc_els_req_build(fchs, d_id, s_id, ox_id);
 
-       flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size);
+       flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
        flogi->port_name = port_name;
        flogi->node_name = node_name;
 
@@ -346,7 +346,7 @@ fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
                if (!plogi->class3.class_valid)
                        return FC_PARSE_FAILURE;
 
-               if (bfa_os_ntohs(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
+               if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
                        return FC_PARSE_FAILURE;
 
                return FC_PARSE_OK;
@@ -363,8 +363,8 @@ fc_plogi_parse(struct fchs_s *fchs)
        if (plogi->class3.class_valid != 1)
                return FC_PARSE_FAILURE;
 
-       if ((bfa_os_ntohs(plogi->class3.rxsz) < FC_MIN_PDUSZ)
-           || (bfa_os_ntohs(plogi->class3.rxsz) > FC_MAX_PDUSZ)
+       if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ)
+           || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ)
            || (plogi->class3.rxsz == 0))
                return FC_PARSE_FAILURE;
 
@@ -378,7 +378,7 @@ fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
        struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
 
        fc_els_req_build(fchs, d_id, s_id, ox_id);
-       bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
+       memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
 
        prli->command = FC_ELS_PRLI;
        prli->parampage.servparams.initiator     = 1;
@@ -397,7 +397,7 @@ fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
        struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
 
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
-       bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
+       memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
 
        prli->command = FC_ELS_ACC;
 
@@ -448,7 +448,7 @@ fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id,
 {
        fc_els_req_build(fchs, d_id, s_id, ox_id);
 
-       bfa_os_memset(logo, '\0', sizeof(struct fc_logo_s));
+       memset(logo, '\0', sizeof(struct fc_logo_s));
        logo->els_cmd.els_code = FC_ELS_LOGO;
        logo->nport_id = (s_id);
        logo->orig_port_name = port_name;
@@ -461,7 +461,7 @@ fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
                 u32 s_id, u16 ox_id, wwn_t port_name,
                 wwn_t node_name, u8 els_code)
 {
-       bfa_os_memset(adisc, '\0', sizeof(struct fc_adisc_s));
+       memset(adisc, '\0', sizeof(struct fc_adisc_s));
 
        adisc->els_cmd.els_code = els_code;
 
@@ -537,7 +537,7 @@ fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
        if (pdisc->class3.class_valid != 1)
                return FC_PARSE_FAILURE;
 
-       if ((bfa_os_ntohs(pdisc->class3.rxsz) <
+       if ((be16_to_cpu(pdisc->class3.rxsz) <
                (FC_MIN_PDUSZ - sizeof(struct fchs_s)))
            || (pdisc->class3.rxsz == 0))
                return FC_PARSE_FAILURE;
@@ -554,11 +554,11 @@ fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
 u16
 fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
 {
-       bfa_os_memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
+       memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
        fchs->cat_info = FC_CAT_ABTS;
        fchs->d_id = (d_id);
        fchs->s_id = (s_id);
-       fchs->ox_id = bfa_os_htons(ox_id);
+       fchs->ox_id = cpu_to_be16(ox_id);
 
        return sizeof(struct fchs_s);
 }
@@ -582,9 +582,9 @@ fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id,
        /*
         * build rrq payload
         */
-       bfa_os_memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
+       memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
        rrq->s_id = (s_id);
-       rrq->ox_id = bfa_os_htons(rrq_oxid);
+       rrq->ox_id = cpu_to_be16(rrq_oxid);
        rrq->rx_id = FC_RXID_ANY;
 
        return sizeof(struct fc_rrq_s);
@@ -598,7 +598,7 @@ fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 
-       bfa_os_memset(acc, 0, sizeof(struct fc_els_cmd_s));
+       memset(acc, 0, sizeof(struct fc_els_cmd_s));
        acc->els_code = FC_ELS_ACC;
 
        return sizeof(struct fc_els_cmd_s);
@@ -610,7 +610,7 @@ fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
                u8 reason_code_expl)
 {
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
-       bfa_os_memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
+       memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
 
        ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT;
        ls_rjt->reason_code = reason_code;
@@ -626,7 +626,7 @@ fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
 {
        fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
 
-       bfa_os_memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
+       memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
 
        fchs->rx_id = rx_id;
 
@@ -641,7 +641,7 @@ fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id,
                u32 s_id, u16 ox_id)
 {
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
-       bfa_os_memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
+       memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
        els_cmd->els_code = FC_ELS_ACC;
 
        return sizeof(struct fc_els_cmd_s);
@@ -656,10 +656,10 @@ fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
 
        if (els_code == FC_ELS_PRLO) {
                prlo = (struct fc_prlo_s *) (fc_frame + 1);
-               num_pages = (bfa_os_ntohs(prlo->payload_len) - 4) / 16;
+               num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16;
        } else {
                tprlo = (struct fc_tprlo_s *) (fc_frame + 1);
-               num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16;
+               num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
        }
        return num_pages;
 }
@@ -672,11 +672,11 @@ fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
 
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 
-       bfa_os_memset(tprlo_acc, 0, (num_pages * 16) + 4);
+       memset(tprlo_acc, 0, (num_pages * 16) + 4);
        tprlo_acc->command = FC_ELS_ACC;
 
        tprlo_acc->page_len = 0x10;
-       tprlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4);
+       tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
 
        for (page = 0; page < num_pages; page++) {
                tprlo_acc->tprlo_acc_params[page].opa_valid = 0;
@@ -685,7 +685,7 @@ fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
                tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
                tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
        }
-       return bfa_os_ntohs(tprlo_acc->payload_len);
+       return be16_to_cpu(tprlo_acc->payload_len);
 }
 
 u16
@@ -696,10 +696,10 @@ fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
 
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 
-       bfa_os_memset(prlo_acc, 0, (num_pages * 16) + 4);
+       memset(prlo_acc, 0, (num_pages * 16) + 4);
        prlo_acc->command = FC_ELS_ACC;
        prlo_acc->page_len = 0x10;
-       prlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4);
+       prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
 
        for (page = 0; page < num_pages; page++) {
                prlo_acc->prlo_acc_params[page].opa_valid = 0;
@@ -709,7 +709,7 @@ fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
                prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
        }
 
-       return bfa_os_ntohs(prlo_acc->payload_len);
+       return be16_to_cpu(prlo_acc->payload_len);
 }
 
 u16
@@ -718,7 +718,7 @@ fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
 {
        fc_els_req_build(fchs, d_id, s_id, ox_id);
 
-       bfa_os_memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
+       memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
 
        rnid->els_cmd.els_code = FC_ELS_RNID;
        rnid->node_id_data_format = data_format;
@@ -732,7 +732,7 @@ fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
                  struct fc_rnid_common_id_data_s *common_id_data,
                  struct fc_rnid_general_topology_data_s *gen_topo_data)
 {
-       bfa_os_memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
+       memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
 
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 
@@ -745,7 +745,7 @@ fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
        if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
                rnid_acc->specific_id_data_length =
                        sizeof(struct fc_rnid_general_topology_data_s);
-               bfa_os_assign(rnid_acc->gen_topology_data, *gen_topo_data);
+               rnid_acc->gen_topology_data = *gen_topo_data;
                return sizeof(struct fc_rnid_acc_s);
        } else {
                return sizeof(struct fc_rnid_acc_s) -
@@ -760,7 +760,7 @@ fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id,
 {
        fc_els_req_build(fchs, d_id, s_id, ox_id);
 
-       bfa_os_memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
+       memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
 
        rpsc->els_cmd.els_code = FC_ELS_RPSC;
        return sizeof(struct fc_rpsc_cmd_s);
@@ -775,11 +775,11 @@ fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
 
        fc_els_req_build(fchs, bfa_os_hton3b(dctlr_id), s_id, 0);
 
-       bfa_os_memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
+       memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
 
        rpsc2->els_cmd.els_code = FC_ELS_RPSC;
-       rpsc2->token = bfa_os_htonl(FC_BRCD_TOKEN);
-       rpsc2->num_pids  = bfa_os_htons(npids);
+       rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN);
+       rpsc2->num_pids  = cpu_to_be16(npids);
        for (i = 0; i < npids; i++)
                rpsc2->pid_list[i].pid = pid_list[i];
 
@@ -791,18 +791,18 @@ fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
                u32 d_id, u32 s_id, u16 ox_id,
                  struct fc_rpsc_speed_info_s *oper_speed)
 {
-       bfa_os_memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
+       memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
 
        fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 
        rpsc_acc->command = FC_ELS_ACC;
-       rpsc_acc->num_entries = bfa_os_htons(1);
+       rpsc_acc->num_entries = cpu_to_be16(1);
 
        rpsc_acc->speed_info[0].port_speed_cap =
-               bfa_os_htons(oper_speed->port_speed_cap);
+               cpu_to_be16(oper_speed->port_speed_cap);
 
        rpsc_acc->speed_info[0].port_op_speed =
-               bfa_os_htons(oper_speed->port_op_speed);
+               cpu_to_be16(oper_speed->port_op_speed);
 
        return sizeof(struct fc_rpsc_acc_s);
 }
@@ -830,12 +830,12 @@ fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
 {
        struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
 
-       bfa_os_memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
+       memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
 
        pdisc->els_cmd.els_code = FC_ELS_PDISC;
        fc_els_req_build(fchs, d_id, s_id, ox_id);
 
-       pdisc->csp.rxsz = pdisc->class3.rxsz = bfa_os_htons(pdu_size);
+       pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size);
        pdisc->port_name = port_name;
        pdisc->node_name = node_name;
 
@@ -859,7 +859,7 @@ fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
        if (!pdisc->class3.class_valid)
                return FC_PARSE_NWWN_NOT_EQUAL;
 
-       if (bfa_os_ntohs(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
+       if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
                return FC_PARSE_RXSZ_INVAL;
 
        return FC_PARSE_OK;
@@ -873,10 +873,10 @@ fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
        int             page;
 
        fc_els_req_build(fchs, d_id, s_id, ox_id);
-       bfa_os_memset(prlo, 0, (num_pages * 16) + 4);
+       memset(prlo, 0, (num_pages * 16) + 4);
        prlo->command = FC_ELS_PRLO;
        prlo->page_len = 0x10;
-       prlo->payload_len = bfa_os_htons((num_pages * 16) + 4);
+       prlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
 
        for (page = 0; page < num_pages; page++) {
                prlo->prlo_params[page].type = FC_TYPE_FCP;
@@ -886,7 +886,7 @@ fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
                prlo->prlo_params[page].resp_process_assc = 0;
        }
 
-       return bfa_os_ntohs(prlo->payload_len);
+       return be16_to_cpu(prlo->payload_len);
 }
 
 u16
@@ -901,7 +901,7 @@ fc_prlo_rsp_parse(struct fchs_s *fchs, int len)
        if (prlo->command != FC_ELS_ACC)
                return FC_PARSE_FAILURE;
 
-       num_pages = ((bfa_os_ntohs(prlo->payload_len)) - 4) / 16;
+       num_pages = ((be16_to_cpu(prlo->payload_len)) - 4) / 16;
 
        for (page = 0; page < num_pages; page++) {
                if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP)
@@ -931,10 +931,10 @@ fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
        int             page;
 
        fc_els_req_build(fchs, d_id, s_id, ox_id);
-       bfa_os_memset(tprlo, 0, (num_pages * 16) + 4);
+       memset(tprlo, 0, (num_pages * 16) + 4);
        tprlo->command = FC_ELS_TPRLO;
        tprlo->page_len = 0x10;
-       tprlo->payload_len = bfa_os_htons((num_pages * 16) + 4);
+       tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
 
        for (page = 0; page < num_pages; page++) {
                tprlo->tprlo_params[page].type = FC_TYPE_FCP;
@@ -950,7 +950,7 @@ fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
                }
        }
 
-       return bfa_os_ntohs(tprlo->payload_len);
+       return be16_to_cpu(tprlo->payload_len);
 }
 
 u16
@@ -965,7 +965,7 @@ fc_tprlo_rsp_parse(struct fchs_s *fchs, int len)
        if (tprlo->command != FC_ELS_ACC)
                return FC_PARSE_ACC_INVAL;
 
-       num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16;
+       num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
 
        for (page = 0; page < num_pages; page++) {
                if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP)
@@ -1011,32 +1011,32 @@ fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
 static void
 fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
 {
-       bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s));
+       memset(cthdr, 0, sizeof(struct ct_hdr_s));
        cthdr->rev_id = CT_GS3_REVISION;
        cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
        cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
-       cthdr->cmd_rsp_code = bfa_os_htons(cmd_code);
+       cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
 }
 
 static void
 fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
 {
-       bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s));
+       memset(cthdr, 0, sizeof(struct ct_hdr_s));
        cthdr->rev_id = CT_GS3_REVISION;
        cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
        cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
-       cthdr->cmd_rsp_code = bfa_os_htons(cmd_code);
+       cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
 }
 
 static void
 fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
                                         u8 sub_type)
 {
-       bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s));
+       memset(cthdr, 0, sizeof(struct ct_hdr_s));
        cthdr->rev_id = CT_GS3_REVISION;
        cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
        cthdr->gs_sub_type = sub_type;
-       cthdr->cmd_rsp_code = bfa_os_htons(cmd_code);
+       cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
 }
 
 u16
@@ -1050,7 +1050,7 @@ fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
 
-       bfa_os_memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
+       memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
        gidpn->port_name = port_name;
        return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
 }
@@ -1066,7 +1066,7 @@ fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
 
-       bfa_os_memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
+       memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
        gpnid->dap = port_id;
        return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
 }
@@ -1082,7 +1082,7 @@ fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
 
-       bfa_os_memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
+       memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
        gnnid->dap = port_id;
        return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
 }
@@ -1090,7 +1090,7 @@ fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
 u16
 fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
 {
-       if (bfa_os_ntohs(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
+       if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
                if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
                        return FC_PARSE_BUSY;
                else
@@ -1108,7 +1108,7 @@ fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
 
        fc_els_req_build(fchs, d_id, s_id, ox_id);
 
-       bfa_os_memset(scr, 0, sizeof(struct fc_scr_s));
+       memset(scr, 0, sizeof(struct fc_scr_s));
        scr->command = FC_ELS_SCR;
        scr->reg_func = FC_SCR_REG_FUNC_FULL;
        if (set_br_reg)
@@ -1129,7 +1129,7 @@ fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
        rscn->pagelen = sizeof(rscn->event[0]);
 
        payldlen = sizeof(u32) + rscn->pagelen;
-       rscn->payldlen = bfa_os_htons(payldlen);
+       rscn->payldlen = cpu_to_be16(payldlen);
 
        rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
        rscn->event[0].portid = s_id;
@@ -1149,14 +1149,14 @@ fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
 
-       bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
+       memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
 
        rftid->dap = s_id;
 
        /* By default, FCP FC4 Type is registered */
        index = FC_TYPE_FCP >> 5;
        type_value = 1 << (FC_TYPE_FCP % 32);
-       rftid->fc4_type[index] = bfa_os_htonl(type_value);
+       rftid->fc4_type[index] = cpu_to_be32(type_value);
 
        return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
 }
@@ -1172,10 +1172,10 @@ fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
 
-       bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
+       memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
 
        rftid->dap = s_id;
-       bfa_os_memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
+       memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
                (bitmap_size < 32 ? bitmap_size : 32));
 
        return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
@@ -1192,7 +1192,7 @@ fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
 
-       bfa_os_memset(rffid, 0, sizeof(struct fcgs_rffid_req_s));
+       memset(rffid, 0, sizeof(struct fcgs_rffid_req_s));
 
        rffid->dap          = s_id;
        rffid->fc4ftr_bits  = fc4_ftrs;
@@ -1214,7 +1214,7 @@ fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
        fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
 
-       bfa_os_memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
+       memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
 
        rspnid->dap = s_id;
        rspnid->spn_len = (u8) strlen((char *)name);
@@ -1235,7 +1235,7 @@ fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type)
 
        fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT);
 
-       bfa_os_memset(gidft, 0, sizeof(struct fcgs_gidft_req_s));
+       memset(gidft, 0, sizeof(struct fcgs_gidft_req_s));
        gidft->fc4_type = fc4_type;
        gidft->domain_id = 0;
        gidft->area_id = 0;
@@ -1254,7 +1254,7 @@ fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
 
-       bfa_os_memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s));
+       memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s));
        rpnid->port_id = port_id;
        rpnid->port_name = port_name;
 
@@ -1272,7 +1272,7 @@ fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
 
-       bfa_os_memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s));
+       memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s));
        rnnid->port_id = port_id;
        rnnid->node_name = node_name;
 
@@ -1291,7 +1291,7 @@ fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
 
-       bfa_os_memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s));
+       memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s));
        rcsid->port_id = port_id;
        rcsid->cos = cos;
 
@@ -1309,7 +1309,7 @@ fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
 
-       bfa_os_memset(rptid, 0, sizeof(struct fcgs_rptid_req_s));
+       memset(rptid, 0, sizeof(struct fcgs_rptid_req_s));
        rptid->port_id = port_id;
        rptid->port_type = port_type;
 
@@ -1326,7 +1326,7 @@ fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
        fc_gs_fchdr_build(fchs, d_id, s_id, 0);
        fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
 
-       bfa_os_memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
+       memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
        ganxt->port_id = port_id;
 
        return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s);
@@ -1365,7 +1365,7 @@ fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
 
        index = fc4_type >> 5;
        type_value = 1 << (fc4_type % 32);
-       ptr[index] = bfa_os_htonl(type_value);
+       ptr[index] = cpu_to_be32(type_value);
 
 }
 
@@ -1383,7 +1383,7 @@ fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
        fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
                        CT_GSSUBTYPE_CFGSERVER);
 
-       bfa_os_memset(gmal, 0, sizeof(fcgs_gmal_req_t));
+       memset(gmal, 0, sizeof(fcgs_gmal_req_t));
        gmal->wwn = wwn;
 
        return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t);
@@ -1403,7 +1403,7 @@ fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
        fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
                        CT_GSSUBTYPE_CFGSERVER);
 
-       bfa_os_memset(gfn, 0, sizeof(fcgs_gfn_req_t));
+       memset(gfn, 0, sizeof(fcgs_gfn_req_t));
        gfn->wwn = wwn;
 
        return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t);
index 33c8dd51f4748677fadc78b518fc51964a318859..135c4427801cf66abc97719c6e9fe78ea6a9a8d1 100644 (file)
@@ -26,7 +26,7 @@ BFA_MODULE(fcpim);
        (__l->__stats += __r->__stats)
 
 
-/**
+/*
  *  BFA ITNIM Related definitions
  */
 static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
@@ -72,7 +72,7 @@ static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
        }                                                               \
 } while (0)
 
-/**
+/*
  *  bfa_itnim_sm BFA itnim state machine
  */
 
@@ -89,7 +89,7 @@ enum bfa_itnim_event {
        BFA_ITNIM_SM_QRESUME = 9,       /*  queue space available */
 };
 
-/**
+/*
  *  BFA IOIM related definitions
  */
 #define bfa_ioim_move_to_comp_q(__ioim) do {                           \
@@ -107,11 +107,11 @@ enum bfa_itnim_event {
        if ((__fcpim)->profile_start)                                   \
                (__fcpim)->profile_start(__ioim);                       \
 } while (0)
-/**
+/*
  *  hal_ioim_sm
  */
 
-/**
+/*
  * IO state machine events
  */
 enum bfa_ioim_event {
@@ -136,11 +136,11 @@ enum bfa_ioim_event {
 };
 
 
-/**
+/*
  *  BFA TSKIM related definitions
  */
 
-/**
+/*
  * task management completion handling
  */
 #define bfa_tskim_qcomp(__tskim, __cbfn) do {                          \
@@ -165,7 +165,7 @@ enum bfa_tskim_event {
        BFA_TSKIM_SM_CLEANUP_DONE = 9,  /*  TM abort completion */
 };
 
-/**
+/*
  * forward declaration for BFA ITNIM functions
  */
 static void     bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim);
@@ -183,7 +183,7 @@ static void     bfa_itnim_iotov_start(struct bfa_itnim_s *itnim);
 static void     bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim);
 static void     bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim);
 
-/**
+/*
  * forward declaration of ITNIM state machine
  */
 static void     bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim,
@@ -217,7 +217,7 @@ static void     bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
 static void     bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
                                        enum bfa_itnim_event event);
 
-/**
+/*
  * forward declaration for BFA IOIM functions
  */
 static bfa_boolean_t   bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim);
@@ -233,7 +233,7 @@ static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
 static bfa_boolean_t    bfa_ioim_is_abortable(struct bfa_ioim_s *ioim);
 
 
-/**
+/*
  * forward declaration of BFA IO state machine
  */
 static void     bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim,
@@ -261,7 +261,7 @@ static void     bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim,
 static void    bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim,
                                        enum bfa_ioim_event event);
 
-/**
+/*
  * forward declaration for BFA TSKIM functions
  */
 static void     __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete);
@@ -276,7 +276,7 @@ static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim);
 static void     bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim);
 
 
-/**
+/*
  * forward declaration of BFA TSKIM state machine
  */
 static void     bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim,
@@ -294,11 +294,11 @@ static void     bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
 static void     bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim,
                                        enum bfa_tskim_event event);
 
-/**
+/*
  *  hal_fcpim_mod BFA FCP Initiator Mode module
  */
 
-/**
+/*
  *     Compute and return memory needed by FCP(im) module.
  */
 static void
@@ -307,7 +307,7 @@ bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
 {
        bfa_itnim_meminfo(cfg, km_len, dm_len);
 
-       /**
+       /*
         * IO memory
         */
        if (cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN)
@@ -320,7 +320,7 @@ bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
 
        *dm_len += cfg->fwcfg.num_ioim_reqs * BFI_IOIM_SNSLEN;
 
-       /**
+       /*
         * task management command memory
         */
        if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN)
@@ -463,7 +463,7 @@ bfa_fcpim_port_iostats(struct bfa_s *bfa, struct bfa_itnim_iostats_s *stats,
        struct bfa_itnim_s *itnim;
 
        /* accumulate IO stats from itnim */
-       bfa_os_memset(stats, 0, sizeof(struct bfa_itnim_iostats_s));
+       memset(stats, 0, sizeof(struct bfa_itnim_iostats_s));
        list_for_each_safe(qe, qen, &fcpim->itnim_q) {
                itnim = (struct bfa_itnim_s *) qe;
                if (itnim->rport->rport_info.lp_tag != lp_tag)
@@ -480,7 +480,7 @@ bfa_fcpim_get_modstats(struct bfa_s *bfa, struct bfa_itnim_iostats_s *modstats)
        struct bfa_itnim_s *itnim;
 
        /* accumulate IO stats from itnim */
-       bfa_os_memset(modstats, 0, sizeof(struct bfa_itnim_iostats_s));
+       memset(modstats, 0, sizeof(struct bfa_itnim_iostats_s));
        list_for_each_safe(qe, qen, &fcpim->itnim_q) {
                itnim = (struct bfa_itnim_s *) qe;
                bfa_fcpim_add_stats(modstats, &(itnim->stats));
@@ -560,7 +560,7 @@ bfa_fcpim_clr_modstats(struct bfa_s *bfa)
                itnim = (struct bfa_itnim_s *) qe;
                bfa_itnim_clear_stats(itnim);
        }
-       bfa_os_memset(&fcpim->del_itn_stats, 0,
+       memset(&fcpim->del_itn_stats, 0,
                sizeof(struct bfa_fcpim_del_itn_stats_s));
 
        return BFA_STATUS_OK;
@@ -604,11 +604,11 @@ bfa_fcpim_set_ioredirect(struct bfa_s *bfa, bfa_boolean_t state)
 
 
 
-/**
+/*
  *  BFA ITNIM module state machine functions
  */
 
-/**
+/*
  *     Beginning/unallocated state - no events expected.
  */
 static void
@@ -629,7 +629,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
        }
 }
 
-/**
+/*
  *     Beginning state, only online event expected.
  */
 static void
@@ -660,7 +660,7 @@ bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
        }
 }
 
-/**
+/*
  *     Waiting for itnim create response from firmware.
  */
 static void
@@ -732,7 +732,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
        }
 }
 
-/**
+/*
  *     Waiting for itnim create response from firmware, a delete is pending.
  */
 static void
@@ -760,7 +760,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
        }
 }
 
-/**
+/*
  *     Online state - normal parking state.
  */
 static void
@@ -802,7 +802,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
        }
 }
 
-/**
+/*
  *     Second level error recovery need.
  */
 static void
@@ -833,7 +833,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
        }
 }
 
-/**
+/*
  *     Going offline. Waiting for active IO cleanup.
  */
 static void
@@ -870,7 +870,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
        }
 }
 
-/**
+/*
  *     Deleting itnim. Waiting for active IO cleanup.
  */
 static void
@@ -898,7 +898,7 @@ bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
        }
 }
 
-/**
+/*
  * Rport offline. Fimrware itnim is being deleted - awaiting f/w response.
  */
 static void
@@ -955,7 +955,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
        }
 }
 
-/**
+/*
  *     Offline state.
  */
 static void
@@ -987,7 +987,7 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
        }
 }
 
-/**
+/*
  *     IOC h/w failed state.
  */
 static void
@@ -1023,7 +1023,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
        }
 }
 
-/**
+/*
  *     Itnim is deleted, waiting for firmware response to delete.
  */
 static void
@@ -1068,7 +1068,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
        }
 }
 
-/**
+/*
  *     Initiate cleanup of all IOs on an IOC failure.
  */
 static void
@@ -1088,7 +1088,7 @@ bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
                bfa_ioim_iocdisable(ioim);
        }
 
-       /**
+       /*
         * For IO request in pending queue, we pretend an early timeout.
         */
        list_for_each_safe(qe, qen, &itnim->pending_q) {
@@ -1102,7 +1102,7 @@ bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
        }
 }
 
-/**
+/*
  *     IO cleanup completion
  */
 static void
@@ -1114,7 +1114,7 @@ bfa_itnim_cleanp_comp(void *itnim_cbarg)
        bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP);
 }
 
-/**
+/*
  *     Initiate cleanup of all IOs.
  */
 static void
@@ -1129,7 +1129,7 @@ bfa_itnim_cleanup(struct bfa_itnim_s *itnim)
        list_for_each_safe(qe, qen, &itnim->io_q) {
                ioim = (struct bfa_ioim_s *) qe;
 
-               /**
+               /*
                 * Move IO to a cleanup queue from active queue so that a later
                 * TM will not pickup this IO.
                 */
@@ -1176,7 +1176,7 @@ __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete)
                bfa_cb_itnim_sler(itnim->ditn);
 }
 
-/**
+/*
  * Call to resume any I/O requests waiting for room in request queue.
  */
 static void
@@ -1190,7 +1190,7 @@ bfa_itnim_qresume(void *cbarg)
 
 
 
-/**
+/*
  *  bfa_itnim_public
  */
 
@@ -1210,7 +1210,7 @@ void
 bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
                u32 *dm_len)
 {
-       /**
+       /*
         * ITN memory
         */
        *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s);
@@ -1229,7 +1229,7 @@ bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
        fcpim->itnim_arr = itnim;
 
        for (i = 0; i < fcpim->num_itnims; i++, itnim++) {
-               bfa_os_memset(itnim, 0, sizeof(struct bfa_itnim_s));
+               memset(itnim, 0, sizeof(struct bfa_itnim_s));
                itnim->bfa = bfa;
                itnim->fcpim = fcpim;
                itnim->reqq = BFA_REQQ_QOS_LO;
@@ -1264,7 +1264,7 @@ bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim)
 
        itnim->msg_no++;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(itnim->bfa, itnim->reqq);
@@ -1281,7 +1281,7 @@ bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim)
        m->msg_no = itnim->msg_no;
        bfa_stats(itnim, fw_create);
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(itnim->bfa, itnim->reqq);
@@ -1293,7 +1293,7 @@ bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim)
 {
        struct bfi_itnim_delete_req_s *m;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(itnim->bfa, itnim->reqq);
@@ -1307,14 +1307,14 @@ bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim)
        m->fw_handle = itnim->rport->fw_handle;
        bfa_stats(itnim, fw_delete);
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(itnim->bfa, itnim->reqq);
        return BFA_TRUE;
 }
 
-/**
+/*
  * Cleanup all pending failed inflight requests.
  */
 static void
@@ -1329,7 +1329,7 @@ bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov)
        }
 }
 
-/**
+/*
  * Start all pending IO requests.
  */
 static void
@@ -1339,12 +1339,12 @@ bfa_itnim_iotov_online(struct bfa_itnim_s *itnim)
 
        bfa_itnim_iotov_stop(itnim);
 
-       /**
+       /*
         * Abort all inflight IO requests in the queue
         */
        bfa_itnim_delayed_comp(itnim, BFA_FALSE);
 
-       /**
+       /*
         * Start all pending IO requests.
         */
        while (!list_empty(&itnim->pending_q)) {
@@ -1354,7 +1354,7 @@ bfa_itnim_iotov_online(struct bfa_itnim_s *itnim)
        }
 }
 
-/**
+/*
  * Fail all pending IO requests
  */
 static void
@@ -1362,12 +1362,12 @@ bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim)
 {
        struct bfa_ioim_s *ioim;
 
-       /**
+       /*
         * Fail all inflight IO requests in the queue
         */
        bfa_itnim_delayed_comp(itnim, BFA_TRUE);
 
-       /**
+       /*
         * Fail any pending IO requests.
         */
        while (!list_empty(&itnim->pending_q)) {
@@ -1377,7 +1377,7 @@ bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim)
        }
 }
 
-/**
+/*
  * IO TOV timer callback. Fail any pending IO requests.
  */
 static void
@@ -1392,7 +1392,7 @@ bfa_itnim_iotov(void *itnim_arg)
        bfa_cb_itnim_tov(itnim->ditn);
 }
 
-/**
+/*
  * Start IO TOV timer for failing back pending IO requests in offline state.
  */
 static void
@@ -1407,7 +1407,7 @@ bfa_itnim_iotov_start(struct bfa_itnim_s *itnim)
        }
 }
 
-/**
+/*
  * Stop IO TOV timer.
  */
 static void
@@ -1419,7 +1419,7 @@ bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim)
        }
 }
 
-/**
+/*
  * Stop IO TOV timer.
  */
 static void
@@ -1459,11 +1459,11 @@ bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim)
 
 
 
-/**
+/*
  *  bfa_itnim_public
  */
 
-/**
+/*
  *     Itnim interrupt processing.
  */
 void
@@ -1509,7 +1509,7 @@ bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
 
 
 
-/**
+/*
  *  bfa_itnim_api
  */
 
@@ -1552,7 +1552,7 @@ bfa_itnim_offline(struct bfa_itnim_s *itnim)
        bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE);
 }
 
-/**
+/*
  * Return true if itnim is considered offline for holding off IO request.
  * IO is not held if itnim is being deleted.
  */
@@ -1597,17 +1597,17 @@ void
 bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
 {
        int j;
-       bfa_os_memset(&itnim->stats, 0, sizeof(itnim->stats));
-       bfa_os_memset(&itnim->ioprofile, 0, sizeof(itnim->ioprofile));
+       memset(&itnim->stats, 0, sizeof(itnim->stats));
+       memset(&itnim->ioprofile, 0, sizeof(itnim->ioprofile));
        for (j = 0; j < BFA_IOBUCKET_MAX; j++)
                itnim->ioprofile.io_latency.min[j] = ~0;
 }
 
-/**
+/*
  *  BFA IO module state machine functions
  */
 
-/**
+/*
  *     IO is not started (unallocated).
  */
 static void
@@ -1657,7 +1657,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        case BFA_IOIM_SM_ABORT:
-               /**
+               /*
                 * IO in pending queue can get abort requests. Complete abort
                 * requests immediately.
                 */
@@ -1672,7 +1672,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  *     IO is waiting for SG pages.
  */
 static void
@@ -1719,7 +1719,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  *     IO is active.
  */
 static void
@@ -1803,7 +1803,7 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
 *      IO is retried with new tag.
 */
 static void
@@ -1844,7 +1844,7 @@ bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        case BFA_IOIM_SM_ABORT:
-               /** in this state IO abort is done.
+               /* in this state IO abort is done.
                 * Waiting for IO tag resource free.
                 */
                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
@@ -1857,7 +1857,7 @@ bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  *     IO is being aborted, waiting for completion from firmware.
  */
 static void
@@ -1919,7 +1919,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  * IO is being cleaned up (implicit abort), waiting for completion from
  * firmware.
  */
@@ -1937,7 +1937,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        case BFA_IOIM_SM_ABORT:
-               /**
+               /*
                 * IO is already being aborted implicitly
                 */
                ioim->io_cbfn = __bfa_cb_ioim_abort;
@@ -1969,7 +1969,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        case BFA_IOIM_SM_CLEANUP:
-               /**
+               /*
                 * IO can be in cleanup state already due to TM command.
                 * 2nd cleanup request comes from ITN offline event.
                 */
@@ -1980,7 +1980,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  *     IO is waiting for room in request CQ
  */
 static void
@@ -2024,7 +2024,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  *     Active IO is being aborted, waiting for room in request CQ.
  */
 static void
@@ -2075,7 +2075,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  *     Active IO is being cleaned up, waiting for room in request CQ.
  */
 static void
@@ -2091,7 +2091,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
                break;
 
        case BFA_IOIM_SM_ABORT:
-               /**
+               /*
                 * IO is alraedy being cleaned up implicitly
                 */
                ioim->io_cbfn = __bfa_cb_ioim_abort;
@@ -2125,7 +2125,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  * IO bfa callback is pending.
  */
 static void
@@ -2152,7 +2152,7 @@ bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  * IO bfa callback is pending. IO resource cannot be freed.
  */
 static void
@@ -2185,7 +2185,7 @@ bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
        }
 }
 
-/**
+/*
  * IO is completed, waiting resource free from firmware.
  */
 static void
@@ -2214,7 +2214,7 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
 
 
 
-/**
+/*
  *  hal_ioim_private
  */
 
@@ -2247,7 +2247,7 @@ __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
 
        m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg;
        if (m->io_status == BFI_IOIM_STS_OK) {
-               /**
+               /*
                 * setup sense information, if present
                 */
                if ((m->scsi_status == SCSI_STATUS_CHECK_CONDITION) &&
@@ -2256,15 +2256,15 @@ __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
                        snsinfo = ioim->iosp->snsinfo;
                }
 
-               /**
+               /*
                 * setup residue value correctly for normal completions
                 */
                if (m->resid_flags == FCP_RESID_UNDER) {
-                       residue = bfa_os_ntohl(m->residue);
+                       residue = be32_to_cpu(m->residue);
                        bfa_stats(ioim->itnim, iocomp_underrun);
                }
                if (m->resid_flags == FCP_RESID_OVER) {
-                       residue = bfa_os_ntohl(m->residue);
+                       residue = be32_to_cpu(m->residue);
                        residue = -residue;
                        bfa_stats(ioim->itnim, iocomp_overrun);
                }
@@ -2327,7 +2327,7 @@ bfa_ioim_sgpg_alloced(void *cbarg)
        bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED);
 }
 
-/**
+/*
  * Send I/O request to firmware.
  */
 static bfa_boolean_t
@@ -2343,7 +2343,7 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
        struct scatterlist *sg;
        struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(ioim->bfa, ioim->reqq);
@@ -2354,14 +2354,14 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
                return BFA_FALSE;
        }
 
-       /**
+       /*
         * build i/o request message next
         */
-       m->io_tag = bfa_os_htons(ioim->iotag);
+       m->io_tag = cpu_to_be16(ioim->iotag);
        m->rport_hdl = ioim->itnim->rport->fw_handle;
        m->io_timeout = bfa_cb_ioim_get_timeout(ioim->dio);
 
-       /**
+       /*
         * build inline IO SG element here
         */
        sge = &m->sges[0];
@@ -2387,18 +2387,17 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
        sge->flags = BFI_SGE_PGDLEN;
        bfa_sge_to_be(sge);
 
-       /**
+       /*
         * set up I/O command parameters
         */
-       bfa_os_assign(m->cmnd, cmnd_z0);
+       m->cmnd = cmnd_z0;
        m->cmnd.lun = bfa_cb_ioim_get_lun(ioim->dio);
        m->cmnd.iodir = bfa_cb_ioim_get_iodir(ioim->dio);
-       bfa_os_assign(m->cmnd.cdb,
-                       *(scsi_cdb_t *)bfa_cb_ioim_get_cdb(ioim->dio));
+       m->cmnd.cdb = *(scsi_cdb_t *)bfa_cb_ioim_get_cdb(ioim->dio);
        fcp_dl = bfa_cb_ioim_get_size(ioim->dio);
-       m->cmnd.fcp_dl = bfa_os_htonl(fcp_dl);
+       m->cmnd.fcp_dl = cpu_to_be32(fcp_dl);
 
-       /**
+       /*
         * set up I/O message header
         */
        switch (m->cmnd.iodir) {
@@ -2427,28 +2426,28 @@ bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
        m->cmnd.priority = bfa_cb_ioim_get_priority(ioim->dio);
        m->cmnd.taskattr = bfa_cb_ioim_get_taskattr(ioim->dio);
 
-       /**
+       /*
         * Handle large CDB (>16 bytes).
         */
        m->cmnd.addl_cdb_len = (bfa_cb_ioim_get_cdblen(ioim->dio) -
                                        FCP_CMND_CDB_LEN) / sizeof(u32);
        if (m->cmnd.addl_cdb_len) {
-               bfa_os_memcpy(&m->cmnd.cdb + 1, (scsi_cdb_t *)
+               memcpy(&m->cmnd.cdb + 1, (scsi_cdb_t *)
                                bfa_cb_ioim_get_cdb(ioim->dio) + 1,
                                m->cmnd.addl_cdb_len * sizeof(u32));
                fcp_cmnd_fcpdl(&m->cmnd) =
-                               bfa_os_htonl(bfa_cb_ioim_get_size(ioim->dio));
+                               cpu_to_be32(bfa_cb_ioim_get_size(ioim->dio));
        }
 #endif
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(ioim->bfa, ioim->reqq);
        return BFA_TRUE;
 }
 
-/**
+/*
  * Setup any additional SG pages needed.Inline SG element is setup
  * at queuing time.
  */
@@ -2459,7 +2458,7 @@ bfa_ioim_sge_setup(struct bfa_ioim_s *ioim)
 
        bfa_assert(ioim->nsges > BFI_SGE_INLINE);
 
-       /**
+       /*
         * allocate SG pages needed
         */
        nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
@@ -2508,7 +2507,7 @@ bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
                        sge->sg_len = sg_dma_len(sg);
                        pgcumsz += sge->sg_len;
 
-                       /**
+                       /*
                         * set flags
                         */
                        if (i < (nsges - 1))
@@ -2523,7 +2522,7 @@ bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
 
                sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
 
-               /**
+               /*
                 * set the link element of each page
                 */
                if (sgeid == ioim->nsges) {
@@ -2540,7 +2539,7 @@ bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
        } while (sgeid < ioim->nsges);
 }
 
-/**
+/*
  * Send I/O abort request to firmware.
  */
 static bfa_boolean_t
@@ -2549,14 +2548,14 @@ bfa_ioim_send_abort(struct bfa_ioim_s *ioim)
        struct bfi_ioim_abort_req_s *m;
        enum bfi_ioim_h2i       msgop;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(ioim->bfa, ioim->reqq);
        if (!m)
                return BFA_FALSE;
 
-       /**
+       /*
         * build i/o request message next
         */
        if (ioim->iosp->abort_explicit)
@@ -2565,17 +2564,17 @@ bfa_ioim_send_abort(struct bfa_ioim_s *ioim)
                msgop = BFI_IOIM_H2I_IOCLEANUP_REQ;
 
        bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_lpuid(ioim->bfa));
-       m->io_tag    = bfa_os_htons(ioim->iotag);
+       m->io_tag    = cpu_to_be16(ioim->iotag);
        m->abort_tag = ++ioim->abort_tag;
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(ioim->bfa, ioim->reqq);
        return BFA_TRUE;
 }
 
-/**
+/*
  * Call to resume any I/O requests waiting for room in request queue.
  */
 static void
@@ -2591,7 +2590,7 @@ bfa_ioim_qresume(void *cbarg)
 static void
 bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim)
 {
-       /**
+       /*
         * Move IO from itnim queue to fcpim global queue since itnim will be
         * freed.
         */
@@ -2624,13 +2623,13 @@ bfa_ioim_is_abortable(struct bfa_ioim_s *ioim)
        return BFA_TRUE;
 }
 
-/**
+/*
  *     or after the link comes back.
  */
 void
 bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
 {
-       /**
+       /*
         * If path tov timer expired, failback with PATHTOV status - these
         * IO requests are not normally retried by IO stack.
         *
@@ -2645,7 +2644,7 @@ bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
        }
        bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
 
-       /**
+       /*
         * Move IO to fcpim global queue since itnim will be
         * freed.
         */
@@ -2655,11 +2654,11 @@ bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
 
 
 
-/**
+/*
  *  hal_ioim_friend
  */
 
-/**
+/*
  * Memory allocation and initialization.
  */
 void
@@ -2671,7 +2670,7 @@ bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
        u8                      *snsinfo;
        u32             snsbufsz;
 
-       /**
+       /*
         * claim memory first
         */
        ioim = (struct bfa_ioim_s *) bfa_meminfo_kva(minfo);
@@ -2682,7 +2681,7 @@ bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
        fcpim->ioim_sp_arr = iosp;
        bfa_meminfo_kva(minfo) = (u8 *) (iosp + fcpim->num_ioim_reqs);
 
-       /**
+       /*
         * Claim DMA memory for per IO sense data.
         */
        snsbufsz = fcpim->num_ioim_reqs * BFI_IOIM_SNSLEN;
@@ -2694,7 +2693,7 @@ bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
        snsinfo = fcpim->snsbase.kva;
        bfa_iocfc_set_snsbase(fcpim->bfa, fcpim->snsbase.pa);
 
-       /**
+       /*
         * Initialize ioim free queues
         */
        INIT_LIST_HEAD(&fcpim->ioim_free_q);
@@ -2706,7 +2705,7 @@ bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
                /*
                 * initialize IOIM
                 */
-               bfa_os_memset(ioim, 0, sizeof(struct bfa_ioim_s));
+               memset(ioim, 0, sizeof(struct bfa_ioim_s));
                ioim->iotag   = i;
                ioim->bfa     = fcpim->bfa;
                ioim->fcpim   = fcpim;
@@ -2723,7 +2722,7 @@ bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
        }
 }
 
-/**
+/*
  * Driver detach time call.
  */
 void
@@ -2740,7 +2739,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
        u16     iotag;
        enum bfa_ioim_event evt = BFA_IOIM_SM_COMP;
 
-       iotag = bfa_os_ntohs(rsp->io_tag);
+       iotag = be16_to_cpu(rsp->io_tag);
 
        ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
        bfa_assert(ioim->iotag == iotag);
@@ -2750,7 +2749,7 @@ bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
        bfa_trc(ioim->bfa, rsp->reuse_io_tag);
 
        if (bfa_sm_cmp_state(ioim, bfa_ioim_sm_active))
-               bfa_os_assign(ioim->iosp->comp_rspmsg, *m);
+               ioim->iosp->comp_rspmsg = *m;
 
        switch (rsp->io_status) {
        case BFI_IOIM_STS_OK:
@@ -2823,7 +2822,7 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
        struct bfa_ioim_s *ioim;
        u16     iotag;
 
-       iotag = bfa_os_ntohs(rsp->io_tag);
+       iotag = be16_to_cpu(rsp->io_tag);
 
        ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
        bfa_assert(ioim->iotag == iotag);
@@ -2837,7 +2836,7 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
 void
 bfa_ioim_profile_start(struct bfa_ioim_s *ioim)
 {
-       ioim->start_time = bfa_os_get_clock();
+       ioim->start_time = jiffies;
 }
 
 void
@@ -2845,7 +2844,7 @@ bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
 {
        u32 fcp_dl = bfa_cb_ioim_get_size(ioim->dio);
        u32 index = bfa_ioim_get_index(fcp_dl);
-       u64 end_time = bfa_os_get_clock();
+       u64 end_time = jiffies;
        struct bfa_itnim_latency_s *io_lat =
                        &(ioim->itnim->ioprofile.io_latency);
        u32 val = (u32)(end_time - ioim->start_time);
@@ -2859,7 +2858,7 @@ bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
                io_lat->max[index] : val;
        io_lat->avg[index] += val;
 }
-/**
+/*
  * Called by itnim to clean up IO while going offline.
  */
 void
@@ -2882,7 +2881,7 @@ bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim, struct bfa_tskim_s *tskim)
        bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
 }
 
-/**
+/*
  * IOC failure handling.
  */
 void
@@ -2893,7 +2892,7 @@ bfa_ioim_iocdisable(struct bfa_ioim_s *ioim)
        bfa_sm_send_event(ioim, BFA_IOIM_SM_HWFAIL);
 }
 
-/**
+/*
  * IO offline TOV popped. Fail the pending IO.
  */
 void
@@ -2905,11 +2904,11 @@ bfa_ioim_tov(struct bfa_ioim_s *ioim)
 
 
 
-/**
+/*
  *  hal_ioim_api
  */
 
-/**
+/*
  * Allocate IOIM resource for initiator mode I/O request.
  */
 struct bfa_ioim_s *
@@ -2919,7 +2918,7 @@ bfa_ioim_alloc(struct bfa_s *bfa, struct bfad_ioim_s *dio,
        struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
        struct bfa_ioim_s *ioim;
 
-       /**
+       /*
         * alocate IOIM resource
         */
        bfa_q_deq(&fcpim->ioim_free_q, &ioim);
@@ -2970,7 +2969,7 @@ bfa_ioim_start(struct bfa_ioim_s *ioim)
 
        bfa_ioim_cb_profile_start(ioim->fcpim, ioim);
 
-       /**
+       /*
         * Obtain the queue over which this request has to be issued
         */
        ioim->reqq = bfa_fcpim_ioredirect_enabled(ioim->bfa) ?
@@ -2980,7 +2979,7 @@ bfa_ioim_start(struct bfa_ioim_s *ioim)
        bfa_sm_send_event(ioim, BFA_IOIM_SM_START);
 }
 
-/**
+/*
  * Driver I/O abort request.
  */
 bfa_status_t
@@ -2999,11 +2998,11 @@ bfa_ioim_abort(struct bfa_ioim_s *ioim)
 }
 
 
-/**
+/*
  *  BFA TSKIM state machine functions
  */
 
-/**
+/*
  *     Task management command beginning state.
  */
 static void
@@ -3016,7 +3015,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                bfa_sm_set_state(tskim, bfa_tskim_sm_active);
                bfa_tskim_gather_ios(tskim);
 
-               /**
+               /*
                 * If device is offline, do not send TM on wire. Just cleanup
                 * any pending IO requests and complete TM request.
                 */
@@ -3040,7 +3039,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
        }
 }
 
-/**
+/*
  * brief
  *     TM command is active, awaiting completion from firmware to
  *     cleanup IO requests in TM scope.
@@ -3077,7 +3076,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
        }
 }
 
-/**
+/*
  *     An active TM is being cleaned up since ITN is offline. Awaiting cleanup
  *     completion event from firmware.
  */
@@ -3088,7 +3087,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
 
        switch (event) {
        case BFA_TSKIM_SM_DONE:
-               /**
+               /*
                 * Ignore and wait for ABORT completion from firmware.
                 */
                break;
@@ -3121,7 +3120,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        case BFA_TSKIM_SM_CLEANUP:
-               /**
+               /*
                 * Ignore, TM command completed on wire.
                 * Notify TM conmpletion on IO cleanup completion.
                 */
@@ -3138,7 +3137,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
        }
 }
 
-/**
+/*
  *     Task management command is waiting for room in request CQ
  */
 static void
@@ -3153,7 +3152,7 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
                break;
 
        case BFA_TSKIM_SM_CLEANUP:
-               /**
+               /*
                 * No need to send TM on wire since ITN is offline.
                 */
                bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
@@ -3173,7 +3172,7 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
        }
 }
 
-/**
+/*
  *     Task management command is active, awaiting for room in request CQ
  *     to send clean up request.
  */
@@ -3186,7 +3185,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
        switch (event) {
        case BFA_TSKIM_SM_DONE:
                bfa_reqq_wcancel(&tskim->reqq_wait);
-               /**
+               /*
                 *
                 * Fall through !!!
                 */
@@ -3208,7 +3207,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
        }
 }
 
-/**
+/*
  *     BFA callback is pending
  */
 static void
@@ -3236,7 +3235,7 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
 
 
 
-/**
+/*
  *  hal_tskim_private
  */
 
@@ -3289,7 +3288,7 @@ bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun)
        return BFA_FALSE;
 }
 
-/**
+/*
  *     Gather affected IO requests and task management commands.
  */
 static void
@@ -3301,7 +3300,7 @@ bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
 
        INIT_LIST_HEAD(&tskim->io_q);
 
-       /**
+       /*
         * Gather any active IO requests first.
         */
        list_for_each_safe(qe, qen, &itnim->io_q) {
@@ -3313,7 +3312,7 @@ bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
                }
        }
 
-       /**
+       /*
         * Failback any pending IO requests immediately.
         */
        list_for_each_safe(qe, qen, &itnim->pending_q) {
@@ -3327,7 +3326,7 @@ bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
        }
 }
 
-/**
+/*
  *     IO cleanup completion
  */
 static void
@@ -3339,7 +3338,7 @@ bfa_tskim_cleanp_comp(void *tskim_cbarg)
        bfa_sm_send_event(tskim, BFA_TSKIM_SM_IOS_DONE);
 }
 
-/**
+/*
  *     Gather affected IO requests and task management commands.
  */
 static void
@@ -3359,7 +3358,7 @@ bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
        bfa_wc_wait(&tskim->wc);
 }
 
-/**
+/*
  *     Send task management request to firmware.
  */
 static bfa_boolean_t
@@ -3368,33 +3367,33 @@ bfa_tskim_send(struct bfa_tskim_s *tskim)
        struct bfa_itnim_s *itnim = tskim->itnim;
        struct bfi_tskim_req_s *m;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(tskim->bfa, itnim->reqq);
        if (!m)
                return BFA_FALSE;
 
-       /**
+       /*
         * build i/o request message next
         */
        bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_TM_REQ,
                        bfa_lpuid(tskim->bfa));
 
-       m->tsk_tag = bfa_os_htons(tskim->tsk_tag);
+       m->tsk_tag = cpu_to_be16(tskim->tsk_tag);
        m->itn_fhdl = tskim->itnim->rport->fw_handle;
        m->t_secs = tskim->tsecs;
        m->lun = tskim->lun;
        m->tm_flags = tskim->tm_cmnd;
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(tskim->bfa, itnim->reqq);
        return BFA_TRUE;
 }
 
-/**
+/*
  *     Send abort request to cleanup an active TM to firmware.
  */
 static bfa_boolean_t
@@ -3403,29 +3402,29 @@ bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
        struct bfa_itnim_s      *itnim = tskim->itnim;
        struct bfi_tskim_abortreq_s     *m;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(tskim->bfa, itnim->reqq);
        if (!m)
                return BFA_FALSE;
 
-       /**
+       /*
         * build i/o request message next
         */
        bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_ABORT_REQ,
                        bfa_lpuid(tskim->bfa));
 
-       m->tsk_tag  = bfa_os_htons(tskim->tsk_tag);
+       m->tsk_tag  = cpu_to_be16(tskim->tsk_tag);
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(tskim->bfa, itnim->reqq);
        return BFA_TRUE;
 }
 
-/**
+/*
  *     Call to resume task management cmnd waiting for room in request queue.
  */
 static void
@@ -3437,7 +3436,7 @@ bfa_tskim_qresume(void *cbarg)
        bfa_sm_send_event(tskim, BFA_TSKIM_SM_QRESUME);
 }
 
-/**
+/*
  * Cleanup IOs associated with a task mangement command on IOC failures.
  */
 static void
@@ -3454,11 +3453,11 @@ bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim)
 
 
 
-/**
+/*
  *  hal_tskim_friend
  */
 
-/**
+/*
  * Notification on completions from related ioim.
  */
 void
@@ -3467,7 +3466,7 @@ bfa_tskim_iodone(struct bfa_tskim_s *tskim)
        bfa_wc_down(&tskim->wc);
 }
 
-/**
+/*
  * Handle IOC h/w failure notification from itnim.
  */
 void
@@ -3478,7 +3477,7 @@ bfa_tskim_iocdisable(struct bfa_tskim_s *tskim)
        bfa_sm_send_event(tskim, BFA_TSKIM_SM_HWFAIL);
 }
 
-/**
+/*
  * Cleanup TM command and associated IOs as part of ITNIM offline.
  */
 void
@@ -3489,7 +3488,7 @@ bfa_tskim_cleanup(struct bfa_tskim_s *tskim)
        bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP);
 }
 
-/**
+/*
  *     Memory allocation and initialization.
  */
 void
@@ -3507,7 +3506,7 @@ bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
                /*
                 * initialize TSKIM
                 */
-               bfa_os_memset(tskim, 0, sizeof(struct bfa_tskim_s));
+               memset(tskim, 0, sizeof(struct bfa_tskim_s));
                tskim->tsk_tag = i;
                tskim->bfa      = fcpim->bfa;
                tskim->fcpim    = fcpim;
@@ -3525,7 +3524,7 @@ bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
 void
 bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim)
 {
-       /**
+       /*
        * @todo
        */
 }
@@ -3536,14 +3535,14 @@ bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
        struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
        struct bfi_tskim_rsp_s *rsp = (struct bfi_tskim_rsp_s *) m;
        struct bfa_tskim_s *tskim;
-       u16     tsk_tag = bfa_os_ntohs(rsp->tsk_tag);
+       u16     tsk_tag = be16_to_cpu(rsp->tsk_tag);
 
        tskim = BFA_TSKIM_FROM_TAG(fcpim, tsk_tag);
        bfa_assert(tskim->tsk_tag == tsk_tag);
 
        tskim->tsk_status = rsp->tsk_status;
 
-       /**
+       /*
         * Firmware sends BFI_TSKIM_STS_ABORTED status for abort
         * requests. All other statuses are for normal completions.
         */
@@ -3558,7 +3557,7 @@ bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
 
 
 
-/**
+/*
  *  hal_tskim_api
  */
 
@@ -3585,7 +3584,7 @@ bfa_tskim_free(struct bfa_tskim_s *tskim)
        list_add_tail(&tskim->qe, &tskim->fcpim->tskim_free_q);
 }
 
-/**
+/*
  *     Start a task management command.
  *
  * @param[in]  tskim   BFA task management command instance
index 3bf343160aacbcfc0a2188ad72b06ed9529bd143..db53717eeb4bb49912a728483c455acabed54d67 100644 (file)
@@ -104,7 +104,7 @@ struct bfa_fcpim_mod_s {
        bfa_fcpim_profile_t     profile_start;
 };
 
-/**
+/*
  * BFA IO (initiator mode)
  */
 struct bfa_ioim_s {
@@ -137,7 +137,7 @@ struct bfa_ioim_sp_s {
        struct bfa_tskim_s      *tskim;         /*  Relevant TM cmd     */
 };
 
-/**
+/*
  * BFA Task management command (initiator mode)
  */
 struct bfa_tskim_s {
@@ -160,7 +160,7 @@ struct bfa_tskim_s {
 };
 
 
-/**
+/*
  * BFA i-t-n (initiator mode)
  */
 struct bfa_itnim_s {
@@ -303,7 +303,7 @@ bfa_status_t        bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
                struct bfa_itnim_ioprofile_s *ioprofile);
 #define bfa_itnim_get_reqq(__ioim) (((struct bfa_ioim_s *)__ioim)->itnim->reqq)
 
-/**
+/*
  *     BFA completion callback for bfa_itnim_online().
  *
  * @param[in]          itnim           FCS or driver itnim instance
@@ -312,7 +312,7 @@ bfa_status_t        bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
  */
 void   bfa_cb_itnim_online(void *itnim);
 
-/**
+/*
  *     BFA completion callback for bfa_itnim_offline().
  *
  * @param[in]          itnim           FCS or driver itnim instance
@@ -323,7 +323,7 @@ void        bfa_cb_itnim_offline(void *itnim);
 void   bfa_cb_itnim_tov_begin(void *itnim);
 void   bfa_cb_itnim_tov(void *itnim);
 
-/**
+/*
  *     BFA notification to FCS/driver for second level error recovery.
  *
  * Atleast one I/O request has timedout and target is unresponsive to
@@ -351,7 +351,7 @@ void                bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim,
                                      bfa_boolean_t iotov);
 
 
-/**
+/*
  *     I/O completion notification.
  *
  * @param[in]          dio                     driver IO structure
@@ -368,7 +368,7 @@ void        bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio,
                                  u8 scsi_status, int sns_len,
                                  u8 *sns_info, s32 residue);
 
-/**
+/*
  *     I/O good completion notification.
  *
  * @param[in]          dio                     driver IO structure
@@ -377,7 +377,7 @@ void        bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio,
  */
 void   bfa_cb_ioim_good_comp(void *bfad, struct bfad_ioim_s *dio);
 
-/**
+/*
  *     I/O abort completion notification
  *
  * @param[in]          dio                     driver IO that was aborted
index 9cebbe30a6782dbf8e8d9fedea033d7f19531d68..c94502dfac664f55fd42080695989d9e1cb1697b 100644 (file)
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 
-/**
+/*
  *  bfa_fcs.c BFA FCS main
  */
 
@@ -25,7 +25,7 @@
 
 BFA_TRC_FILE(FCS, FCS);
 
-/**
+/*
  * FCS sub-modules
  */
 struct bfa_fcs_mod_s {
@@ -43,7 +43,7 @@ static struct bfa_fcs_mod_s fcs_modules[] = {
          bfa_fcs_fabric_modexit },
 };
 
-/**
+/*
  *  fcs_api BFA FCS API
  */
 
@@ -58,11 +58,11 @@ bfa_fcs_exit_comp(void *fcs_cbarg)
 
 
 
-/**
+/*
  *  fcs_api BFA FCS API
  */
 
-/**
+/*
  * fcs attach -- called once to initialize data structures at driver attach time
  */
 void
@@ -86,7 +86,7 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
        }
 }
 
-/**
+/*
  * fcs initialization, called once after bfa initialization is complete
  */
 void
@@ -110,7 +110,7 @@ bfa_fcs_init(struct bfa_fcs_s *fcs)
        }
 }
 
-/**
+/*
  * Start FCS operations.
  */
 void
@@ -119,7 +119,7 @@ bfa_fcs_start(struct bfa_fcs_s *fcs)
        bfa_fcs_fabric_modstart(fcs);
 }
 
-/**
+/*
  *     brief
  *             FCS driver details initialization.
  *
@@ -138,7 +138,7 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
        bfa_fcs_fabric_psymb_init(&fcs->fabric);
 }
 
-/**
+/*
  *     brief
  *             FCS FDMI Driver Parameter Initialization
  *
@@ -154,7 +154,7 @@ bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable)
        fcs->fdmi_enabled = fdmi_enable;
 
 }
-/**
+/*
  *     brief
  *             FCS instance cleanup and exit.
  *
@@ -196,7 +196,7 @@ bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs)
        bfa_wc_down(&fcs->wc);
 }
 
-/**
+/*
  * Fabric module implementation.
  */
 
@@ -232,11 +232,11 @@ static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
                                         u32 rsp_len,
                                         u32 resid_len,
                                         struct fchs_s *rspfchs);
-/**
+/*
  *  fcs_fabric_sm fabric state machine functions
  */
 
-/**
+/*
  * Fabric state machine events
  */
 enum bfa_fcs_fabric_event {
@@ -286,7 +286,7 @@ static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
                                           enum bfa_fcs_fabric_event event);
 static void    bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
                                           enum bfa_fcs_fabric_event event);
-/**
+/*
  *   Beginning state before fabric creation.
  */
 static void
@@ -312,7 +312,7 @@ bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   Beginning state before fabric creation.
  */
 static void
@@ -345,7 +345,7 @@ bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   Link is down, awaiting LINK UP event from port. This is also the
  *   first state at fabric creation.
  */
@@ -375,7 +375,7 @@ bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   FLOGI is in progress, awaiting FLOGI reply.
  */
 static void
@@ -468,7 +468,7 @@ bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   Authentication is in progress, awaiting authentication results.
  */
 static void
@@ -508,7 +508,7 @@ bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   Authentication failed
  */
 static void
@@ -534,7 +534,7 @@ bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   Port is in loopback mode.
  */
 static void
@@ -560,7 +560,7 @@ bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   There is no attached fabric - private loop or NPort-to-NPort topology.
  */
 static void
@@ -593,7 +593,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   Fabric is online - normal operating state.
  */
 static void
@@ -628,7 +628,7 @@ bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   Exchanging virtual fabric parameters.
  */
 static void
@@ -652,7 +652,7 @@ bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
+/*
  *   EVFP exchange complete and VFT tagging is enabled.
  */
 static void
@@ -663,7 +663,7 @@ bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
        bfa_trc(fabric->fcs, event);
 }
 
-/**
+/*
  *   Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
  */
 static void
@@ -684,7 +684,7 @@ bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
                fabric->event_arg.swp_vfid);
 }
 
-/**
+/*
  *   Fabric is being deleted, awaiting vport delete completions.
  */
 static void
@@ -714,7 +714,7 @@ bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
 
 
 
-/**
+/*
  *  fcs_fabric_private fabric private functions
  */
 
@@ -728,7 +728,7 @@ bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
        port_cfg->pwwn = bfa_ioc_get_pwwn(&fabric->fcs->bfa->ioc);
 }
 
-/**
+/*
  * Port Symbolic Name Creation for base port.
  */
 void
@@ -789,7 +789,7 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
        port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
 }
 
-/**
+/*
  * bfa lps login completion callback
  */
 void
@@ -867,7 +867,7 @@ bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
        bfa_trc(fabric->fcs, fabric->is_npiv);
        bfa_trc(fabric->fcs, fabric->is_auth);
 }
-/**
+/*
  *             Allocate and send FLOGI.
  */
 static void
@@ -897,7 +897,7 @@ bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
        bfa_fcs_fabric_set_opertype(fabric);
        fabric->stats.fabric_onlines++;
 
-       /**
+       /*
         * notify online event to base and then virtual ports
         */
        bfa_fcs_lport_online(&fabric->bport);
@@ -917,7 +917,7 @@ bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
        bfa_trc(fabric->fcs, fabric->fabric_name);
        fabric->stats.fabric_offlines++;
 
-       /**
+       /*
         * notify offline event first to vports and then base port.
         */
        list_for_each_safe(qe, qen, &fabric->vport_q) {
@@ -939,7 +939,7 @@ bfa_fcs_fabric_delay(void *cbarg)
        bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
 }
 
-/**
+/*
  * Delete all vports and wait for vport delete completions.
  */
 static void
@@ -965,11 +965,11 @@ bfa_fcs_fabric_delete_comp(void *cbarg)
        bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
 }
 
-/**
+/*
  *  fcs_fabric_public fabric public functions
  */
 
-/**
+/*
  * Attach time initialization.
  */
 void
@@ -978,9 +978,9 @@ bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
        struct bfa_fcs_fabric_s *fabric;
 
        fabric = &fcs->fabric;
-       bfa_os_memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
+       memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
 
-       /**
+       /*
         * Initialize base fabric.
         */
        fabric->fcs = fcs;
@@ -989,7 +989,7 @@ bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
        fabric->lps = bfa_lps_alloc(fcs->bfa);
        bfa_assert(fabric->lps);
 
-       /**
+       /*
         * Initialize fabric delete completion handler. Fabric deletion is
         * complete when the last vport delete is complete.
         */
@@ -1007,7 +1007,7 @@ bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
        bfa_trc(fcs, 0);
 }
 
-/**
+/*
  *   Module cleanup
  */
 void
@@ -1017,7 +1017,7 @@ bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
 
        bfa_trc(fcs, 0);
 
-       /**
+       /*
         * Cleanup base fabric.
         */
        fabric = &fcs->fabric;
@@ -1025,7 +1025,7 @@ bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
        bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
 }
 
-/**
+/*
  * Fabric module start -- kick starts FCS actions
  */
 void
@@ -1038,7 +1038,7 @@ bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
        bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
 }
 
-/**
+/*
  *   Suspend fabric activity as part of driver suspend.
  */
 void
@@ -1064,7 +1064,7 @@ bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
        return fabric->oper_type;
 }
 
-/**
+/*
  *   Link up notification from BFA physical port module.
  */
 void
@@ -1074,7 +1074,7 @@ bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
        bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
 }
 
-/**
+/*
  *   Link down notification from BFA physical port module.
  */
 void
@@ -1084,7 +1084,7 @@ bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
        bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
 }
 
-/**
+/*
  *   A child vport is being created in the fabric.
  *
  *   Call from vport module at vport creation. A list of base port and vports
@@ -1099,7 +1099,7 @@ void
 bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
                        struct bfa_fcs_vport_s *vport)
 {
-       /**
+       /*
         * - add vport to fabric's vport_q
         */
        bfa_trc(fabric->fcs, fabric->vf_id);
@@ -1109,7 +1109,7 @@ bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
        bfa_wc_up(&fabric->wc);
 }
 
-/**
+/*
  *   A child vport is being deleted from fabric.
  *
  *   Vport is being deleted.
@@ -1123,7 +1123,7 @@ bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
        bfa_wc_down(&fabric->wc);
 }
 
-/**
+/*
  *   Base port is deleted.
  */
 void
@@ -1133,7 +1133,7 @@ bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric)
 }
 
 
-/**
+/*
  *    Check if fabric is online.
  *
  *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
@@ -1146,7 +1146,7 @@ bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
        return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online);
 }
 
-/**
+/*
  *     brief
  *
  */
@@ -1158,7 +1158,7 @@ bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf, struct bfa_fcs_s *fcs,
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Lookup for a vport withing a fabric given its pwwn
  */
 struct bfa_fcs_vport_s *
@@ -1176,7 +1176,7 @@ bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
        return NULL;
 }
 
-/**
+/*
  *    In a given fabric, return the number of lports.
  *
  *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
@@ -1214,7 +1214,7 @@ bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
 
        return oui;
 }
-/**
+/*
  *             Unsolicited frame receive handling.
  */
 void
@@ -1230,7 +1230,7 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
        bfa_trc(fabric->fcs, len);
        bfa_trc(fabric->fcs, pid);
 
-       /**
+       /*
         * Look for our own FLOGI frames being looped back. This means an
         * external loopback cable is in place. Our own FLOGI frames are
         * sometimes looped back when switch port gets temporarily bypassed.
@@ -1242,7 +1242,7 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
                return;
        }
 
-       /**
+       /*
         * FLOGI/EVFP exchanges should be consumed by base fabric.
         */
        if (fchs->d_id == bfa_os_hton3b(FC_FABRIC_PORT)) {
@@ -1252,7 +1252,7 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
        }
 
        if (fabric->bport.pid == pid) {
-               /**
+               /*
                 * All authentication frames should be routed to auth
                 */
                bfa_trc(fabric->fcs, els_cmd->els_code);
@@ -1266,7 +1266,7 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
                return;
        }
 
-       /**
+       /*
         * look for a matching local port ID
         */
        list_for_each(qe, &fabric->vport_q) {
@@ -1280,7 +1280,7 @@ bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
        bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
 }
 
-/**
+/*
  *             Unsolicited frames to be processed by fabric.
  */
 static void
@@ -1304,7 +1304,7 @@ bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
        }
 }
 
-/**
+/*
  *     Process incoming FLOGI
  */
 static void
@@ -1329,7 +1329,7 @@ bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
                return;
        }
 
-       fabric->bb_credit = bfa_os_ntohs(flogi->csp.bbcred);
+       fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred);
        bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
        bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
 
@@ -1351,7 +1351,7 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
        struct fchs_s   fchs;
 
        fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
-       /**
+       /*
         * Do not expect this failure -- expect remote node to retry
         */
        if (!fcxp)
@@ -1370,7 +1370,7 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
                      FC_MAX_PDUSZ, 0);
 }
 
-/**
+/*
  *   Flogi Acc completion callback.
  */
 static void
@@ -1417,130 +1417,7 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
        }
 }
 
-/**
- *  fcs_vf_api virtual fabrics API
- */
-
-/**
- * Enable VF mode.
- *
- * @param[in]          fcs             fcs module instance
- * @param[in]          vf_id           default vf_id of port, FC_VF_ID_NULL
- *                                     to use standard default vf_id of 1.
- *
- * @retval     BFA_STATUS_OK           vf mode is enabled
- * @retval     BFA_STATUS_BUSY         Port is active. Port must be disabled
- *                                     before VF mode can be enabled.
- */
-bfa_status_t
-bfa_fcs_vf_mode_enable(struct bfa_fcs_s *fcs, u16 vf_id)
-{
-       return BFA_STATUS_OK;
-}
-
-/**
- * Disable VF mode.
- *
- * @param[in]          fcs             fcs module instance
- *
- * @retval     BFA_STATUS_OK           vf mode is disabled
- * @retval     BFA_STATUS_BUSY         VFs are present and being used. All
- *                                     VFs must be deleted before disabling
- *                                     VF mode.
- */
-bfa_status_t
-bfa_fcs_vf_mode_disable(struct bfa_fcs_s *fcs)
-{
-       return BFA_STATUS_OK;
-}
-
-/**
- *  Create a new VF instance.
- *
- *  A new VF is created using the given VF configuration. A VF is identified
- *  by VF id. No duplicate VF creation is allowed with the same VF id. Once
- *  a VF is created, VF is automatically started after link initialization
- *  and EVFP exchange is completed.
- *
- *     param[in] vf     -      FCS vf data structure. Memory is
- *                             allocated by caller (driver)
- *     param[in] fcs    -      FCS module
- *     param[in] vf_cfg -      VF configuration
- *     param[in] vf_drv -      Opaque handle back to the driver's
- *                             virtual vf structure
- *
- *     retval BFA_STATUS_OK VF creation is successful
- *     retval BFA_STATUS_FAILED VF creation failed
- *     retval BFA_STATUS_EEXIST A VF exists with the given vf_id
- */
-bfa_status_t
-bfa_fcs_vf_create(bfa_fcs_vf_t *vf, struct bfa_fcs_s *fcs, u16 vf_id,
-                 struct bfa_lport_cfg_s *port_cfg, struct bfad_vf_s *vf_drv)
-{
-       bfa_trc(fcs, vf_id);
-       return BFA_STATUS_OK;
-}
-
-/**
- *     Use this function to delete a BFA VF object. VF object should
- *     be stopped before this function call.
- *
- *     param[in] vf - pointer to bfa_vf_t.
- *
- *     retval BFA_STATUS_OK    On vf deletion success
- *     retval BFA_STATUS_BUSY VF is not in a stopped state
- *     retval BFA_STATUS_INPROGRESS VF deletion in in progress
- */
-bfa_status_t
-bfa_fcs_vf_delete(bfa_fcs_vf_t *vf)
-{
-       bfa_trc(vf->fcs, vf->vf_id);
-       return BFA_STATUS_OK;
-}
-
-
-/**
- *     Returns attributes of the given VF.
- *
- *     param[in]       vf      pointer to bfa_vf_t.
- *     param[out] vf_attr      vf attributes returned
- *
- *     return None
- */
-void
-bfa_fcs_vf_get_attr(bfa_fcs_vf_t *vf, struct bfa_vf_attr_s *vf_attr)
-{
-       bfa_trc(vf->fcs, vf->vf_id);
-}
-
-/**
- *     Return statistics associated with the given vf.
- *
- *     param[in] vf            pointer to bfa_vf_t.
- *     param[out] vf_stats     vf statistics returned
- *
- *     @return None
- */
-void
-bfa_fcs_vf_get_stats(bfa_fcs_vf_t *vf, struct bfa_vf_stats_s *vf_stats)
-{
-       bfa_os_memcpy(vf_stats, &vf->stats, sizeof(struct bfa_vf_stats_s));
-}
-
-/**
- *     clear statistics associated with the given vf.
- *
- *     param[in]       vf      pointer to bfa_vf_t.
- *
- *     @return None
- */
-void
-bfa_fcs_vf_clear_stats(bfa_fcs_vf_t *vf)
-{
-       bfa_os_memset(&vf->stats, 0, sizeof(struct bfa_vf_stats_s));
-}
-
-/**
+/*
  *     Returns FCS vf structure for a given vf_id.
  *
  *     param[in]       vf_id - VF_ID
@@ -1558,81 +1435,7 @@ bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
        return NULL;
 }
 
-/**
- *     Return the list of VFs configured.
- *
- *     param[in]       fcs     fcs module instance
- *     param[out]      vf_ids  returned list of vf_ids
- *     param[in,out]   nvfs    in:size of vf_ids array,
- *                             out:total elements present,
- *                             actual elements returned is limited by the size
- *
- *     return Driver VF structure
- */
-void
-bfa_fcs_vf_list(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs)
-{
-       bfa_trc(fcs, *nvfs);
-}
-
-/**
- *     Return the list of all VFs visible from fabric.
- *
- *     param[in]       fcs     fcs module instance
- *     param[out]      vf_ids  returned list of vf_ids
- *     param[in,out]   nvfs    in:size of vf_ids array,
- *                             out:total elements present,
- *                             actual elements returned is limited by the size
- *
- *     return Driver VF structure
- */
-void
-bfa_fcs_vf_list_all(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs)
-{
-       bfa_trc(fcs, *nvfs);
-}
-
-/**
- *     Return the list of local logical ports present in the given VF.
- *
- *     param[in]       vf      vf for which logical ports are returned
- *     param[out]      lpwwn   returned logical port wwn list
- *     param[in,out]   nlports in:size of lpwwn list;
- *                             out:total elements present,
- *                             actual elements returned is limited by the size
- */
-void
-bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t lpwwn[], int *nlports)
-{
-       struct list_head        *qe;
-       struct bfa_fcs_vport_s *vport;
-       int     i;
-       struct bfa_fcs_s      *fcs;
-
-       if (vf == NULL || lpwwn == NULL || *nlports == 0)
-               return;
-
-       fcs = vf->fcs;
-
-       bfa_trc(fcs, vf->vf_id);
-       bfa_trc(fcs, (u32) *nlports);
-
-       i = 0;
-       lpwwn[i++] = vf->bport.port_cfg.pwwn;
-
-       list_for_each(qe, &vf->vport_q) {
-               if (i >= *nlports)
-                       break;
-
-               vport = (struct bfa_fcs_vport_s *) qe;
-               lpwwn[i++] = vport->lport.port_cfg.pwwn;
-       }
-
-       bfa_trc(fcs, i);
-       *nlports = i;
-}
-
-/**
+/*
  * BFA FCS PPORT ( physical port)
  */
 static void
@@ -1662,11 +1465,11 @@ bfa_fcs_port_attach(struct bfa_fcs_s *fcs)
        bfa_fcport_event_register(fcs->bfa, bfa_fcs_port_event_handler, fcs);
 }
 
-/**
+/*
  * BFA FCS UF ( Unsolicited Frames)
  */
 
-/**
+/*
  *             BFA callback for unsolicited frame receive handler.
  *
  * @param[in]          cbarg           callback arg for receive handler
@@ -1683,7 +1486,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
        struct fc_vft_s *vft;
        struct bfa_fcs_fabric_s *fabric;
 
-       /**
+       /*
         * check for VFT header
         */
        if (fchs->routing == FC_RTG_EXT_HDR &&
@@ -1695,7 +1498,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
                else
                        fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
 
-               /**
+               /*
                 * drop frame if vfid is unknown
                 */
                if (!fabric) {
@@ -1705,7 +1508,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
                        return;
                }
 
-               /**
+               /*
                 * skip vft header
                 */
                fchs = (struct fchs_s *) (vft + 1);
index d75045df1e7e2202f817eb20cf8f70ee5423c14f..9cb6a55977c3ad932642a80a5eecff8cb803fe24 100644 (file)
@@ -196,7 +196,7 @@ struct bfa_fcs_fabric_s {
 #define bfa_fcs_fabric_is_switched(__f)                        \
        ((__f)->fab_type == BFA_FCS_FABRIC_SWITCHED)
 
-/**
+/*
  *   The design calls for a single implementation of base fabric and vf.
  */
 #define bfa_fcs_vf_t struct bfa_fcs_fabric_s
@@ -216,7 +216,7 @@ struct bfa_fcs_fabric_s;
 
 #define bfa_fcs_lport_t struct bfa_fcs_lport_s
 
-/**
+/*
  * Symbolic Name related defines
  *  Total bytes 255.
  *  Physical Port's symbolic name 128 bytes.
@@ -239,7 +239,7 @@ struct bfa_fcs_fabric_s;
 #define BFA_FCS_PORT_SYMBNAME_OSINFO_SZ                        48
 #define BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ               16
 
-/**
+/*
  * Get FC port ID for a logical port.
  */
 #define bfa_fcs_lport_get_fcid(_lport) ((_lport)->pid)
@@ -262,7 +262,7 @@ bfa_fcs_lport_get_drvport(struct bfa_fcs_lport_s *port)
 #define bfa_fcs_lport_get_fabric_ipaddr(_lport)                \
                ((_lport)->fabric->fabric_ip_addr)
 
-/**
+/*
  * bfa fcs port public functions
  */
 
@@ -342,7 +342,7 @@ struct bfa_fcs_vport_s {
 #define bfa_fcs_vport_get_port(vport)                  \
        ((struct bfa_fcs_lport_s  *)(&vport->port))
 
-/**
+/*
  * bfa fcs vport public functions
  */
 bfa_status_t bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport,
@@ -393,7 +393,7 @@ struct bfa_fcs_rpf_s {
        enum bfa_port_speed     rpsc_speed;
        /*  Current Speed from RPSC. O if RPSC fails */
        enum bfa_port_speed     assigned_speed;
-       /**
+       /*
         * Speed assigned by the user.  will be used if RPSC is
         * not supported by the rport.
         */
@@ -434,7 +434,7 @@ bfa_fcs_rport_get_halrport(struct bfa_fcs_rport_s *rport)
        return rport->bfa_rport;
 }
 
-/**
+/*
  * bfa fcs rport API functions
  */
 bfa_status_t bfa_fcs_rport_add(struct bfa_fcs_lport_s *port, wwn_t *pwwn,
@@ -573,7 +573,7 @@ bfa_fcs_itnim_get_halitn(struct bfa_fcs_itnim_s *itnim)
        return itnim->bfa_itnim;
 }
 
-/**
+/*
  * bfa fcs FCP Initiator mode API functions
  */
 void bfa_fcs_itnim_get_attr(struct bfa_fcs_itnim_s *itnim,
@@ -677,22 +677,9 @@ void bfa_fcs_exit(struct bfa_fcs_s *fcs);
 void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod);
 void           bfa_fcs_start(struct bfa_fcs_s *fcs);
 
-/**
+/*
  * bfa fcs vf public functions
  */
-bfa_status_t bfa_fcs_vf_mode_enable(struct bfa_fcs_s *fcs, u16 vf_id);
-bfa_status_t bfa_fcs_vf_mode_disable(struct bfa_fcs_s *fcs);
-bfa_status_t bfa_fcs_vf_create(bfa_fcs_vf_t *vf, struct bfa_fcs_s *fcs,
-                              u16 vf_id, struct bfa_lport_cfg_s *port_cfg,
-                              struct bfad_vf_s *vf_drv);
-bfa_status_t bfa_fcs_vf_delete(bfa_fcs_vf_t *vf);
-void bfa_fcs_vf_list(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs);
-void bfa_fcs_vf_list_all(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs);
-void bfa_fcs_vf_get_attr(bfa_fcs_vf_t *vf, struct bfa_vf_attr_s *vf_attr);
-void bfa_fcs_vf_get_stats(bfa_fcs_vf_t *vf,
-                         struct bfa_vf_stats_s *vf_stats);
-void bfa_fcs_vf_clear_stats(bfa_fcs_vf_t *vf);
-void bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t vpwwn[], int *nports);
 bfa_fcs_vf_t *bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id);
 u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
 
@@ -729,11 +716,11 @@ u16 bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric);
 void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs);
 void bfa_fcs_port_attach(struct bfa_fcs_s *fcs);
 
-/**
+/*
  * BFA FCS callback interfaces
  */
 
-/**
+/*
  * fcb Main fcs callbacks
  */
 
@@ -742,7 +729,7 @@ struct bfad_vf_s;
 struct bfad_vport_s;
 struct bfad_rport_s;
 
-/**
+/*
  * lport callbacks
  */
 struct bfad_port_s *bfa_fcb_lport_new(struct bfad_s *bfad,
@@ -754,19 +741,19 @@ void bfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles,
                          struct bfad_vf_s *vf_drv,
                          struct bfad_vport_s *vp_drv);
 
-/**
+/*
  * vport callbacks
  */
 void bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s);
 
-/**
+/*
  * rport callbacks
  */
 bfa_status_t bfa_fcb_rport_alloc(struct bfad_s *bfad,
                                 struct bfa_fcs_rport_s **rport,
                                 struct bfad_rport_s **rport_drv);
 
-/**
+/*
  * itnim callbacks
  */
 void bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
index 569dfefab70d7a1ae71143895e08571d0b015b5c..9662bcdeb41d64c50ab7530fd34ab17d543fc44c 100644 (file)
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 
-/**
+/*
  *  fcpim.c - FCP initiator mode i-t nexus state machine
  */
 
@@ -38,7 +38,7 @@ static void   bfa_fcs_itnim_prli_response(void *fcsarg,
                            bfa_status_t req_status, u32 rsp_len,
                            u32 resid_len, struct fchs_s *rsp_fchs);
 
-/**
+/*
  *  fcs_itnim_sm FCS itnim state machine events
  */
 
@@ -84,7 +84,7 @@ static struct bfa_sm_table_s itnim_sm_table[] = {
        {BFA_SM(bfa_fcs_itnim_sm_initiator), BFA_ITNIM_INITIATIOR},
 };
 
-/**
+/*
  *  fcs_itnim_sm FCS itnim state machine
  */
 
@@ -494,11 +494,11 @@ bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim)
 
 
 
-/**
+/*
  *  itnim_public FCS ITNIM public interfaces
  */
 
-/**
+/*
  *     Called by rport when a new rport is created.
  *
  * @param[in] rport    -  remote port.
@@ -554,7 +554,7 @@ bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
        return itnim;
 }
 
-/**
+/*
  *     Called by rport to delete  the instance of FCPIM.
  *
  * @param[in] rport    -  remote port.
@@ -566,7 +566,7 @@ bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim)
        bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_DELETE);
 }
 
-/**
+/*
  * Notification from rport that PLOGI is complete to initiate FC-4 session.
  */
 void
@@ -586,7 +586,7 @@ bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim)
        }
 }
 
-/**
+/*
  * Called by rport to handle a remote device offline.
  */
 void
@@ -596,7 +596,7 @@ bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim)
        bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_OFFLINE);
 }
 
-/**
+/*
  * Called by rport when remote port is known to be an initiator from
  * PRLI received.
  */
@@ -608,7 +608,7 @@ bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim)
        bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR);
 }
 
-/**
+/*
  * Called by rport to check if the itnim is online.
  */
 bfa_status_t
@@ -625,7 +625,7 @@ bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim)
        }
 }
 
-/**
+/*
  * BFA completion callback for bfa_itnim_online().
  */
 void
@@ -637,7 +637,7 @@ bfa_cb_itnim_online(void *cbarg)
        bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_ONLINE);
 }
 
-/**
+/*
  * BFA completion callback for bfa_itnim_offline().
  */
 void
@@ -649,7 +649,7 @@ bfa_cb_itnim_offline(void *cb_arg)
        bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_OFFLINE);
 }
 
-/**
+/*
  * Mark the beginning of PATH TOV handling. IO completion callbacks
  * are still pending.
  */
@@ -661,7 +661,7 @@ bfa_cb_itnim_tov_begin(void *cb_arg)
        bfa_trc(itnim->fcs, itnim->rport->pwwn);
 }
 
-/**
+/*
  * Mark the end of PATH TOV handling. All pending IOs are already cleaned up.
  */
 void
@@ -674,7 +674,7 @@ bfa_cb_itnim_tov(void *cb_arg)
        itnim_drv->state = ITNIM_STATE_TIMEOUT;
 }
 
-/**
+/*
  *             BFA notification to FCS/driver for second level error recovery.
  *
  * Atleast one I/O request has timedout and target is unresponsive to
@@ -736,7 +736,7 @@ bfa_fcs_itnim_stats_get(struct bfa_fcs_lport_s *port, wwn_t rpwwn,
        if (itnim == NULL)
                return BFA_STATUS_NO_FCPIM_NEXUS;
 
-       bfa_os_memcpy(stats, &itnim->stats, sizeof(struct bfa_itnim_stats_s));
+       memcpy(stats, &itnim->stats, sizeof(struct bfa_itnim_stats_s));
 
        return BFA_STATUS_OK;
 }
@@ -753,7 +753,7 @@ bfa_fcs_itnim_stats_clear(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
        if (itnim == NULL)
                return BFA_STATUS_NO_FCPIM_NEXUS;
 
-       bfa_os_memset(&itnim->stats, 0, sizeof(struct bfa_itnim_stats_s));
+       memset(&itnim->stats, 0, sizeof(struct bfa_itnim_stats_s));
        return BFA_STATUS_OK;
 }
 
index b522bf30247a62d2f63be931b2c46dc73df4a583..377cbfff6f2ec88a467b6e8014d27c91d3b4a0c3 100644 (file)
  * General Public License for more details.
  */
 
-/**
- *  bfa_fcs_lport.c BFA FCS port
- */
-
 #include "bfa_fcs.h"
 #include "bfa_fcbuild.h"
 #include "bfa_fc.h"
 
 BFA_TRC_FILE(FCS, PORT);
 
-/**
- * Forward declarations
- */
-
 static void     bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port,
                                         struct fchs_s *rx_fchs, u8 reason_code,
                                         u8 reason_code_expl);
@@ -72,7 +64,7 @@ static struct {
                        bfa_fcs_lport_n2n_offline},
        };
 
-/**
+/*
  *  fcs_port_sm FCS logical port state machine
  */
 
@@ -240,7 +232,7 @@ bfa_fcs_lport_sm_deleting(
        }
 }
 
-/**
+/*
  *  fcs_port_pvt
  */
 
@@ -272,7 +264,7 @@ bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
                          FC_MAX_PDUSZ, 0);
 }
 
-/**
+/*
  * Process incoming plogi from a remote port.
  */
 static void
@@ -303,7 +295,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
                return;
        }
 
-       /**
+       /*
         * Direct Attach P2P mode : verify address assigned by the r-port.
         */
        if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
@@ -319,12 +311,12 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
                port->pid  = rx_fchs->d_id;
        }
 
-       /**
+       /*
         * First, check if we know the device by pwwn.
         */
        rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name);
        if (rport) {
-               /**
+               /*
                 * Direct Attach P2P mode : handle address assigned by r-port.
                 */
                if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
@@ -337,37 +329,37 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
                return;
        }
 
-       /**
+       /*
         * Next, lookup rport by PID.
         */
        rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id);
        if (!rport) {
-               /**
+               /*
                 * Inbound PLOGI from a new device.
                 */
                bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
                return;
        }
 
-       /**
+       /*
         * Rport is known only by PID.
         */
        if (rport->pwwn) {
-               /**
+               /*
                 * This is a different device with the same pid. Old device
                 * disappeared. Send implicit LOGO to old device.
                 */
                bfa_assert(rport->pwwn != plogi->port_name);
                bfa_fcs_rport_logo_imp(rport);
 
-               /**
+               /*
                 * Inbound PLOGI from a new device (with old PID).
                 */
                bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
                return;
        }
 
-       /**
+       /*
         * PLOGI crossing each other.
         */
        bfa_assert(rport->pwwn == WWN_NULL);
@@ -479,12 +471,12 @@ static void
 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
                        struct fc_rnid_general_topology_data_s *gen_topo_data)
 {
-       bfa_os_memset(gen_topo_data, 0,
+       memset(gen_topo_data, 0,
                      sizeof(struct fc_rnid_general_topology_data_s));
 
-       gen_topo_data->asso_type = bfa_os_htonl(RNID_ASSOCIATED_TYPE_HOST);
+       gen_topo_data->asso_type = cpu_to_be32(RNID_ASSOCIATED_TYPE_HOST);
        gen_topo_data->phy_port_num = 0;        /* @todo */
-       gen_topo_data->num_attached_nodes = bfa_os_htonl(1);
+       gen_topo_data->num_attached_nodes = cpu_to_be32(1);
 }
 
 static void
@@ -598,10 +590,10 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
 
 
 
-/**
+/*
  *  fcs_lport_api BFA FCS port API
  */
-/**
+/*
  *   Module initialization
  */
 void
@@ -610,7 +602,7 @@ bfa_fcs_lport_modinit(struct bfa_fcs_s *fcs)
 
 }
 
-/**
+/*
  *   Module cleanup
  */
 void
@@ -619,7 +611,7 @@ bfa_fcs_lport_modexit(struct bfa_fcs_s *fcs)
        bfa_fcs_modexit_comp(fcs);
 }
 
-/**
+/*
  * Unsolicited frame receive handling.
  */
 void
@@ -637,7 +629,7 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
                return;
        }
 
-       /**
+       /*
         * First, handle ELSs that donot require a login.
         */
        /*
@@ -673,7 +665,7 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
                        bfa_fcs_lport_abts_acc(lport, fchs);
                return;
        }
-       /**
+       /*
         * look for a matching remote port ID
         */
        rport = bfa_fcs_lport_get_rport_by_pid(lport, pid);
@@ -686,7 +678,7 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
                return;
        }
 
-       /**
+       /*
         * Only handles ELS frames for now.
         */
        if (fchs->type != FC_TYPE_ELS) {
@@ -702,20 +694,20 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
        }
 
        if (els_cmd->els_code == FC_ELS_LOGO) {
-               /**
+               /*
                 * @todo Handle LOGO frames received.
                 */
                return;
        }
 
        if (els_cmd->els_code == FC_ELS_PRLI) {
-               /**
+               /*
                 * @todo Handle PRLI frames received.
                 */
                return;
        }
 
-       /**
+       /*
         * Unhandled ELS frames. Send a LS_RJT.
         */
        bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
@@ -723,7 +715,7 @@ bfa_fcs_lport_uf_recv(struct bfa_fcs_lport_s *lport,
 
 }
 
-/**
+/*
  *   PID based Lookup for a R-Port in the Port R-Port Queue
  */
 struct bfa_fcs_rport_s *
@@ -742,7 +734,7 @@ bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid)
        return NULL;
 }
 
-/**
+/*
  *   PWWN based Lookup for a R-Port in the Port R-Port Queue
  */
 struct bfa_fcs_rport_s *
@@ -761,7 +753,7 @@ bfa_fcs_lport_get_rport_by_pwwn(struct bfa_fcs_lport_s *port, wwn_t pwwn)
        return NULL;
 }
 
-/**
+/*
  *   NWWN based Lookup for a R-Port in the Port R-Port Queue
  */
 struct bfa_fcs_rport_s *
@@ -780,7 +772,7 @@ bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
        return NULL;
 }
 
-/**
+/*
  * Called by rport module when new rports are discovered.
  */
 void
@@ -792,7 +784,7 @@ bfa_fcs_lport_add_rport(
        port->num_rports++;
 }
 
-/**
+/*
  * Called by rport module to when rports are deleted.
  */
 void
@@ -807,7 +799,7 @@ bfa_fcs_lport_del_rport(
        bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
 }
 
-/**
+/*
  * Called by fabric for base port when fabric login is complete.
  * Called by vport for virtual ports when FDISC is complete.
  */
@@ -817,7 +809,7 @@ bfa_fcs_lport_online(struct bfa_fcs_lport_s *port)
        bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
 }
 
-/**
+/*
  * Called by fabric for base port when fabric goes offline.
  * Called by vport for virtual ports when virtual port becomes offline.
  */
@@ -827,7 +819,7 @@ bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port)
        bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
 }
 
-/**
+/*
  * Called by fabric to delete base lport and associated resources.
  *
  * Called by vport to delete lport and associated resources. Should call
@@ -839,7 +831,7 @@ bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port)
        bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
 }
 
-/**
+/*
  * Return TRUE if port is online, else return FALSE
  */
 bfa_boolean_t
@@ -848,7 +840,7 @@ bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port)
        return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online);
 }
 
-/**
+/*
   * Attach time initialization of logical ports.
  */
 void
@@ -865,7 +857,7 @@ bfa_fcs_lport_attach(struct bfa_fcs_lport_s *lport, struct bfa_fcs_s *fcs,
        lport->num_rports = 0;
 }
 
-/**
+/*
  * Logical port initialization of base or virtual port.
  * Called by fabric for base port or by vport for virtual ports.
  */
@@ -878,7 +870,7 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
        struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad;
        char    lpwwn_buf[BFA_STRING_32];
 
-       bfa_os_assign(lport->port_cfg, *port_cfg);
+       lport->port_cfg = *port_cfg;
 
        lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport,
                                        lport->port_cfg.roles,
@@ -894,7 +886,7 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
        bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
 }
 
-/**
+/*
  *  fcs_lport_api
  */
 
@@ -934,11 +926,11 @@ bfa_fcs_lport_get_attr(
        }
 }
 
-/**
+/*
  *  bfa_fcs_lport_fab port fab functions
  */
 
-/**
+/*
  *   Called by port to initialize fabric services of the base port.
  */
 static void
@@ -949,7 +941,7 @@ bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port)
        bfa_fcs_lport_ms_init(port);
 }
 
-/**
+/*
  *   Called by port to notify transition to online state.
  */
 static void
@@ -959,7 +951,7 @@ bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
        bfa_fcs_lport_scn_online(port);
 }
 
-/**
+/*
  *   Called by port to notify transition to offline state.
  */
 static void
@@ -970,11 +962,11 @@ bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port)
        bfa_fcs_lport_ms_offline(port);
 }
 
-/**
+/*
  *  bfa_fcs_lport_n2n  functions
  */
 
-/**
+/*
  *   Called by fcs/port to initialize N2N topology.
  */
 static void
@@ -982,7 +974,7 @@ bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port)
 {
 }
 
-/**
+/*
  *   Called by fcs/port to notify transition to online state.
  */
 static void
@@ -1006,7 +998,7 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
            ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
             sizeof(wwn_t)) > 0) {
                port->pid = N2N_LOCAL_PID;
-               /**
+               /*
                 * First, check if we know the device by pwwn.
                 */
                rport = bfa_fcs_lport_get_rport_by_pwwn(port,
@@ -1035,7 +1027,7 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
        }
 }
 
-/**
+/*
  *   Called by fcs/port to notify transition to offline state.
  */
 static void
@@ -1094,11 +1086,11 @@ static void     bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
                                 struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
 static void    bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
                                  struct bfa_fcs_fdmi_port_attr_s *port_attr);
-/**
+/*
  *  fcs_fdmi_sm FCS FDMI state machine
  */
 
-/**
+/*
  *  FDMI State Machine events
  */
 enum port_fdmi_event {
@@ -1143,7 +1135,7 @@ static void     bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
 static void     bfa_fcs_lport_fdmi_sm_disabled(
                                struct bfa_fcs_lport_fdmi_s *fdmi,
                                enum port_fdmi_event event);
-/**
+/*
  *     Start in offline state - awaiting MS to send start.
  */
 static void
@@ -1510,7 +1502,7 @@ bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
                bfa_sm_fault(port->fcs, event);
        }
 }
-/**
+/*
  *  FDMI is disabled state.
  */
 static void
@@ -1525,7 +1517,7 @@ bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi,
        /* No op State. It can only be enabled at Driver Init. */
 }
 
-/**
+/*
 *  RHBA : Register HBA Attributes.
  */
 static void
@@ -1549,7 +1541,7 @@ bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        fdmi->fcxp = fcxp;
 
        pyld = bfa_fcxp_get_reqbuf(fcxp);
-       bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
+       memset(pyld, 0, FC_MAX_PDUSZ);
 
        len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
                                   FDMI_RHBA);
@@ -1584,7 +1576,7 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
        bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
 
        rhba->hba_id = bfa_fcs_lport_get_pwwn(port);
-       rhba->port_list.num_ports = bfa_os_htonl(1);
+       rhba->port_list.num_ports = cpu_to_be32(1);
        rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port);
 
        len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
@@ -1601,86 +1593,69 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         * Node Name
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_NODENAME);
+       attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODENAME);
        attr->len = sizeof(wwn_t);
        memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), attr->len);
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        count++;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
         * Manufacturer
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MANUFACTURER);
+       attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MANUFACTURER);
        attr->len = (u16) strlen(fcs_hba_attr->manufacturer);
        memcpy(attr->value, fcs_hba_attr->manufacturer, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                                *fields need
-                                                                *to be 4 byte
-                                                                *aligned */
+       attr->len = fc_roundup(attr->len, sizeof(u32));
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        count++;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
         * Serial Number
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_SERIALNUM);
+       attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_SERIALNUM);
        attr->len = (u16) strlen(fcs_hba_attr->serial_num);
        memcpy(attr->value, fcs_hba_attr->serial_num, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                                *fields need
-                                                                *to be 4 byte
-                                                                *aligned */
+       attr->len = fc_roundup(attr->len, sizeof(u32));
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        count++;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
         * Model
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL);
+       attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL);
        attr->len = (u16) strlen(fcs_hba_attr->model);
        memcpy(attr->value, fcs_hba_attr->model, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                                *fields need
-                                                                *to be 4 byte
-                                                                *aligned */
+       attr->len = fc_roundup(attr->len, sizeof(u32));
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        count++;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
         * Model Desc
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL_DESC);
+       attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MODEL_DESC);
        attr->len = (u16) strlen(fcs_hba_attr->model_desc);
        memcpy(attr->value, fcs_hba_attr->model_desc, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                        *fields need
-                                                        *to be 4 byte
-                                                        *aligned */
+       attr->len = fc_roundup(attr->len, sizeof(u32));
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        count++;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
@@ -1688,18 +1663,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         */
        if (fcs_hba_attr->hw_version[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
-               attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_HW_VERSION);
+               attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_HW_VERSION);
                attr->len = (u16) strlen(fcs_hba_attr->hw_version);
                memcpy(attr->value, fcs_hba_attr->hw_version, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                                *fields need
-                                                                *to be 4 byte
-                                                                *aligned */
+               attr->len = fc_roundup(attr->len, sizeof(u32));
                curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
                len += attr->len;
                count++;
-               attr->len =
-                       bfa_os_htons(attr->len + sizeof(attr->type) +
+               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                                         sizeof(attr->len));
        }
 
@@ -1707,18 +1678,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         * Driver Version
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_DRIVER_VERSION);
+       attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_DRIVER_VERSION);
        attr->len = (u16) strlen(fcs_hba_attr->driver_version);
        memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                        *fields need
-                                                        *to be 4 byte
-                                                        *aligned */
+       attr->len = fc_roundup(attr->len, sizeof(u32));
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;;
        count++;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
@@ -1726,18 +1693,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         */
        if (fcs_hba_attr->option_rom_ver[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
-               attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_ROM_VERSION);
+               attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_ROM_VERSION);
                attr->len = (u16) strlen(fcs_hba_attr->option_rom_ver);
                memcpy(attr->value, fcs_hba_attr->option_rom_ver, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                                *fields need
-                                                                *to be 4 byte
-                                                                *aligned */
+               attr->len = fc_roundup(attr->len, sizeof(u32));
                curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
                len += attr->len;
                count++;
-               attr->len =
-                       bfa_os_htons(attr->len + sizeof(attr->type) +
+               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                                         sizeof(attr->len));
        }
 
@@ -1745,18 +1708,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         * f/w Version = driver version
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_FW_VERSION);
+       attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FW_VERSION);
        attr->len = (u16) strlen(fcs_hba_attr->driver_version);
        memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
-       attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                        *fields need
-                                                        *to be 4 byte
-                                                        *aligned */
+       attr->len = fc_roundup(attr->len, sizeof(u32));
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        count++;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
@@ -1764,18 +1723,14 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         */
        if (fcs_hba_attr->os_name[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
-               attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_OS_NAME);
+               attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_OS_NAME);
                attr->len = (u16) strlen(fcs_hba_attr->os_name);
                memcpy(attr->value, fcs_hba_attr->os_name, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                            *fields need
-                                                            *to be 4 byte
-                                                            *aligned */
+               attr->len = fc_roundup(attr->len, sizeof(u32));
                curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
                len += attr->len;
                count++;
-               attr->len =
-                       bfa_os_htons(attr->len + sizeof(attr->type) +
+               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                                        sizeof(attr->len));
        }
 
@@ -1783,22 +1738,20 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
         * MAX_CT_PAYLOAD
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MAX_CT);
+       attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
        attr->len = sizeof(fcs_hba_attr->max_ct_pyld);
        memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, attr->len);
        len += attr->len;
        count++;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
         * Update size of payload
         */
-       len += ((sizeof(attr->type) +
-                sizeof(attr->len)) * count);
+       len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
 
-       rhba->hba_attr_blk.attr_count = bfa_os_htonl(count);
+       rhba->hba_attr_blk.attr_count = cpu_to_be32(count);
        return len;
 }
 
@@ -1825,7 +1778,7 @@ bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
@@ -1837,7 +1790,7 @@ bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
 }
 
-/**
+/*
 *  RPRT : Register Port
  */
 static void
@@ -1861,7 +1814,7 @@ bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        fdmi->fcxp = fcxp;
 
        pyld = bfa_fcxp_get_reqbuf(fcxp);
-       bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
+       memset(pyld, 0, FC_MAX_PDUSZ);
 
        len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
                                   FDMI_RPRT);
@@ -1879,7 +1832,7 @@ bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
 }
 
-/**
+/*
  * This routine builds Port Attribute Block that used in RPA, RPRT commands.
  */
 static          u16
@@ -1909,56 +1862,54 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
         * FC4 Types
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FC4_TYPES);
+       attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FC4_TYPES);
        attr->len = sizeof(fcs_port_attr.supp_fc4_types);
        memcpy(attr->value, fcs_port_attr.supp_fc4_types, attr->len);
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        ++count;
        attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+               cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
         * Supported Speed
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_SUPP_SPEED);
+       attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_SPEED);
        attr->len = sizeof(fcs_port_attr.supp_speed);
        memcpy(attr->value, &fcs_port_attr.supp_speed, attr->len);
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        ++count;
        attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+               cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
         * current Port Speed
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_PORT_SPEED);
+       attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SPEED);
        attr->len = sizeof(fcs_port_attr.curr_speed);
        memcpy(attr->value, &fcs_port_attr.curr_speed, attr->len);
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        ++count;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
         * max frame size
         */
        attr = (struct fdmi_attr_s *) curr_ptr;
-       attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FRAME_SIZE);
+       attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_FRAME_SIZE);
        attr->len = sizeof(fcs_port_attr.max_frm_size);
        memcpy(attr->value, &fcs_port_attr.max_frm_size, attr->len);
        curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
        len += attr->len;
        ++count;
-       attr->len =
-               bfa_os_htons(attr->len + sizeof(attr->type) +
+       attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                             sizeof(attr->len));
 
        /*
@@ -1966,18 +1917,14 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
         */
        if (fcs_port_attr.os_device_name[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
-               attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_DEV_NAME);
+               attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_DEV_NAME);
                attr->len = (u16) strlen(fcs_port_attr.os_device_name);
                memcpy(attr->value, fcs_port_attr.os_device_name, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                            *fields need
-                                                            *to be 4 byte
-                                                            *aligned */
+               attr->len = fc_roundup(attr->len, sizeof(u32));
                curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
                len += attr->len;
                ++count;
-               attr->len =
-                       bfa_os_htons(attr->len + sizeof(attr->type) +
+               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                                        sizeof(attr->len));
        }
        /*
@@ -1985,27 +1932,22 @@ bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
         */
        if (fcs_port_attr.host_name[0] != '\0') {
                attr = (struct fdmi_attr_s *) curr_ptr;
-               attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_HOST_NAME);
+               attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_HOST_NAME);
                attr->len = (u16) strlen(fcs_port_attr.host_name);
                memcpy(attr->value, fcs_port_attr.host_name, attr->len);
-               attr->len = fc_roundup(attr->len, sizeof(u32)); /* variable
-                                                            *fields need
-                                                            *to be 4 byte
-                                                            *aligned */
+               attr->len = fc_roundup(attr->len, sizeof(u32));
                curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
                len += attr->len;
                ++count;
-               attr->len =
-                       bfa_os_htons(attr->len + sizeof(attr->type) +
+               attr->len = cpu_to_be16(attr->len + sizeof(attr->type) +
                                sizeof(attr->len));
        }
 
        /*
         * Update size of payload
         */
-       port_attrib->attr_count = bfa_os_htonl(count);
-       len += ((sizeof(attr->type) +
-                sizeof(attr->len)) * count);
+       port_attrib->attr_count = cpu_to_be32(count);
+       len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
        return len;
 }
 
@@ -2050,7 +1992,7 @@ bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
@@ -2062,7 +2004,7 @@ bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
 }
 
-/**
+/*
 *  RPA : Register Port Attributes.
  */
 static void
@@ -2086,15 +2028,13 @@ bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        fdmi->fcxp = fcxp;
 
        pyld = bfa_fcxp_get_reqbuf(fcxp);
-       bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
+       memset(pyld, 0, FC_MAX_PDUSZ);
 
        len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
                                   FDMI_RPA);
 
-       attr_len =
-               bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi,
-                                        (u8 *) ((struct ct_hdr_s *) pyld
-                                                     + 1));
+       attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi,
+                               (u8 *) ((struct ct_hdr_s *) pyld + 1));
 
        bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
                          FC_CLASS_3, len + attr_len, &fchs,
@@ -2143,7 +2083,7 @@ bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
@@ -2170,7 +2110,7 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
        struct bfa_fcs_lport_s *port = fdmi->ms->port;
        struct bfa_fcs_driver_info_s  *driver_info = &port->fcs->driver_info;
 
-       bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
+       memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
 
        bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
                                        hba_attr->manufacturer);
@@ -2204,7 +2144,7 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
                                sizeof(driver_info->host_os_patch));
        }
 
-       hba_attr->max_ct_pyld = bfa_os_htonl(FC_MAX_PDUSZ);
+       hba_attr->max_ct_pyld = cpu_to_be32(FC_MAX_PDUSZ);
 }
 
 void
@@ -2215,7 +2155,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
        struct bfa_fcs_driver_info_s  *driver_info = &port->fcs->driver_info;
        struct bfa_port_attr_s pport_attr;
 
-       bfa_os_memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
+       memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
 
        /*
         * get pport attributes from hal
@@ -2230,17 +2170,17 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
        /*
         * Supported Speeds
         */
-       port_attr->supp_speed = bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS);
+       port_attr->supp_speed = cpu_to_be32(BFA_FCS_FDMI_SUPORTED_SPEEDS);
 
        /*
         * Current Speed
         */
-       port_attr->curr_speed = bfa_os_htonl(pport_attr.speed);
+       port_attr->curr_speed = cpu_to_be32(pport_attr.speed);
 
        /*
         * Max PDU Size.
         */
-       port_attr->max_frm_size = bfa_os_htonl(FC_MAX_PDUSZ);
+       port_attr->max_frm_size = cpu_to_be32(FC_MAX_PDUSZ);
 
        /*
         * OS device Name
@@ -2321,11 +2261,11 @@ static void     bfa_fcs_lport_ms_gfn_response(void *fcsarg,
                                               u32 rsp_len,
                                               u32 resid_len,
                                               struct fchs_s *rsp_fchs);
-/**
+/*
  *  fcs_ms_sm FCS MS state machine
  */
 
-/**
+/*
  *  MS State Machine events
  */
 enum port_ms_event {
@@ -2360,7 +2300,7 @@ static void     bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
                                               enum port_ms_event event);
 static void     bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
                                          enum port_ms_event event);
-/**
+/*
  *     Start in offline state - awaiting NS to send start.
  */
 static void
@@ -2432,7 +2372,7 @@ bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
                 */
                bfa_fcs_lport_fdmi_online(ms);
 
-               /**
+               /*
                 * if this is a Vport, go to online state.
                 */
                if (ms->port->vport) {
@@ -2595,7 +2535,7 @@ bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
                bfa_sm_fault(ms->port->fcs, event);
        }
 }
-/**
+/*
  *  ms_pvt MS local functions
  */
 
@@ -2657,12 +2597,12 @@ bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
 
-               num_entries = bfa_os_ntohl(gmal_resp->ms_len);
+               num_entries = be32_to_cpu(gmal_resp->ms_len);
                if (num_entries == 0) {
                        bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
                        return;
@@ -2795,7 +2735,7 @@ bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
                bfa_sm_fault(ms->port->fcs, event);
        }
 }
-/**
+/*
  *  ms_pvt MS local functions
  */
 
@@ -2853,7 +2793,7 @@ bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                gfn_resp = (wwn_t *)(cthdr + 1);
@@ -2871,7 +2811,7 @@ bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
 }
 
-/**
+/*
  *  ms_pvt MS local functions
  */
 
@@ -3017,7 +2957,7 @@ bfa_fcs_lport_ms_fabric_rscn(struct bfa_fcs_lport_s *port)
                bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
 }
 
-/**
+/*
  * @page ns_sm_info VPORT NS State Machine
  *
  * @section ns_sm_interactions VPORT NS State Machine Interactions
@@ -3080,11 +3020,11 @@ static void     bfa_fcs_lport_ns_process_gidft_pids(
                                u32 *pid_buf, u32 n_pids);
 
 static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port);
-/**
+/*
  *  fcs_ns_sm FCS nameserver interface state machine
  */
 
-/**
+/*
  * VPort NS State Machine events
  */
 enum vport_ns_event {
@@ -3139,7 +3079,7 @@ static void     bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
                                                enum vport_ns_event event);
 static void     bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
                                          enum vport_ns_event event);
-/**
+/*
  *     Start in offline state - awaiting linkup
  */
 static void
@@ -3628,7 +3568,7 @@ bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
 
 
 
-/**
+/*
  *  ns_pvt Nameserver local functions
  */
 
@@ -3724,7 +3664,7 @@ bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 }
 
-/**
+/*
  * Register the symbolic port name.
  */
 static void
@@ -3738,7 +3678,7 @@ bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        u8         symbl[256];
        u8         *psymbl = &symbl[0];
 
-       bfa_os_memset(symbl, 0, sizeof(symbl));
+       memset(symbl, 0, sizeof(symbl));
 
        bfa_trc(port->fcs, port->port_cfg.pwwn);
 
@@ -3755,7 +3695,7 @@ bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
         * for V-Port, form a Port Symbolic Name
         */
        if (port->vport) {
-               /**
+               /*
                 * For Vports, we append the vport's port symbolic name
                 * to that of the base port.
                 */
@@ -3815,7 +3755,7 @@ bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                port->stats.ns_rspnid_accepts++;
@@ -3829,7 +3769,7 @@ bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
 }
 
-/**
+/*
  * Register FC4-Types
  */
 static void
@@ -3887,7 +3827,7 @@ bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                port->stats.ns_rftid_accepts++;
@@ -3901,7 +3841,7 @@ bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
 }
 
-/**
+/*
  * Register FC4-Features : Should be done after RFT_ID
  */
 static void
@@ -3964,7 +3904,7 @@ bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                port->stats.ns_rffid_accepts++;
@@ -3982,7 +3922,7 @@ bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        } else
                bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
 }
-/**
+/*
  * Query Fabric for FC4-Types Devices.
  *
 * TBD : Need to use a local (FCS private) response buffer, since the response
@@ -4058,7 +3998,7 @@ bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        switch (cthdr->cmd_rsp_code) {
 
@@ -4102,7 +4042,7 @@ bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
        }
 }
 
-/**
+/*
  *     This routine will be called by bfa_timer on timer timeouts.
  *
  *     param[in]       port - pointer to bfa_fcs_lport_t.
@@ -4166,7 +4106,7 @@ bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
        }
 }
 
-/**
+/*
  *  fcs_ns_public FCS nameserver public interfaces
  */
 
@@ -4227,7 +4167,7 @@ bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
        }
 }
 
-/**
+/*
  * FCS SCN
  */
 
@@ -4250,11 +4190,11 @@ static void     bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
                                             struct fchs_s *rx_fchs);
 static void     bfa_fcs_lport_scn_timeout(void *arg);
 
-/**
+/*
  *  fcs_scm_sm FCS SCN state machine
  */
 
-/**
+/*
  * VPort SCN State Machine events
  */
 enum port_scn_event {
@@ -4278,7 +4218,7 @@ static void     bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
 static void     bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
                                           enum port_scn_event event);
 
-/**
+/*
  *     Starting state - awaiting link up.
  */
 static void
@@ -4382,11 +4322,11 @@ bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
 
 
 
-/**
+/*
  *  fcs_scn_private FCS SCN private functions
  */
 
-/**
+/*
  * This routine will be called to send a SCR command.
  */
 static void
@@ -4499,7 +4439,7 @@ bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
                          FC_MAX_PDUSZ, 0);
 }
 
-/**
+/*
  *     This routine will be called by bfa_timer on timer timeouts.
  *
  *     param[in]       vport           - pointer to bfa_fcs_lport_t.
@@ -4522,7 +4462,7 @@ bfa_fcs_lport_scn_timeout(void *arg)
 
 
 
-/**
+/*
  *  fcs_scn_public FCS state change notification public interfaces
  */
 
@@ -4563,7 +4503,7 @@ bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
 
        bfa_trc(port->fcs, rpid);
 
-       /**
+       /*
         * If this is an unknown device, then it just came online.
         * Otherwise let rport handle the RSCN event.
         */
@@ -4579,7 +4519,7 @@ bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
                bfa_fcs_rport_scn(rport);
 }
 
-/**
+/*
  * rscn format based PID comparison
  */
 #define __fc_pid_match(__c0, __c1, __fmt)              \
@@ -4624,7 +4564,7 @@ bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
        int             i = 0, j;
 
        num_entries =
-               (bfa_os_ntohs(rscn->payldlen) -
+               (be16_to_cpu(rscn->payldlen) -
                 sizeof(u32)) / sizeof(rscn->event[0]);
 
        bfa_trc(port->fcs, num_entries);
@@ -4691,18 +4631,18 @@ bfa_fcs_lport_scn_process_rscn(struct bfa_fcs_lport_s *port,
                }
        }
 
-       /**
-        * If any of area, domain or fabric RSCN is received, do a fresh discovery
-        * to find new devices.
+       /*
+        * If any of area, domain or fabric RSCN is received, do a fresh
+        * discovery to find new devices.
         */
        if (nsquery)
                bfa_fcs_lport_ns_query(port);
 }
 
-/**
+/*
  * BFA FCS port
  */
-/**
+/*
  *  fcs_port_api BFA FCS port API
  */
 struct bfa_fcs_lport_s *
@@ -4943,10 +4883,10 @@ bfa_fcs_lport_get_stats(struct bfa_fcs_lport_s *fcs_port,
 void
 bfa_fcs_lport_clear_stats(struct bfa_fcs_lport_s *fcs_port)
 {
-       bfa_os_memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
+       memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
 }
 
-/**
+/*
  * FCS virtual port state machine
  */
 
@@ -4967,11 +4907,11 @@ static void     bfa_fcs_vport_timeout(void *vport_arg);
 static void     bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
 static void     bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
 
-/**
+/*
  *  fcs_vport_sm FCS virtual port state machine
  */
 
-/**
+/*
  * VPort State Machine events
  */
 enum bfa_fcs_vport_event {
@@ -5024,7 +4964,7 @@ static struct bfa_sm_table_s  vport_sm_table[] = {
        {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
 };
 
-/**
+/*
  * Beginning state.
  */
 static void
@@ -5045,7 +4985,7 @@ bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
        }
 }
 
-/**
+/*
  * Created state - a start event is required to start up the state machine.
  */
 static void
@@ -5062,7 +5002,7 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
                        bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
                        bfa_fcs_vport_do_fdisc(vport);
                } else {
-                       /**
+                       /*
                         * Fabric is offline or not NPIV capable, stay in
                         * offline state.
                         */
@@ -5078,7 +5018,7 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
 
        case BFA_FCS_VPORT_SM_ONLINE:
        case BFA_FCS_VPORT_SM_OFFLINE:
-               /**
+               /*
                 * Ignore ONLINE/OFFLINE events from fabric
                 * till vport is started.
                 */
@@ -5089,7 +5029,7 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
        }
 }
 
-/**
+/*
  * Offline state - awaiting ONLINE event from fabric SM.
  */
 static void
@@ -5127,7 +5067,7 @@ bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
 }
 
 
-/**
+/*
  * FDISC is sent and awaiting reply from fabric.
  */
 static void
@@ -5174,7 +5114,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
        }
 }
 
-/**
+/*
  * FDISC attempt failed - a timer is active to retry FDISC.
  */
 static void
@@ -5208,7 +5148,7 @@ bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
        }
 }
 
-/**
+/*
  * Vport is online (FDISC is complete).
  */
 static void
@@ -5235,7 +5175,7 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
        }
 }
 
-/**
+/*
  * Vport is being deleted - awaiting lport delete completion to send
  * LOGO to fabric.
  */
@@ -5264,7 +5204,7 @@ bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
        }
 }
 
-/**
+/*
  * Error State.
  * This state will be set when the Vport Creation fails due
  * to errors like Dup WWN. In this state only operation allowed
@@ -5288,7 +5228,7 @@ bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
        }
 }
 
-/**
+/*
  * Lport cleanup is in progress since vport is being deleted. Fabric is
  * offline, so no LOGO is needed to complete vport deletion.
  */
@@ -5313,7 +5253,7 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
        }
 }
 
-/**
+/*
  * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
  * is done.
  */
@@ -5347,10 +5287,10 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
 
 
 
-/**
+/*
  *  fcs_vport_private FCS virtual port private functions
  */
-/**
+/*
  * This routine will be called to send a FDISC command.
  */
 static void
@@ -5397,7 +5337,7 @@ bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
        }
 }
 
-/**
+/*
  *     Called to send a logout to the fabric. Used when a V-Port is
  *     deleted/stopped.
  */
@@ -5411,7 +5351,7 @@ bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
 }
 
 
-/**
+/*
  *     This routine will be called by bfa_timer on timer timeouts.
  *
  *     param[in]       vport           - pointer to bfa_fcs_vport_t.
@@ -5449,11 +5389,11 @@ bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
 
 
 
-/**
+/*
  *  fcs_vport_public FCS virtual port public interfaces
  */
 
-/**
+/*
  * Online notification from fabric SM.
  */
 void
@@ -5463,7 +5403,7 @@ bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
        bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
 }
 
-/**
+/*
  * Offline notification from fabric SM.
  */
 void
@@ -5473,7 +5413,7 @@ bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport)
        bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
 }
 
-/**
+/*
  * Cleanup notification from fabric SM on link timer expiry.
  */
 void
@@ -5481,7 +5421,7 @@ bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
 {
        vport->vport_stats.fab_cleanup++;
 }
-/**
+/*
  * delete notification from fabric SM. To be invoked from within FCS.
  */
 void
@@ -5490,7 +5430,7 @@ bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport)
        bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
 }
 
-/**
+/*
  * Delete completion callback from associated lport
  */
 void
@@ -5501,11 +5441,11 @@ bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
 
 
 
-/**
+/*
  *  fcs_vport_api Virtual port API
  */
 
-/**
+/*
  *     Use this function to instantiate a new FCS vport object. This
  *     function will not trigger any HW initialization process (which will be
  *     done in vport_start() call)
@@ -5555,7 +5495,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  *     Use this function to instantiate a new FCS PBC vport object. This
  *     function will not trigger any HW initialization process (which will be
  *     done in vport_start() call)
@@ -5585,7 +5525,7 @@ bfa_fcs_pbc_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
        return rc;
 }
 
-/**
+/*
  *     Use this function to findout if this is a pbc vport or not.
  *
  * @param[in] vport - pointer to bfa_fcs_vport_t.
@@ -5603,7 +5543,7 @@ bfa_fcs_is_pbc_vport(struct bfa_fcs_vport_s *vport)
 
 }
 
-/**
+/*
  * Use this function initialize the vport.
  *
  * @param[in] vport - pointer to bfa_fcs_vport_t.
@@ -5618,7 +5558,7 @@ bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  *     Use this function quiese the vport object. This function will return
  *     immediately, when the vport is actually stopped, the
  *     bfa_drv_vport_stop_cb() will be called.
@@ -5635,7 +5575,7 @@ bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  *     Use this function to delete a vport object. Fabric object should
  *     be stopped before this function call.
  *
@@ -5657,7 +5597,7 @@ bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  *     Use this function to get vport's current status info.
  *
  *     param[in] vport         pointer to bfa_fcs_vport_t.
@@ -5672,13 +5612,13 @@ bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
        if (vport == NULL || attr == NULL)
                return;
 
-       bfa_os_memset(attr, 0, sizeof(struct bfa_vport_attr_s));
+       memset(attr, 0, sizeof(struct bfa_vport_attr_s));
 
        bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr);
        attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
 }
 
-/**
+/*
  *     Use this function to get vport's statistics.
  *
  *     param[in]       vport   pointer to bfa_fcs_vport_t.
@@ -5693,7 +5633,7 @@ bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
        *stats = vport->vport_stats;
 }
 
-/**
+/*
  *     Use this function to clear vport's statistics.
  *
  *     param[in]       vport   pointer to bfa_fcs_vport_t.
@@ -5703,10 +5643,10 @@ bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
 void
 bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport)
 {
-       bfa_os_memset(&vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s));
+       memset(&vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s));
 }
 
-/**
+/*
  *     Lookup a virtual port. Excludes base port from lookup.
  */
 struct bfa_fcs_vport_s *
@@ -5728,7 +5668,7 @@ bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn)
        return vport;
 }
 
-/**
+/*
  * FDISC Response
  */
 void
@@ -5784,7 +5724,7 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
        }
 }
 
-/**
+/*
  * LOGO response
  */
 void
@@ -5794,7 +5734,7 @@ bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
        bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
 }
 
-/**
+/*
  * Received clear virtual link
  */
 void
index 635f0cd887145deeb96b2f24914a8622269b3319..47f35c0ef29a0c69f5d6842a6db0d173a0195e84 100644 (file)
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 
-/**
+/*
  *  rport.c Remote port implementation.
  */
 
@@ -75,7 +75,7 @@ static void   bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
 static void    bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
                                struct fchs_s *rx_fchs, u16 len);
 static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
-/**
+/*
  *  fcs_rport_sm FCS rport state machine events
  */
 
@@ -172,7 +172,7 @@ static struct bfa_sm_table_s rport_sm_table[] = {
        {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
 };
 
-/**
+/*
  *             Beginning state.
  */
 static void
@@ -210,7 +210,7 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
        }
 }
 
-/**
+/*
  *             PLOGI is being sent.
  */
 static void
@@ -262,7 +262,7 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             PLOGI is being sent.
  */
 static void
@@ -287,7 +287,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
 
        case RPSM_EVENT_PLOGI_RCVD:
        case RPSM_EVENT_SCN:
-               /**
+               /*
                 * Ignore, SCN is possibly online notification.
                 */
                break;
@@ -309,7 +309,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
                break;
 
        case RPSM_EVENT_HCB_OFFLINE:
-               /**
+               /*
                 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
                 */
                break;
@@ -319,7 +319,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             PLOGI is sent.
  */
 static void
@@ -380,7 +380,7 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             PLOGI is sent.
  */
 static void
@@ -475,7 +475,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
        }
 }
 
-/**
+/*
  *             PLOGI is complete. Awaiting BFA rport online callback. FC-4s
  *             are offline.
  */
@@ -519,7 +519,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
                break;
 
        case RPSM_EVENT_SCN:
-               /**
+               /*
                 * @todo
                 * Ignore SCN - PLOGI just completed, FC-4 login should detect
                 * device failures.
@@ -531,7 +531,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             Rport is ONLINE. FC-4s active.
  */
 static void
@@ -580,7 +580,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
        }
 }
 
-/**
+/*
  *             An SCN event is received in ONLINE state. NS query is being sent
  *             prior to ADISC authentication with rport. FC-4s are paused.
  */
@@ -604,7 +604,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
                break;
 
        case RPSM_EVENT_SCN:
-               /**
+               /*
                 * ignore SCN, wait for response to query itself
                 */
                break;
@@ -638,7 +638,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *     An SCN event is received in ONLINE state. NS query is sent to rport.
  *     FC-4s are paused.
  */
@@ -697,7 +697,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
        }
 }
 
-/**
+/*
  *     An SCN event is received in ONLINE state. ADISC is being sent for
  *     authenticating with rport. FC-4s are paused.
  */
@@ -748,7 +748,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             An SCN event is received in ONLINE state. ADISC is to rport.
  *             FC-4s are paused.
  */
@@ -765,7 +765,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
                break;
 
        case RPSM_EVENT_PLOGI_RCVD:
-               /**
+               /*
                 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
                 * At least go offline when a PLOGI is received.
                 */
@@ -787,7 +787,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
                break;
 
        case RPSM_EVENT_SCN:
-               /**
+               /*
                 * already processing RSCN
                 */
                break;
@@ -810,7 +810,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
        }
 }
 
-/**
+/*
  *             Rport has sent LOGO. Awaiting FC-4 offline completion callback.
  */
 static void
@@ -841,7 +841,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             LOGO needs to be sent to rport. Awaiting FC-4 offline completion
  *             callback.
  */
@@ -864,7 +864,7 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *     Rport is going offline. Awaiting FC-4 offline completion callback.
  */
 static void
@@ -886,7 +886,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
        case RPSM_EVENT_LOGO_RCVD:
        case RPSM_EVENT_PRLO_RCVD:
        case RPSM_EVENT_ADDRESS_CHANGE:
-               /**
+               /*
                 * rport is already going offline.
                 * SCN - ignore and wait till transitioning to offline state
                 */
@@ -901,7 +901,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             Rport is offline. FC-4s are offline. Awaiting BFA rport offline
  *             callback.
  */
@@ -945,7 +945,7 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
        case RPSM_EVENT_SCN:
        case RPSM_EVENT_LOGO_RCVD:
        case RPSM_EVENT_PRLO_RCVD:
-               /**
+               /*
                 * Ignore, already offline.
                 */
                break;
@@ -955,7 +955,7 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             Rport is offline. FC-4s are offline. Awaiting BFA rport offline
  *             callback to send LOGO accept.
  */
@@ -1009,7 +1009,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
 
        case RPSM_EVENT_LOGO_RCVD:
        case RPSM_EVENT_PRLO_RCVD:
-               /**
+               /*
                 * Ignore - already processing a LOGO.
                 */
                break;
@@ -1019,7 +1019,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             Rport is being deleted. FC-4s are offline.
  *  Awaiting BFA rport offline
  *             callback to send LOGO.
@@ -1048,7 +1048,7 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             Rport is being deleted. FC-4s are offline. LOGO is being sent.
  */
 static void
@@ -1082,7 +1082,7 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             Rport is offline. FC-4s are offline. BFA rport is offline.
  *             Timer active to delete stale rport.
  */
@@ -1142,7 +1142,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
        }
 }
 
-/**
+/*
  *     Rport address has changed. Nameserver discovery request is being sent.
  */
 static void
@@ -1199,7 +1199,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             Nameserver discovery failed. Waiting for timeout to retry.
  */
 static void
@@ -1263,7 +1263,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *             Rport address has changed. Nameserver discovery request is sent.
  */
 static void
@@ -1329,13 +1329,13 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
                bfa_fcs_rport_send_prlo_acc(rport);
                break;
        case RPSM_EVENT_SCN:
-               /**
+               /*
                 * ignore, wait for NS query response
                 */
                break;
 
        case RPSM_EVENT_LOGO_RCVD:
-               /**
+               /*
                 * Not logged-in yet. Accept LOGO.
                 */
                bfa_fcs_rport_send_logo_acc(rport);
@@ -1354,7 +1354,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
 
 
 
-/**
+/*
  *  fcs_rport_private FCS RPORT provate functions
  */
 
@@ -1415,7 +1415,7 @@ bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
 
        plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
 
-       /**
+       /*
         * Check for failure first.
         */
        if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
@@ -1436,7 +1436,7 @@ bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
                return;
        }
 
-       /**
+       /*
         * PLOGI is complete. Make sure this device is not one of the known
         * device with a new FC port address.
         */
@@ -1468,7 +1468,7 @@ bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
                }
        }
 
-       /**
+       /*
         * Normal login path -- no evil twins.
         */
        rport->stats.plogi_accs++;
@@ -1621,7 +1621,7 @@ bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
        bfa_trc(rport->fcs, rport->pwwn);
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                /* Check if the pid is the same as before. */
@@ -1691,7 +1691,7 @@ bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
        bfa_trc(rport->fcs, rport->pwwn);
 
        cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
-       cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
+       cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
 
        if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
                bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
@@ -1722,7 +1722,7 @@ bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
        }
 }
 
-/**
+/*
  *     Called to send a logout to the rport.
  */
 static void
@@ -1759,7 +1759,7 @@ bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
        bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
 }
 
-/**
+/*
  *     Send ACC for a LOGO received.
  */
 static void
@@ -1788,7 +1788,7 @@ bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
                        FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
 }
 
-/**
+/*
  *     brief
  *     This routine will be called by bfa_timer on timer timeouts.
  *
@@ -1961,7 +1961,7 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
        struct bfa_fcs_rport_s *rport;
        struct bfad_rport_s     *rport_drv;
 
-       /**
+       /*
         * allocate rport
         */
        if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
@@ -1979,7 +1979,7 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
        rport->pid = rpid;
        rport->pwwn = pwwn;
 
-       /**
+       /*
         * allocate BFA rport
         */
        rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport);
@@ -1989,7 +1989,7 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
                return NULL;
        }
 
-       /**
+       /*
         * allocate FC-4s
         */
        bfa_assert(bfa_fcs_lport_is_initiator(port));
@@ -2021,7 +2021,7 @@ bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
 {
        struct bfa_fcs_lport_s *port = rport->port;
 
-       /**
+       /*
         * - delete FC-4s
         * - delete BFA rport
         * - remove from queue of rports
@@ -2093,7 +2093,7 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
        }
 }
 
-/**
+/*
  * Update rport parameters from PLOGI or PLOGI accept.
  */
 static void
@@ -2101,14 +2101,14 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
 {
        bfa_fcs_lport_t *port = rport->port;
 
-       /**
+       /*
         * - port name
         * - node name
         */
        rport->pwwn = plogi->port_name;
        rport->nwwn = plogi->node_name;
 
-       /**
+       /*
         * - class of service
         */
        rport->fc_cos = 0;
@@ -2118,16 +2118,16 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
        if (plogi->class2.class_valid)
                rport->fc_cos |= FC_CLASS_2;
 
-       /**
+       /*
         * - CISC
         * - MAX receive frame size
         */
        rport->cisc = plogi->csp.cisc;
-       rport->maxfrsize = bfa_os_ntohs(plogi->class3.rxsz);
+       rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
 
-       bfa_trc(port->fcs, bfa_os_ntohs(plogi->csp.bbcred));
+       bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
        bfa_trc(port->fcs, port->fabric->bb_credit);
-       /**
+       /*
         * Direct Attach P2P mode :
         * This is to handle a bug (233476) in IBM targets in Direct Attach
         *  Mode. Basically, in FLOGI Accept the target would have
@@ -2136,19 +2136,19 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
         * in PLOGI.
         */
        if ((!bfa_fcs_fabric_is_switched(port->fabric))  &&
-               (bfa_os_ntohs(plogi->csp.bbcred) < port->fabric->bb_credit)) {
+               (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
 
-               bfa_trc(port->fcs, bfa_os_ntohs(plogi->csp.bbcred));
+               bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
                bfa_trc(port->fcs, port->fabric->bb_credit);
 
-               port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred);
+               port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
                bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
                                          port->fabric->bb_credit);
        }
 
 }
 
-/**
+/*
  *     Called to handle LOGO received from an existing remote port.
  */
 static void
@@ -2164,11 +2164,11 @@ bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
 
 
 
-/**
+/*
  *  fcs_rport_public FCS rport public interfaces
  */
 
-/**
+/*
  *     Called by bport/vport to create a remote port instance for a discovered
  *     remote device.
  *
@@ -2191,7 +2191,7 @@ bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
        return rport;
 }
 
-/**
+/*
  * Called to create a rport for which only the wwn is known.
  *
  * @param[in] port     - base port
@@ -2211,7 +2211,7 @@ bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
        bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
        return rport;
 }
-/**
+/*
  * Called by bport in private loop topology to indicate that a
  * rport has been discovered and plogi has been completed.
  *
@@ -2233,7 +2233,7 @@ bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
        bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
 }
 
-/**
+/*
  *     Called by bport/vport to handle PLOGI received from a new remote port.
  *     If an existing rport does a plogi, it will be handled separately.
  */
@@ -2272,7 +2272,7 @@ wwn_compare(wwn_t wwn1, wwn_t wwn2)
        return 0;
 }
 
-/**
+/*
  *     Called by bport/vport to handle PLOGI received from an existing
  *      remote port.
  */
@@ -2280,7 +2280,7 @@ void
 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
                        struct fc_logi_s *plogi)
 {
-       /**
+       /*
         * @todo Handle P2P and initiator-initiator.
         */
 
@@ -2289,7 +2289,7 @@ bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
        rport->reply_oxid = rx_fchs->ox_id;
        bfa_trc(rport->fcs, rport->reply_oxid);
 
-       /**
+       /*
         * In Switched fabric topology,
         * PLOGI to each other. If our pwwn is smaller, ignore it,
         * if it is not a well known address.
@@ -2307,7 +2307,7 @@ bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
        bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
 }
 
-/**
+/*
  * Called by bport/vport to delete a remote port instance.
  *
  * Rport delete is called under the following conditions:
@@ -2321,7 +2321,7 @@ bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport)
        bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
 }
 
-/**
+/*
  * Called by bport/vport to  when a target goes offline.
  *
  */
@@ -2331,7 +2331,7 @@ bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport)
        bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
 }
 
-/**
+/*
  * Called by bport in n2n when a target (attached port) becomes online.
  *
  */
@@ -2340,7 +2340,7 @@ bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport)
 {
        bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
 }
-/**
+/*
  *     Called by bport/vport to notify SCN for the remote port
  */
 void
@@ -2350,7 +2350,7 @@ bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
        bfa_sm_send_event(rport, RPSM_EVENT_SCN);
 }
 
-/**
+/*
  *     Called by       fcpim to notify that the ITN cleanup is done.
  */
 void
@@ -2359,7 +2359,7 @@ bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport)
        bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
 }
 
-/**
+/*
  *     Called by fcptm to notify that the ITN cleanup is done.
  */
 void
@@ -2368,7 +2368,7 @@ bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport)
        bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
 }
 
-/**
+/*
  *     brief
  *     This routine BFA callback for bfa_rport_online() call.
  *
@@ -2391,7 +2391,7 @@ bfa_cb_rport_online(void *cbarg)
        bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
 }
 
-/**
+/*
  *     brief
  *     This routine BFA callback for bfa_rport_offline() call.
  *
@@ -2413,7 +2413,7 @@ bfa_cb_rport_offline(void *cbarg)
        bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
 }
 
-/**
+/*
  *     brief
  *     This routine is a static BFA callback when there is a QoS flow_id
  *     change notification
@@ -2437,7 +2437,7 @@ bfa_cb_rport_qos_scn_flowid(void *cbarg,
        bfa_trc(rport->fcs, rport->pwwn);
 }
 
-/**
+/*
  *     brief
  *     This routine is a static BFA callback when there is a QoS priority
  *     change notification
@@ -2461,7 +2461,7 @@ bfa_cb_rport_qos_scn_prio(void *cbarg,
        bfa_trc(rport->fcs, rport->pwwn);
 }
 
-/**
+/*
  *             Called to process any unsolicted frames from this remote port
  */
 void
@@ -2470,7 +2470,7 @@ bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport)
        bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
 }
 
-/**
+/*
  *             Called to process any unsolicted frames from this remote port
  */
 void
@@ -2577,7 +2577,7 @@ bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
                        FC_MAX_PDUSZ, 0);
 }
 
-/**
+/*
  * Return state of rport.
  */
 int
@@ -2586,7 +2586,7 @@ bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
        return bfa_sm_to_state(rport_sm_table, rport->sm);
 }
 
-/**
+/*
  *     brief
  *              Called by the Driver to set rport delete/ageout timeout
  *
@@ -2613,15 +2613,15 @@ bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, u16 ox_id)
 
 
 
-/**
+/*
  * Remote port implementation.
  */
 
-/**
+/*
  *  fcs_rport_api FCS rport API.
  */
 
-/**
+/*
  *     Direct API to add a target by port wwn. This interface is used, for
  *     example, by bios when target pwwn is known from boot lun configuration.
  */
@@ -2634,7 +2634,7 @@ bfa_fcs_rport_add(struct bfa_fcs_lport_s *port, wwn_t *pwwn,
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  *     Direct API to remove a target and its associated resources. This
  *     interface is used, for example, by driver to remove target
  *     ports from the target list for a VM.
@@ -2663,7 +2663,7 @@ bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport_in)
 
 }
 
-/**
+/*
  *     Remote device status for display/debug.
  */
 void
@@ -2674,7 +2674,7 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
        bfa_fcs_lport_t *port = rport->port;
        bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
 
-       bfa_os_memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
+       memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
 
        rport_attr->pid = rport->pid;
        rport_attr->pwwn = rport->pwwn;
@@ -2704,7 +2704,7 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
        }
 }
 
-/**
+/*
  *     Per remote device statistics.
  */
 void
@@ -2717,7 +2717,7 @@ bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
 void
 bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport)
 {
-       bfa_os_memset((char *)&rport->stats, 0,
+       memset((char *)&rport->stats, 0,
                        sizeof(struct bfa_rport_stats_s));
 }
 
@@ -2767,7 +2767,7 @@ bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport, bfa_port_speed_t speed)
 
 
 
-/**
+/*
  * Remote port features (RPF) implementation.
  */
 
@@ -2786,7 +2786,7 @@ static void     bfa_fcs_rpf_rpsc2_response(void *fcsarg,
 
 static void     bfa_fcs_rpf_timeout(void *arg);
 
-/**
+/*
  *  fcs_rport_ftrs_sm FCS rport state machine events
  */
 
@@ -2981,7 +2981,7 @@ bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
                bfa_sm_fault(rport->fcs, event);
        }
 }
-/**
+/*
  * Called when Rport is created.
  */
 void
@@ -2995,7 +2995,7 @@ bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
        bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
 }
 
-/**
+/*
  * Called when Rport becomes online
  */
 void
@@ -3010,7 +3010,7 @@ bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
                bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
 }
 
-/**
+/*
  * Called when Rport becomes offline
  */
 void
@@ -3090,16 +3090,16 @@ bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
        rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
        if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
                rport->stats.rpsc_accs++;
-               num_ents = bfa_os_ntohs(rpsc2_acc->num_pids);
+               num_ents = be16_to_cpu(rpsc2_acc->num_pids);
                bfa_trc(rport->fcs, num_ents);
                if (num_ents > 0) {
                        bfa_assert(rpsc2_acc->port_info[0].pid != rport->pid);
                        bfa_trc(rport->fcs,
-                               bfa_os_ntohs(rpsc2_acc->port_info[0].pid));
+                               be16_to_cpu(rpsc2_acc->port_info[0].pid));
                        bfa_trc(rport->fcs,
-                               bfa_os_ntohs(rpsc2_acc->port_info[0].speed));
+                               be16_to_cpu(rpsc2_acc->port_info[0].speed));
                        bfa_trc(rport->fcs,
-                               bfa_os_ntohs(rpsc2_acc->port_info[0].index));
+                               be16_to_cpu(rpsc2_acc->port_info[0].index));
                        bfa_trc(rport->fcs,
                                rpsc2_acc->port_info[0].type);
 
@@ -3109,7 +3109,7 @@ bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
                        }
 
                        rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
-                               bfa_os_ntohs(rpsc2_acc->port_info[0].speed));
+                               be16_to_cpu(rpsc2_acc->port_info[0].speed));
 
                        bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
                }
index c787d3af0886e2172d6180d792c5202c695b9a30..d8464ae60070438b01ed785d2bd667042eb1160d 100644 (file)
@@ -22,7 +22,7 @@ void
 bfa_hwcb_reginit(struct bfa_s *bfa)
 {
        struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs;
-       bfa_os_addr_t           kva = bfa_ioc_bar0(&bfa->ioc);
+       void __iomem *kva = bfa_ioc_bar0(&bfa->ioc);
        int                     i, q, fn = bfa_ioc_pcifn(&bfa->ioc);
 
        if (fn == 0) {
@@ -60,8 +60,8 @@ bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq)
 static void
 bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
 {
-       bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
-               __HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq));
+       writel(__HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq),
+                       bfa->iocfc.bfa_regs.intr_status);
 }
 
 void
@@ -72,8 +72,8 @@ bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
 static void
 bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq)
 {
-       bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
-               __HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq));
+       writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq),
+                       bfa->iocfc.bfa_regs.intr_status);
 }
 
 void
@@ -102,7 +102,7 @@ bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
        *num_vecs = __HFN_NUMINTS;
 }
 
-/**
+/*
  * No special setup required for crossbow -- vector assignments are implicit.
  */
 void
@@ -129,7 +129,7 @@ bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs)
                bfa->msix.handler[i] = bfa_msix_lpu_err;
 }
 
-/**
+/*
  * Crossbow -- dummy, interrupts are masked
  */
 void
@@ -142,7 +142,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
 {
 }
 
-/**
+/*
  * No special enable/disable -- vector assignments are implicit.
  */
 void
index c97ebafec5ea980ec0a4597aa9ac4719001184fd..b0efbc713ffe7c12a83bffe2172876d11baff9da 100644 (file)
@@ -31,15 +31,15 @@ static void
 bfa_hwct_msix_lpu_err_set(struct bfa_s *bfa, bfa_boolean_t msix, int vec)
 {
        int fn = bfa_ioc_pcifn(&bfa->ioc);
-       bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc);
+       void __iomem *kva = bfa_ioc_bar0(&bfa->ioc);
 
        if (msix)
-               bfa_reg_write(kva + __ct_msix_err_vec_reg[fn], vec);
+               writel(vec, kva + __ct_msix_err_vec_reg[fn]);
        else
-               bfa_reg_write(kva + __ct_msix_err_vec_reg[fn], 0);
+               writel(0, kva + __ct_msix_err_vec_reg[fn]);
 }
 
-/**
+/*
  * Dummy interrupt handler for handling spurious interrupt during chip-reinit.
  */
 static void
@@ -51,7 +51,7 @@ void
 bfa_hwct_reginit(struct bfa_s *bfa)
 {
        struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs;
-       bfa_os_addr_t           kva = bfa_ioc_bar0(&bfa->ioc);
+       void __iomem *kva = bfa_ioc_bar0(&bfa->ioc);
        int                     i, q, fn = bfa_ioc_pcifn(&bfa->ioc);
 
        if (fn == 0) {
@@ -88,8 +88,8 @@ bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
 {
        u32     r32;
 
-       r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
-       bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32);
+       r32 = readl(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
+       writel(r32, bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
 }
 
 void
@@ -97,8 +97,8 @@ bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
 {
        u32     r32;
 
-       r32 = bfa_reg_read(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
-       bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq], r32);
+       r32 = readl(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
+       writel(r32, bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
 }
 
 void
@@ -110,7 +110,7 @@ bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
        *num_vecs = BFA_MSIX_CT_MAX;
 }
 
-/**
+/*
  * Setup MSI-X vector for catapult
  */
 void
@@ -156,7 +156,7 @@ bfa_hwct_msix_uninstall(struct bfa_s *bfa)
                bfa->msix.handler[i] = bfa_hwct_msix_dummy;
 }
 
-/**
+/*
  * Enable MSI-X vectors
  */
 void
index 6795b247791a5d48f8b4572997f5f68afbd7ec95..54475b53a5ab1494490f2561fdc0c9d7884c0a55 100644 (file)
@@ -23,7 +23,7 @@
 
 BFA_TRC_FILE(CNA, IOC);
 
-/**
+/*
  * IOC local definitions
  */
 #define BFA_IOC_TOV            3000    /* msecs */
@@ -49,7 +49,7 @@ BFA_TRC_FILE(CNA, IOC);
          BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
 #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
 
-/**
+/*
  * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
  */
 
@@ -73,7 +73,7 @@ BFA_TRC_FILE(CNA, IOC);
 
 #define bfa_ioc_mbox_cmd_pending(__ioc)                \
                        (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
-                       bfa_reg_read((__ioc)->ioc_regs.hfn_mbox_cmd))
+                       readl((__ioc)->ioc_regs.hfn_mbox_cmd))
 
 bfa_boolean_t bfa_auto_recover = BFA_TRUE;
 
@@ -101,11 +101,11 @@ static void bfa_ioc_pf_disabled(struct bfa_ioc_s *ioc);
 static void bfa_ioc_pf_failed(struct bfa_ioc_s *ioc);
 static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
 
-/**
+/*
  *  hal_ioc_sm
  */
 
-/**
+/*
  * IOC state machine definitions/declarations
  */
 enum ioc_event {
@@ -144,7 +144,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
        {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
 };
 
-/**
+/*
  * IOCPF state machine definitions/declarations
  */
 
@@ -174,7 +174,7 @@ static void bfa_iocpf_stop(struct bfa_ioc_s *ioc);
 static void bfa_iocpf_timeout(void *ioc_arg);
 static void bfa_iocpf_sem_timeout(void *ioc_arg);
 
-/**
+/*
  * IOCPF state machine events
  */
 enum iocpf_event {
@@ -191,7 +191,7 @@ enum iocpf_event {
        IOCPF_E_TIMEOUT         = 11,   /*  f/w response timeout        */
 };
 
-/**
+/*
  * IOCPF states
  */
 enum bfa_iocpf_state {
@@ -232,11 +232,11 @@ static struct bfa_sm_table_s iocpf_sm_table[] = {
        {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED},
 };
 
-/**
+/*
  * IOC State Machine
  */
 
-/**
+/*
  * Beginning state. IOC uninit state.
  */
 
@@ -245,7 +245,7 @@ bfa_ioc_sm_uninit_entry(struct bfa_ioc_s *ioc)
 {
 }
 
-/**
+/*
  * IOC is in uninit state.
  */
 static void
@@ -262,7 +262,7 @@ bfa_ioc_sm_uninit(struct bfa_ioc_s *ioc, enum ioc_event event)
                bfa_sm_fault(ioc, event);
        }
 }
-/**
+/*
  * Reset entry actions -- initialize state machine
  */
 static void
@@ -271,7 +271,7 @@ bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc)
        bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset);
 }
 
-/**
+/*
  * IOC is in reset state.
  */
 static void
@@ -304,7 +304,7 @@ bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
        bfa_iocpf_enable(ioc);
 }
 
-/**
+/*
  * Host IOC function is being enabled, awaiting response from firmware.
  * Semaphore is acquired.
  */
@@ -352,7 +352,7 @@ bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc)
        bfa_ioc_send_getattr(ioc);
 }
 
-/**
+/*
  * IOC configuration in progress. Timer is active.
  */
 static void
@@ -447,7 +447,7 @@ bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
        BFA_LOG(KERN_INFO, bfad, log_level, "IOC disabled\n");
 }
 
-/**
+/*
  * IOC is being disabled
  */
 static void
@@ -474,7 +474,7 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
        }
 }
 
-/**
+/*
  * IOC disable completion entry.
  */
 static void
@@ -514,7 +514,7 @@ bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc)
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
 }
 
-/**
+/*
  * Hardware initialization failed.
  */
 static void
@@ -528,7 +528,7 @@ bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
                break;
 
        case IOC_E_FAILED:
-               /**
+               /*
                 * Initialization failure during iocpf init retry.
                 */
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
@@ -556,7 +556,7 @@ bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
        struct bfa_ioc_hbfail_notify_s  *notify;
        struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
 
-       /**
+       /*
         * Notify driver and common modules registered for notification.
         */
        ioc->cbfn->hbfail_cbfn(ioc->bfa);
@@ -569,7 +569,7 @@ bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
                "Heart Beat of IOC has failed\n");
 }
 
-/**
+/*
  * IOC failure.
  */
 static void
@@ -580,7 +580,7 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
        switch (event) {
 
        case IOC_E_FAILED:
-               /**
+               /*
                 * Initialization failure during iocpf recovery.
                 * !!! Fall through !!!
                 */
@@ -608,12 +608,12 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
 
 
 
-/**
+/*
  * IOCPF State Machine
  */
 
 
-/**
+/*
  * Reset entry actions -- initialize state machine
  */
 static void
@@ -623,7 +623,7 @@ bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf)
        iocpf->auto_recover = bfa_auto_recover;
 }
 
-/**
+/*
  * Beginning state. IOC is in reset state.
  */
 static void
@@ -646,7 +646,7 @@ bfa_iocpf_sm_reset(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
-/**
+/*
  * Semaphore should be acquired for version check.
  */
 static void
@@ -655,7 +655,7 @@ bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf)
        bfa_ioc_hw_sem_get(iocpf->ioc);
 }
 
-/**
+/*
  * Awaiting h/w semaphore to continue with version check.
  */
 static void
@@ -692,7 +692,7 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
-/**
+/*
  * Notify enable completion callback.
  */
 static void
@@ -708,7 +708,7 @@ bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf_s *iocpf)
        bfa_iocpf_timer_start(iocpf->ioc);
 }
 
-/**
+/*
  * Awaiting firmware version match.
  */
 static void
@@ -739,7 +739,7 @@ bfa_iocpf_sm_mismatch(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
-/**
+/*
  * Request for semaphore.
  */
 static void
@@ -748,7 +748,7 @@ bfa_iocpf_sm_semwait_entry(struct bfa_iocpf_s *iocpf)
        bfa_ioc_hw_sem_get(iocpf->ioc);
 }
 
-/**
+/*
  * Awaiting semaphore for h/w initialzation.
  */
 static void
@@ -782,7 +782,7 @@ bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf)
        bfa_ioc_reset(iocpf->ioc, BFA_FALSE);
 }
 
-/**
+/*
  * Hardware is being initialized. Interrupts are enabled.
  * Holding hardware semaphore lock.
  */
@@ -839,7 +839,7 @@ bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf)
        bfa_ioc_send_enable(iocpf->ioc);
 }
 
-/**
+/*
  * Host IOC function is being enabled, awaiting response from firmware.
  * Semaphore is acquired.
  */
@@ -866,8 +866,7 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        case IOCPF_E_TIMEOUT:
                iocpf->retry_count++;
                if (iocpf->retry_count < BFA_IOC_HWINIT_MAX) {
-                       bfa_reg_write(ioc->ioc_regs.ioc_fwstate,
-                                     BFI_IOC_UNINIT);
+                       writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
                        bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
                        break;
                }
@@ -944,7 +943,7 @@ bfa_iocpf_sm_disabling_entry(struct bfa_iocpf_s *iocpf)
        bfa_ioc_send_disable(iocpf->ioc);
 }
 
-/**
+/*
  * IOC is being disabled
  */
 static void
@@ -968,7 +967,7 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
                 */
 
        case IOCPF_E_TIMEOUT:
-               bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
+               writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
                bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
                break;
 
@@ -980,7 +979,7 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
        }
 }
 
-/**
+/*
  * IOC disable completion entry.
  */
 static void
@@ -1018,7 +1017,7 @@ bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf)
        bfa_iocpf_timer_start(iocpf->ioc);
 }
 
-/**
+/*
  * Hardware initialization failed.
  */
 static void
@@ -1053,18 +1052,18 @@ bfa_iocpf_sm_initfail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
 static void
 bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
 {
-       /**
+       /*
         * Mark IOC as failed in hardware and stop firmware.
         */
        bfa_ioc_lpu_stop(iocpf->ioc);
-       bfa_reg_write(iocpf->ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL);
+       writel(BFI_IOC_FAIL, iocpf->ioc->ioc_regs.ioc_fwstate);
 
-       /**
+       /*
         * Notify other functions on HB failure.
         */
        bfa_ioc_notify_hbfail(iocpf->ioc);
 
-       /**
+       /*
         * Flush any queued up mailbox requests.
         */
        bfa_ioc_mbox_hbfail(iocpf->ioc);
@@ -1073,7 +1072,7 @@ bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
                bfa_iocpf_recovery_timer_start(iocpf->ioc);
 }
 
-/**
+/*
  * IOC is in failed state.
  */
 static void
@@ -1101,7 +1100,7 @@ bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
 
 
 
-/**
+/*
  *  hal_ioc_pvt BFA IOC private functions
  */
 
@@ -1113,7 +1112,7 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
 
        ioc->cbfn->disable_cbfn(ioc->bfa);
 
-       /**
+       /*
         * Notify common modules registered for notification.
         */
        list_for_each(qe, &ioc->hb_notify_q) {
@@ -1123,18 +1122,18 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
 }
 
 bfa_boolean_t
-bfa_ioc_sem_get(bfa_os_addr_t sem_reg)
+bfa_ioc_sem_get(void __iomem *sem_reg)
 {
        u32 r32;
        int cnt = 0;
 #define BFA_SEM_SPINCNT        3000
 
-       r32 = bfa_reg_read(sem_reg);
+       r32 = readl(sem_reg);
 
        while (r32 && (cnt < BFA_SEM_SPINCNT)) {
                cnt++;
-               bfa_os_udelay(2);
-               r32 = bfa_reg_read(sem_reg);
+               udelay(2);
+               r32 = readl(sem_reg);
        }
 
        if (r32 == 0)
@@ -1145,9 +1144,9 @@ bfa_ioc_sem_get(bfa_os_addr_t sem_reg)
 }
 
 void
-bfa_ioc_sem_release(bfa_os_addr_t sem_reg)
+bfa_ioc_sem_release(void __iomem *sem_reg)
 {
-       bfa_reg_write(sem_reg, 1);
+       writel(1, sem_reg);
 }
 
 static void
@@ -1155,11 +1154,11 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
 {
        u32     r32;
 
-       /**
+       /*
         * First read to the semaphore register will return 0, subsequent reads
         * will return 1. Semaphore is released by writing 1 to the register
         */
-       r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+       r32 = readl(ioc->ioc_regs.ioc_sem_reg);
        if (r32 == 0) {
                bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
                return;
@@ -1171,7 +1170,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
 void
 bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
 {
-       bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
+       writel(1, ioc->ioc_regs.ioc_sem_reg);
 }
 
 static void
@@ -1180,7 +1179,7 @@ bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc)
        bfa_sem_timer_stop(ioc);
 }
 
-/**
+/*
  * Initialize LPU local memory (aka secondary memory / SRAM)
  */
 static void
@@ -1190,7 +1189,7 @@ bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
        int             i;
 #define PSS_LMEM_INIT_TIME  10000
 
-       pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
+       pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
        pss_ctl &= ~__PSS_LMEM_RESET;
        pss_ctl |= __PSS_LMEM_INIT_EN;
 
@@ -1198,18 +1197,18 @@ bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
         * i2c workaround 12.5khz clock
         */
        pss_ctl |= __PSS_I2C_CLK_DIV(3UL);
-       bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
+       writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
 
-       /**
+       /*
         * wait for memory initialization to be complete
         */
        i = 0;
        do {
-               pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
+               pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
                i++;
        } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
 
-       /**
+       /*
         * If memory initialization is not successful, IOC timeout will catch
         * such failures.
         */
@@ -1217,7 +1216,7 @@ bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
        bfa_trc(ioc, pss_ctl);
 
        pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
-       bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
+       writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
 }
 
 static void
@@ -1225,13 +1224,13 @@ bfa_ioc_lpu_start(struct bfa_ioc_s *ioc)
 {
        u32     pss_ctl;
 
-       /**
+       /*
         * Take processor out of reset.
         */
-       pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
+       pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
        pss_ctl &= ~__PSS_LPU0_RESET;
 
-       bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
+       writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
 }
 
 static void
@@ -1239,16 +1238,16 @@ bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
 {
        u32     pss_ctl;
 
-       /**
+       /*
         * Put processors in reset.
         */
-       pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
+       pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
        pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
 
-       bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
+       writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
 }
 
-/**
+/*
  * Get driver and firmware versions.
  */
 void
@@ -1261,7 +1260,7 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
 
        pgnum = bfa_ioc_smem_pgnum(ioc, loff);
        pgoff = bfa_ioc_smem_pgoff(ioc, loff);
-       bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+       writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
        for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
             i++) {
@@ -1271,7 +1270,7 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
        }
 }
 
-/**
+/*
  * Returns TRUE if same.
  */
 bfa_boolean_t
@@ -1296,7 +1295,7 @@ bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
        return BFA_TRUE;
 }
 
-/**
+/*
  * Return true if current running version is valid. Firmware signature and
  * execution context (driver/bios) must match.
  */
@@ -1305,7 +1304,7 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
 {
        struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr;
 
-       /**
+       /*
         * If bios/efi boot (flash based) -- return true
         */
        if (bfa_ioc_is_bios_optrom(ioc))
@@ -1321,7 +1320,7 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
                return BFA_FALSE;
        }
 
-       if (bfa_os_swap32(fwhdr.param) != boot_env) {
+       if (swab32(fwhdr.param) != boot_env) {
                bfa_trc(ioc, fwhdr.param);
                bfa_trc(ioc, boot_env);
                return BFA_FALSE;
@@ -1330,7 +1329,7 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
        return bfa_ioc_fwver_cmp(ioc, &fwhdr);
 }
 
-/**
+/*
  * Conditionally flush any pending message from firmware at start.
  */
 static void
@@ -1338,9 +1337,9 @@ bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
 {
        u32     r32;
 
-       r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
+       r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
        if (r32)
-               bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
+               writel(1, ioc->ioc_regs.lpu_mbox_cmd);
 }
 
 
@@ -1352,7 +1351,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
        u32 boot_type;
        u32 boot_env;
 
-       ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
+       ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
 
        if (force)
                ioc_fwstate = BFI_IOC_UNINIT;
@@ -1362,7 +1361,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
        boot_type = BFI_BOOT_TYPE_NORMAL;
        boot_env = BFI_BOOT_LOADER_OS;
 
-       /**
+       /*
         * Flash based firmware boot BIOS env.
         */
        if (bfa_ioc_is_bios_optrom(ioc)) {
@@ -1370,7 +1369,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
                boot_env = BFI_BOOT_LOADER_BIOS;
        }
 
-       /**
+       /*
         * Flash based firmware boot UEFI env.
         */
        if (bfa_ioc_is_uefi(ioc)) {
@@ -1378,7 +1377,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
                boot_env = BFI_BOOT_LOADER_UEFI;
        }
 
-       /**
+       /*
         * check if firmware is valid
         */
        fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
@@ -1389,7 +1388,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
                return;
        }
 
-       /**
+       /*
         * If hardware initialization is in progress (initialized by other IOC),
         * just wait for an initialization completion interrupt.
         */
@@ -1398,7 +1397,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
                return;
        }
 
-       /**
+       /*
         * If IOC function is disabled and firmware version is same,
         * just re-enable IOC.
         *
@@ -1409,7 +1408,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
        if (ioc_fwstate == BFI_IOC_DISABLED ||
            (!bfa_ioc_is_bios_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) {
 
-               /**
+               /*
                 * When using MSI-X any pending firmware ready event should
                 * be flushed. Otherwise MSI-X interrupts are not delivered.
                 */
@@ -1419,7 +1418,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
                return;
        }
 
-       /**
+       /*
         * Initialize the h/w for any other states.
         */
        bfa_ioc_boot(ioc, boot_type, boot_env);
@@ -1449,17 +1448,17 @@ bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
         * first write msg to mailbox registers
         */
        for (i = 0; i < len / sizeof(u32); i++)
-               bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32),
-                             bfa_os_wtole(msgp[i]));
+               writel(cpu_to_le32(msgp[i]),
+                       ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
 
        for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
-               bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32), 0);
+               writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
 
        /*
         * write 1 to mailbox CMD to trigger LPU event
         */
-       bfa_reg_write(ioc->ioc_regs.hfn_mbox_cmd, 1);
-       (void) bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
+       writel(1, ioc->ioc_regs.hfn_mbox_cmd);
+       (void) readl(ioc->ioc_regs.hfn_mbox_cmd);
 }
 
 static void
@@ -1472,7 +1471,7 @@ bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
                    bfa_ioc_portid(ioc));
        enable_req.ioc_class = ioc->ioc_mc;
        bfa_os_gettimeofday(&tv);
-       enable_req.tv_sec = bfa_os_ntohl(tv.tv_sec);
+       enable_req.tv_sec = be32_to_cpu(tv.tv_sec);
        bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
 }
 
@@ -1503,7 +1502,7 @@ bfa_ioc_hb_check(void *cbarg)
        struct bfa_ioc_s  *ioc = cbarg;
        u32     hb_count;
 
-       hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
+       hb_count = readl(ioc->ioc_regs.heartbeat);
        if (ioc->hb_count == hb_count) {
                printk(KERN_CRIT "Firmware heartbeat failure at %d", hb_count);
                bfa_ioc_recover(ioc);
@@ -1519,7 +1518,7 @@ bfa_ioc_hb_check(void *cbarg)
 static void
 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
 {
-       ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
+       ioc->hb_count = readl(ioc->ioc_regs.heartbeat);
        bfa_hb_timer_start(ioc);
 }
 
@@ -1530,7 +1529,7 @@ bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
 }
 
 
-/**
+/*
  *     Initiate a full firmware download.
  */
 static void
@@ -1543,7 +1542,7 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
        u32 chunkno = 0;
        u32 i;
 
-       /**
+       /*
         * Initialize LMEM first before code download
         */
        bfa_ioc_lmem_init(ioc);
@@ -1554,7 +1553,7 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
        pgnum = bfa_ioc_smem_pgnum(ioc, loff);
        pgoff = bfa_ioc_smem_pgoff(ioc, loff);
 
-       bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+       writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
        for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) {
 
@@ -1564,7 +1563,7 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
                                        BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
                }
 
-               /**
+               /*
                 * write smem
                 */
                bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
@@ -1572,27 +1571,25 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
 
                loff += sizeof(u32);
 
-               /**
+               /*
                 * handle page offset wrap around
                 */
                loff = PSS_SMEM_PGOFF(loff);
                if (loff == 0) {
                        pgnum++;
-                       bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
-                                     pgnum);
+                       writel(pgnum, ioc->ioc_regs.host_page_num_fn);
                }
        }
 
-       bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
-                     bfa_ioc_smem_pgnum(ioc, 0));
+       writel(bfa_ioc_smem_pgnum(ioc, 0), ioc->ioc_regs.host_page_num_fn);
 
        /*
         * Set boot type and boot param at the end.
        */
        bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF,
-                       bfa_os_swap32(boot_type));
+                       swab32(boot_type));
        bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_LOADER_OFF,
-                       bfa_os_swap32(boot_env));
+                       swab32(boot_env));
 }
 
 static void
@@ -1601,7 +1598,7 @@ bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force)
        bfa_ioc_hwinit(ioc, force);
 }
 
-/**
+/*
  * Update BFA configuration from firmware configuration.
  */
 static void
@@ -1609,14 +1606,14 @@ bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
 {
        struct bfi_ioc_attr_s   *attr = ioc->attr;
 
-       attr->adapter_prop  = bfa_os_ntohl(attr->adapter_prop);
-       attr->card_type     = bfa_os_ntohl(attr->card_type);
-       attr->maxfrsize     = bfa_os_ntohs(attr->maxfrsize);
+       attr->adapter_prop  = be32_to_cpu(attr->adapter_prop);
+       attr->card_type     = be32_to_cpu(attr->card_type);
+       attr->maxfrsize     = be16_to_cpu(attr->maxfrsize);
 
        bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
 }
 
-/**
+/*
  * Attach time initialization of mbox logic.
  */
 static void
@@ -1632,7 +1629,7 @@ bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc)
        }
 }
 
-/**
+/*
  * Mbox poll timer -- restarts any pending mailbox requests.
  */
 static void
@@ -1642,27 +1639,27 @@ bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc)
        struct bfa_mbox_cmd_s           *cmd;
        u32                     stat;
 
-       /**
+       /*
         * If no command pending, do nothing
         */
        if (list_empty(&mod->cmd_q))
                return;
 
-       /**
+       /*
         * If previous command is not yet fetched by firmware, do nothing
         */
-       stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
+       stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
        if (stat)
                return;
 
-       /**
+       /*
         * Enqueue command to firmware.
         */
        bfa_q_deq(&mod->cmd_q, &cmd);
        bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
 }
 
-/**
+/*
  * Cleanup any pending requests.
  */
 static void
@@ -1675,7 +1672,7 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
                bfa_q_deq(&mod->cmd_q, &cmd);
 }
 
-/**
+/*
  * Read data from SMEM to host through PCI memmap
  *
  * @param[in]  ioc     memory for IOC
@@ -1704,26 +1701,25 @@ bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
                return BFA_STATUS_FAILED;
        }
 
-       bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+       writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
        len = sz/sizeof(u32);
        bfa_trc(ioc, len);
        for (i = 0; i < len; i++) {
                r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
-               buf[i] = bfa_os_ntohl(r32);
+               buf[i] = be32_to_cpu(r32);
                loff += sizeof(u32);
 
-               /**
+               /*
                 * handle page offset wrap around
                 */
                loff = PSS_SMEM_PGOFF(loff);
                if (loff == 0) {
                        pgnum++;
-                       bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+                       writel(pgnum, ioc->ioc_regs.host_page_num_fn);
                }
        }
-       bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
-                     bfa_ioc_smem_pgnum(ioc, 0));
+       writel(bfa_ioc_smem_pgnum(ioc, 0), ioc->ioc_regs.host_page_num_fn);
        /*
         *  release semaphore.
         */
@@ -1733,7 +1729,7 @@ bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Clear SMEM data from host through PCI memmap
  *
  * @param[in]  ioc     memory for IOC
@@ -1760,7 +1756,7 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
                return BFA_STATUS_FAILED;
        }
 
-       bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+       writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
        len = sz/sizeof(u32); /* len in words */
        bfa_trc(ioc, len);
@@ -1768,17 +1764,16 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
                bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 0);
                loff += sizeof(u32);
 
-               /**
+               /*
                 * handle page offset wrap around
                 */
                loff = PSS_SMEM_PGOFF(loff);
                if (loff == 0) {
                        pgnum++;
-                       bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
+                       writel(pgnum, ioc->ioc_regs.host_page_num_fn);
                }
        }
-       bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
-                     bfa_ioc_smem_pgnum(ioc, 0));
+       writel(bfa_ioc_smem_pgnum(ioc, 0), ioc->ioc_regs.host_page_num_fn);
 
        /*
         *  release semaphore.
@@ -1788,7 +1783,7 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * hal iocpf to ioc interface
  */
 static void
@@ -1813,7 +1808,7 @@ static void
 bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
 {
        struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
-       /**
+       /*
         * Provide enable completion callback.
         */
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
@@ -1824,7 +1819,7 @@ bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
 
 
 
-/**
+/*
  *  hal_ioc_public
  */
 
@@ -1848,43 +1843,43 @@ bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Interface used by diag module to do firmware boot with memory test
  * as the entry vector.
  */
 void
 bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env)
 {
-       bfa_os_addr_t   rb;
+       void __iomem *rb;
 
        bfa_ioc_stats(ioc, ioc_boots);
 
        if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
                return;
 
-       /**
+       /*
         * Initialize IOC state of all functions on a chip reset.
         */
        rb = ioc->pcidev.pci_bar_kva;
        if (boot_type == BFI_BOOT_TYPE_MEMTEST) {
-               bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_MEMTEST);
-               bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_MEMTEST);
+               writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG));
+               writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG));
        } else {
-               bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_INITING);
-               bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_INITING);
+               writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG));
+               writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG));
        }
 
        bfa_ioc_msgflush(ioc);
        bfa_ioc_download_fw(ioc, boot_type, boot_env);
 
-       /**
+       /*
         * Enable interrupts just before starting LPU
         */
        ioc->cbfn->reset_cbfn(ioc->bfa);
        bfa_ioc_lpu_start(ioc);
 }
 
-/**
+/*
  * Enable/disable IOC failure auto recovery.
  */
 void
@@ -1904,7 +1899,7 @@ bfa_ioc_is_operational(struct bfa_ioc_s *ioc)
 bfa_boolean_t
 bfa_ioc_is_initialized(struct bfa_ioc_s *ioc)
 {
-       u32 r32 = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
+       u32 r32 = readl(ioc->ioc_regs.ioc_fwstate);
 
        return ((r32 != BFI_IOC_UNINIT) &&
                (r32 != BFI_IOC_INITING) &&
@@ -1918,21 +1913,21 @@ bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
        u32     r32;
        int             i;
 
-       /**
+       /*
         * read the MBOX msg
         */
        for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
             i++) {
-               r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox +
+               r32 = readl(ioc->ioc_regs.lpu_mbox +
                                   i * sizeof(u32));
-               msgp[i] = bfa_os_htonl(r32);
+               msgp[i] = cpu_to_be32(r32);
        }
 
-       /**
+       /*
         * turn off mailbox interrupt by clearing mailbox status
         */
-       bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
-       bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
+       writel(1, ioc->ioc_regs.lpu_mbox_cmd);
+       readl(ioc->ioc_regs.lpu_mbox_cmd);
 }
 
 void
@@ -1971,7 +1966,7 @@ bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
        }
 }
 
-/**
+/*
  * IOC attach time initialization and setup.
  *
  * @param[in]  ioc     memory for IOC
@@ -1996,7 +1991,7 @@ bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn,
        bfa_fsm_send_event(ioc, IOC_E_RESET);
 }
 
-/**
+/*
  * Driver detach time IOC cleanup.
  */
 void
@@ -2005,7 +2000,7 @@ bfa_ioc_detach(struct bfa_ioc_s *ioc)
        bfa_fsm_send_event(ioc, IOC_E_DETACH);
 }
 
-/**
+/*
  * Setup IOC PCI properties.
  *
  * @param[in]  pcidev  PCI device information for this IOC
@@ -2019,7 +2014,7 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
        ioc->ctdev      = bfa_asic_id_ct(ioc->pcidev.device_id);
        ioc->cna        = ioc->ctdev && !ioc->fcmode;
 
-       /**
+       /*
         * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
         */
        if (ioc->ctdev)
@@ -2031,7 +2026,7 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
        bfa_ioc_reg_init(ioc);
 }
 
-/**
+/*
  * Initialize IOC dma memory
  *
  * @param[in]  dm_kva  kernel virtual address of IOC dma memory
@@ -2040,7 +2035,7 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
 void
 bfa_ioc_mem_claim(struct bfa_ioc_s *ioc,  u8 *dm_kva, u64 dm_pa)
 {
-       /**
+       /*
         * dma memory for firmware attribute
         */
        ioc->attr_dma.kva = dm_kva;
@@ -2048,7 +2043,7 @@ bfa_ioc_mem_claim(struct bfa_ioc_s *ioc,  u8 *dm_kva, u64 dm_pa)
        ioc->attr = (struct bfi_ioc_attr_s *) dm_kva;
 }
 
-/**
+/*
  * Return size of dma memory required.
  */
 u32
@@ -2073,7 +2068,7 @@ bfa_ioc_disable(struct bfa_ioc_s *ioc)
        bfa_fsm_send_event(ioc, IOC_E_DISABLE);
 }
 
-/**
+/*
  * Returns memory required for saving firmware trace in case of crash.
  * Driver must call this interface to allocate memory required for
  * automatic saving of firmware trace. Driver should call
@@ -2086,7 +2081,7 @@ bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover)
        return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
 }
 
-/**
+/*
  * Initialize memory for saving firmware trace. Driver must initialize
  * trace memory before call bfa_ioc_enable().
  */
@@ -2109,7 +2104,7 @@ bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr)
        return PSS_SMEM_PGOFF(fmaddr);
 }
 
-/**
+/*
  * Register mailbox message handler functions
  *
  * @param[in]  ioc             IOC instance
@@ -2125,7 +2120,7 @@ bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs)
                mod->mbhdlr[mc].cbfn = mcfuncs[mc];
 }
 
-/**
+/*
  * Register mailbox message handler function, to be called by common modules
  */
 void
@@ -2138,7 +2133,7 @@ bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
        mod->mbhdlr[mc].cbarg   = cbarg;
 }
 
-/**
+/*
  * Queue a mailbox command request to firmware. Waits if mailbox is busy.
  * Responsibility of caller to serialize
  *
@@ -2151,7 +2146,7 @@ bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
        struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
        u32                     stat;
 
-       /**
+       /*
         * If a previous command is pending, queue new command
         */
        if (!list_empty(&mod->cmd_q)) {
@@ -2159,22 +2154,22 @@ bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
                return;
        }
 
-       /**
+       /*
         * If mailbox is busy, queue command for poll timer
         */
-       stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
+       stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
        if (stat) {
                list_add_tail(&cmd->qe, &mod->cmd_q);
                return;
        }
 
-       /**
+       /*
         * mailbox is free -- queue command to firmware
         */
        bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
 }
 
-/**
+/*
  * Handle mailbox interrupts
  */
 void
@@ -2186,7 +2181,7 @@ bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
 
        bfa_ioc_msgget(ioc, &m);
 
-       /**
+       /*
         * Treat IOC message class as special.
         */
        mc = m.mh.msg_class;
@@ -2214,7 +2209,7 @@ bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
        ioc->port_id = bfa_ioc_pcifn(ioc);
 }
 
-/**
+/*
  * return true if IOC is disabled
  */
 bfa_boolean_t
@@ -2224,7 +2219,7 @@ bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
                bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
 }
 
-/**
+/*
  * return true if IOC firmware is different.
  */
 bfa_boolean_t
@@ -2243,7 +2238,7 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
         ((__sm) == BFI_IOC_FAIL) ||            \
         ((__sm) == BFI_IOC_CFG_DISABLED))
 
-/**
+/*
  * Check if adapter is disabled -- both IOCs should be in a disabled
  * state.
  */
@@ -2251,17 +2246,17 @@ bfa_boolean_t
 bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
 {
        u32     ioc_state;
-       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       void __iomem *rb = ioc->pcidev.pci_bar_kva;
 
        if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
                return BFA_FALSE;
 
-       ioc_state = bfa_reg_read(rb + BFA_IOC0_STATE_REG);
+       ioc_state = readl(rb + BFA_IOC0_STATE_REG);
        if (!bfa_ioc_state_disabled(ioc_state))
                return BFA_FALSE;
 
        if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) {
-               ioc_state = bfa_reg_read(rb + BFA_IOC1_STATE_REG);
+               ioc_state = readl(rb + BFA_IOC1_STATE_REG);
                if (!bfa_ioc_state_disabled(ioc_state))
                        return BFA_FALSE;
        }
@@ -2269,7 +2264,7 @@ bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
        return BFA_TRUE;
 }
 
-/**
+/*
  * Add to IOC heartbeat failure notification queue. To be used by common
  * modules such as cee, port, diag.
  */
@@ -2293,7 +2288,7 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
        bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
        bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
        bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
-       bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
+       memcpy(&ad_attr->vpd, &ioc_attr->vpd,
                      sizeof(struct bfa_mfg_vpd_s));
 
        ad_attr->nports = bfa_ioc_get_nports(ioc);
@@ -2343,8 +2338,8 @@ bfa_ioc_get_type(struct bfa_ioc_s *ioc)
 void
 bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
 {
-       bfa_os_memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
-       bfa_os_memcpy((void *)serial_num,
+       memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
+       memcpy((void *)serial_num,
                        (void *)ioc->attr->brcd_serialnum,
                        BFA_ADAPTER_SERIAL_NUM_LEN);
 }
@@ -2352,8 +2347,8 @@ bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
 void
 bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
 {
-       bfa_os_memset((void *)fw_ver, 0, BFA_VERSION_LEN);
-       bfa_os_memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
+       memset((void *)fw_ver, 0, BFA_VERSION_LEN);
+       memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
 }
 
 void
@@ -2361,7 +2356,7 @@ bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
 {
        bfa_assert(chip_rev);
 
-       bfa_os_memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
+       memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
 
        chip_rev[0] = 'R';
        chip_rev[1] = 'e';
@@ -2374,16 +2369,16 @@ bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
 void
 bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
 {
-       bfa_os_memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
-       bfa_os_memcpy(optrom_ver, ioc->attr->optrom_version,
+       memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
+       memcpy(optrom_ver, ioc->attr->optrom_version,
                      BFA_VERSION_LEN);
 }
 
 void
 bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
 {
-       bfa_os_memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
-       bfa_os_memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
+       memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
+       memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
 }
 
 void
@@ -2392,14 +2387,14 @@ bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
        struct bfi_ioc_attr_s   *ioc_attr;
 
        bfa_assert(model);
-       bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
+       memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
 
        ioc_attr = ioc->attr;
 
-       /**
+       /*
         * model name
         */
-       bfa_os_snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
+       snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
                BFA_MFG_NAME, ioc_attr->card_type);
 }
 
@@ -2446,7 +2441,7 @@ bfa_ioc_get_state(struct bfa_ioc_s *ioc)
 void
 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
 {
-       bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
+       memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
 
        ioc_attr->state = bfa_ioc_get_state(ioc);
        ioc_attr->port_id = ioc->port_id;
@@ -2460,7 +2455,7 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
        bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
 }
 
-/**
+/*
  *  hal_wwn_public
  */
 wwn_t
@@ -2526,7 +2521,7 @@ bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
        return ioc->fcmode || !bfa_asic_id_ct(ioc->pcidev.device_id);
 }
 
-/**
+/*
  * Retrieve saved firmware trace from a prior IOC failure.
  */
 bfa_status_t
@@ -2541,12 +2536,12 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
        if (tlen > ioc->dbg_fwsave_len)
                tlen = ioc->dbg_fwsave_len;
 
-       bfa_os_memcpy(trcdata, ioc->dbg_fwsave, tlen);
+       memcpy(trcdata, ioc->dbg_fwsave, tlen);
        *trclen = tlen;
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Clear saved firmware trace
  */
 void
@@ -2555,7 +2550,7 @@ bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc)
        ioc->dbg_fwsave_once = BFA_TRUE;
 }
 
-/**
+/*
  * Retrieve saved firmware trace from a prior IOC failure.
  */
 bfa_status_t
@@ -2595,7 +2590,7 @@ bfa_ioc_fwsync(struct bfa_ioc_s *ioc)
 
        bfa_ioc_send_fwsync(ioc);
 
-       /**
+       /*
         * After sending a fw sync mbox command wait for it to
         * take effect.  We will not wait for a response because
         *    1. fw_sync mbox cmd doesn't have a response.
@@ -2610,7 +2605,7 @@ bfa_ioc_fwsync(struct bfa_ioc_s *ioc)
                fwsync_iter--;
 }
 
-/**
+/*
  * Dump firmware smem
  */
 bfa_status_t
@@ -2630,7 +2625,7 @@ bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf,
        loff = *offset;
        dlen = *buflen;
 
-       /**
+       /*
         * First smem read, sync smem before proceeding
         * No need to sync before reading every chunk.
         */
@@ -2657,7 +2652,7 @@ bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf,
        return status;
 }
 
-/**
+/*
  * Firmware statistics
  */
 bfa_status_t
@@ -2702,7 +2697,7 @@ bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc)
        return status;
 }
 
-/**
+/*
  * Save firmware trace if configured.
  */
 static void
@@ -2716,7 +2711,7 @@ bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
        }
 }
 
-/**
+/*
  * Firmware failure detected. Start recovery actions.
  */
 static void
@@ -2738,7 +2733,7 @@ bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc)
                return;
 }
 
-/**
+/*
  *  hal_iocpf_pvt BFA IOC PF private functions
  */
 
@@ -2795,7 +2790,7 @@ bfa_iocpf_sem_timeout(void *ioc_arg)
        bfa_ioc_hw_sem_get(ioc);
 }
 
-/**
+/*
  *  bfa timer function
  */
 void
@@ -2840,7 +2835,7 @@ bfa_timer_beat(struct bfa_timer_mod_s *mod)
        }
 }
 
-/**
+/*
  * Should be called with lock protection
  */
 void
@@ -2858,7 +2853,7 @@ bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
        list_add_tail(&timer->qe, &mod->timer_q);
 }
 
-/**
+/*
  * Should be called with lock protection
  */
 void
index 288c5801aace553021d68472824f342ce9aac0e0..9c407a87a1a1e01e228531c5dd48a4a0f1c85f3b 100644 (file)
 #include "bfa_cs.h"
 #include "bfi.h"
 
-/**
+/*
  * BFA timer declarations
  */
 typedef void (*bfa_timer_cbfn_t)(void *);
 
-/**
+/*
  * BFA timer data structure
  */
 struct bfa_timer_s {
        struct list_head        qe;
        bfa_timer_cbfn_t timercb;
        void            *arg;
-       int             timeout;        /**< in millisecs. */
+       int             timeout;        /* in millisecs */
 };
 
-/**
+/*
  * Timer module structure
  */
 struct bfa_timer_mod_s {
        struct list_head timer_q;
 };
 
-#define BFA_TIMER_FREQ 200 /**< specified in millisecs */
+#define BFA_TIMER_FREQ 200 /* specified in millisecs */
 
 void bfa_timer_beat(struct bfa_timer_mod_s *mod);
 void bfa_timer_init(struct bfa_timer_mod_s *mod);
@@ -53,7 +53,7 @@ void bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
                        unsigned int timeout);
 void bfa_timer_stop(struct bfa_timer_s *timer);
 
-/**
+/*
  * Generic Scatter Gather Element used by driver
  */
 struct bfa_sge_s {
@@ -62,9 +62,9 @@ struct bfa_sge_s {
 };
 
 #define bfa_sge_word_swap(__sge) do {                                       \
-       ((u32 *)(__sge))[0] = bfa_os_swap32(((u32 *)(__sge))[0]);      \
-       ((u32 *)(__sge))[1] = bfa_os_swap32(((u32 *)(__sge))[1]);      \
-       ((u32 *)(__sge))[2] = bfa_os_swap32(((u32 *)(__sge))[2]);      \
+       ((u32 *)(__sge))[0] = swab32(((u32 *)(__sge))[0]);      \
+       ((u32 *)(__sge))[1] = swab32(((u32 *)(__sge))[1]);      \
+       ((u32 *)(__sge))[2] = swab32(((u32 *)(__sge))[2]);      \
 } while (0)
 
 #define bfa_swap_words(_x)  (  \
@@ -80,17 +80,17 @@ struct bfa_sge_s {
 #define bfa_sgaddr_le(_x)      (_x)
 #endif
 
-/**
+/*
  * PCI device information required by IOC
  */
 struct bfa_pcidev_s {
        int             pci_slot;
        u8              pci_func;
-       u16     device_id;
-       bfa_os_addr_t   pci_bar_kva;
+       u16             device_id;
+       void __iomem    *pci_bar_kva;
 };
 
-/**
+/*
  * Structure used to remember the DMA-able memory block's KVA and Physical
  * Address
  */
@@ -102,7 +102,7 @@ struct bfa_dma_s {
 #define BFA_DMA_ALIGN_SZ       256
 #define BFA_ROUNDUP(_l, _s)    (((_l) + ((_s) - 1)) & ~((_s) - 1))
 
-/**
+/*
  * smem size for Crossbow and Catapult
  */
 #define BFI_SMEM_CB_SIZE       0x200000U       /* ! 2MB for crossbow   */
@@ -125,40 +125,38 @@ __bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
 static inline void
 __bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa)
 {
-       dma_addr->a32.addr_lo = (u32) bfa_os_htonl(pa);
-       dma_addr->a32.addr_hi = (u32) bfa_os_htonl(bfa_os_u32(pa));
+       dma_addr->a32.addr_lo = (u32) cpu_to_be32(pa);
+       dma_addr->a32.addr_hi = (u32) cpu_to_be32(bfa_os_u32(pa));
 }
 
 struct bfa_ioc_regs_s {
-       bfa_os_addr_t   hfn_mbox_cmd;
-       bfa_os_addr_t   hfn_mbox;
-       bfa_os_addr_t   lpu_mbox_cmd;
-       bfa_os_addr_t   lpu_mbox;
-       bfa_os_addr_t   pss_ctl_reg;
-       bfa_os_addr_t   pss_err_status_reg;
-       bfa_os_addr_t   app_pll_fast_ctl_reg;
-       bfa_os_addr_t   app_pll_slow_ctl_reg;
-       bfa_os_addr_t   ioc_sem_reg;
-       bfa_os_addr_t   ioc_usage_sem_reg;
-       bfa_os_addr_t   ioc_init_sem_reg;
-       bfa_os_addr_t   ioc_usage_reg;
-       bfa_os_addr_t   host_page_num_fn;
-       bfa_os_addr_t   heartbeat;
-       bfa_os_addr_t   ioc_fwstate;
-       bfa_os_addr_t   ll_halt;
-       bfa_os_addr_t   err_set;
-       bfa_os_addr_t   shirq_isr_next;
-       bfa_os_addr_t   shirq_msk_next;
-       bfa_os_addr_t   smem_page_start;
+       void __iomem *hfn_mbox_cmd;
+       void __iomem *hfn_mbox;
+       void __iomem *lpu_mbox_cmd;
+       void __iomem *lpu_mbox;
+       void __iomem *pss_ctl_reg;
+       void __iomem *pss_err_status_reg;
+       void __iomem *app_pll_fast_ctl_reg;
+       void __iomem *app_pll_slow_ctl_reg;
+       void __iomem *ioc_sem_reg;
+       void __iomem *ioc_usage_sem_reg;
+       void __iomem *ioc_init_sem_reg;
+       void __iomem *ioc_usage_reg;
+       void __iomem *host_page_num_fn;
+       void __iomem *heartbeat;
+       void __iomem *ioc_fwstate;
+       void __iomem *ll_halt;
+       void __iomem *err_set;
+       void __iomem *shirq_isr_next;
+       void __iomem *shirq_msk_next;
+       void __iomem *smem_page_start;
        u32     smem_pg0;
 };
 
-#define bfa_reg_read(_raddr)   bfa_os_reg_read(_raddr)
-#define bfa_reg_write(_raddr, _val)    bfa_os_reg_write(_raddr, _val)
-#define bfa_mem_read(_raddr, _off)     bfa_os_mem_read(_raddr, _off)
+#define bfa_mem_read(_raddr, _off)     swab32(readl(((_raddr) + (_off))))
 #define bfa_mem_write(_raddr, _off, _val)      \
-                                       bfa_os_mem_write(_raddr, _off, _val)
-/**
+                       writel(swab32((_val)), ((_raddr) + (_off)))
+/*
  * IOC Mailbox structures
  */
 struct bfa_mbox_cmd_s {
@@ -166,7 +164,7 @@ struct bfa_mbox_cmd_s {
        u32     msg[BFI_IOC_MSGSZ];
 };
 
-/**
+/*
  * IOC mailbox module
  */
 typedef void (*bfa_ioc_mbox_mcfunc_t)(void *cbarg, struct bfi_mbmsg_s *m);
@@ -179,7 +177,7 @@ struct bfa_ioc_mbox_mod_s {
        } mbhdlr[BFI_MC_MAX];
 };
 
-/**
+/*
  * IOC callback function interfaces
  */
 typedef void (*bfa_ioc_enable_cbfn_t)(void *bfa, enum bfa_status status);
@@ -193,7 +191,7 @@ struct bfa_ioc_cbfn_s {
        bfa_ioc_reset_cbfn_t    reset_cbfn;
 };
 
-/**
+/*
  * Heartbeat failure notification queue element.
  */
 struct bfa_ioc_hbfail_notify_s {
@@ -202,7 +200,7 @@ struct bfa_ioc_hbfail_notify_s {
        void                    *cbarg;
 };
 
-/**
+/*
  * Initialize a heartbeat failure notification structure
  */
 #define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do {    \
@@ -249,7 +247,7 @@ struct bfa_ioc_s {
 };
 
 struct bfa_ioc_hwif_s {
-       bfa_status_t (*ioc_pll_init) (bfa_os_addr_t rb, bfa_boolean_t fcmode);
+       bfa_status_t (*ioc_pll_init) (void __iomem *rb, bfa_boolean_t fcmode);
        bfa_boolean_t   (*ioc_firmware_lock)    (struct bfa_ioc_s *ioc);
        void            (*ioc_firmware_unlock)  (struct bfa_ioc_s *ioc);
        void            (*ioc_reg_init) (struct bfa_ioc_s *ioc);
@@ -267,7 +265,7 @@ struct bfa_ioc_hwif_s {
 #define bfa_ioc_fetch_stats(__ioc, __stats) \
                (((__stats)->drv_stats) = (__ioc)->stats)
 #define bfa_ioc_clr_stats(__ioc)       \
-               bfa_os_memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats))
+               memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats))
 #define bfa_ioc_maxfrsize(__ioc)       ((__ioc)->attr->maxfrsize)
 #define bfa_ioc_rx_bbcredit(__ioc)     ((__ioc)->attr->rx_bbcredit)
 #define bfa_ioc_speed_sup(__ioc)       \
@@ -287,7 +285,7 @@ struct bfa_ioc_hwif_s {
 #define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off)     (off % BFI_FLASH_CHUNK_SZ_WORDS)
 #define BFA_IOC_FLASH_CHUNK_ADDR(chunkno)  (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
 
-/**
+/*
  * IOC mailbox interface
  */
 void bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd);
@@ -299,7 +297,7 @@ void bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg);
 void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
                bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg);
 
-/**
+/*
  * IOC interfaces
  */
 
@@ -308,9 +306,9 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
                           (__ioc)->fcmode))
 
 bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
-bfa_status_t bfa_ioc_cb_pll_init(bfa_os_addr_t rb, bfa_boolean_t fcmode);
-bfa_boolean_t bfa_ioc_ct_pll_init_complete(bfa_os_addr_t rb);
-bfa_status_t bfa_ioc_ct_pll_init(bfa_os_addr_t rb, bfa_boolean_t fcmode);
+bfa_status_t bfa_ioc_cb_pll_init(void __iomem *rb, bfa_boolean_t fcmode);
+bfa_boolean_t bfa_ioc_ct_pll_init_complete(void __iomem *rb);
+bfa_status_t bfa_ioc_ct_pll_init(void __iomem *rb, bfa_boolean_t fcmode);
 
 #define        bfa_ioc_isr_mode_set(__ioc, __msix)                     \
                        ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix))
@@ -370,8 +368,8 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
 bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
 void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
        struct bfa_ioc_hbfail_notify_s *notify);
-bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg);
-void bfa_ioc_sem_release(bfa_os_addr_t sem_reg);
+bfa_boolean_t bfa_ioc_sem_get(void __iomem *sem_reg);
+void bfa_ioc_sem_release(void __iomem *sem_reg);
 void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
 void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
                        struct bfi_ioc_image_hdr_s *fwhdr);
@@ -441,7 +439,7 @@ bfa_cb_image_get_size(int type)
        }
 }
 
-/**
+/*
  * CNA TRCMOD declaration
  */
 /*
index d7ac864d8539de35a1fc56c28c33091be71534a9..909945043850fbbeaf5b3a0699fd46e11186bd9e 100644 (file)
@@ -34,7 +34,7 @@ static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
 
 struct bfa_ioc_hwif_s hwif_cb;
 
-/**
+/*
  * Called from bfa_ioc_attach() to map asic specific calls.
  */
 void
@@ -52,7 +52,7 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
        ioc->ioc_hwif = &hwif_cb;
 }
 
-/**
+/*
  * Return true if firmware of current driver matches the running firmware.
  */
 static bfa_boolean_t
@@ -66,17 +66,17 @@ bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc)
 {
 }
 
-/**
+/*
  * Notify other functions on HB failure.
  */
 static void
 bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc)
 {
-       bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
-       bfa_reg_read(ioc->ioc_regs.err_set);
+       writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
+       readl(ioc->ioc_regs.err_set);
 }
 
-/**
+/*
  * Host to LPU mailbox message addresses
  */
 static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
@@ -84,7 +84,7 @@ static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
        { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }
 };
 
-/**
+/*
  * Host <-> LPU mailbox command/status registers
  */
 static struct { u32 hfn, lpu; } iocreg_mbcmd[] = {
@@ -96,7 +96,7 @@ static struct { u32 hfn, lpu; } iocreg_mbcmd[] = {
 static void
 bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
 {
-       bfa_os_addr_t   rb;
+       void __iomem *rb;
        int             pcifn = bfa_ioc_pcifn(ioc);
 
        rb = bfa_ioc_bar0(ioc);
@@ -113,7 +113,7 @@ bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
                ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
        }
 
-       /**
+       /*
         * Host <-> LPU mailbox command/status registers
         */
        ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn;
@@ -133,7 +133,7 @@ bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
        ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
        ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
 
-       /**
+       /*
         * sram memory access
         */
        ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
@@ -145,14 +145,14 @@ bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc)
        ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
 }
 
-/**
+/*
  * Initialize IOC to port mapping.
  */
 
 static void
 bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
 {
-       /**
+       /*
         * For crossbow, port id is same as pci function.
         */
        ioc->port_id = bfa_ioc_pcifn(ioc);
@@ -160,7 +160,7 @@ bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc)
        bfa_trc(ioc, ioc->port_id);
 }
 
-/**
+/*
  * Set interrupt mode for a function: INTX or MSIX
  */
 static void
@@ -168,7 +168,7 @@ bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
 {
 }
 
-/**
+/*
  * Cleanup hw semaphore and usecnt registers
  */
 static void
@@ -180,14 +180,14 @@ bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc)
         * before we clear it. If it is not locked, writing 1
         * will lock it instead of clearing it.
         */
-       bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+       readl(ioc->ioc_regs.ioc_sem_reg);
        bfa_ioc_hw_sem_release(ioc);
 }
 
 
 
 bfa_status_t
-bfa_ioc_cb_pll_init(bfa_os_addr_t rb, bfa_boolean_t fcmode)
+bfa_ioc_cb_pll_init(void __iomem *rb, bfa_boolean_t fcmode)
 {
        u32     pll_sclk, pll_fclk;
 
@@ -199,38 +199,32 @@ bfa_ioc_cb_pll_init(bfa_os_addr_t rb, bfa_boolean_t fcmode)
                __APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) |
                __APP_PLL_400_JITLMT0_1(3U) |
                __APP_PLL_400_CNTLMT0_1(3U);
-       bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
-       bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
-       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-       bfa_reg_write(rb + APP_PLL_212_CTL_REG,
-                         __APP_PLL_212_LOGIC_SOFT_RESET);
-       bfa_reg_write(rb + APP_PLL_212_CTL_REG,
-                         __APP_PLL_212_BYPASS |
-                         __APP_PLL_212_LOGIC_SOFT_RESET);
-       bfa_reg_write(rb + APP_PLL_400_CTL_REG,
-                         __APP_PLL_400_LOGIC_SOFT_RESET);
-       bfa_reg_write(rb + APP_PLL_400_CTL_REG,
-                         __APP_PLL_400_BYPASS |
-                         __APP_PLL_400_LOGIC_SOFT_RESET);
-       bfa_os_udelay(2);
-       bfa_reg_write(rb + APP_PLL_212_CTL_REG,
-                         __APP_PLL_212_LOGIC_SOFT_RESET);
-       bfa_reg_write(rb + APP_PLL_400_CTL_REG,
-                         __APP_PLL_400_LOGIC_SOFT_RESET);
-       bfa_reg_write(rb + APP_PLL_212_CTL_REG,
-                         pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET);
-       bfa_reg_write(rb + APP_PLL_400_CTL_REG,
-                         pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET);
-       bfa_os_udelay(2000);
-       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + APP_PLL_212_CTL_REG), pll_sclk);
-       bfa_reg_write((rb + APP_PLL_400_CTL_REG), pll_fclk);
+       writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG));
+       writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG));
+       writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
+       writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
+       writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
+       writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
+       writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
+       writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
+       writel(__APP_PLL_212_LOGIC_SOFT_RESET, rb + APP_PLL_212_CTL_REG);
+       writel(__APP_PLL_212_BYPASS | __APP_PLL_212_LOGIC_SOFT_RESET,
+                       rb + APP_PLL_212_CTL_REG);
+       writel(__APP_PLL_400_LOGIC_SOFT_RESET, rb + APP_PLL_400_CTL_REG);
+       writel(__APP_PLL_400_BYPASS | __APP_PLL_400_LOGIC_SOFT_RESET,
+                       rb + APP_PLL_400_CTL_REG);
+       udelay(2);
+       writel(__APP_PLL_212_LOGIC_SOFT_RESET, rb + APP_PLL_212_CTL_REG);
+       writel(__APP_PLL_400_LOGIC_SOFT_RESET, rb + APP_PLL_400_CTL_REG);
+       writel(pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET,
+                       rb + APP_PLL_212_CTL_REG);
+       writel(pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET,
+                       rb + APP_PLL_400_CTL_REG);
+       udelay(2000);
+       writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
+       writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
+       writel(pll_sclk, (rb + APP_PLL_212_CTL_REG));
+       writel(pll_fclk, (rb + APP_PLL_400_CTL_REG));
 
        return BFA_STATUS_OK;
 }
index f21b82c5f64c64cf271b378099d38484dbf2611c..115730c0aa77f321aa25ee6f0d7136f43c8c2b90 100644 (file)
@@ -34,7 +34,7 @@ static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
 
 struct bfa_ioc_hwif_s hwif_ct;
 
-/**
+/*
  * Called from bfa_ioc_attach() to map asic specific calls.
  */
 void
@@ -52,7 +52,7 @@ bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
        ioc->ioc_hwif = &hwif_ct;
 }
 
-/**
+/*
  * Return true if firmware of current driver matches the running firmware.
  */
 static bfa_boolean_t
@@ -62,13 +62,13 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
        u32 usecnt;
        struct bfi_ioc_image_hdr_s fwhdr;
 
-       /**
+       /*
         * Firmware match check is relevant only for CNA.
         */
        if (!ioc->cna)
                return BFA_TRUE;
 
-       /**
+       /*
         * If bios boot (flash based) -- do not increment usage count
         */
        if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
@@ -76,27 +76,27 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
                return BFA_TRUE;
 
        bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
-       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+       usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
 
-       /**
+       /*
         * If usage count is 0, always return TRUE.
         */
        if (usecnt == 0) {
-               bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
+               writel(1, ioc->ioc_regs.ioc_usage_reg);
                bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
                bfa_trc(ioc, usecnt);
                return BFA_TRUE;
        }
 
-       ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
+       ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
        bfa_trc(ioc, ioc_fwstate);
 
-       /**
+       /*
         * Use count cannot be non-zero and chip in uninitialized state.
         */
        bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
 
-       /**
+       /*
         * Check if another driver with a different firmware is active
         */
        bfa_ioc_fwver_get(ioc, &fwhdr);
@@ -106,11 +106,11 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
                return BFA_FALSE;
        }
 
-       /**
+       /*
         * Same firmware version. Increment the reference count.
         */
        usecnt++;
-       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+       writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
        bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
        bfa_trc(ioc, usecnt);
        return BFA_TRUE;
@@ -121,50 +121,50 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
 {
        u32 usecnt;
 
-       /**
+       /*
         * Firmware lock is relevant only for CNA.
         */
        if (!ioc->cna)
                return;
 
-       /**
+       /*
         * If bios boot (flash based) -- do not decrement usage count
         */
        if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
                                                BFA_IOC_FWIMG_MINSZ)
                return;
 
-       /**
+       /*
         * decrement usage count
         */
        bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
-       usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
+       usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
        bfa_assert(usecnt > 0);
 
        usecnt--;
-       bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
+       writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
        bfa_trc(ioc, usecnt);
 
        bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
 }
 
-/**
+/*
  * Notify other functions on HB failure.
  */
 static void
 bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
 {
        if (ioc->cna) {
-               bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
+               writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
                /* Wait for halt to take effect */
-               bfa_reg_read(ioc->ioc_regs.ll_halt);
+               readl(ioc->ioc_regs.ll_halt);
        } else {
-               bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
-               bfa_reg_read(ioc->ioc_regs.err_set);
+               writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
+               readl(ioc->ioc_regs.err_set);
        }
 }
 
-/**
+/*
  * Host to LPU mailbox message addresses
  */
 static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
@@ -174,7 +174,7 @@ static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
        { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
 };
 
-/**
+/*
  * Host <-> LPU mailbox command/status registers - port 0
  */
 static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
@@ -184,7 +184,7 @@ static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
        { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
 };
 
-/**
+/*
  * Host <-> LPU mailbox command/status registers - port 1
  */
 static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
@@ -197,7 +197,7 @@ static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
 static void
 bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
 {
-       bfa_os_addr_t   rb;
+       void __iomem *rb;
        int             pcifn = bfa_ioc_pcifn(ioc);
 
        rb = bfa_ioc_bar0(ioc);
@@ -236,7 +236,7 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
        ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
        ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
 
-       /**
+       /*
         * sram memory access
         */
        ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
@@ -248,7 +248,7 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
        ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
 }
 
-/**
+/*
  * Initialize IOC to port mapping.
  */
 
@@ -256,13 +256,13 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
 static void
 bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
 {
-       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       void __iomem *rb = ioc->pcidev.pci_bar_kva;
        u32     r32;
 
-       /**
+       /*
         * For catapult, base port id on personality register and IOC type
         */
-       r32 = bfa_reg_read(rb + FNC_PERS_REG);
+       r32 = readl(rb + FNC_PERS_REG);
        r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
        ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
 
@@ -270,22 +270,22 @@ bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
        bfa_trc(ioc, ioc->port_id);
 }
 
-/**
+/*
  * Set interrupt mode for a function: INTX or MSIX
  */
 static void
 bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
 {
-       bfa_os_addr_t   rb = ioc->pcidev.pci_bar_kva;
+       void __iomem *rb = ioc->pcidev.pci_bar_kva;
        u32     r32, mode;
 
-       r32 = bfa_reg_read(rb + FNC_PERS_REG);
+       r32 = readl(rb + FNC_PERS_REG);
        bfa_trc(ioc, r32);
 
        mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
                __F0_INTX_STATUS;
 
-       /**
+       /*
         * If already in desired mode, do not change anything
         */
        if (!msix && mode)
@@ -300,10 +300,10 @@ bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
        r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
        bfa_trc(ioc, r32);
 
-       bfa_reg_write(rb + FNC_PERS_REG, r32);
+       writel(r32, rb + FNC_PERS_REG);
 }
 
-/**
+/*
  * Cleanup hw semaphore and usecnt registers
  */
 static void
@@ -312,7 +312,7 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
 
        if (ioc->cna) {
                bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
-               bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
+               writel(0, ioc->ioc_regs.ioc_usage_reg);
                bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
        }
 
@@ -321,7 +321,7 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
         * before we clear it. If it is not locked, writing 1
         * will lock it instead of clearing it.
         */
-       bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
+       readl(ioc->ioc_regs.ioc_sem_reg);
        bfa_ioc_hw_sem_release(ioc);
 }
 
@@ -331,17 +331,17 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
  * Check the firmware state to know if pll_init has been completed already
  */
 bfa_boolean_t
-bfa_ioc_ct_pll_init_complete(bfa_os_addr_t rb)
+bfa_ioc_ct_pll_init_complete(void __iomem *rb)
 {
-       if ((bfa_reg_read(rb + BFA_IOC0_STATE_REG) == BFI_IOC_OP) ||
-         (bfa_reg_read(rb + BFA_IOC1_STATE_REG) == BFI_IOC_OP))
+       if ((readl(rb + BFA_IOC0_STATE_REG) == BFI_IOC_OP) ||
+         (readl(rb + BFA_IOC1_STATE_REG) == BFI_IOC_OP))
                return BFA_TRUE;
 
        return BFA_FALSE;
 }
 
 bfa_status_t
-bfa_ioc_ct_pll_init(bfa_os_addr_t rb, bfa_boolean_t fcmode)
+bfa_ioc_ct_pll_init(void __iomem *rb, bfa_boolean_t fcmode)
 {
        u32     pll_sclk, pll_fclk, r32;
 
@@ -354,56 +354,51 @@ bfa_ioc_ct_pll_init(bfa_os_addr_t rb, bfa_boolean_t fcmode)
                __APP_PLL_425_JITLMT0_1(3U) |
                __APP_PLL_425_CNTLMT0_1(1U);
        if (fcmode) {
-               bfa_reg_write((rb + OP_MODE), 0);
-               bfa_reg_write((rb + ETH_MAC_SER_REG),
-                               __APP_EMS_CMLCKSEL |
-                               __APP_EMS_REFCKBUFEN2 |
-                               __APP_EMS_CHANNEL_SEL);
+               writel(0, (rb + OP_MODE));
+               writel(__APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2 |
+                        __APP_EMS_CHANNEL_SEL, (rb + ETH_MAC_SER_REG));
        } else {
-               bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
-               bfa_reg_write((rb + ETH_MAC_SER_REG),
-                               __APP_EMS_REFCKBUFEN1);
+               writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE));
+               writel(__APP_EMS_REFCKBUFEN1, (rb + ETH_MAC_SER_REG));
        }
-       bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
-       bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
-       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
-       bfa_reg_write(rb + APP_PLL_312_CTL_REG, pll_sclk |
-               __APP_PLL_312_LOGIC_SOFT_RESET);
-       bfa_reg_write(rb + APP_PLL_425_CTL_REG, pll_fclk |
-               __APP_PLL_425_LOGIC_SOFT_RESET);
-       bfa_reg_write(rb + APP_PLL_312_CTL_REG, pll_sclk |
-               __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE);
-       bfa_reg_write(rb + APP_PLL_425_CTL_REG, pll_fclk |
-               __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE);
-       bfa_reg_read(rb + HOSTFN0_INT_MSK);
-       bfa_os_udelay(2000);
-       bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
-       bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
-       bfa_reg_write(rb + APP_PLL_312_CTL_REG, pll_sclk |
-               __APP_PLL_312_ENABLE);
-       bfa_reg_write(rb + APP_PLL_425_CTL_REG, pll_fclk |
-               __APP_PLL_425_ENABLE);
+       writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG));
+       writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG));
+       writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
+       writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
+       writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
+       writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
+       writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
+       writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
+       writel(pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET,
+                       rb + APP_PLL_312_CTL_REG);
+       writel(pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET,
+                       rb + APP_PLL_425_CTL_REG);
+       writel(pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE,
+                       rb + APP_PLL_312_CTL_REG);
+       writel(pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE,
+                       rb + APP_PLL_425_CTL_REG);
+       readl(rb + HOSTFN0_INT_MSK);
+       udelay(2000);
+       writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
+       writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
+       writel(pll_sclk | __APP_PLL_312_ENABLE, rb + APP_PLL_312_CTL_REG);
+       writel(pll_fclk | __APP_PLL_425_ENABLE, rb + APP_PLL_425_CTL_REG);
        if (!fcmode) {
-               bfa_reg_write((rb + PMM_1T_RESET_REG_P0), __PMM_1T_RESET_P);
-               bfa_reg_write((rb + PMM_1T_RESET_REG_P1), __PMM_1T_RESET_P);
+               writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0));
+               writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1));
        }
-       r32 = bfa_reg_read((rb + PSS_CTL_REG));
+       r32 = readl((rb + PSS_CTL_REG));
        r32 &= ~__PSS_LMEM_RESET;
-       bfa_reg_write((rb + PSS_CTL_REG), r32);
-       bfa_os_udelay(1000);
+       writel(r32, (rb + PSS_CTL_REG));
+       udelay(1000);
        if (!fcmode) {
-               bfa_reg_write((rb + PMM_1T_RESET_REG_P0), 0);
-               bfa_reg_write((rb + PMM_1T_RESET_REG_P1), 0);
+               writel(0, (rb + PMM_1T_RESET_REG_P0));
+               writel(0, (rb + PMM_1T_RESET_REG_P1));
        }
 
-       bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
-       bfa_os_udelay(1000);
-       r32 = bfa_reg_read((rb + MBIST_STAT_REG));
-       bfa_reg_write((rb + MBIST_CTL_REG), 0);
+       writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG));
+       udelay(1000);
+       r32 = readl((rb + MBIST_STAT_REG));
+       writel(0, (rb + MBIST_CTL_REG));
        return BFA_STATUS_OK;
 }
index 2cd52733867750e76ae7d52cd65c1dae30e812e1..15407ab39e77759e3cafa96214636b19c2fc22bc 100644 (file)
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 
-/**
+/*
  *  bfa_modules.h BFA modules
  */
 
@@ -52,7 +52,7 @@ enum {
 };
 
 
-/**
+/*
  * Macro to define a new BFA module
  */
 #define BFA_MODULE(__mod)                                              \
@@ -80,7 +80,7 @@ enum {
 
 #define BFA_CACHELINE_SZ       (256)
 
-/**
+/*
  * Structure used to interact between different BFA sub modules
  *
  * Each sub module needs to implement only the entry points relevant to it (and
index 788a250ffb8a01b05a6701cab2ecd1e3308016f7..65df62ef437fa349029f05ba76aa774f818ba8cf 100644 (file)
  * General Public License for more details.
  */
 
-/**
- * Contains declarations all OS Specific files needed for BFA layer
- */
-
 #ifndef __BFA_OS_INC_H__
 #define __BFA_OS_INC_H__
 
 #define __BIGENDIAN
 #endif
 
-static inline u64 bfa_os_get_clock(void)
-{
-       return jiffies;
-}
-
 static inline u64 bfa_os_get_log_time(void)
 {
        u64 system_time = 0;
@@ -63,13 +54,6 @@ static inline u64 bfa_os_get_log_time(void)
 #define bfa_io_lat_clock_res_div HZ
 #define bfa_io_lat_clock_res_mul 1000
 
-#define BFA_ASSERT(p) do {                                             \
-       if (!(p)) {      \
-               printk(KERN_ERR "assert(%s) failed at %s:%d\n",         \
-               #p, __FILE__, __LINE__);      \
-       }                                                               \
-} while (0)
-
 #define BFA_LOG(level, bfad, mask, fmt, arg...)                                \
 do {                                                                   \
        if (((mask) == 4) || (level[1] <= '4'))                         \
@@ -81,22 +65,6 @@ do {                                                                 \
        ((_x) & 0x00ff00) |                     \
        (((_x) & 0xff0000) >> 16))
 
-#define bfa_swap_8b(_x)                                        \
-       ((((_x) & 0xff00000000000000ull) >> 56)         \
-        | (((_x) & 0x00ff000000000000ull) >> 40)       \
-        | (((_x) & 0x0000ff0000000000ull) >> 24)       \
-        | (((_x) & 0x000000ff00000000ull) >> 8)        \
-        | (((_x) & 0x00000000ff000000ull) << 8)        \
-        | (((_x) & 0x0000000000ff0000ull) << 24)       \
-        | (((_x) & 0x000000000000ff00ull) << 40)       \
-        | (((_x) & 0x00000000000000ffull) << 56))
-
-#define bfa_os_swap32(_x)                      \
-       ((((_x) & 0xff) << 24)          |       \
-       (((_x) & 0x0000ff00) << 8)      |       \
-       (((_x) & 0x00ff0000) >> 8)      |       \
-       (((_x) & 0xff000000) >> 24))
-
 #define bfa_os_swap_sgaddr(_x)  ((u64)(                                 \
        (((u64)(_x) & (u64)0x00000000000000ffull) << 32)        |       \
        (((u64)(_x) & (u64)0x000000000000ff00ull) << 32)        |       \
@@ -108,59 +76,27 @@ do {                                                                       \
        (((u64)(_x) & (u64)0xff00000000000000ull) >> 32)))
 
 #ifndef __BIGENDIAN
-#define bfa_os_htons(_x) ((u16)((((_x) & 0xff00) >> 8) | \
-                                (((_x) & 0x00ff) << 8)))
-#define bfa_os_htonl(_x)       bfa_os_swap32(_x)
-#define bfa_os_htonll(_x)      bfa_swap_8b(_x)
-#define bfa_os_hton3b(_x)      bfa_swap_3b(_x)
-#define bfa_os_wtole(_x)   (_x)
+#define bfa_os_hton3b(_x)  bfa_swap_3b(_x)
 #define bfa_os_sgaddr(_x)  (_x)
-
 #else
-
-#define bfa_os_htons(_x)   (_x)
-#define bfa_os_htonl(_x)   (_x)
 #define bfa_os_hton3b(_x)  (_x)
-#define bfa_os_htonll(_x)  (_x)
-#define bfa_os_wtole(_x)   bfa_os_swap32(_x)
 #define bfa_os_sgaddr(_x)  bfa_os_swap_sgaddr(_x)
-
 #endif
 
-#define bfa_os_ntohs(_x)   bfa_os_htons(_x)
-#define bfa_os_ntohl(_x)   bfa_os_htonl(_x)
-#define bfa_os_ntohll(_x)  bfa_os_htonll(_x)
 #define bfa_os_ntoh3b(_x)  bfa_os_hton3b(_x)
-
 #define bfa_os_u32(__pa64) ((__pa64) >> 32)
 
-#define bfa_os_memset  memset
-#define bfa_os_memcpy  memcpy
-#define bfa_os_udelay  udelay
-#define bfa_os_vsprintf vsprintf
-#define bfa_os_snprintf snprintf
-
-#define bfa_os_assign(__t, __s) __t = __s
-#define bfa_os_addr_t void __iomem *
-
-#define bfa_os_reg_read(_raddr) readl(_raddr)
-#define bfa_os_reg_write(_raddr, _val) writel((_val), (_raddr))
-#define bfa_os_mem_read(_raddr, _off)                                  \
-       bfa_os_swap32(readl(((_raddr) + (_off))))
-#define bfa_os_mem_write(_raddr, _off, _val)                           \
-       writel(bfa_os_swap32((_val)), ((_raddr) + (_off)))
-
-#define BFA_TRC_TS(_trcm)                                              \
-                       ({                                              \
-                               struct timeval tv;                      \
-                                                                       \
-                               do_gettimeofday(&tv);      \
-                               (tv.tv_sec*1000000+tv.tv_usec);      \
-                        })
+#define BFA_TRC_TS(_trcm)                              \
+       ({                                              \
+               struct timeval tv;                      \
+                                                       \
+               do_gettimeofday(&tv);                   \
+               (tv.tv_sec*1000000+tv.tv_usec);         \
+        })
 
 #define boolean_t int
 
-/**
+/*
  * For current time stamp, OS API will fill-in
  */
 struct bfa_timeval_s {
index b6d170a13bea4f88c8ebbc78d4c63a523b4781b8..fff96226a383c6c06363d9e1036301f88d5bf8ac 100644 (file)
@@ -37,16 +37,16 @@ bfa_port_stats_swap(struct bfa_port_s *port, union bfa_port_stats_u *stats)
                t0 = dip[i];
                t1 = dip[i + 1];
 #ifdef __BIGENDIAN
-               dip[i] = bfa_os_ntohl(t0);
-               dip[i + 1] = bfa_os_ntohl(t1);
+               dip[i] = be32_to_cpu(t0);
+               dip[i + 1] = be32_to_cpu(t1);
 #else
-               dip[i] = bfa_os_ntohl(t1);
-               dip[i + 1] = bfa_os_ntohl(t0);
+               dip[i] = be32_to_cpu(t1);
+               dip[i + 1] = be32_to_cpu(t0);
 #endif
        }
 }
 
-/**
+/*
  * bfa_port_enable_isr()
  *
  *
@@ -63,7 +63,7 @@ bfa_port_enable_isr(struct bfa_port_s *port, bfa_status_t status)
        port->endis_cbfn(port->endis_cbarg, status);
 }
 
-/**
+/*
  * bfa_port_disable_isr()
  *
  *
@@ -80,7 +80,7 @@ bfa_port_disable_isr(struct bfa_port_s *port, bfa_status_t status)
        port->endis_cbfn(port->endis_cbarg, status);
 }
 
-/**
+/*
  * bfa_port_get_stats_isr()
  *
  *
@@ -112,7 +112,7 @@ bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
        }
 }
 
-/**
+/*
  * bfa_port_clear_stats_isr()
  *
  *
@@ -129,7 +129,7 @@ bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
        port->stats_status = status;
        port->stats_busy   = BFA_FALSE;
 
-       /**
+       /*
        * re-initialize time stamp for stats reset
        */
        bfa_os_gettimeofday(&tv);
@@ -141,7 +141,7 @@ bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
        }
 }
 
-/**
+/*
  * bfa_port_isr()
  *
  *
@@ -189,7 +189,7 @@ bfa_port_isr(void *cbarg, struct bfi_mbmsg_s *m)
        }
 }
 
-/**
+/*
  * bfa_port_meminfo()
  *
  *
@@ -203,7 +203,7 @@ bfa_port_meminfo(void)
        return BFA_ROUNDUP(sizeof(union bfa_port_stats_u), BFA_DMA_ALIGN_SZ);
 }
 
-/**
+/*
  * bfa_port_mem_claim()
  *
  *
@@ -220,7 +220,7 @@ bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva, u64 dma_pa)
        port->stats_dma.pa  = dma_pa;
 }
 
-/**
+/*
  * bfa_port_enable()
  *
  *   Send the Port enable request to the f/w
@@ -264,7 +264,7 @@ bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * bfa_port_disable()
  *
  *   Send the Port disable request to the f/w
@@ -308,7 +308,7 @@ bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * bfa_port_get_stats()
  *
  *   Send the request to the f/w to fetch Port statistics.
@@ -348,7 +348,7 @@ bfa_port_get_stats(struct bfa_port_s *port, union bfa_port_stats_u *stats,
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * bfa_port_clear_stats()
  *
  *
@@ -385,7 +385,7 @@ bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn,
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * bfa_port_hbfail()
  *
  *
@@ -415,7 +415,7 @@ bfa_port_hbfail(void *arg)
        }
 }
 
-/**
+/*
  * bfa_port_attach()
  *
  *
@@ -449,7 +449,7 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
        bfa_ioc_hbfail_init(&port->hbfail, bfa_port_hbfail, port);
        bfa_ioc_hbfail_register(port->ioc, &port->hbfail);
 
-       /**
+       /*
         * initialize time stamp for stats reset
         */
        bfa_os_gettimeofday(&tv);
@@ -458,7 +458,7 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
        bfa_trc(port, 0);
 }
 
-/**
+/*
  * bfa_port_detach()
  *
  *
index aa1dc749b28195eca325ee97921f91bdeaa95c42..c768143f4805a7cb5f0094682a39c30b73ea433d 100644 (file)
@@ -29,7 +29,7 @@ BFA_MODULE(fcport);
 BFA_MODULE(rport);
 BFA_MODULE(uf);
 
-/**
+/*
  * LPS related definitions
  */
 #define BFA_LPS_MIN_LPORTS      (1)
@@ -41,7 +41,7 @@ BFA_MODULE(uf);
 #define BFA_LPS_MAX_VPORTS_SUPP_CB  255
 #define BFA_LPS_MAX_VPORTS_SUPP_CT  190
 
-/**
+/*
  *  lps_pvt BFA LPS private functions
  */
 
@@ -55,7 +55,7 @@ enum bfa_lps_event {
        BFA_LPS_SM_RX_CVL       = 7,    /* Rx clear virtual link        */
 };
 
-/**
+/*
  * FC PORT related definitions
  */
 /*
@@ -67,7 +67,7 @@ enum bfa_lps_event {
        (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
 
 
-/**
+/*
  * BFA port state machine events
  */
 enum bfa_fcport_sm_event {
@@ -82,7 +82,7 @@ enum bfa_fcport_sm_event {
        BFA_FCPORT_SM_HWFAIL    = 9,    /*  IOC h/w failure             */
 };
 
-/**
+/*
  * BFA port link notification state machine events
  */
 
@@ -92,7 +92,7 @@ enum bfa_fcport_ln_sm_event {
        BFA_FCPORT_LN_SM_NOTIFICATION   = 3     /*  done notification   */
 };
 
-/**
+/*
  * RPORT related definitions
  */
 #define bfa_rport_offline_cb(__rp) do {                                        \
@@ -126,7 +126,7 @@ enum bfa_rport_event {
        BFA_RPORT_SM_QRESUME    = 9,    /*  space in requeue queue      */
 };
 
-/**
+/*
  * forward declarations FCXP related functions
  */
 static void    __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete);
@@ -138,7 +138,7 @@ static void bfa_fcxp_qresume(void *cbarg);
 static void    bfa_fcxp_queue(struct bfa_fcxp_s *fcxp,
                                struct bfi_fcxp_send_req_s *send_req);
 
-/**
+/*
  * forward declarations for LPS functions
  */
 static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
@@ -163,7 +163,7 @@ static void bfa_lps_login_comp(struct bfa_lps_s *lps);
 static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
 static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
 
-/**
+/*
  * forward declaration for LPS state machine
  */
 static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
@@ -175,7 +175,7 @@ static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event);
 static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event
                                        event);
 
-/**
+/*
  * forward declaration for FC Port functions
  */
 static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
@@ -193,7 +193,7 @@ static void bfa_fcport_stats_get_timeout(void *cbarg);
 static void bfa_fcport_stats_clr_timeout(void *cbarg);
 static void bfa_trunk_iocdisable(struct bfa_s *bfa);
 
-/**
+/*
  * forward declaration for FC PORT state machine
  */
 static void     bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
@@ -252,7 +252,7 @@ static struct bfa_sm_table_s hal_port_sm_table[] = {
 };
 
 
-/**
+/*
  * forward declaration for RPORT related functions
  */
 static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod);
@@ -265,7 +265,7 @@ static void         __bfa_cb_rport_online(void *cbarg,
 static void            __bfa_cb_rport_offline(void *cbarg,
                                                bfa_boolean_t complete);
 
-/**
+/*
  * forward declaration for RPORT state machine
  */
 static void     bfa_rport_sm_uninit(struct bfa_rport_s *rp,
@@ -295,7 +295,7 @@ static void     bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp,
 static void     bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp,
                                        enum bfa_rport_event event);
 
-/**
+/*
  * PLOG related definitions
  */
 static int
@@ -330,7 +330,7 @@ bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
 
        pl_recp = &(plog->plog_recs[tail]);
 
-       bfa_os_memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s));
+       memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s));
 
        pl_recp->tv = bfa_os_get_log_time();
        BFA_PL_LOG_REC_INCR(plog->tail);
@@ -342,9 +342,9 @@ bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
 void
 bfa_plog_init(struct bfa_plog_s *plog)
 {
-       bfa_os_memset((char *)plog, 0, sizeof(struct bfa_plog_s));
+       memset((char *)plog, 0, sizeof(struct bfa_plog_s));
 
-       bfa_os_memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN);
+       memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN);
        plog->head = plog->tail = 0;
        plog->plog_enabled = 1;
 }
@@ -357,7 +357,7 @@ bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
        struct bfa_plog_rec_s  lp;
 
        if (plog->plog_enabled) {
-               bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
+               memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
                lp.mid = mid;
                lp.eid = event;
                lp.log_type = BFA_PL_LOG_TYPE_STRING;
@@ -381,15 +381,14 @@ bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
                num_ints = BFA_PL_INT_LOG_SZ;
 
        if (plog->plog_enabled) {
-               bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
+               memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
                lp.mid = mid;
                lp.eid = event;
                lp.log_type = BFA_PL_LOG_TYPE_INT;
                lp.misc = misc;
 
                for (i = 0; i < num_ints; i++)
-                       bfa_os_assign(lp.log_entry.int_log[i],
-                                       intarr[i]);
+                       lp.log_entry.int_log[i] = intarr[i];
 
                lp.log_num_ints = (u8) num_ints;
 
@@ -407,7 +406,7 @@ bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
        u32     ints[BFA_PL_INT_LOG_SZ];
 
        if (plog->plog_enabled) {
-               bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
+               memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
 
                ints[0] = tmp_int[0];
                ints[1] = tmp_int[1];
@@ -427,7 +426,7 @@ bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
        u32     ints[BFA_PL_INT_LOG_SZ];
 
        if (plog->plog_enabled) {
-               bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
+               memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
 
                ints[0] = tmp_int[0];
                ints[1] = tmp_int[1];
@@ -462,7 +461,7 @@ bfa_plog_get_setting(struct bfa_plog_s *plog)
        return (bfa_boolean_t)plog->plog_enabled;
 }
 
-/**
+/*
  *  fcxp_pvt BFA FCXP private functions
  */
 
@@ -485,7 +484,7 @@ claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
        mod->req_pld_list_pa = dm_pa;
        dm_kva += buf_pool_sz;
        dm_pa += buf_pool_sz;
-       bfa_os_memset(mod->req_pld_list_kva, 0, buf_pool_sz);
+       memset(mod->req_pld_list_kva, 0, buf_pool_sz);
 
        /*
         * Initialize the fcxp rsp payload list
@@ -495,7 +494,7 @@ claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
        mod->rsp_pld_list_pa = dm_pa;
        dm_kva += buf_pool_sz;
        dm_pa += buf_pool_sz;
-       bfa_os_memset(mod->rsp_pld_list_kva, 0, buf_pool_sz);
+       memset(mod->rsp_pld_list_kva, 0, buf_pool_sz);
 
        bfa_meminfo_dma_virt(mi) = dm_kva;
        bfa_meminfo_dma_phys(mi) = dm_pa;
@@ -508,7 +507,7 @@ claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
        struct bfa_fcxp_s *fcxp;
 
        fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi);
-       bfa_os_memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
+       memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
 
        INIT_LIST_HEAD(&mod->fcxp_free_q);
        INIT_LIST_HEAD(&mod->fcxp_active_q);
@@ -559,11 +558,11 @@ bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 {
        struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
 
-       bfa_os_memset(mod, 0, sizeof(struct bfa_fcxp_mod_s));
+       memset(mod, 0, sizeof(struct bfa_fcxp_mod_s));
        mod->bfa = bfa;
        mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs;
 
-       /**
+       /*
         * Initialize FCXP request and response payload sizes.
         */
        mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ;
@@ -741,20 +740,20 @@ hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
 {
        struct bfa_fcxp_mod_s   *mod = BFA_FCXP_MOD(bfa);
        struct bfa_fcxp_s       *fcxp;
-       u16             fcxp_tag = bfa_os_ntohs(fcxp_rsp->fcxp_tag);
+       u16             fcxp_tag = be16_to_cpu(fcxp_rsp->fcxp_tag);
 
        bfa_trc(bfa, fcxp_tag);
 
-       fcxp_rsp->rsp_len = bfa_os_ntohl(fcxp_rsp->rsp_len);
+       fcxp_rsp->rsp_len = be32_to_cpu(fcxp_rsp->rsp_len);
 
-       /**
+       /*
         * @todo f/w should not set residue to non-0 when everything
         *       is received.
         */
        if (fcxp_rsp->req_status == BFA_STATUS_OK)
                fcxp_rsp->residue_len = 0;
        else
-               fcxp_rsp->residue_len = bfa_os_ntohl(fcxp_rsp->residue_len);
+               fcxp_rsp->residue_len = be32_to_cpu(fcxp_rsp->residue_len);
 
        fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
 
@@ -856,7 +855,7 @@ hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
        }
 }
 
-/**
+/*
  * Handler to resume sending fcxp when space in available in cpe queue.
  */
 static void
@@ -871,7 +870,7 @@ bfa_fcxp_qresume(void *cbarg)
        bfa_fcxp_queue(fcxp, send_req);
 }
 
-/**
+/*
  * Queue fcxp send request to foimrware.
  */
 static void
@@ -885,26 +884,26 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
        bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
                    bfa_lpuid(bfa));
 
-       send_req->fcxp_tag = bfa_os_htons(fcxp->fcxp_tag);
+       send_req->fcxp_tag = cpu_to_be16(fcxp->fcxp_tag);
        if (rport) {
                send_req->rport_fw_hndl = rport->fw_handle;
-               send_req->max_frmsz = bfa_os_htons(rport->rport_info.max_frmsz);
+               send_req->max_frmsz = cpu_to_be16(rport->rport_info.max_frmsz);
                if (send_req->max_frmsz == 0)
-                       send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
+                       send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ);
        } else {
                send_req->rport_fw_hndl = 0;
-               send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
+               send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ);
        }
 
-       send_req->vf_id = bfa_os_htons(reqi->vf_id);
+       send_req->vf_id = cpu_to_be16(reqi->vf_id);
        send_req->lp_tag = reqi->lp_tag;
        send_req->class = reqi->class;
        send_req->rsp_timeout = rspi->rsp_timeout;
        send_req->cts = reqi->cts;
        send_req->fchs = reqi->fchs;
 
-       send_req->req_len = bfa_os_htonl(reqi->req_tot_len);
-       send_req->rsp_maxlen = bfa_os_htonl(rspi->rsp_maxlen);
+       send_req->req_len = cpu_to_be32(reqi->req_tot_len);
+       send_req->rsp_maxlen = cpu_to_be32(rspi->rsp_maxlen);
 
        /*
         * setup req sgles
@@ -955,11 +954,11 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
        bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
 }
 
-/**
+/*
  *  hal_fcxp_api BFA FCXP API
  */
 
-/**
+/*
  * Allocate an FCXP instance to send a response or to send a request
  * that has a response. Request/response buffers are allocated by caller.
  *
@@ -1005,7 +1004,7 @@ bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
        return fcxp;
 }
 
-/**
+/*
  * Get the internal request buffer pointer
  *
  * @param[in]  fcxp    BFA fcxp pointer
@@ -1032,7 +1031,7 @@ bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
        return mod->req_pld_sz;
 }
 
-/**
+/*
  * Get the internal response buffer pointer
  *
  * @param[in]  fcxp    BFA fcxp pointer
@@ -1052,7 +1051,7 @@ bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
        return rspbuf;
 }
 
-/**
+/*
  *             Free the BFA FCXP
  *
  * @param[in]  fcxp                    BFA fcxp pointer
@@ -1069,7 +1068,7 @@ bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
        bfa_fcxp_put(fcxp);
 }
 
-/**
+/*
  * Send a FCXP request
  *
  * @param[in]  fcxp    BFA fcxp pointer
@@ -1103,7 +1102,7 @@ bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
 
        bfa_trc(bfa, fcxp->fcxp_tag);
 
-       /**
+       /*
         * setup request/response info
         */
        reqi->bfa_rport = rport;
@@ -1118,7 +1117,7 @@ bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
        fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp;
        fcxp->send_cbarg = cbarg;
 
-       /**
+       /*
         * If no room in CPE queue, wait for space in request queue
         */
        send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
@@ -1132,7 +1131,7 @@ bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
        bfa_fcxp_queue(fcxp, send_req);
 }
 
-/**
+/*
  * Abort a BFA FCXP
  *
  * @param[in]  fcxp    BFA fcxp pointer
@@ -1186,7 +1185,7 @@ bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
 void
 bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
 {
-       /**
+       /*
         * If waiting for room in request queue, cancel reqq wait
         * and free fcxp.
         */
@@ -1202,7 +1201,7 @@ bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
 
 
 
-/**
+/*
  *  hal_fcxp_public BFA FCXP public functions
  */
 
@@ -1229,11 +1228,11 @@ bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
 }
 
 
-/**
+/*
  *  BFA LPS state machine functions
  */
 
-/**
+/*
  * Init state -- no login
  */
 static void
@@ -1285,7 +1284,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
        }
 }
 
-/**
+/*
  * login is in progress -- awaiting response from firmware
  */
 static void
@@ -1327,7 +1326,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
        }
 }
 
-/**
+/*
  * login pending - awaiting space in request queue
  */
 static void
@@ -1359,7 +1358,7 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
        }
 }
 
-/**
+/*
  * login complete
  */
 static void
@@ -1400,7 +1399,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
        }
 }
 
-/**
+/*
  * logout in progress - awaiting firmware response
  */
 static void
@@ -1424,7 +1423,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
        }
 }
 
-/**
+/*
  * logout pending -- awaiting space in request queue
  */
 static void
@@ -1451,11 +1450,11 @@ bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
 
 
 
-/**
+/*
  *  lps_pvt BFA LPS private functions
  */
 
-/**
+/*
  * return memory requirement
  */
 static void
@@ -1468,7 +1467,7 @@ bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
                *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS;
 }
 
-/**
+/*
  * bfa module attach at initialization time
  */
 static void
@@ -1479,7 +1478,7 @@ bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        struct bfa_lps_s        *lps;
        int                     i;
 
-       bfa_os_memset(mod, 0, sizeof(struct bfa_lps_mod_s));
+       memset(mod, 0, sizeof(struct bfa_lps_mod_s));
        mod->num_lps = BFA_LPS_MAX_LPORTS;
        if (cfg->drvcfg.min_cfg)
                mod->num_lps = BFA_LPS_MIN_LPORTS;
@@ -1516,7 +1515,7 @@ bfa_lps_stop(struct bfa_s *bfa)
 {
 }
 
-/**
+/*
  * IOC in disabled state -- consider all lps offline
  */
 static void
@@ -1532,7 +1531,7 @@ bfa_lps_iocdisable(struct bfa_s *bfa)
        }
 }
 
-/**
+/*
  * Firmware login response
  */
 static void
@@ -1550,7 +1549,7 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
                lps->fport      = rsp->f_port;
                lps->npiv_en    = rsp->npiv_en;
                lps->lp_pid     = rsp->lp_pid;
-               lps->pr_bbcred  = bfa_os_ntohs(rsp->bb_credit);
+               lps->pr_bbcred  = be16_to_cpu(rsp->bb_credit);
                lps->pr_pwwn    = rsp->port_name;
                lps->pr_nwwn    = rsp->node_name;
                lps->auth_req   = rsp->auth_req;
@@ -1579,7 +1578,7 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
        bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
 }
 
-/**
+/*
  * Firmware logout response
  */
 static void
@@ -1594,7 +1593,7 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
        bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
 }
 
-/**
+/*
  * Firmware received a Clear virtual link request (for FCoE)
  */
 static void
@@ -1608,7 +1607,7 @@ bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
        bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
 }
 
-/**
+/*
  * Space is available in request queue, resume queueing request to firmware.
  */
 static void
@@ -1619,7 +1618,7 @@ bfa_lps_reqq_resume(void *lps_arg)
        bfa_sm_send_event(lps, BFA_LPS_SM_RESUME);
 }
 
-/**
+/*
  * lps is freed -- triggered by vport delete
  */
 static void
@@ -1632,7 +1631,7 @@ bfa_lps_free(struct bfa_lps_s *lps)
        list_add_tail(&lps->qe, &mod->lps_free_q);
 }
 
-/**
+/*
  * send login request to firmware
  */
 static void
@@ -1648,7 +1647,7 @@ bfa_lps_send_login(struct bfa_lps_s *lps)
 
        m->lp_tag       = lps->lp_tag;
        m->alpa         = lps->alpa;
-       m->pdu_size     = bfa_os_htons(lps->pdusz);
+       m->pdu_size     = cpu_to_be16(lps->pdusz);
        m->pwwn         = lps->pwwn;
        m->nwwn         = lps->nwwn;
        m->fdisc        = lps->fdisc;
@@ -1657,7 +1656,7 @@ bfa_lps_send_login(struct bfa_lps_s *lps)
        bfa_reqq_produce(lps->bfa, lps->reqq);
 }
 
-/**
+/*
  * send logout request to firmware
  */
 static void
@@ -1676,7 +1675,7 @@ bfa_lps_send_logout(struct bfa_lps_s *lps)
        bfa_reqq_produce(lps->bfa, lps->reqq);
 }
 
-/**
+/*
  * Indirect login completion handler for non-fcs
  */
 static void
@@ -1693,7 +1692,7 @@ bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete)
                bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
 }
 
-/**
+/*
  * Login completion handler -- direct call for fcs, queue for others
  */
 static void
@@ -1711,7 +1710,7 @@ bfa_lps_login_comp(struct bfa_lps_s *lps)
                bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
 }
 
-/**
+/*
  * Indirect logout completion handler for non-fcs
  */
 static void
@@ -1726,7 +1725,7 @@ bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete)
                bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
 }
 
-/**
+/*
  * Logout completion handler -- direct call for fcs, queue for others
  */
 static void
@@ -1741,7 +1740,7 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps)
                bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
 }
 
-/**
+/*
  * Clear virtual link completion handler for non-fcs
  */
 static void
@@ -1757,7 +1756,7 @@ bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
                bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
 }
 
-/**
+/*
  * Received Clear virtual link event --direct call for fcs,
  * queue for others
  */
@@ -1777,7 +1776,7 @@ bfa_lps_cvl_event(struct bfa_lps_s *lps)
 
 
 
-/**
+/*
  *  lps_public BFA LPS public functions
  */
 
@@ -1790,7 +1789,7 @@ bfa_lps_get_max_vport(struct bfa_s *bfa)
                return BFA_LPS_MAX_VPORTS_SUPP_CB;
 }
 
-/**
+/*
  * Allocate a lport srvice tag.
  */
 struct bfa_lps_s  *
@@ -1810,7 +1809,7 @@ bfa_lps_alloc(struct bfa_s *bfa)
        return lps;
 }
 
-/**
+/*
  * Free lport service tag. This can be called anytime after an alloc.
  * No need to wait for any pending login/logout completions.
  */
@@ -1820,7 +1819,7 @@ bfa_lps_delete(struct bfa_lps_s *lps)
        bfa_sm_send_event(lps, BFA_LPS_SM_DELETE);
 }
 
-/**
+/*
  * Initiate a lport login.
  */
 void
@@ -1837,7 +1836,7 @@ bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
        bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
 }
 
-/**
+/*
  * Initiate a lport fdisc login.
  */
 void
@@ -1854,7 +1853,7 @@ bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
        bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
 }
 
-/**
+/*
  * Initiate a lport logout (flogi).
  */
 void
@@ -1863,7 +1862,7 @@ bfa_lps_flogo(struct bfa_lps_s *lps)
        bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
 }
 
-/**
+/*
  * Initiate a lport FDSIC logout.
  */
 void
@@ -1872,7 +1871,7 @@ bfa_lps_fdisclogo(struct bfa_lps_s *lps)
        bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
 }
 
-/**
+/*
  * Discard a pending login request -- should be called only for
  * link down handling.
  */
@@ -1882,7 +1881,7 @@ bfa_lps_discard(struct bfa_lps_s *lps)
        bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
 }
 
-/**
+/*
  * Return lport services tag
  */
 u8
@@ -1891,7 +1890,7 @@ bfa_lps_get_tag(struct bfa_lps_s *lps)
        return lps->lp_tag;
 }
 
-/**
+/*
  * Return lport services tag given the pid
  */
 u8
@@ -1910,7 +1909,7 @@ bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid)
        return 0;
 }
 
-/**
+/*
  * return if fabric login indicates support for NPIV
  */
 bfa_boolean_t
@@ -1919,7 +1918,7 @@ bfa_lps_is_npiv_en(struct bfa_lps_s *lps)
        return lps->npiv_en;
 }
 
-/**
+/*
  * Return TRUE if attached to F-Port, else return FALSE
  */
 bfa_boolean_t
@@ -1928,7 +1927,7 @@ bfa_lps_is_fport(struct bfa_lps_s *lps)
        return lps->fport;
 }
 
-/**
+/*
  * Return TRUE if attached to a Brocade Fabric
  */
 bfa_boolean_t
@@ -1936,7 +1935,7 @@ bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps)
 {
        return lps->brcd_switch;
 }
-/**
+/*
  * return TRUE if authentication is required
  */
 bfa_boolean_t
@@ -1951,7 +1950,7 @@ bfa_lps_get_extstatus(struct bfa_lps_s *lps)
        return lps->ext_status;
 }
 
-/**
+/*
  * return port id assigned to the lport
  */
 u32
@@ -1960,7 +1959,7 @@ bfa_lps_get_pid(struct bfa_lps_s *lps)
        return lps->lp_pid;
 }
 
-/**
+/*
  * return port id assigned to the base lport
  */
 u32
@@ -1971,7 +1970,7 @@ bfa_lps_get_base_pid(struct bfa_s *bfa)
        return BFA_LPS_FROM_TAG(mod, 0)->lp_pid;
 }
 
-/**
+/*
  * Return bb_credit assigned in FLOGI response
  */
 u16
@@ -1980,7 +1979,7 @@ bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps)
        return lps->pr_bbcred;
 }
 
-/**
+/*
  * Return peer port name
  */
 wwn_t
@@ -1989,7 +1988,7 @@ bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps)
        return lps->pr_pwwn;
 }
 
-/**
+/*
  * Return peer node name
  */
 wwn_t
@@ -1998,7 +1997,7 @@ bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps)
        return lps->pr_nwwn;
 }
 
-/**
+/*
  * return reason code if login request is rejected
  */
 u8
@@ -2007,7 +2006,7 @@ bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps)
        return lps->lsrjt_rsn;
 }
 
-/**
+/*
  * return explanation code if login request is rejected
  */
 u8
@@ -2016,7 +2015,7 @@ bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
        return lps->lsrjt_expl;
 }
 
-/**
+/*
  * Return fpma/spma MAC for lport
  */
 mac_t
@@ -2025,7 +2024,7 @@ bfa_lps_get_lp_mac(struct bfa_lps_s *lps)
        return lps->lp_mac;
 }
 
-/**
+/*
  * LPS firmware message class handler.
  */
 void
@@ -2055,7 +2054,7 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
        }
 }
 
-/**
+/*
  * FC PORT state machine functions
  */
 static void
@@ -2066,7 +2065,7 @@ bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
 
        switch (event) {
        case BFA_FCPORT_SM_START:
-               /**
+               /*
                 * Start event after IOC is configured and BFA is started.
                 */
                if (bfa_fcport_send_enable(fcport)) {
@@ -2080,7 +2079,7 @@ bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
                break;
 
        case BFA_FCPORT_SM_ENABLE:
-               /**
+               /*
                 * Port is persistently configured to be in enabled state. Do
                 * not change state. Port enabling is done when START event is
                 * received.
@@ -2088,7 +2087,7 @@ bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
                break;
 
        case BFA_FCPORT_SM_DISABLE:
-               /**
+               /*
                 * If a port is persistently configured to be disabled, the
                 * first event will a port disable request.
                 */
@@ -2124,13 +2123,13 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
                break;
 
        case BFA_FCPORT_SM_ENABLE:
-               /**
+               /*
                 * Already enable is in progress.
                 */
                break;
 
        case BFA_FCPORT_SM_DISABLE:
-               /**
+               /*
                 * Just send disable request to firmware when room becomes
                 * available in request queue.
                 */
@@ -2145,7 +2144,7 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
 
        case BFA_FCPORT_SM_LINKUP:
        case BFA_FCPORT_SM_LINKDOWN:
-               /**
+               /*
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
@@ -2184,7 +2183,7 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
                break;
 
        case BFA_FCPORT_SM_ENABLE:
-               /**
+               /*
                 * Already being enabled.
                 */
                break;
@@ -2257,13 +2256,13 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
                break;
 
        case BFA_FCPORT_SM_LINKDOWN:
-               /**
+               /*
                 * Possible to get link down event.
                 */
                break;
 
        case BFA_FCPORT_SM_ENABLE:
-               /**
+               /*
                 * Already enabled.
                 */
                break;
@@ -2306,7 +2305,7 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
 
        switch (event) {
        case BFA_FCPORT_SM_ENABLE:
-               /**
+               /*
                 * Already enabled.
                 */
                break;
@@ -2399,14 +2398,14 @@ bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
                break;
 
        case BFA_FCPORT_SM_DISABLE:
-               /**
+               /*
                 * Already being disabled.
                 */
                break;
 
        case BFA_FCPORT_SM_LINKUP:
        case BFA_FCPORT_SM_LINKDOWN:
-               /**
+               /*
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
@@ -2453,7 +2452,7 @@ bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport,
 
        case BFA_FCPORT_SM_LINKUP:
        case BFA_FCPORT_SM_LINKDOWN:
-               /**
+               /*
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
@@ -2483,7 +2482,7 @@ bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
                break;
 
        case BFA_FCPORT_SM_DISABLE:
-               /**
+               /*
                 * Already being disabled.
                 */
                break;
@@ -2508,7 +2507,7 @@ bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
 
        case BFA_FCPORT_SM_LINKUP:
        case BFA_FCPORT_SM_LINKDOWN:
-               /**
+               /*
                 * Possible to get link events when doing back-to-back
                 * enable/disables.
                 */
@@ -2533,7 +2532,7 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
 
        switch (event) {
        case BFA_FCPORT_SM_START:
-               /**
+               /*
                 * Ignore start event for a port that is disabled.
                 */
                break;
@@ -2557,7 +2556,7 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
                break;
 
        case BFA_FCPORT_SM_DISABLE:
-               /**
+               /*
                 * Already disabled.
                 */
                break;
@@ -2587,14 +2586,14 @@ bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
                break;
 
        default:
-               /**
+               /*
                 * Ignore all other events.
                 */
                ;
        }
 }
 
-/**
+/*
  * Port is enabled. IOC is down/failed.
  */
 static void
@@ -2613,14 +2612,14 @@ bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
                break;
 
        default:
-               /**
+               /*
                 * Ignore all events.
                 */
                ;
        }
 }
 
-/**
+/*
  * Port is disabled. IOC is down/failed.
  */
 static void
@@ -2639,14 +2638,14 @@ bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
                break;
 
        default:
-               /**
+               /*
                 * Ignore all events.
                 */
                ;
        }
 }
 
-/**
+/*
  * Link state is down
  */
 static void
@@ -2666,7 +2665,7 @@ bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
        }
 }
 
-/**
+/*
  * Link state is waiting for down notification
  */
 static void
@@ -2689,7 +2688,7 @@ bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
        }
 }
 
-/**
+/*
  * Link state is waiting for down notification and there is a pending up
  */
 static void
@@ -2713,7 +2712,7 @@ bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
        }
 }
 
-/**
+/*
  * Link state is up
  */
 static void
@@ -2733,7 +2732,7 @@ bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
        }
 }
 
-/**
+/*
  * Link state is waiting for up notification
  */
 static void
@@ -2756,7 +2755,7 @@ bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
        }
 }
 
-/**
+/*
  * Link state is waiting for up notification and there is a pending down
  */
 static void
@@ -2780,7 +2779,7 @@ bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
        }
 }
 
-/**
+/*
  * Link state is waiting for up notification and there are pending down and up
  */
 static void
@@ -2806,7 +2805,7 @@ bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
 
 
 
-/**
+/*
  *  hal_port_private
  */
 
@@ -2821,7 +2820,7 @@ __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
                bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
 }
 
-/**
+/*
  * Send SCN notification to upper layers.
  * trunk - false if caller is fcport to ignore fcport event in trunked mode
  */
@@ -2897,7 +2896,7 @@ bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
        bfa_meminfo_dma_phys(meminfo) = dm_pa;
 }
 
-/**
+/*
  * Memory initialization.
  */
 static void
@@ -2909,7 +2908,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        struct bfa_fcport_ln_s *ln = &fcport->ln;
        struct bfa_timeval_s tv;
 
-       bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
+       memset(fcport, 0, sizeof(struct bfa_fcport_s));
        fcport->bfa = bfa;
        ln->fcport = fcport;
 
@@ -2918,13 +2917,13 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
        bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
 
-       /**
+       /*
         * initialize time stamp for stats reset
         */
        bfa_os_gettimeofday(&tv);
        fcport->stats_reset_time = tv.tv_sec;
 
-       /**
+       /*
         * initialize and set default configuration
         */
        port_cfg->topology = BFA_PORT_TOPOLOGY_P2P;
@@ -2942,7 +2941,7 @@ bfa_fcport_detach(struct bfa_s *bfa)
 {
 }
 
-/**
+/*
  * Called when IOC is ready.
  */
 static void
@@ -2951,7 +2950,7 @@ bfa_fcport_start(struct bfa_s *bfa)
        bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
 }
 
-/**
+/*
  * Called before IOC is stopped.
  */
 static void
@@ -2961,7 +2960,7 @@ bfa_fcport_stop(struct bfa_s *bfa)
        bfa_trunk_iocdisable(bfa);
 }
 
-/**
+/*
  * Called when IOC failure is detected.
  */
 static void
@@ -2986,18 +2985,17 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
                fcport->myalpa = 0;
 
        /* QoS Details */
-       bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
-       bfa_os_assign(fcport->qos_vc_attr,
-               pevent->link_state.vc_fcf.qos_vc_attr);
+       fcport->qos_attr = pevent->link_state.qos_attr;
+       fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr;
 
-       /**
+       /*
         * update trunk state if applicable
         */
        if (!fcport->cfg.trunked)
                trunk->attr.state = BFA_TRUNK_DISABLED;
 
        /* update FCoE specific */
-       fcport->fcoe_vlan = bfa_os_ntohs(pevent->link_state.vc_fcf.fcf.vlan);
+       fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan);
 
        bfa_trc(fcport->bfa, fcport->speed);
        bfa_trc(fcport->bfa, fcport->topology);
@@ -3010,7 +3008,7 @@ bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
        fcport->topology = BFA_PORT_TOPOLOGY_NONE;
 }
 
-/**
+/*
  * Send port enable message to firmware.
  */
 static bfa_boolean_t
@@ -3018,13 +3016,13 @@ bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
 {
        struct bfi_fcport_enable_req_s *m;
 
-       /**
+       /*
         * Increment message tag before queue check, so that responses to old
         * requests are discarded.
         */
        fcport->msgtag++;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
@@ -3040,19 +3038,19 @@ bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
        m->pwwn = fcport->pwwn;
        m->port_cfg = fcport->cfg;
        m->msgtag = fcport->msgtag;
-       m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize);
+       m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize);
        bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
        bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
        bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
        return BFA_TRUE;
 }
 
-/**
+/*
  * Send port disable message to firmware.
  */
 static bfa_boolean_t
@@ -3060,13 +3058,13 @@ bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
 {
        struct bfi_fcport_req_s *m;
 
-       /**
+       /*
         * Increment message tag before queue check, so that responses to old
         * requests are discarded.
         */
        fcport->msgtag++;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
@@ -3080,7 +3078,7 @@ bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
                        bfa_lpuid(fcport->bfa));
        m->msgtag = fcport->msgtag;
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
@@ -3105,7 +3103,7 @@ bfa_fcport_send_txcredit(void *port_cbarg)
        struct bfa_fcport_s *fcport = port_cbarg;
        struct bfi_fcport_set_svc_params_req_s *m;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
@@ -3116,9 +3114,9 @@ bfa_fcport_send_txcredit(void *port_cbarg)
 
        bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
                        bfa_lpuid(fcport->bfa));
-       m->tx_bbcredit = bfa_os_htons((u16)fcport->cfg.tx_bbcredit);
+       m->tx_bbcredit = cpu_to_be16((u16)fcport->cfg.tx_bbcredit);
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
@@ -3134,7 +3132,7 @@ bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
 
        /* Now swap the 32 bit fields */
        for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
-               dip[i] = bfa_os_ntohl(sip[i]);
+               dip[i] = be32_to_cpu(sip[i]);
 }
 
 static void
@@ -3148,11 +3146,11 @@ bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
        for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
             i = i + 2) {
 #ifdef __BIGENDIAN
-               dip[i] = bfa_os_ntohl(sip[i]);
-               dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
+               dip[i] = be32_to_cpu(sip[i]);
+               dip[i + 1] = be32_to_cpu(sip[i + 1]);
 #else
-               dip[i] = bfa_os_ntohl(sip[i + 1]);
-               dip[i + 1] = bfa_os_ntohl(sip[i]);
+               dip[i] = be32_to_cpu(sip[i + 1]);
+               dip[i + 1] = be32_to_cpu(sip[i]);
 #endif
        }
 }
@@ -3223,7 +3221,7 @@ bfa_fcport_send_stats_get(void *cbarg)
        }
        fcport->stats_qfull = BFA_FALSE;
 
-       bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+       memset(msg, 0, sizeof(struct bfi_fcport_req_s));
        bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
                        bfa_lpuid(fcport->bfa));
        bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
@@ -3237,7 +3235,7 @@ __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
        if (complete) {
                struct bfa_timeval_s tv;
 
-               /**
+               /*
                 * re-initialize time stamp for stats reset
                 */
                bfa_os_gettimeofday(&tv);
@@ -3285,13 +3283,13 @@ bfa_fcport_send_stats_clear(void *cbarg)
        }
        fcport->stats_qfull = BFA_FALSE;
 
-       bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
+       memset(msg, 0, sizeof(struct bfi_fcport_req_s));
        bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
                        bfa_lpuid(fcport->bfa));
        bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
 }
 
-/**
+/*
  * Handle trunk SCN event from firmware.
  */
 static void
@@ -3312,7 +3310,7 @@ bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn)
        bfa_trc(fcport->bfa, scn->trunk_state);
        bfa_trc(fcport->bfa, scn->trunk_speed);
 
-       /**
+       /*
         * Save off new state for trunk attribute query
         */
        state_prev = trunk->attr.state;
@@ -3327,7 +3325,7 @@ bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn)
                lattr->trunk_wwn  = tlink->trunk_wwn;
                lattr->fctl       = tlink->fctl;
                lattr->speed      = tlink->speed;
-               lattr->deskew     = bfa_os_ntohl(tlink->deskew);
+               lattr->deskew     = be32_to_cpu(tlink->deskew);
 
                if (tlink->state == BFA_TRUNK_LINK_STATE_UP) {
                        fcport->speed    = tlink->speed;
@@ -3360,7 +3358,7 @@ bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn)
                        BFA_PL_EID_TRUNK_SCN, 0, "Trunk down");
        }
 
-       /**
+       /*
         * Notify upper layers if trunk state changed.
         */
        if ((state_prev != trunk->attr.state) ||
@@ -3376,7 +3374,7 @@ bfa_trunk_iocdisable(struct bfa_s *bfa)
        struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
        int i = 0;
 
-       /**
+       /*
         * In trunked mode, notify upper layers that link is down
         */
        if (fcport->cfg.trunked) {
@@ -3400,11 +3398,11 @@ bfa_trunk_iocdisable(struct bfa_s *bfa)
 
 
 
-/**
+/*
  *  hal_port_public
  */
 
-/**
+/*
  * Called to initialize port attributes
  */
 void
@@ -3412,7 +3410,7 @@ bfa_fcport_init(struct bfa_s *bfa)
 {
        struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       /**
+       /*
         * Initialize port attributes from IOC hardware data.
         */
        bfa_fcport_set_wwns(fcport);
@@ -3426,7 +3424,7 @@ bfa_fcport_init(struct bfa_s *bfa)
        bfa_assert(fcport->speed_sup);
 }
 
-/**
+/*
  * Firmware message handler.
  */
 void
@@ -3507,11 +3505,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
 
 
 
-/**
+/*
  *  hal_port_api
  */
 
-/**
+/*
  * Registered callback for port events.
  */
 void
@@ -3552,7 +3550,7 @@ bfa_fcport_disable(struct bfa_s *bfa)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Configure port speed.
  */
 bfa_status_t
@@ -3574,7 +3572,7 @@ bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Get current speed.
  */
 enum bfa_port_speed
@@ -3585,7 +3583,7 @@ bfa_fcport_get_speed(struct bfa_s *bfa)
        return fcport->speed;
 }
 
-/**
+/*
  * Configure port topology.
  */
 bfa_status_t
@@ -3610,7 +3608,7 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Get current topology.
  */
 enum bfa_port_topology
@@ -3710,7 +3708,7 @@ bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
        bfa_fcport_send_txcredit(fcport);
 }
 
-/**
+/*
  * Get port attributes.
  */
 
@@ -3729,7 +3727,7 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
 {
        struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
-       bfa_os_memset(attr, 0, sizeof(struct bfa_port_attr_s));
+       memset(attr, 0, sizeof(struct bfa_port_attr_s));
 
        attr->nwwn = fcport->nwwn;
        attr->pwwn = fcport->pwwn;
@@ -3737,7 +3735,7 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
        attr->factorypwwn =  bfa_ioc_get_mfg_pwwn(&bfa->ioc);
        attr->factorynwwn =  bfa_ioc_get_mfg_nwwn(&bfa->ioc);
 
-       bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
+       memcpy(&attr->pport_cfg, &fcport->cfg,
                sizeof(struct bfa_port_cfg_s));
        /* speed attributes */
        attr->pport_cfg.speed = fcport->cfg.speed;
@@ -3770,7 +3768,7 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
 
 #define BFA_FCPORT_STATS_TOV   1000
 
-/**
+/*
  * Fetch port statistics (FCQoS or FCoE).
  */
 bfa_status_t
@@ -3796,7 +3794,7 @@ bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Reset port statistics (FCQoS or FCoE).
  */
 bfa_status_t
@@ -3820,7 +3818,7 @@ bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Fetch FCQoS port statistics
  */
 bfa_status_t
@@ -3833,7 +3831,7 @@ bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
        return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
-/**
+/*
  * Reset FCoE port statistics
  */
 bfa_status_t
@@ -3845,7 +3843,7 @@ bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg)
        return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
 }
 
-/**
+/*
  * Fetch FCQoS port statistics
  */
 bfa_status_t
@@ -3858,7 +3856,7 @@ bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
        return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
 }
 
-/**
+/*
  * Reset FCoE port statistics
  */
 bfa_status_t
@@ -3876,7 +3874,7 @@ bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
        struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
        qos_attr->state = fcport->qos_attr.state;
-       qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr);
+       qos_attr->total_bb_cr = be32_to_cpu(fcport->qos_attr.total_bb_cr);
 }
 
 void
@@ -3887,10 +3885,10 @@ bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
        struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
        u32 i = 0;
 
-       qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
-       qos_vc_attr->shared_credit  = bfa_os_ntohs(bfa_vc_attr->shared_credit);
+       qos_vc_attr->total_vc_count = be16_to_cpu(bfa_vc_attr->total_vc_count);
+       qos_vc_attr->shared_credit  = be16_to_cpu(bfa_vc_attr->shared_credit);
        qos_vc_attr->elp_opmode_flags  =
-                       bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags);
+                       be32_to_cpu(bfa_vc_attr->elp_opmode_flags);
 
        /* Individual VC info */
        while (i < qos_vc_attr->total_vc_count) {
@@ -3904,7 +3902,7 @@ bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
        }
 }
 
-/**
+/*
  * Fetch port attributes.
  */
 bfa_boolean_t
@@ -3939,7 +3937,7 @@ bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
 
        if (ioc_type == BFA_IOC_TYPE_FC) {
                fcport->cfg.qos_enabled = on_off;
-               /**
+               /*
                 * Notify fcpim of the change in QoS state
                 */
                bfa_fcpim_update_ioredirect(bfa);
@@ -3959,7 +3957,7 @@ bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
                fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS;
 }
 
-/**
+/*
  * Configure default minimum ratelim speed
  */
 bfa_status_t
@@ -3980,7 +3978,7 @@ bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Get default minimum ratelim speed
  */
 enum bfa_port_speed
@@ -4095,10 +4093,10 @@ bfa_trunk_disable(struct bfa_s *bfa)
 }
 
 
-/**
+/*
  * Rport State machine functions
  */
-/**
+/*
  * Beginning state, only online event expected.
  */
 static void
@@ -4151,7 +4149,7 @@ bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
        }
 }
 
-/**
+/*
  * Waiting for rport create response from firmware.
  */
 static void
@@ -4188,7 +4186,7 @@ bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
        }
 }
 
-/**
+/*
  * Request queue is full, awaiting queue resume to send create request.
  */
 static void
@@ -4229,7 +4227,7 @@ bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
        }
 }
 
-/**
+/*
  * Online state - normal parking state.
  */
 static void
@@ -4275,9 +4273,9 @@ bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
                bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority);
 
                qos_scn->old_qos_attr.qos_flow_id  =
-                       bfa_os_ntohl(qos_scn->old_qos_attr.qos_flow_id);
+                       be32_to_cpu(qos_scn->old_qos_attr.qos_flow_id);
                qos_scn->new_qos_attr.qos_flow_id  =
-                       bfa_os_ntohl(qos_scn->new_qos_attr.qos_flow_id);
+                       be32_to_cpu(qos_scn->new_qos_attr.qos_flow_id);
 
                if (qos_scn->old_qos_attr.qos_flow_id !=
                        qos_scn->new_qos_attr.qos_flow_id)
@@ -4297,7 +4295,7 @@ bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
        }
 }
 
-/**
+/*
  * Firmware rport is being deleted - awaiting f/w response.
  */
 static void
@@ -4360,7 +4358,7 @@ bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
        }
 }
 
-/**
+/*
  * Offline state.
  */
 static void
@@ -4395,7 +4393,7 @@ bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
        }
 }
 
-/**
+/*
  * Rport is deleted, waiting for firmware response to delete.
  */
 static void
@@ -4447,7 +4445,7 @@ bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
        }
 }
 
-/**
+/*
  * Waiting for rport create response from firmware. A delete is pending.
  */
 static void
@@ -4478,7 +4476,7 @@ bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
        }
 }
 
-/**
+/*
  * Waiting for rport create response from firmware. Rport offline is pending.
  */
 static void
@@ -4513,7 +4511,7 @@ bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
        }
 }
 
-/**
+/*
  * IOC h/w failed.
  */
 static void
@@ -4553,7 +4551,7 @@ bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
 
 
 
-/**
+/*
  *  bfa_rport_private BFA rport private functions
  */
 
@@ -4612,12 +4610,12 @@ bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
                   !(mod->num_rports & (mod->num_rports - 1)));
 
        for (i = 0; i < mod->num_rports; i++, rp++) {
-               bfa_os_memset(rp, 0, sizeof(struct bfa_rport_s));
+               memset(rp, 0, sizeof(struct bfa_rport_s));
                rp->bfa = bfa;
                rp->rport_tag = i;
                bfa_sm_set_state(rp, bfa_rport_sm_uninit);
 
-               /**
+               /*
                 *  - is unused
                 */
                if (i)
@@ -4626,7 +4624,7 @@ bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
                bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp);
        }
 
-       /**
+       /*
         * consume memory
         */
        bfa_meminfo_kva(meminfo) = (u8 *) rp;
@@ -4687,7 +4685,7 @@ bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
 {
        struct bfi_rport_create_req_s *m;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
@@ -4699,7 +4697,7 @@ bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
        bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ,
                        bfa_lpuid(rp->bfa));
        m->bfa_handle = rp->rport_tag;
-       m->max_frmsz = bfa_os_htons(rp->rport_info.max_frmsz);
+       m->max_frmsz = cpu_to_be16(rp->rport_info.max_frmsz);
        m->pid = rp->rport_info.pid;
        m->lp_tag = rp->rport_info.lp_tag;
        m->local_pid = rp->rport_info.local_pid;
@@ -4708,7 +4706,7 @@ bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
        m->vf_id = rp->rport_info.vf_id;
        m->cisc = rp->rport_info.cisc;
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
@@ -4720,7 +4718,7 @@ bfa_rport_send_fwdelete(struct bfa_rport_s *rp)
 {
        struct bfi_rport_delete_req_s *m;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
@@ -4733,7 +4731,7 @@ bfa_rport_send_fwdelete(struct bfa_rport_s *rp)
                        bfa_lpuid(rp->bfa));
        m->fw_handle = rp->fw_handle;
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
@@ -4745,7 +4743,7 @@ bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
 {
        struct bfa_rport_speed_req_s *m;
 
-       /**
+       /*
         * check for room in queue to send request now
         */
        m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
@@ -4759,7 +4757,7 @@ bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
        m->fw_handle = rp->fw_handle;
        m->speed = (u8)rp->rport_info.speed;
 
-       /**
+       /*
         * queue I/O message to firmware
         */
        bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
@@ -4768,11 +4766,11 @@ bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
 
 
 
-/**
+/*
  *  bfa_rport_public
  */
 
-/**
+/*
  * Rport interrupt processing.
  */
 void
@@ -4814,7 +4812,7 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
 
 
 
-/**
+/*
  *  bfa_rport_api
  */
 
@@ -4849,7 +4847,7 @@ bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
 {
        bfa_assert(rport_info->max_frmsz != 0);
 
-       /**
+       /*
         * Some JBODs are seen to be not setting PDU size correctly in PLOGI
         * responses. Default to minimum size.
         */
@@ -4858,7 +4856,7 @@ bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
                rport_info->max_frmsz = FC_MIN_PDUSZ;
        }
 
-       bfa_os_assign(rport->rport_info, *rport_info);
+       rport->rport_info = *rport_info;
        bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE);
 }
 
@@ -4890,22 +4888,22 @@ bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
                                        struct bfa_rport_qos_attr_s *qos_attr)
 {
        qos_attr->qos_priority  = rport->qos_attr.qos_priority;
-       qos_attr->qos_flow_id  = bfa_os_ntohl(rport->qos_attr.qos_flow_id);
+       qos_attr->qos_flow_id  = be32_to_cpu(rport->qos_attr.qos_flow_id);
 
 }
 
 void
 bfa_rport_clear_stats(struct bfa_rport_s *rport)
 {
-       bfa_os_memset(&rport->stats, 0, sizeof(rport->stats));
+       memset(&rport->stats, 0, sizeof(rport->stats));
 }
 
 
-/**
+/*
  * SGPG related functions
  */
 
-/**
+/*
  * Compute and return memory needed by FCP(im) module.
  */
 static void
@@ -4957,8 +4955,8 @@ bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        bfa_assert(!(sgpg_pa.pa & (sizeof(struct bfi_sgpg_s) - 1)));
 
        for (i = 0; i < mod->num_sgpgs; i++) {
-               bfa_os_memset(hsgpg, 0, sizeof(*hsgpg));
-               bfa_os_memset(sgpg, 0, sizeof(*sgpg));
+               memset(hsgpg, 0, sizeof(*hsgpg));
+               memset(sgpg, 0, sizeof(*sgpg));
 
                hsgpg->sgpg = sgpg;
                sgpg_pa_tmp.pa = bfa_sgaddr_le(sgpg_pa.pa);
@@ -4997,7 +4995,7 @@ bfa_sgpg_iocdisable(struct bfa_s *bfa)
 
 
 
-/**
+/*
  *  hal_sgpg_public BFA SGPG public functions
  */
 
@@ -5039,7 +5037,7 @@ bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg)
        if (list_empty(&mod->sgpg_wait_q))
                return;
 
-       /**
+       /*
         * satisfy as many waiting requests as possible
         */
        do {
@@ -5067,11 +5065,11 @@ bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg)
 
        wqe->nsgpg_total = wqe->nsgpg = nsgpg;
 
-       /**
+       /*
         * allocate any left to this one first
         */
        if (mod->free_sgpgs) {
-               /**
+               /*
                 * no one else is waiting for SGPG
                 */
                bfa_assert(list_empty(&mod->sgpg_wait_q));
@@ -5105,7 +5103,7 @@ bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg),
        wqe->cbarg = cbarg;
 }
 
-/**
+/*
  *  UF related functions
  */
 /*
@@ -5136,7 +5134,7 @@ claim_uf_pbs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
        bfa_meminfo_dma_virt(mi) += uf_pb_tot_sz;
        bfa_meminfo_dma_phys(mi) += uf_pb_tot_sz;
 
-       bfa_os_memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz);
+       memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz);
 }
 
 static void
@@ -5153,11 +5151,11 @@ claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
 
        for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs;
             i++, uf_bp_msg++) {
-               bfa_os_memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s));
+               memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s));
 
                uf_bp_msg->buf_tag = i;
                buf_len = sizeof(struct bfa_uf_buf_s);
-               uf_bp_msg->buf_len = bfa_os_htons(buf_len);
+               uf_bp_msg->buf_len = cpu_to_be16(buf_len);
                bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST,
                            bfa_lpuid(ufm->bfa));
 
@@ -5173,7 +5171,7 @@ claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
                bfa_sge_to_be(&sge[1]);
        }
 
-       /**
+       /*
         * advance pointer beyond consumed memory
         */
        bfa_meminfo_kva(mi) = (u8 *) uf_bp_msg;
@@ -5194,7 +5192,7 @@ claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
         * Initialize UFs and queue it in UF free queue
         */
        for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) {
-               bfa_os_memset(uf, 0, sizeof(struct bfa_uf_s));
+               memset(uf, 0, sizeof(struct bfa_uf_s));
                uf->bfa = ufm->bfa;
                uf->uf_tag = i;
                uf->pb_len = sizeof(struct bfa_uf_buf_s);
@@ -5203,7 +5201,7 @@ claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
                list_add_tail(&uf->qe, &ufm->uf_free_q);
        }
 
-       /**
+       /*
         * advance memory pointer
         */
        bfa_meminfo_kva(mi) = (u8 *) uf;
@@ -5241,7 +5239,7 @@ bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
 {
        struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
 
-       bfa_os_memset(ufm, 0, sizeof(struct bfa_uf_mod_s));
+       memset(ufm, 0, sizeof(struct bfa_uf_mod_s));
        ufm->bfa = bfa;
        ufm->num_ufs = cfg->fwcfg.num_uf_bufs;
        INIT_LIST_HEAD(&ufm->uf_free_q);
@@ -5279,7 +5277,7 @@ bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf)
        if (!uf_post_msg)
                return BFA_STATUS_FAILED;
 
-       bfa_os_memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag],
+       memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag],
                      sizeof(struct bfi_uf_buf_post_s));
        bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP);
 
@@ -5310,8 +5308,8 @@ uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m)
        u8 *buf = &uf_buf->d[0];
        struct fchs_s *fchs;
 
-       m->frm_len = bfa_os_ntohs(m->frm_len);
-       m->xfr_len = bfa_os_ntohs(m->xfr_len);
+       m->frm_len = be16_to_cpu(m->frm_len);
+       m->xfr_len = be16_to_cpu(m->xfr_len);
 
        fchs = (struct fchs_s *)uf_buf;
 
@@ -5365,11 +5363,11 @@ bfa_uf_start(struct bfa_s *bfa)
 
 
 
-/**
+/*
  *  hal_uf_api
  */
 
-/**
+/*
  * Register handler for all unsolicted recieve frames.
  *
  * @param[in]  bfa             BFA instance
@@ -5385,7 +5383,7 @@ bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg)
        ufm->cbarg = cbarg;
 }
 
-/**
+/*
  *     Free an unsolicited frame back to BFA.
  *
  * @param[in]          uf              unsolicited frame to be freed
@@ -5401,7 +5399,7 @@ bfa_uf_free(struct bfa_uf_s *uf)
 
 
 
-/**
+/*
  *  uf_pub BFA uf module public functions
  */
 void
index 9921dad0d0392e4dc58df172871e0fd73c9fa39c..e2349d5cdb931124132e2c6a2b3cc52200dcf40b 100644 (file)
 #include "bfi_ms.h"
 
 
-/**
+/*
  * Scatter-gather DMA related defines
  */
 #define BFA_SGPG_MIN   (16)
 
-/**
+/*
  * Alignment macro for SG page allocation
  */
 #define BFA_SGPG_ROUNDUP(_l) (((_l) + (sizeof(struct bfi_sgpg_s) - 1)) \
@@ -48,7 +48,7 @@ struct bfa_sgpg_s {
        union bfi_addr_u sgpg_pa;       /*  pa of SG page               */
 };
 
-/**
+/*
  * Given number of SG elements, BFA_SGPG_NPAGE() returns the number of
  * SG pages required.
  */
@@ -75,7 +75,7 @@ void bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpgs);
 void bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe);
 
 
-/**
+/*
  * FCXP related defines
  */
 #define BFA_FCXP_MIN           (1)
@@ -115,12 +115,12 @@ typedef void (*bfa_fcxp_alloc_cbfn_t) (void *cbarg, struct bfa_fcxp_s *fcxp);
 
 
 
-/**
+/*
  * Information needed for a FCXP request
  */
 struct bfa_fcxp_req_info_s {
        struct bfa_rport_s *bfa_rport;
-                                       /** Pointer to the bfa rport that was
+                                       /* Pointer to the bfa rport that was
                                         * returned from bfa_rport_create().
                                         * This could be left NULL for WKA or
                                         * for FCXP interactions before the
@@ -137,11 +137,10 @@ struct bfa_fcxp_req_info_s {
 
 struct bfa_fcxp_rsp_info_s {
        struct fchs_s   rsp_fchs;
-                               /** !< Response frame's FC header will
+                               /* Response frame's FC header will
                                 * be sent back in this field */
        u8              rsp_timeout;
-                               /** !< timeout in seconds, 0-no response
-                                */
+                               /* timeout in seconds, 0-no response */
        u8              rsvd2[3];
        u32     rsp_maxlen;     /*  max response length expected */
 };
@@ -218,7 +217,7 @@ struct bfa_fcxp_wqe_s {
 void   bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 
 
-/**
+/*
  * RPORT related defines
  */
 #define BFA_RPORT_MIN  4
@@ -232,7 +231,7 @@ struct bfa_rport_mod_s {
 
 #define BFA_RPORT_MOD(__bfa)   (&(__bfa)->modules.rport_mod)
 
-/**
+/*
  * Convert rport tag to RPORT
  */
 #define BFA_RPORT_FROM_TAG(__bfa, _tag)                                \
@@ -244,7 +243,7 @@ struct bfa_rport_mod_s {
  */
 void   bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 
-/**
+/*
  *     BFA rport information.
  */
 struct bfa_rport_info_s {
@@ -259,7 +258,7 @@ struct bfa_rport_info_s {
        enum bfa_port_speed speed;      /*  Rport's current speed           */
 };
 
-/**
+/*
  * BFA rport data structure
  */
 struct bfa_rport_s {
@@ -282,7 +281,7 @@ struct bfa_rport_s {
 #define BFA_RPORT_FC_COS(_rport)       ((_rport)->rport_info.fc_class)
 
 
-/**
+/*
  * UF - unsolicited receive related defines
  */
 
@@ -305,7 +304,7 @@ struct bfa_uf_s {
        struct bfa_sge_s sges[BFI_SGE_INLINE_MAX];
 };
 
-/**
+/*
  *      Callback prototype for unsolicited frame receive handler.
  *
  * @param[in]           cbarg           callback arg for receive handler
@@ -338,7 +337,7 @@ void        bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 
 #define BFA_UF_BUFSZ   (2 * 1024 + 256)
 
-/**
+/*
  * @todo private
  */
 struct bfa_uf_buf_s {
@@ -346,7 +345,7 @@ struct bfa_uf_buf_s {
 };
 
 
-/**
+/*
  * LPS - bfa lport login/logout service interface
  */
 struct bfa_lps_s {
@@ -397,14 +396,14 @@ struct bfa_lps_mod_s {
 void   bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
 
 
-/**
+/*
  * FCPORT related defines
  */
 
 #define BFA_FCPORT(_bfa)       (&((_bfa)->modules.port))
 typedef void (*bfa_cb_port_t) (void *cbarg, enum bfa_status status);
 
-/**
+/*
  * Link notification data structure
  */
 struct bfa_fcport_ln_s {
@@ -418,7 +417,7 @@ struct bfa_fcport_trunk_s {
        struct bfa_trunk_attr_s attr;
 };
 
-/**
+/*
  * BFA FC port data structure
  */
 struct bfa_fcport_s {
@@ -613,7 +612,7 @@ void bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv,
                          void *cbarg);
 void bfa_uf_free(struct bfa_uf_s *uf);
 
-/**
+/*
  * bfa lport service api
  */
 
index 4d8784e06e142a8d0dd4d178cd947dbca6c17ff9..1f938974b84876978600b40d97c265ddd7c2c7c0 100644 (file)
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 
-/**
+/*
  *  bfad.c Linux driver PCI interface module.
  */
 #include <linux/module.h>
@@ -151,7 +151,7 @@ bfad_sm_failed(struct bfad_s *bfad, enum bfad_sm_event event);
 static void
 bfad_sm_fcs_exit(struct bfad_s *bfad, enum bfad_sm_event event);
 
-/**
+/*
  * Beginning state for the driver instance, awaiting the pci_probe event
  */
 static void
@@ -181,7 +181,7 @@ bfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event)
        }
 }
 
-/**
+/*
  * Driver Instance is created, awaiting event INIT to initialize the bfad
  */
 static void
@@ -364,7 +364,7 @@ bfad_sm_stopping(struct bfad_s *bfad, enum bfad_sm_event event)
        }
 }
 
-/**
+/*
  *  BFA callbacks
  */
 void
@@ -376,7 +376,7 @@ bfad_hcb_comp(void *arg, bfa_status_t status)
        complete(&fcomp->comp);
 }
 
-/**
+/*
  * bfa_init callback
  */
 void
@@ -401,7 +401,7 @@ bfa_cb_init(void *drv, bfa_status_t init_status)
        complete(&bfad->comp);
 }
 
-/**
+/*
  *  BFA_FCS callbacks
  */
 struct bfad_port_s *
@@ -457,7 +457,7 @@ bfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles,
        }
 }
 
-/**
+/*
  * FCS RPORT alloc callback, after successful PLOGI by FCS
  */
 bfa_status_t
@@ -478,7 +478,7 @@ ext:
        return rc;
 }
 
-/**
+/*
  * FCS PBC VPORT Create
  */
 void
@@ -663,7 +663,7 @@ ext:
        return rc;
 }
 
-/**
+/*
  * Create a vport under a vf.
  */
 bfa_status_t
@@ -716,30 +716,6 @@ ext:
        return rc;
 }
 
-/**
- * Create a vf and its base vport implicitely.
- */
-bfa_status_t
-bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
-              struct bfa_lport_cfg_s *port_cfg)
-{
-       struct bfad_vf_s      *vf;
-       int             rc = BFA_STATUS_OK;
-
-       vf = kzalloc(sizeof(struct bfad_vf_s), GFP_KERNEL);
-       if (!vf) {
-               rc = BFA_STATUS_FAILED;
-               goto ext;
-       }
-
-       rc = bfa_fcs_vf_create(&vf->fcs_vf, &bfad->bfa_fcs, vf_id, port_cfg,
-                              vf);
-       if (rc != BFA_STATUS_OK)
-               kfree(vf);
-ext:
-       return rc;
-}
-
 void
 bfad_bfa_tmo(unsigned long data)
 {
@@ -885,20 +861,6 @@ bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
        pci_set_drvdata(pdev, NULL);
 }
 
-void
-bfad_fcs_port_cfg(struct bfad_s *bfad)
-{
-       struct bfa_lport_cfg_s  port_cfg;
-       struct bfa_port_attr_s attr;
-       char            symname[BFA_SYMNAME_MAXLEN];
-
-       sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
-       memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
-       bfa_fcport_get_attr(&bfad->bfa, &attr);
-       port_cfg.nwwn = attr.nwwn;
-       port_cfg.pwwn = attr.pwwn;
-}
-
 bfa_status_t
 bfad_drv_init(struct bfad_s *bfad)
 {
@@ -1089,9 +1051,6 @@ bfad_start_ops(struct bfad_s *bfad) {
        bfa_fcs_init(&bfad->bfa_fcs);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
-       /* PPORT FCS config */
-       bfad_fcs_port_cfg(bfad);
-
        retval = bfad_cfg_pport(bfad, BFA_LPORT_ROLE_FCP_IM);
        if (retval != BFA_STATUS_OK) {
                if (bfa_sm_cmp_state(bfad, bfad_sm_initializing))
@@ -1181,7 +1140,7 @@ bfad_worker(void *ptr)
        return 0;
 }
 
-/**
+/*
  *  BFA driver interrupt functions
  */
 irqreturn_t
@@ -1240,7 +1199,7 @@ bfad_msix(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-/**
+/*
  * Initialize the MSIX entry table.
  */
 static void
@@ -1293,7 +1252,7 @@ bfad_install_msix_handler(struct bfad_s *bfad)
        return 0;
 }
 
-/**
+/*
  * Setup MSIX based interrupt.
  */
 int
@@ -1374,7 +1333,7 @@ bfad_remove_intr(struct bfad_s *bfad)
        }
 }
 
-/**
+/*
  * PCI probe entry.
  */
 int
@@ -1460,7 +1419,7 @@ out:
        return error;
 }
 
-/**
+/*
  * PCI remove entry.
  */
 void
@@ -1541,7 +1500,7 @@ static struct pci_driver bfad_pci_driver = {
        .remove = __devexit_p(bfad_pci_remove),
 };
 
-/**
+/*
  * Driver module init.
  */
 static int __init
@@ -1581,7 +1540,7 @@ ext:
        return error;
 }
 
-/**
+/*
  * Driver module exit.
  */
 static void __exit
index d8843720eac1b42b39606c6af93f1cde39653b5c..ed9fff440b5c3ef00014502120f7f475072b764e 100644 (file)
  * General Public License for more details.
  */
 
-/**
+/*
  *  bfa_attr.c Linux driver configuration interface module.
  */
 
 #include "bfad_drv.h"
 #include "bfad_im.h"
 
-/**
+/*
  * FC transport template entry, get SCSI target port ID.
  */
 void
@@ -48,7 +48,7 @@ bfad_im_get_starget_port_id(struct scsi_target *starget)
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 }
 
-/**
+/*
  * FC transport template entry, get SCSI target nwwn.
  */
 void
@@ -70,11 +70,11 @@ bfad_im_get_starget_node_name(struct scsi_target *starget)
        if (itnim)
                node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim);
 
-       fc_starget_node_name(starget) = bfa_os_htonll(node_name);
+       fc_starget_node_name(starget) = cpu_to_be64(node_name);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 }
 
-/**
+/*
  * FC transport template entry, get SCSI target pwwn.
  */
 void
@@ -96,11 +96,11 @@ bfad_im_get_starget_port_name(struct scsi_target *starget)
        if (itnim)
                port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
 
-       fc_starget_port_name(starget) = bfa_os_htonll(port_name);
+       fc_starget_port_name(starget) = cpu_to_be64(port_name);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 }
 
-/**
+/*
  * FC transport template entry, get SCSI host port ID.
  */
 void
@@ -114,7 +114,7 @@ bfad_im_get_host_port_id(struct Scsi_Host *shost)
                        bfa_os_hton3b(bfa_fcs_lport_get_fcid(port->fcs_port));
 }
 
-/**
+/*
  * FC transport template entry, get SCSI host port type.
  */
 static void
@@ -146,7 +146,7 @@ bfad_im_get_host_port_type(struct Scsi_Host *shost)
        }
 }
 
-/**
+/*
  * FC transport template entry, get SCSI host port state.
  */
 static void
@@ -183,7 +183,7 @@ bfad_im_get_host_port_state(struct Scsi_Host *shost)
        }
 }
 
-/**
+/*
  * FC transport template entry, get SCSI host active fc4s.
  */
 static void
@@ -202,7 +202,7 @@ bfad_im_get_host_active_fc4s(struct Scsi_Host *shost)
        fc_host_active_fc4s(shost)[7] = 1;
 }
 
-/**
+/*
  * FC transport template entry, get SCSI host link speed.
  */
 static void
@@ -236,7 +236,7 @@ bfad_im_get_host_speed(struct Scsi_Host *shost)
        }
 }
 
-/**
+/*
  * FC transport template entry, get SCSI host port type.
  */
 static void
@@ -249,11 +249,11 @@ bfad_im_get_host_fabric_name(struct Scsi_Host *shost)
 
        fabric_nwwn = bfa_fcs_lport_get_fabric_name(port->fcs_port);
 
-       fc_host_fabric_name(shost) = bfa_os_htonll(fabric_nwwn);
+       fc_host_fabric_name(shost) = cpu_to_be64(fabric_nwwn);
 
 }
 
-/**
+/*
  * FC transport template entry, get BFAD statistics.
  */
 static struct fc_host_statistics *
@@ -304,7 +304,7 @@ bfad_im_get_stats(struct Scsi_Host *shost)
        return hstats;
 }
 
-/**
+/*
  * FC transport template entry, reset BFAD statistics.
  */
 static void
@@ -331,7 +331,7 @@ bfad_im_reset_stats(struct Scsi_Host *shost)
        return;
 }
 
-/**
+/*
  * FC transport template entry, get rport loss timeout.
  */
 static void
@@ -347,7 +347,7 @@ bfad_im_get_rport_loss_tmo(struct fc_rport *rport)
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 }
 
-/**
+/*
  * FC transport template entry, set rport loss timeout.
  */
 static void
@@ -633,7 +633,7 @@ struct fc_function_template bfad_im_vport_fc_function_template = {
        .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
 };
 
-/**
+/*
  *  Scsi_Host_attrs SCSI host attributes
  */
 static ssize_t
@@ -733,7 +733,7 @@ bfad_im_node_name_show(struct device *dev, struct device_attribute *attr,
        u64        nwwn;
 
        nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port);
-       return snprintf(buf, PAGE_SIZE, "0x%llx\n", bfa_os_htonll(nwwn));
+       return snprintf(buf, PAGE_SIZE, "0x%llx\n", cpu_to_be64(nwwn));
 }
 
 static ssize_t
index 69ed1c4a903eac810fc40a70d86b20e7f440f6c1..1fedeeb4ac1f87dd69e4945c6c3b65fdd4cdab37 100644 (file)
@@ -318,7 +318,7 @@ bfad_debugfs_write_regrd(struct file *file, const char __user *buf,
        regbuf =  (u32 *)bfad->regdata;
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        for (i = 0; i < len; i++) {
-               *regbuf = bfa_reg_read(reg_addr);
+               *regbuf = readl(reg_addr);
                regbuf++;
                reg_addr += sizeof(u32);
        }
@@ -361,7 +361,7 @@ bfad_debugfs_write_regwr(struct file *file, const char __user *buf,
 
        reg_addr = (u32 *) ((u8 *) bfa_ioc_bar0(ioc) + addr);
        spin_lock_irqsave(&bfad->bfad_lock, flags);
-       bfa_reg_write(reg_addr, val);
+       writel(val, reg_addr);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
        return nbytes;
index 98420bbb4f3f1d01f6c9035472d42f69a258ab88..97f9b6c0937e75cf3a16762092ac46ac6f6cb890 100644 (file)
  * General Public License for more details.
  */
 
-/**
+/*
  * Contains base driver definitions.
  */
 
-/**
+/*
  *  bfa_drv.h Linux driver data structures.
  */
 
@@ -309,7 +309,6 @@ void                bfad_bfa_tmo(unsigned long data);
 void           bfad_init_timer(struct bfad_s *bfad);
 int            bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad);
 void           bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad);
-void           bfad_fcs_port_cfg(struct bfad_s *bfad);
 void           bfad_drv_uninit(struct bfad_s *bfad);
 int            bfad_worker(void *ptr);
 void           bfad_debugfs_init(struct bfad_port_s *port);
index d950ee44016eeefcf3e8870483f9322f667551ce..8daa716739d1bd6d2a6a4180c008161e7f148f27 100644 (file)
@@ -15,7 +15,7 @@
  * General Public License for more details.
  */
 
-/**
+/*
  *  bfad_im.c Linux driver IM module.
  */
 
@@ -164,10 +164,10 @@ bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
                wake_up(wq);
 }
 
-/**
+/*
  *  Scsi_Host_template SCSI host template
  */
-/**
+/*
  * Scsi_Host template entry, returns BFAD PCI info.
  */
 static const char *
@@ -196,7 +196,7 @@ bfad_im_info(struct Scsi_Host *shost)
        return bfa_buf;
 }
 
-/**
+/*
  * Scsi_Host template entry, aborts the specified SCSI command.
  *
  * Returns: SUCCESS or FAILED.
@@ -280,7 +280,7 @@ out:
        return rc;
 }
 
-/**
+/*
  * Scsi_Host template entry, resets a LUN and abort its all commands.
  *
  * Returns: SUCCESS or FAILED.
@@ -319,7 +319,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
                goto out;
        }
 
-       /**
+       /*
         * Set host_scribble to NULL to avoid aborting a task command
         * if happens.
         */
@@ -346,7 +346,7 @@ out:
        return rc;
 }
 
-/**
+/*
  * Scsi_Host template entry, resets the bus and abort all commands.
  */
 static int
@@ -396,7 +396,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd)
        return SUCCESS;
 }
 
-/**
+/*
  * Scsi_Host template entry slave_destroy.
  */
 static void
@@ -406,11 +406,11 @@ bfad_im_slave_destroy(struct scsi_device *sdev)
        return;
 }
 
-/**
+/*
  *  BFA FCS itnim callbacks
  */
 
-/**
+/*
  * BFA FCS itnim alloc callback, after successful PRLI
  * Context: Interrupt
  */
@@ -433,7 +433,7 @@ bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
        bfad->bfad_flags |= BFAD_RPORT_ONLINE;
 }
 
-/**
+/*
  * BFA FCS itnim free callback.
  * Context: Interrupt. bfad_lock is held
  */
@@ -471,7 +471,7 @@ bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv)
                queue_work(im->drv_workq, &itnim_drv->itnim_work);
 }
 
-/**
+/*
  * BFA FCS itnim online callback.
  * Context: Interrupt. bfad_lock is held
  */
@@ -492,7 +492,7 @@ bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv)
                queue_work(im->drv_workq, &itnim_drv->itnim_work);
 }
 
-/**
+/*
  * BFA FCS itnim offline callback.
  * Context: Interrupt. bfad_lock is held
  */
@@ -519,7 +519,7 @@ bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv)
                queue_work(im->drv_workq, &itnim_drv->itnim_work);
 }
 
-/**
+/*
  * Allocate a Scsi_Host for a port.
  */
 int
@@ -751,7 +751,7 @@ bfad_os_thread_workq(struct bfad_s *bfad)
        return BFA_STATUS_OK;
 }
 
-/**
+/*
  * Scsi_Host template entry.
  *
  * Description:
@@ -896,7 +896,7 @@ bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id)
        return NULL;
 }
 
-/**
+/*
  * Scsi_Host template entry slave_alloc
  */
 static int
@@ -915,12 +915,16 @@ bfad_im_slave_alloc(struct scsi_device *sdev)
 static u32
 bfad_im_supported_speeds(struct bfa_s *bfa)
 {
-       struct bfa_ioc_attr_s ioc_attr;
+       struct bfa_ioc_attr_s *ioc_attr;
        u32 supported_speed = 0;
 
-       bfa_get_attr(bfa, &ioc_attr);
-       if (ioc_attr.adapter_attr.max_speed == BFA_PORT_SPEED_8GBPS) {
-               if (ioc_attr.adapter_attr.is_mezz) {
+       ioc_attr = kzalloc(sizeof(struct bfa_ioc_attr_s), GFP_KERNEL);
+       if (!ioc_attr)
+               return 0;
+
+       bfa_get_attr(bfa, ioc_attr);
+       if (ioc_attr->adapter_attr.max_speed == BFA_PORT_SPEED_8GBPS) {
+               if (ioc_attr->adapter_attr.is_mezz) {
                        supported_speed |= FC_PORTSPEED_8GBIT |
                                FC_PORTSPEED_4GBIT |
                                FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
@@ -929,12 +933,13 @@ bfad_im_supported_speeds(struct bfa_s *bfa)
                                FC_PORTSPEED_4GBIT |
                                FC_PORTSPEED_2GBIT;
                }
-       } else if (ioc_attr.adapter_attr.max_speed == BFA_PORT_SPEED_4GBPS) {
+       } else if (ioc_attr->adapter_attr.max_speed == BFA_PORT_SPEED_4GBPS) {
                supported_speed |=  FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
                                FC_PORTSPEED_1GBIT;
-       } else if (ioc_attr.adapter_attr.max_speed == BFA_PORT_SPEED_10GBPS) {
+       } else if (ioc_attr->adapter_attr.max_speed == BFA_PORT_SPEED_10GBPS) {
                supported_speed |= FC_PORTSPEED_10GBIT;
        }
+       kfree(ioc_attr);
        return supported_speed;
 }
 
@@ -944,14 +949,13 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
        struct Scsi_Host *host = im_port->shost;
        struct bfad_s         *bfad = im_port->bfad;
        struct bfad_port_s    *port = im_port->port;
-       struct bfa_port_attr_s pattr;
-       struct bfa_lport_attr_s port_attr;
        char symname[BFA_SYMNAME_MAXLEN];
+       struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
 
        fc_host_node_name(host) =
-               bfa_os_htonll((bfa_fcs_lport_get_nwwn(port->fcs_port)));
+               cpu_to_be64((bfa_fcs_lport_get_nwwn(port->fcs_port)));
        fc_host_port_name(host) =
-               bfa_os_htonll((bfa_fcs_lport_get_pwwn(port->fcs_port)));
+               cpu_to_be64((bfa_fcs_lport_get_pwwn(port->fcs_port)));
        fc_host_max_npiv_vports(host) = bfa_lps_get_max_vport(&bfad->bfa);
 
        fc_host_supported_classes(host) = FC_COS_CLASS3;
@@ -964,15 +968,12 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
        /* For fibre channel services type 0x20 */
        fc_host_supported_fc4s(host)[7] = 1;
 
-       bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
-       strncpy(symname, port_attr.port_cfg.sym_name.symname,
+       strncpy(symname, bfad->bfa_fcs.fabric.bport.port_cfg.sym_name.symname,
                BFA_SYMNAME_MAXLEN);
        sprintf(fc_host_symbolic_name(host), "%s", symname);
 
        fc_host_supported_speeds(host) = bfad_im_supported_speeds(&bfad->bfa);
-
-       bfa_fcport_get_attr(&bfad->bfa, &pattr);
-       fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize;
+       fc_host_maxframe_size(host) = fcport->cfg.maxfrsize;
 }
 
 static void
@@ -983,9 +984,9 @@ bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim)
        struct bfad_itnim_data_s *itnim_data;
 
        rport_ids.node_name =
-               bfa_os_htonll(bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim));
+               cpu_to_be64(bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim));
        rport_ids.port_name =
-               bfa_os_htonll(bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
+               cpu_to_be64(bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
        rport_ids.port_id =
                bfa_os_hton3b(bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim));
        rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
@@ -1015,7 +1016,7 @@ bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim)
        return;
 }
 
-/**
+/*
  * Work queue handler using FC transport service
 * Context: kernel
  */
@@ -1115,7 +1116,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 }
 
-/**
+/*
  * Scsi_Host template entry, queue a SCSI command to the BFAD.
  */
 static int
index 85f2224a5733cf2847377c103c818d1fb545632e..58796d1284b70ae2b49b238d5b2e66737ca5d1a3 100644 (file)
@@ -23,7 +23,7 @@
 
 #pragma pack(1)
 
-/**
+/*
  * BFI FW image type
  */
 #define        BFI_FLASH_CHUNK_SZ                      256     /*  Flash chunk size */
@@ -35,7 +35,7 @@ enum {
        BFI_IMAGE_MAX,
 };
 
-/**
+/*
  * Msg header common to all msgs
  */
 struct bfi_mhdr_s {
@@ -68,7 +68,7 @@ struct bfi_mhdr_s {
 #define BFI_I2H_OPCODE_BASE    128
 #define BFA_I2HM(_x)           ((_x) + BFI_I2H_OPCODE_BASE)
 
-/**
+/*
  ****************************************************************************
  *
  * Scatter Gather Element and Page definition
@@ -79,7 +79,7 @@ struct bfi_mhdr_s {
 #define BFI_SGE_INLINE 1
 #define BFI_SGE_INLINE_MAX     (BFI_SGE_INLINE + 1)
 
-/**
+/*
  * SG Flags
  */
 enum {
@@ -90,7 +90,7 @@ enum {
        BFI_SGE_PGDLEN          = 2,    /*  cumulative data length for page */
 };
 
-/**
+/*
  * DMA addresses
  */
 union bfi_addr_u {
@@ -100,7 +100,7 @@ union bfi_addr_u {
        } a32;
 };
 
-/**
+/*
  * Scatter Gather Element
  */
 struct bfi_sge_s {
@@ -116,7 +116,7 @@ struct bfi_sge_s {
        union bfi_addr_u sga;
 };
 
-/**
+/*
  * Scatter Gather Page
  */
 #define BFI_SGPG_DATA_SGES             7
@@ -139,7 +139,7 @@ struct bfi_msg_s {
        u32     pl[BFI_LMSG_PL_WSZ];
 };
 
-/**
+/*
  * Mailbox message structure
  */
 #define BFI_MBMSG_SZ           7
@@ -148,7 +148,7 @@ struct bfi_mbmsg_s {
        u32             pl[BFI_MBMSG_SZ];
 };
 
-/**
+/*
  * Message Classes
  */
 enum bfi_mclass {
@@ -186,7 +186,7 @@ enum bfi_mclass {
 #define BFI_BOOT_LOADER_BIOS           1
 #define BFI_BOOT_LOADER_UEFI           2
 
-/**
+/*
  *----------------------------------------------------------------------
  *                             IOC
  *----------------------------------------------------------------------
@@ -208,7 +208,7 @@ enum bfi_ioc_i2h_msgs {
        BFI_IOC_I2H_HBEAT               = BFA_I2HM(5),
 };
 
-/**
+/*
  * BFI_IOC_H2I_GETATTR_REQ message
  */
 struct bfi_ioc_getattr_req_s {
@@ -242,7 +242,7 @@ struct bfi_ioc_attr_s {
        u32     card_type;      /*  card type                   */
 };
 
-/**
+/*
  * BFI_IOC_I2H_GETATTR_REPLY message
  */
 struct bfi_ioc_getattr_reply_s {
@@ -251,19 +251,19 @@ struct bfi_ioc_getattr_reply_s {
        u8                      rsvd[3];
 };
 
-/**
+/*
  * Firmware memory page offsets
  */
 #define BFI_IOC_SMEM_PG0_CB    (0x40)
 #define BFI_IOC_SMEM_PG0_CT    (0x180)
 
-/**
+/*
  * Firmware statistic offset
  */
 #define BFI_IOC_FWSTATS_OFF    (0x6B40)
 #define BFI_IOC_FWSTATS_SZ     (4096)
 
-/**
+/*
  * Firmware trace offset
  */
 #define BFI_IOC_TRC_OFF                (0x4b00)
@@ -280,7 +280,7 @@ struct bfi_ioc_image_hdr_s {
        u32     md5sum[BFI_IOC_MD5SUM_SZ];
 };
 
-/**
+/*
  *  BFI_IOC_I2H_READY_EVENT message
  */
 struct bfi_ioc_rdy_event_s {
@@ -294,7 +294,7 @@ struct bfi_ioc_hbeat_s {
        u32        hb_count;    /*  current heart beat count    */
 };
 
-/**
+/*
  * IOC hardware/firmware state
  */
 enum bfi_ioc_state {
@@ -340,7 +340,7 @@ enum {
        ((__adap_type) & (BFI_ADAPTER_TTV | BFI_ADAPTER_PROTO | \
                        BFI_ADAPTER_UNSUPP))
 
-/**
+/*
  * BFI_IOC_H2I_ENABLE_REQ & BFI_IOC_H2I_DISABLE_REQ messages
  */
 struct bfi_ioc_ctrl_req_s {
@@ -352,7 +352,7 @@ struct bfi_ioc_ctrl_req_s {
 #define bfi_ioc_enable_req_t struct bfi_ioc_ctrl_req_s;
 #define bfi_ioc_disable_req_t struct bfi_ioc_ctrl_req_s;
 
-/**
+/*
  * BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages
  */
 struct bfi_ioc_ctrl_reply_s {
@@ -364,7 +364,7 @@ struct bfi_ioc_ctrl_reply_s {
 #define bfi_ioc_disable_reply_t struct bfi_ioc_ctrl_reply_s;
 
 #define BFI_IOC_MSGSZ   8
-/**
+/*
  * H2I Messages
  */
 union bfi_ioc_h2i_msg_u {
@@ -375,7 +375,7 @@ union bfi_ioc_h2i_msg_u {
        u32                     mboxmsg[BFI_IOC_MSGSZ];
 };
 
-/**
+/*
  * I2H Messages
  */
 union bfi_ioc_i2h_msg_u {
@@ -385,7 +385,7 @@ union bfi_ioc_i2h_msg_u {
 };
 
 
-/**
+/*
  *----------------------------------------------------------------------
  *                             PBC
  *----------------------------------------------------------------------
@@ -394,7 +394,7 @@ union bfi_ioc_i2h_msg_u {
 #define BFI_PBC_MAX_BLUNS      8
 #define BFI_PBC_MAX_VPORTS     16
 
-/**
+/*
  * PBC boot lun configuration
  */
 struct bfi_pbc_blun_s {
@@ -402,7 +402,7 @@ struct bfi_pbc_blun_s {
        lun_t           tgt_lun;
 };
 
-/**
+/*
  * PBC virtual port configuration
  */
 struct bfi_pbc_vport_s {
@@ -410,7 +410,7 @@ struct bfi_pbc_vport_s {
        wwn_t           vp_nwwn;
 };
 
-/**
+/*
  * BFI pre-boot configuration information
  */
 struct bfi_pbc_s {
@@ -427,7 +427,7 @@ struct bfi_pbc_s {
        struct bfi_pbc_vport_s vport[BFI_PBC_MAX_VPORTS];
 };
 
-/**
+/*
  *----------------------------------------------------------------------
  *                             MSGQ
  *----------------------------------------------------------------------
@@ -531,7 +531,7 @@ enum bfi_port_i2h {
        BFI_PORT_I2H_CLEAR_STATS_RSP    = BFA_I2HM(4),
 };
 
-/**
+/*
  * Generic REQ type
  */
 struct bfi_port_generic_req_s {
@@ -540,7 +540,7 @@ struct bfi_port_generic_req_s {
        u32     rsvd;
 };
 
-/**
+/*
  * Generic RSP type
  */
 struct bfi_port_generic_rsp_s {
@@ -550,7 +550,7 @@ struct bfi_port_generic_rsp_s {
        u32     msgtag;         /*  msgtag for reply                */
 };
 
-/**
+/*
  * BFI_PORT_H2I_GET_STATS_REQ
  */
 struct bfi_port_get_stats_req_s {
index 69ac85f9e938c9f8aa4d5b42eb186f05f21a2f9c..fa9f6fb9d45b0decc0920d88439b89c7bc37dbe5 100644 (file)
@@ -41,7 +41,7 @@ struct bfi_iocfc_cfg_s {
        u16     rsvd_1;
        u32     endian_sig;     /*  endian signature of host     */
 
-       /**
+       /*
         * Request and response circular queue base addresses, size and
         * shadow index pointers.
         */
@@ -58,7 +58,7 @@ struct bfi_iocfc_cfg_s {
        struct bfa_iocfc_intr_attr_s intr_attr; /*  IOC interrupt attributes */
 };
 
-/**
+/*
  * Boot target wwn information for this port. This contains either the stored
  * or discovered boot target port wwns for the port.
  */
@@ -75,7 +75,7 @@ struct bfi_iocfc_cfgrsp_s {
        struct bfi_pbc_s                pbc_cfg;
 };
 
-/**
+/*
  * BFI_IOCFC_H2I_CFG_REQ message
  */
 struct bfi_iocfc_cfg_req_s {
@@ -84,7 +84,7 @@ struct bfi_iocfc_cfg_req_s {
 };
 
 
-/**
+/*
  * BFI_IOCFC_I2H_CFG_REPLY message
  */
 struct bfi_iocfc_cfg_reply_s {
@@ -95,7 +95,7 @@ struct bfi_iocfc_cfg_reply_s {
 };
 
 
-/**
+/*
  * BFI_IOCFC_H2I_SET_INTR_REQ message
  */
 struct bfi_iocfc_set_intr_req_s {
@@ -107,7 +107,7 @@ struct bfi_iocfc_set_intr_req_s {
 };
 
 
-/**
+/*
  * BFI_IOCFC_H2I_UPDATEQ_REQ message
  */
 struct bfi_iocfc_updateq_req_s {
@@ -119,7 +119,7 @@ struct bfi_iocfc_updateq_req_s {
 };
 
 
-/**
+/*
  * BFI_IOCFC_I2H_UPDATEQ_RSP message
  */
 struct bfi_iocfc_updateq_rsp_s {
@@ -129,7 +129,7 @@ struct bfi_iocfc_updateq_rsp_s {
 };
 
 
-/**
+/*
  * H2I Messages
  */
 union bfi_iocfc_h2i_msg_u {
@@ -140,7 +140,7 @@ union bfi_iocfc_h2i_msg_u {
 };
 
 
-/**
+/*
  * I2H Messages
  */
 union bfi_iocfc_i2h_msg_u {
@@ -173,7 +173,7 @@ enum bfi_fcport_i2h {
 };
 
 
-/**
+/*
  * Generic REQ type
  */
 struct bfi_fcport_req_s {
@@ -181,7 +181,7 @@ struct bfi_fcport_req_s {
        u32        msgtag;      /*  msgtag for reply                */
 };
 
-/**
+/*
  * Generic RSP type
  */
 struct bfi_fcport_rsp_s {
@@ -191,7 +191,7 @@ struct bfi_fcport_rsp_s {
        u32        msgtag;      /*  msgtag for reply                */
 };
 
-/**
+/*
  * BFI_FCPORT_H2I_ENABLE_REQ
  */
 struct bfi_fcport_enable_req_s {
@@ -205,7 +205,7 @@ struct bfi_fcport_enable_req_s {
        u32        rsvd2;
 };
 
-/**
+/*
  * BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ
  */
 struct bfi_fcport_set_svc_params_req_s {
@@ -214,7 +214,7 @@ struct bfi_fcport_set_svc_params_req_s {
        u16        rsvd;
 };
 
-/**
+/*
  * BFI_FCPORT_I2H_EVENT
  */
 struct bfi_fcport_event_s {
@@ -222,7 +222,7 @@ struct bfi_fcport_event_s {
        struct bfa_port_link_s  link_state;
 };
 
-/**
+/*
  * BFI_FCPORT_I2H_TRUNK_SCN
  */
 struct bfi_fcport_trunk_link_s {
@@ -243,7 +243,7 @@ struct bfi_fcport_trunk_scn_s {
        struct bfi_fcport_trunk_link_s tlink[BFI_FCPORT_MAX_LINKS];
 };
 
-/**
+/*
  * fcport H2I message
  */
 union bfi_fcport_h2i_msg_u {
@@ -255,7 +255,7 @@ union bfi_fcport_h2i_msg_u {
        struct bfi_fcport_req_s                 *pstatsclear;
 };
 
-/**
+/*
  * fcport I2H message
  */
 union bfi_fcport_i2h_msg_u {
@@ -279,7 +279,7 @@ enum bfi_fcxp_i2h {
 
 #define BFA_FCXP_MAX_SGES      2
 
-/**
+/*
  * FCXP send request structure
  */
 struct bfi_fcxp_send_req_s {
@@ -299,7 +299,7 @@ struct bfi_fcxp_send_req_s {
        struct bfi_sge_s   rsp_sge[BFA_FCXP_MAX_SGES];  /*  response buf   */
 };
 
-/**
+/*
  * FCXP send response structure
  */
 struct bfi_fcxp_send_rsp_s {
@@ -565,14 +565,14 @@ enum bfi_ioim_i2h {
        BFI_IOIM_I2H_IOABORT_RSP = BFA_I2HM(2), /*  ABORT rsp    */
 };
 
-/**
+/*
  * IO command DIF info
  */
 struct bfi_ioim_dif_s {
        u32     dif_info[4];
 };
 
-/**
+/*
  * FCP IO messages overview
  *
  * @note
@@ -587,7 +587,7 @@ struct bfi_ioim_req_s {
        u16     rport_hdl;      /*  itnim/rport firmware handle */
        struct fcp_cmnd_s       cmnd;   /*  IO request info     */
 
-       /**
+       /*
         * SG elements array within the IO request must be double word
         * aligned. This aligment is required to optimize SGM setup for the IO.
         */
@@ -598,7 +598,7 @@ struct bfi_ioim_req_s {
        struct bfi_ioim_dif_s  dif;
 };
 
-/**
+/*
  *     This table shows various IO status codes from firmware and their
  *     meaning. Host driver can use these status codes to further process
  *     IO completions.
@@ -684,7 +684,7 @@ enum bfi_ioim_status {
 };
 
 #define BFI_IOIM_SNSLEN        (256)
-/**
+/*
  * I/O response message
  */
 struct bfi_ioim_rsp_s {
@@ -746,7 +746,7 @@ enum bfi_tskim_status {
        BFI_TSKIM_STS_NOT_SUPP = 4,
        BFI_TSKIM_STS_FAILED    = 5,
 
-       /**
+       /*
         * Defined by BFA
         */
        BFI_TSKIM_STS_TIMEOUT  = 10,    /*  TM request timedout */
index 99f2b8c5dd6310420b61df64af22649bcf41b296..8c04fada710b441713f95a1e5bc43fef49728e6e 100644 (file)
@@ -692,6 +692,9 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
                &csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port),
                atid, tid, status, csk, csk->state, csk->flags);
 
+       if (status == CPL_ERR_RTX_NEG_ADVICE)
+               goto rel_skb;
+
        if (status && status != CPL_ERR_TCAM_FULL &&
            status != CPL_ERR_CONN_EXIST &&
            status != CPL_ERR_ARP_MISS)
index b9bcfa4c7d261dd5e1e13725459487d2dfe638f6..5be3ae15cb71b858a7402b06a6c10923facd1edf 100644 (file)
@@ -773,6 +773,8 @@ static const struct scsi_dh_devlist rdac_dev_list[] = {
        {"ENGENIO", "INF-01-00"},
        {"STK", "FLEXLINE 380"},
        {"SUN", "CSM100_R_FC"},
+       {"SUN", "STK6580_6780"},
+       {"SUN", "SUN_6180"},
        {NULL, NULL},
 };
 
index 844d618b84bdd51151c21bdd91dd9d0f9b100455..d23a538a9dfcca1e5bae286fb8305796dd6a8233 100644 (file)
@@ -117,7 +117,7 @@ static void fcoe_recv_frame(struct sk_buff *skb);
 
 static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);
 
-module_param_call(create, fcoe_create, NULL, (void *)FIP_MODE_AUTO, S_IWUSR);
+module_param_call(create, fcoe_create, NULL, (void *)FIP_MODE_FABRIC, S_IWUSR);
 __MODULE_PARM_TYPE(create, "string");
 MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface");
 module_param_call(create_vn2vn, fcoe_create, NULL,
@@ -1243,7 +1243,6 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
        struct fcoe_interface *fcoe;
        struct fc_frame_header *fh;
        struct fcoe_percpu_s *fps;
-       struct fcoe_port *port;
        struct ethhdr *eh;
        unsigned int cpu;
 
@@ -1262,16 +1261,7 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
                        skb_tail_pointer(skb), skb_end_pointer(skb),
                        skb->csum, skb->dev ? skb->dev->name : "<NULL>");
 
-       /* check for mac addresses */
        eh = eth_hdr(skb);
-       port = lport_priv(lport);
-       if (compare_ether_addr(eh->h_dest, port->data_src_addr) &&
-           compare_ether_addr(eh->h_dest, fcoe->ctlr.ctl_src_addr) &&
-           compare_ether_addr(eh->h_dest, (u8[6])FC_FCOE_FLOGI_MAC)) {
-               FCOE_NETDEV_DBG(netdev, "wrong destination mac address:%pM\n",
-                               eh->h_dest);
-               goto err;
-       }
 
        if (is_fip_mode(&fcoe->ctlr) &&
            compare_ether_addr(eh->h_source, fcoe->ctlr.dest_addr)) {
@@ -1291,6 +1281,12 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
        skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
        fh = (struct fc_frame_header *) skb_transport_header(skb);
 
+       if (ntoh24(&eh->h_dest[3]) != ntoh24(fh->fh_d_id)) {
+               FCOE_NETDEV_DBG(netdev, "FC frame d_id mismatch with MAC:%pM\n",
+                               eh->h_dest);
+               goto err;
+       }
+
        fr = fcoe_dev_from_skb(skb);
        fr->fr_dev = lport;
        fr->ptype = ptype;
index aa503d83092a09eb0b69ea1ca76fd227807bd39a..bc17c71232023c7d3b830a541df976de7146a72c 100644 (file)
@@ -2296,7 +2296,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
        struct fip_header *fiph;
        enum fip_vn2vn_subcode sub;
-       union {
+       struct {
                struct fc_rport_priv rdata;
                struct fcoe_rport frport;
        } buf;
index 5a3f93101017b601fe98b2bbf12d9b55fd27152b..841101846b88fe98e55a6c601b013ef9119cdf4a 100644 (file)
@@ -4177,6 +4177,14 @@ static int ioc_general(void __user *arg, char *cmnd)
     ha = gdth_find_ha(gen.ionode);
     if (!ha)
         return -EFAULT;
+
+    if (gen.data_len > INT_MAX)
+        return -EINVAL;
+    if (gen.sense_len > INT_MAX)
+        return -EINVAL;
+    if (gen.data_len + gen.sense_len > INT_MAX)
+        return -EINVAL;
+
     if (gen.data_len + gen.sense_len != 0) {
         if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len,
                                      FALSE, &paddr)))
index df9a12c8b373144618ff051cdb38498648df2df5..fa60d7df44bed7154adf9aa784cecc937db64d23 100644 (file)
@@ -9025,6 +9025,8 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
                PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 0 },
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
                PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 },
+       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2,
+               PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C4, 0, 0, 0 },
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
                PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 },
        { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2,
index aa8bb2f2c6ee286c2fa73c734d37cb8f26573138..b28a00f1082c3e3bbab4e412725030626890652c 100644 (file)
@@ -82,6 +82,7 @@
 
 #define IPR_SUBS_DEV_ID_57B4    0x033B
 #define IPR_SUBS_DEV_ID_57B2    0x035F
+#define IPR_SUBS_DEV_ID_57C4    0x0354
 #define IPR_SUBS_DEV_ID_57C6    0x0357
 #define IPR_SUBS_DEV_ID_57CC    0x035C
 
index 32f67c4b03fc014b8b47935a761a9feb6bdfa59a..911b2736cafae204379b8db7f18767b788d79bc3 100644 (file)
@@ -684,10 +684,9 @@ void fc_disc_stop(struct fc_lport *lport)
 {
        struct fc_disc *disc = &lport->disc;
 
-       if (disc) {
+       if (disc->pending)
                cancel_delayed_work_sync(&disc->disc_work);
-               fc_disc_stop_rports(disc);
-       }
+       fc_disc_stop_rports(disc);
 }
 
 /**
index c797f6b48f05bccff273e06964c0dc06508de174..e340373b509b6528ea0602d410eb902c3b233321 100644 (file)
@@ -58,8 +58,7 @@ struct kmem_cache *scsi_pkt_cachep;
 #define FC_SRB_WRITE           (1 << 0)
 
 /*
- * The SCp.ptr should be tested and set under the host lock. NULL indicates
- * that the command has been retruned to the scsi layer.
+ * The SCp.ptr should be tested and set under the scsi_pkt_queue lock
  */
 #define CMD_SP(Cmnd)               ((struct fc_fcp_pkt *)(Cmnd)->SCp.ptr)
 #define CMD_ENTRY_STATUS(Cmnd)     ((Cmnd)->SCp.have_data_in)
@@ -1880,8 +1879,6 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
 
        lport = fsp->lp;
        si = fc_get_scsi_internal(lport);
-       if (!fsp->cmd)
-               return;
 
        /*
         * if can_queue ramp down is done then try can_queue ramp up
@@ -1891,11 +1888,6 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
                fc_fcp_can_queue_ramp_up(lport);
 
        sc_cmd = fsp->cmd;
-       fsp->cmd = NULL;
-
-       if (!sc_cmd->SCp.ptr)
-               return;
-
        CMD_SCSI_STATUS(sc_cmd) = fsp->cdb_status;
        switch (fsp->status_code) {
        case FC_COMPLETE:
@@ -1971,15 +1963,13 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
                break;
        }
 
-       if (lport->state != LPORT_ST_READY && fsp->status_code != FC_COMPLETE) {
-               sc_cmd->result = (DID_REQUEUE << 16);
-               FC_FCP_DBG(fsp, "Returning DID_REQUEUE to scsi-ml\n");
-       }
+       if (lport->state != LPORT_ST_READY && fsp->status_code != FC_COMPLETE)
+               sc_cmd->result = (DID_TRANSPORT_DISRUPTED << 16);
 
        spin_lock_irqsave(&si->scsi_queue_lock, flags);
        list_del(&fsp->list);
-       spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
        sc_cmd->SCp.ptr = NULL;
+       spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
        sc_cmd->scsi_done(sc_cmd);
 
        /* release ref from initial allocation in queue command */
@@ -1997,6 +1987,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
 {
        struct fc_fcp_pkt *fsp;
        struct fc_lport *lport;
+       struct fc_fcp_internal *si;
        int rc = FAILED;
        unsigned long flags;
 
@@ -2006,7 +1997,8 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
        else if (!lport->link_up)
                return rc;
 
-       spin_lock_irqsave(lport->host->host_lock, flags);
+       si = fc_get_scsi_internal(lport);
+       spin_lock_irqsave(&si->scsi_queue_lock, flags);
        fsp = CMD_SP(sc_cmd);
        if (!fsp) {
                /* command completed while scsi eh was setting up */
@@ -2015,7 +2007,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
        }
        /* grab a ref so the fsp and sc_cmd cannot be relased from under us */
        fc_fcp_pkt_hold(fsp);
-       spin_unlock_irqrestore(lport->host->host_lock, flags);
+       spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
 
        if (fc_fcp_lock_pkt(fsp)) {
                /* completed while we were waiting for timer to be deleted */
index d9b6e11b0e884b122cfe4d7b6fc2888e5e6c507d..9be63edbf8fb9095624222f7dc6398957e0abd28 100644 (file)
@@ -1447,13 +1447,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
        }
 
        did = fc_frame_did(fp);
-
-       if (!did) {
-               FC_LPORT_DBG(lport, "Bad FLOGI response\n");
-               goto out;
-       }
-
-       if (fc_frame_payload_op(fp) == ELS_LS_ACC) {
+       if (fc_frame_payload_op(fp) == ELS_LS_ACC && did) {
                flp = fc_frame_payload_get(fp, sizeof(*flp));
                if (flp) {
                        mfs = ntohs(flp->fl_csp.sp_bb_data) &
@@ -1492,8 +1486,10 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
                                fc_lport_enter_dns(lport);
                        }
                }
-       } else
+       } else {
+               FC_LPORT_DBG(lport, "FLOGI RJT or bad response\n");
                fc_lport_error(lport, fp);
+       }
 
 out:
        fc_frame_free(fp);
index b9f2286fe0cbc9ef849cb8e2a713d9d0b11776f7..a84ef13ed74adf2a0e0d1dd81c644b2f3c9514a7 100644 (file)
@@ -196,9 +196,9 @@ static const char *fc_rport_state(struct fc_rport_priv *rdata)
 void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
 {
        if (timeout)
-               rport->dev_loss_tmo = timeout + 5;
+               rport->dev_loss_tmo = timeout;
        else
-               rport->dev_loss_tmo = 30;
+               rport->dev_loss_tmo = 1;
 }
 EXPORT_SYMBOL(fc_set_rport_loss_tmo);
 
index a50aa03b8ac1826c13d8acb22b6bb613c91e024e..196de40b906c487c0287b56ac3c27c5f4b66a5ee 100644 (file)
@@ -202,9 +202,12 @@ struct lpfc_stats {
        uint32_t elsRcvPRLO;
        uint32_t elsRcvPRLI;
        uint32_t elsRcvLIRR;
+       uint32_t elsRcvRLS;
        uint32_t elsRcvRPS;
        uint32_t elsRcvRPL;
        uint32_t elsRcvRRQ;
+       uint32_t elsRcvRTV;
+       uint32_t elsRcvECHO;
        uint32_t elsXmitFLOGI;
        uint32_t elsXmitFDISC;
        uint32_t elsXmitPLOGI;
@@ -549,9 +552,11 @@ struct lpfc_hba {
 #define ELS_XRI_ABORT_EVENT    0x40
 #define ASYNC_EVENT            0x80
 #define LINK_DISABLED          0x100 /* Link disabled by user */
-#define FCF_DISC_INPROGRESS    0x200 /* FCF discovery in progress */
-#define HBA_FIP_SUPPORT                0x400 /* FIP support in HBA */
-#define HBA_AER_ENABLED                0x800 /* AER enabled with HBA */
+#define FCF_TS_INPROG           0x200 /* FCF table scan in progress */
+#define FCF_RR_INPROG           0x400 /* FCF roundrobin flogi in progress */
+#define HBA_FIP_SUPPORT                0x800 /* FIP support in HBA */
+#define HBA_AER_ENABLED                0x1000 /* AER enabled with HBA */
+#define HBA_DEVLOSS_TMO         0x2000 /* HBA in devloss timeout */
        uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
        struct lpfc_dmabuf slim2p;
 
@@ -573,6 +578,7 @@ struct lpfc_hba {
        /* These fields used to be binfo */
        uint32_t fc_pref_DID;   /* preferred D_ID */
        uint8_t  fc_pref_ALPA;  /* preferred AL_PA */
+       uint32_t fc_edtovResol; /* E_D_TOV timer resolution */
        uint32_t fc_edtov;      /* E_D_TOV timer value */
        uint32_t fc_arbtov;     /* ARB_TOV timer value */
        uint32_t fc_ratov;      /* R_A_TOV timer value */
index f681eea57730a794fccaf792243b8a4791abcee3..c1cbec01345d0849a027748cdad9425e72094356 100644 (file)
@@ -3789,8 +3789,13 @@ sysfs_mbox_read(struct file *filp, struct kobject *kobj,
                        break;
                case MBX_SECURITY_MGMT:
                case MBX_AUTH_PORT:
-                       if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
+                       if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) {
+                               printk(KERN_WARNING "mbox_read:Command 0x%x "
+                                      "is not permitted\n", pmb->mbxCommand);
+                               sysfs_mbox_idle(phba);
+                               spin_unlock_irq(&phba->hbalock);
                                return -EPERM;
+                       }
                        break;
                case MBX_READ_SPARM64:
                case MBX_READ_LA:
index f5d60b55f53a37d5d8e6b2a12b9fb8107771c131..7260c3af555a0723924553fb362cb88aee742cd5 100644 (file)
@@ -3142,12 +3142,12 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
        job = menlo->set_job;
        job->dd_data = NULL; /* so timeout handler does not reply */
 
-       spin_lock_irqsave(&phba->hbalock, flags);
+       spin_lock(&phba->hbalock);
        cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
        if (cmdiocbq->context2 && rspiocbq)
                memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
                       &rspiocbq->iocb, sizeof(IOCB_t));
-       spin_unlock_irqrestore(&phba->hbalock, flags);
+       spin_unlock(&phba->hbalock);
 
        bmp = menlo->bmp;
        rspiocbq = menlo->rspiocbq;
index 03f4ddc185723f94520e112df291cc266b8c45d3..a5f5a093a8a46752e5c802da8a593de4510e7e6e 100644 (file)
@@ -44,6 +44,8 @@ int lpfc_reg_rpi(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *,
 void lpfc_set_var(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
 void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
 void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
+void lpfc_sli4_unreg_all_rpis(struct lpfc_vport *);
+
 void lpfc_reg_vpi(struct lpfc_vport *, LPFC_MBOXQ_t *);
 void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *,
                        struct lpfc_nodelist *);
@@ -229,6 +231,7 @@ void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *);
 uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *);
 int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t);
 void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t);
+int lpfc_sli4_fcf_rr_next_proc(struct lpfc_vport *, uint16_t);
 
 int lpfc_mem_alloc(struct lpfc_hba *, int align);
 void lpfc_mem_free(struct lpfc_hba *);
@@ -271,6 +274,7 @@ int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,
 void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t);
 void lpfc_sli_bemem_bcopy(void *, void *, uint32_t);
 void lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *);
+void lpfc_sli_hba_iocb_abort(struct lpfc_hba *);
 void lpfc_sli_flush_fcp_rings(struct lpfc_hba *);
 int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *,
                             struct lpfc_dmabuf *);
index e6ca12f6c6cb5063857f30f7b3e01b6e5587f14d..884f4d321799cffda5bb5ea56295d4166fb0b32c 100644 (file)
@@ -177,15 +177,18 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
                 (elscmd == ELS_CMD_LOGO)))
                switch (elscmd) {
                case ELS_CMD_FLOGI:
-               elsiocb->iocb_flag |= ((ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
+               elsiocb->iocb_flag |=
+                       ((LPFC_ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
                                        & LPFC_FIP_ELS_ID_MASK);
                break;
                case ELS_CMD_FDISC:
-               elsiocb->iocb_flag |= ((ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
+               elsiocb->iocb_flag |=
+                       ((LPFC_ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
                                        & LPFC_FIP_ELS_ID_MASK);
                break;
                case ELS_CMD_LOGO:
-               elsiocb->iocb_flag |= ((ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
+               elsiocb->iocb_flag |=
+                       ((LPFC_ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
                                        & LPFC_FIP_ELS_ID_MASK);
                break;
                }
@@ -517,18 +520,13 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        if (sp->cmn.edtovResolution)    /* E_D_TOV ticks are in nanoseconds */
                phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000;
 
+       phba->fc_edtovResol = sp->cmn.edtovResolution;
        phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
 
        if (phba->fc_topology == TOPOLOGY_LOOP) {
                spin_lock_irq(shost->host_lock);
                vport->fc_flag |= FC_PUBLIC_LOOP;
                spin_unlock_irq(shost->host_lock);
-       } else {
-               /*
-                * If we are a N-port connected to a Fabric, fixup sparam's so
-                * logins to devices on remote loops work.
-                */
-               vport->fc_sparam.cmn.altBbCredit = 1;
        }
 
        vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
@@ -585,6 +583,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                        lpfc_unreg_rpi(vport, np);
                }
                lpfc_cleanup_pending_mbox(vport);
+
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       lpfc_sli4_unreg_all_rpis(vport);
+
                if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
                        lpfc_mbx_unreg_vpi(vport);
                        spin_lock_irq(shost->host_lock);
@@ -800,7 +802,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 
        if (irsp->ulpStatus) {
                /*
-                * In case of FIP mode, perform round robin FCF failover
+                * In case of FIP mode, perform roundrobin FCF failover
                 * due to new FCF discovery
                 */
                if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
@@ -808,48 +810,16 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                    (irsp->ulpStatus != IOSTAT_LOCAL_REJECT) &&
                    (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED)) {
                        lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
-                                       "2611 FLOGI failed on registered "
-                                       "FCF record fcf_index(%d), status: "
-                                       "x%x/x%x, tmo:x%x, trying to perform "
-                                       "round robin failover\n",
+                                       "2611 FLOGI failed on FCF (x%x), "
+                                       "status:x%x/x%x, tmo:x%x, perform "
+                                       "roundrobin FCF failover\n",
                                        phba->fcf.current_rec.fcf_indx,
                                        irsp->ulpStatus, irsp->un.ulpWord[4],
                                        irsp->ulpTimeout);
                        fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
-                       if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) {
-                               /*
-                                * Exhausted the eligible FCF record list,
-                                * fail through to retry FLOGI on current
-                                * FCF record.
-                                */
-                               lpfc_printf_log(phba, KERN_WARNING,
-                                               LOG_FIP | LOG_ELS,
-                                               "2760 Completed one round "
-                                               "of FLOGI FCF round robin "
-                                               "failover list, retry FLOGI "
-                                               "on currently registered "
-                                               "FCF index:%d\n",
-                                               phba->fcf.current_rec.fcf_indx);
-                       } else {
-                               lpfc_printf_log(phba, KERN_INFO,
-                                               LOG_FIP | LOG_ELS,
-                                               "2794 FLOGI FCF round robin "
-                                               "failover to FCF index x%x\n",
-                                               fcf_index);
-                               rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
-                                                                  fcf_index);
-                               if (rc)
-                                       lpfc_printf_log(phba, KERN_WARNING,
-                                                       LOG_FIP | LOG_ELS,
-                                                       "2761 FLOGI round "
-                                                       "robin FCF failover "
-                                                       "read FCF failed "
-                                                       "rc:x%x, fcf_index:"
-                                                       "%d\n", rc,
-                                               phba->fcf.current_rec.fcf_indx);
-                               else
-                                       goto out;
-                       }
+                       rc = lpfc_sli4_fcf_rr_next_proc(vport, fcf_index);
+                       if (rc)
+                               goto out;
                }
 
                /* FLOGI failure */
@@ -939,6 +909,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        lpfc_nlp_put(ndlp);
                        spin_lock_irq(&phba->hbalock);
                        phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+                       phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
                        spin_unlock_irq(&phba->hbalock);
                        goto out;
                }
@@ -947,13 +918,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        if (phba->hba_flag & HBA_FIP_SUPPORT)
                                lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP |
                                                LOG_ELS,
-                                               "2769 FLOGI successful on FCF "
-                                               "record: current_fcf_index:"
-                                               "x%x, terminate FCF round "
-                                               "robin failover process\n",
+                                               "2769 FLOGI to FCF (x%x) "
+                                               "completed successfully\n",
                                                phba->fcf.current_rec.fcf_indx);
                        spin_lock_irq(&phba->hbalock);
                        phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+                       phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
                        spin_unlock_irq(&phba->hbalock);
                        goto out;
                }
@@ -1175,12 +1145,13 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
                        return 0;
        }
 
-       if (lpfc_issue_els_flogi(vport, ndlp, 0))
+       if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
                /* This decrement of reference count to node shall kick off
                 * the release of the node.
                 */
                lpfc_nlp_put(ndlp);
-
+               return 0;
+       }
        return 1;
 }
 
@@ -1645,6 +1616,13 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
        memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
        sp = (struct serv_parm *) pcmd;
 
+       /*
+        * If we are a N-port connected to a Fabric, fix-up paramm's so logins
+        * to device on remote loops work.
+        */
+       if ((vport->fc_flag & FC_FABRIC) && !(vport->fc_flag & FC_PUBLIC_LOOP))
+               sp->cmn.altBbCredit = 1;
+
        if (sp->cmn.fcphLow < FC_PH_4_3)
                sp->cmn.fcphLow = FC_PH_4_3;
 
@@ -3925,6 +3903,64 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
        return 0;
 }
 
+/**
+ * lpfc_els_rsp_echo_acc - Issue echo acc response
+ * @vport: pointer to a virtual N_Port data structure.
+ * @data: pointer to echo data to return in the accept.
+ * @oldiocb: pointer to the original lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * Return code
+ *   0 - Successfully issued acc echo response
+ *   1 - Failed to issue acc echo response
+ **/
+static int
+lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
+                     struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
+{
+       struct lpfc_hba  *phba = vport->phba;
+       struct lpfc_iocbq *elsiocb;
+       struct lpfc_sli *psli;
+       uint8_t *pcmd;
+       uint16_t cmdsize;
+       int rc;
+
+       psli = &phba->sli;
+       cmdsize = oldiocb->iocb.unsli3.rcvsli3.acc_len;
+
+       elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
+                                    ndlp->nlp_DID, ELS_CMD_ACC);
+       if (!elsiocb)
+               return 1;
+
+       elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext;    /* Xri */
+       /* Xmit ECHO ACC response tag <ulpIoTag> */
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                        "2876 Xmit ECHO ACC response tag x%x xri x%x\n",
+                        elsiocb->iotag, elsiocb->iocb.ulpContext);
+       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+       *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
+       pcmd += sizeof(uint32_t);
+       memcpy(pcmd, data, cmdsize - sizeof(uint32_t));
+
+       lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
+               "Issue ACC ECHO:  did:x%x flg:x%x",
+               ndlp->nlp_DID, ndlp->nlp_flag, 0);
+
+       phba->fc_stat.elsXmitACC++;
+       elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
+       lpfc_nlp_put(ndlp);
+       elsiocb->context1 = NULL;  /* Don't need ndlp for cmpl,
+                                   * it could be freed */
+
+       rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
+       if (rc == IOCB_ERROR) {
+               lpfc_els_free_iocb(phba, elsiocb);
+               return 1;
+       }
+       return 0;
+}
+
 /**
  * lpfc_els_disc_adisc - Issue remaining adisc iocbs to npr nodes of a vport
  * @vport: pointer to a host virtual N_Port data structure.
@@ -4683,6 +4719,30 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        return 0;
 }
 
+/**
+ * lpfc_els_rcv_echo - Process an unsolicited echo iocb
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * Return code
+ *   0 - Successfully processed echo iocb (currently always return 0)
+ **/
+static int
+lpfc_els_rcv_echo(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+                 struct lpfc_nodelist *ndlp)
+{
+       uint8_t *pcmd;
+
+       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
+
+       /* skip over first word of echo command to find echo data */
+       pcmd += sizeof(uint32_t);
+
+       lpfc_els_rsp_echo_acc(vport, pcmd, cmdiocb, ndlp);
+       return 0;
+}
+
 /**
  * lpfc_els_rcv_lirr - Process an unsolicited lirr iocb
  * @vport: pointer to a host virtual N_Port data structure.
@@ -4734,6 +4794,89 @@ lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
 }
 
+/**
+ * lpfc_els_rsp_rls_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * This routine is the completion callback function for the MBX_READ_LNK_STAT
+ * mailbox command. This callback function is to actually send the Accept
+ * (ACC) response to a Read Port Status (RPS) unsolicited IOCB event. It
+ * collects the link statistics from the completion of the MBX_READ_LNK_STAT
+ * mailbox command, constructs the RPS response with the link statistics
+ * collected, and then invokes the lpfc_sli_issue_iocb() routine to send ACC
+ * response to the RPS.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the RPS Accept Response ELS IOCB command.
+ *
+ **/
+static void
+lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+{
+       MAILBOX_t *mb;
+       IOCB_t *icmd;
+       struct RLS_RSP *rls_rsp;
+       uint8_t *pcmd;
+       struct lpfc_iocbq *elsiocb;
+       struct lpfc_nodelist *ndlp;
+       uint16_t xri;
+       uint32_t cmdsize;
+
+       mb = &pmb->u.mb;
+
+       ndlp = (struct lpfc_nodelist *) pmb->context2;
+       xri = (uint16_t) ((unsigned long)(pmb->context1));
+       pmb->context1 = NULL;
+       pmb->context2 = NULL;
+
+       if (mb->mbxStatus) {
+               mempool_free(pmb, phba->mbox_mem_pool);
+               return;
+       }
+
+       cmdsize = sizeof(struct RLS_RSP) + sizeof(uint32_t);
+       mempool_free(pmb, phba->mbox_mem_pool);
+       elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
+                                    lpfc_max_els_tries, ndlp,
+                                    ndlp->nlp_DID, ELS_CMD_ACC);
+
+       /* Decrement the ndlp reference count from previous mbox command */
+       lpfc_nlp_put(ndlp);
+
+       if (!elsiocb)
+               return;
+
+       icmd = &elsiocb->iocb;
+       icmd->ulpContext = xri;
+
+       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+       *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
+       pcmd += sizeof(uint32_t); /* Skip past command */
+       rls_rsp = (struct RLS_RSP *)pcmd;
+
+       rls_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt);
+       rls_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt);
+       rls_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt);
+       rls_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt);
+       rls_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord);
+       rls_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt);
+
+       /* Xmit ELS RLS ACC response tag <ulpIoTag> */
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
+                        "2874 Xmit ELS RLS ACC response tag x%x xri x%x, "
+                        "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
+                        elsiocb->iotag, elsiocb->iocb.ulpContext,
+                        ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+                        ndlp->nlp_rpi);
+       elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
+       phba->fc_stat.elsXmitACC++;
+       if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
+               lpfc_els_free_iocb(phba, elsiocb);
+}
+
 /**
  * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
  * @phba: pointer to lpfc hba data structure.
@@ -4827,7 +4970,155 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 }
 
 /**
- * lpfc_els_rcv_rps - Process an unsolicited rps iocb
+ * lpfc_els_rcv_rls - Process an unsolicited rls iocb
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes Read Port Status (RPL) IOCB received as an
+ * ELS unsolicited event. It first checks the remote port state. If the
+ * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
+ * state, it invokes the lpfc_els_rsl_reject() routine to send the reject
+ * response. Otherwise, it issue the MBX_READ_LNK_STAT mailbox command
+ * for reading the HBA link statistics. It is for the callback function,
+ * lpfc_els_rsp_rls_acc(), set to the MBX_READ_LNK_STAT mailbox command
+ * to actually sending out RPL Accept (ACC) response.
+ *
+ * Return codes
+ *   0 - Successfully processed rls iocb (currently always return 0)
+ **/
+static int
+lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+                struct lpfc_nodelist *ndlp)
+{
+       struct lpfc_hba *phba = vport->phba;
+       LPFC_MBOXQ_t *mbox;
+       struct lpfc_dmabuf *pcmd;
+       struct ls_rjt stat;
+
+       if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
+           (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
+               /* reject the unsolicited RPS request and done with it */
+               goto reject_out;
+
+       pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
+
+       mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
+       if (mbox) {
+               lpfc_read_lnk_stat(phba, mbox);
+               mbox->context1 =
+                   (void *)((unsigned long) cmdiocb->iocb.ulpContext);
+               mbox->context2 = lpfc_nlp_get(ndlp);
+               mbox->vport = vport;
+               mbox->mbox_cmpl = lpfc_els_rsp_rls_acc;
+               if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
+                       != MBX_NOT_FINISHED)
+                       /* Mbox completion will send ELS Response */
+                       return 0;
+               /* Decrement reference count used for the failed mbox
+                * command.
+                */
+               lpfc_nlp_put(ndlp);
+               mempool_free(mbox, phba->mbox_mem_pool);
+       }
+reject_out:
+       /* issue rejection response */
+       stat.un.b.lsRjtRsvd0 = 0;
+       stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
+       stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
+       stat.un.b.vendorUnique = 0;
+       lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
+       return 0;
+}
+
+/**
+ * lpfc_els_rcv_rtv - Process an unsolicited rtv iocb
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes Read Timout Value (RTV) IOCB received as an
+ * ELS unsolicited event. It first checks the remote port state. If the
+ * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
+ * state, it invokes the lpfc_els_rsl_reject() routine to send the reject
+ * response. Otherwise, it sends the Accept(ACC) response to a Read Timeout
+ * Value (RTV) unsolicited IOCB event.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the RPS Accept Response ELS IOCB command.
+ *
+ * Return codes
+ *   0 - Successfully processed rtv iocb (currently always return 0)
+ **/
+static int
+lpfc_els_rcv_rtv(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
+                struct lpfc_nodelist *ndlp)
+{
+       struct lpfc_hba *phba = vport->phba;
+       struct ls_rjt stat;
+       struct RTV_RSP *rtv_rsp;
+       uint8_t *pcmd;
+       struct lpfc_iocbq *elsiocb;
+       uint32_t cmdsize;
+
+
+       if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
+           (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
+               /* reject the unsolicited RPS request and done with it */
+               goto reject_out;
+
+       cmdsize = sizeof(struct RTV_RSP) + sizeof(uint32_t);
+       elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
+                                    lpfc_max_els_tries, ndlp,
+                                    ndlp->nlp_DID, ELS_CMD_ACC);
+
+       if (!elsiocb)
+               return 1;
+
+       pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
+               *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
+       pcmd += sizeof(uint32_t); /* Skip past command */
+
+       /* use the command's xri in the response */
+       elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext;
+
+       rtv_rsp = (struct RTV_RSP *)pcmd;
+
+       /* populate RTV payload */
+       rtv_rsp->ratov = cpu_to_be32(phba->fc_ratov * 1000); /* report msecs */
+       rtv_rsp->edtov = cpu_to_be32(phba->fc_edtov);
+       bf_set(qtov_edtovres, rtv_rsp, phba->fc_edtovResol ? 1 : 0);
+       bf_set(qtov_rttov, rtv_rsp, 0); /* Field is for FC ONLY */
+       rtv_rsp->qtov = cpu_to_be32(rtv_rsp->qtov);
+
+       /* Xmit ELS RLS ACC response tag <ulpIoTag> */
+       lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
+                        "2875 Xmit ELS RTV ACC response tag x%x xri x%x, "
+                        "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x, "
+                        "Data: x%x x%x x%x\n",
+                        elsiocb->iotag, elsiocb->iocb.ulpContext,
+                        ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+                        ndlp->nlp_rpi,
+                       rtv_rsp->ratov, rtv_rsp->edtov, rtv_rsp->qtov);
+       elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
+       phba->fc_stat.elsXmitACC++;
+       if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
+               lpfc_els_free_iocb(phba, elsiocb);
+       return 0;
+
+reject_out:
+       /* issue rejection response */
+       stat.un.b.lsRjtRsvd0 = 0;
+       stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
+       stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
+       stat.un.b.vendorUnique = 0;
+       lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
+       return 0;
+}
+
+/* lpfc_els_rcv_rps - Process an unsolicited rps iocb
  * @vport: pointer to a host virtual N_Port data structure.
  * @cmdiocb: pointer to lpfc command iocb data structure.
  * @ndlp: pointer to a node-list data structure.
@@ -5017,7 +5308,6 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
        lp = (uint32_t *) pcmd->virt;
        rpl = (RPL *) (lp + 1);
-
        maxsize = be32_to_cpu(rpl->maxsize);
 
        /* We support only one port */
@@ -5836,6 +6126,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                if (newnode)
                        lpfc_nlp_put(ndlp);
                break;
+       case ELS_CMD_RLS:
+               lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
+                       "RCV RLS:         did:x%x/ste:x%x flg:x%x",
+                       did, vport->port_state, ndlp->nlp_flag);
+
+               phba->fc_stat.elsRcvRLS++;
+               lpfc_els_rcv_rls(vport, elsiocb, ndlp);
+               if (newnode)
+                       lpfc_nlp_put(ndlp);
+               break;
        case ELS_CMD_RPS:
                lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
                        "RCV RPS:         did:x%x/ste:x%x flg:x%x",
@@ -5866,6 +6166,15 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                if (newnode)
                        lpfc_nlp_put(ndlp);
                break;
+       case ELS_CMD_RTV:
+               lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
+                       "RCV RTV:        did:x%x/ste:x%x flg:x%x",
+                       did, vport->port_state, ndlp->nlp_flag);
+               phba->fc_stat.elsRcvRTV++;
+               lpfc_els_rcv_rtv(vport, elsiocb, ndlp);
+               if (newnode)
+                       lpfc_nlp_put(ndlp);
+               break;
        case ELS_CMD_RRQ:
                lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
                        "RCV RRQ:         did:x%x/ste:x%x flg:x%x",
@@ -5876,6 +6185,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                if (newnode)
                        lpfc_nlp_put(ndlp);
                break;
+       case ELS_CMD_ECHO:
+               lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
+                       "RCV ECHO:        did:x%x/ste:x%x flg:x%x",
+                       did, vport->port_state, ndlp->nlp_flag);
+
+               phba->fc_stat.elsRcvECHO++;
+               lpfc_els_rcv_echo(vport, elsiocb, ndlp);
+               if (newnode)
+                       lpfc_nlp_put(ndlp);
+               break;
        default:
                lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
                        "RCV ELS cmd:     cmd:x%x did:x%x/ste:x%x",
@@ -6170,6 +6489,8 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 
                default:
                        /* Try to recover from this error */
+                       if (phba->sli_rev == LPFC_SLI_REV4)
+                               lpfc_sli4_unreg_all_rpis(vport);
                        lpfc_mbx_unreg_vpi(vport);
                        spin_lock_irq(shost->host_lock);
                        vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
@@ -6437,6 +6758,10 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        lpfc_unreg_rpi(vport, np);
                }
                lpfc_cleanup_pending_mbox(vport);
+
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       lpfc_sli4_unreg_all_rpis(vport);
+
                lpfc_mbx_unreg_vpi(vport);
                spin_lock_irq(shost->host_lock);
                vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
@@ -6452,7 +6777,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                 * to update the MAC address.
                 */
                lpfc_register_new_vport(phba, vport, ndlp);
-               return ;
+               goto out;
        }
 
        if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI)
index a345dde16c86fcf74b121b38d2e505102b3ee698..a5d1695dac3dcd73b1e5cae6651c46c602d57d20 100644 (file)
@@ -20,6 +20,7 @@
  *******************************************************************/
 
 #include <linux/blkdev.h>
+#include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/kthread.h>
@@ -63,6 +64,7 @@ static uint8_t lpfcAlpaArray[] = {
 static void lpfc_disc_timeout_handler(struct lpfc_vport *);
 static void lpfc_disc_flush_list(struct lpfc_vport *vport);
 static void lpfc_unregister_fcfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
+static int lpfc_fcf_inuse(struct lpfc_hba *);
 
 void
 lpfc_terminate_rport_io(struct fc_rport *rport)
@@ -160,11 +162,17 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
        return;
 }
 
-/*
- * This function is called from the worker thread when dev_loss_tmo
- * expire.
- */
-static void
+/**
+ * lpfc_dev_loss_tmo_handler - Remote node devloss timeout handler
+ * @ndlp: Pointer to remote node object.
+ *
+ * This function is called from the worker thread when devloss timeout timer
+ * expires. For SLI4 host, this routine shall return 1 when at lease one
+ * remote node, including this @ndlp, is still in use of FCF; otherwise, this
+ * routine shall return 0 when there is no remote node is still in use of FCF
+ * when devloss timeout happened to this @ndlp.
+ **/
+static int
 lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
 {
        struct lpfc_rport_data *rdata;
@@ -175,17 +183,21 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
        int  put_node;
        int  put_rport;
        int warn_on = 0;
+       int fcf_inuse = 0;
 
        rport = ndlp->rport;
 
        if (!rport)
-               return;
+               return fcf_inuse;
 
        rdata = rport->dd_data;
        name = (uint8_t *) &ndlp->nlp_portname;
        vport = ndlp->vport;
        phba  = vport->phba;
 
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               fcf_inuse = lpfc_fcf_inuse(phba);
+
        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
                "rport devlosstmo:did:x%x type:x%x id:x%x",
                ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id);
@@ -209,7 +221,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
                        lpfc_nlp_put(ndlp);
                if (put_rport)
                        put_device(&rport->dev);
-               return;
+               return fcf_inuse;
        }
 
        if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
@@ -220,7 +232,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
                                 *name, *(name+1), *(name+2), *(name+3),
                                 *(name+4), *(name+5), *(name+6), *(name+7),
                                 ndlp->nlp_DID);
-               return;
+               return fcf_inuse;
        }
 
        if (ndlp->nlp_type & NLP_FABRIC) {
@@ -233,7 +245,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
                        lpfc_nlp_put(ndlp);
                if (put_rport)
                        put_device(&rport->dev);
-               return;
+               return fcf_inuse;
        }
 
        if (ndlp->nlp_sid != NLP_NO_SID) {
@@ -280,6 +292,74 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
            (ndlp->nlp_state != NLP_STE_PRLI_ISSUE))
                lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
 
+       return fcf_inuse;
+}
+
+/**
+ * lpfc_sli4_post_dev_loss_tmo_handler - SLI4 post devloss timeout handler
+ * @phba: Pointer to hba context object.
+ * @fcf_inuse: SLI4 FCF in-use state reported from devloss timeout handler.
+ * @nlp_did: remote node identifer with devloss timeout.
+ *
+ * This function is called from the worker thread after invoking devloss
+ * timeout handler and releasing the reference count for the ndlp with
+ * which the devloss timeout was handled for SLI4 host. For the devloss
+ * timeout of the last remote node which had been in use of FCF, when this
+ * routine is invoked, it shall be guaranteed that none of the remote are
+ * in-use of FCF. When devloss timeout to the last remote using the FCF,
+ * if the FIP engine is neither in FCF table scan process nor roundrobin
+ * failover process, the in-use FCF shall be unregistered. If the FIP
+ * engine is in FCF discovery process, the devloss timeout state shall
+ * be set for either the FCF table scan process or roundrobin failover
+ * process to unregister the in-use FCF.
+ **/
+static void
+lpfc_sli4_post_dev_loss_tmo_handler(struct lpfc_hba *phba, int fcf_inuse,
+                                   uint32_t nlp_did)
+{
+       /* If devloss timeout happened to a remote node when FCF had no
+        * longer been in-use, do nothing.
+        */
+       if (!fcf_inuse)
+               return;
+
+       if ((phba->hba_flag & HBA_FIP_SUPPORT) && !lpfc_fcf_inuse(phba)) {
+               spin_lock_irq(&phba->hbalock);
+               if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
+                       if (phba->hba_flag & HBA_DEVLOSS_TMO) {
+                               spin_unlock_irq(&phba->hbalock);
+                               return;
+                       }
+                       phba->hba_flag |= HBA_DEVLOSS_TMO;
+                       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                                       "2847 Last remote node (x%x) using "
+                                       "FCF devloss tmo\n", nlp_did);
+               }
+               if (phba->fcf.fcf_flag & FCF_REDISC_PROG) {
+                       spin_unlock_irq(&phba->hbalock);
+                       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                                       "2868 Devloss tmo to FCF rediscovery "
+                                       "in progress\n");
+                       return;
+               }
+               if (!(phba->hba_flag & (FCF_TS_INPROG | FCF_RR_INPROG))) {
+                       spin_unlock_irq(&phba->hbalock);
+                       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                                       "2869 Devloss tmo to idle FIP engine, "
+                                       "unreg in-use FCF and rescan.\n");
+                       /* Unregister in-use FCF and rescan */
+                       lpfc_unregister_fcf_rescan(phba);
+                       return;
+               }
+               spin_unlock_irq(&phba->hbalock);
+               if (phba->hba_flag & FCF_TS_INPROG)
+                       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                                       "2870 FCF table scan in progress\n");
+               if (phba->hba_flag & FCF_RR_INPROG)
+                       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                                       "2871 FLOGI roundrobin FCF failover "
+                                       "in progress\n");
+       }
        lpfc_unregister_unused_fcf(phba);
 }
 
@@ -408,6 +488,8 @@ lpfc_work_list_done(struct lpfc_hba *phba)
        struct lpfc_work_evt  *evtp = NULL;
        struct lpfc_nodelist  *ndlp;
        int free_evt;
+       int fcf_inuse;
+       uint32_t nlp_did;
 
        spin_lock_irq(&phba->hbalock);
        while (!list_empty(&phba->work_list)) {
@@ -427,12 +509,17 @@ lpfc_work_list_done(struct lpfc_hba *phba)
                        break;
                case LPFC_EVT_DEV_LOSS:
                        ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
-                       lpfc_dev_loss_tmo_handler(ndlp);
+                       fcf_inuse = lpfc_dev_loss_tmo_handler(ndlp);
                        free_evt = 0;
                        /* decrement the node reference count held for
                         * this queued work
                         */
+                       nlp_did = ndlp->nlp_DID;
                        lpfc_nlp_put(ndlp);
+                       if (phba->sli_rev == LPFC_SLI_REV4)
+                               lpfc_sli4_post_dev_loss_tmo_handler(phba,
+                                                                   fcf_inuse,
+                                                                   nlp_did);
                        break;
                case LPFC_EVT_ONLINE:
                        if (phba->link_state < LPFC_LINK_DOWN)
@@ -707,6 +794,8 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
                                             : NLP_EVT_DEVICE_RECOVERY);
        }
        if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) {
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       lpfc_sli4_unreg_all_rpis(vport);
                lpfc_mbx_unreg_vpi(vport);
                spin_lock_irq(shost->host_lock);
                vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
@@ -1021,8 +1110,7 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                         "2017 REG_FCFI mbxStatus error x%x "
                         "HBA state x%x\n",
                         mboxq->u.mb.mbxStatus, vport->port_state);
-               mempool_free(mboxq, phba->mbox_mem_pool);
-               return;
+               goto fail_out;
        }
 
        /* Start FCoE discovery by sending a FLOGI. */
@@ -1031,20 +1119,30 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
        spin_lock_irq(&phba->hbalock);
        phba->fcf.fcf_flag |= FCF_REGISTERED;
        spin_unlock_irq(&phba->hbalock);
+
        /* If there is a pending FCoE event, restart FCF table scan. */
-       if (lpfc_check_pending_fcoe_event(phba, 1)) {
-               mempool_free(mboxq, phba->mbox_mem_pool);
-               return;
-       }
+       if (lpfc_check_pending_fcoe_event(phba, LPFC_UNREG_FCF))
+               goto fail_out;
+
+       /* Mark successful completion of FCF table scan */
        spin_lock_irq(&phba->hbalock);
        phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE);
-       phba->hba_flag &= ~FCF_DISC_INPROGRESS;
-       spin_unlock_irq(&phba->hbalock);
-       if (vport->port_state != LPFC_FLOGI)
+       phba->hba_flag &= ~FCF_TS_INPROG;
+       if (vport->port_state != LPFC_FLOGI) {
+               phba->hba_flag |= FCF_RR_INPROG;
+               spin_unlock_irq(&phba->hbalock);
                lpfc_initial_flogi(vport);
+               goto out;
+       }
+       spin_unlock_irq(&phba->hbalock);
+       goto out;
 
+fail_out:
+       spin_lock_irq(&phba->hbalock);
+       phba->hba_flag &= ~FCF_RR_INPROG;
+       spin_unlock_irq(&phba->hbalock);
+out:
        mempool_free(mboxq, phba->mbox_mem_pool);
-       return;
 }
 
 /**
@@ -1241,10 +1339,9 @@ lpfc_register_fcf(struct lpfc_hba *phba)
        int rc;
 
        spin_lock_irq(&phba->hbalock);
-
        /* If the FCF is not availabe do nothing. */
        if (!(phba->fcf.fcf_flag & FCF_AVAILABLE)) {
-               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+               phba->hba_flag &= ~(FCF_TS_INPROG | FCF_RR_INPROG);
                spin_unlock_irq(&phba->hbalock);
                return;
        }
@@ -1252,19 +1349,22 @@ lpfc_register_fcf(struct lpfc_hba *phba)
        /* The FCF is already registered, start discovery */
        if (phba->fcf.fcf_flag & FCF_REGISTERED) {
                phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE);
-               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
-               spin_unlock_irq(&phba->hbalock);
-               if (phba->pport->port_state != LPFC_FLOGI)
+               phba->hba_flag &= ~FCF_TS_INPROG;
+               if (phba->pport->port_state != LPFC_FLOGI) {
+                       phba->hba_flag |= FCF_RR_INPROG;
+                       spin_unlock_irq(&phba->hbalock);
                        lpfc_initial_flogi(phba->pport);
+                       return;
+               }
+               spin_unlock_irq(&phba->hbalock);
                return;
        }
        spin_unlock_irq(&phba->hbalock);
 
-       fcf_mbxq = mempool_alloc(phba->mbox_mem_pool,
-               GFP_KERNEL);
+       fcf_mbxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!fcf_mbxq) {
                spin_lock_irq(&phba->hbalock);
-               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+               phba->hba_flag &= ~(FCF_TS_INPROG | FCF_RR_INPROG);
                spin_unlock_irq(&phba->hbalock);
                return;
        }
@@ -1275,7 +1375,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
        rc = lpfc_sli_issue_mbox(phba, fcf_mbxq, MBX_NOWAIT);
        if (rc == MBX_NOT_FINISHED) {
                spin_lock_irq(&phba->hbalock);
-               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+               phba->hba_flag &= ~(FCF_TS_INPROG | FCF_RR_INPROG);
                spin_unlock_irq(&phba->hbalock);
                mempool_free(fcf_mbxq, phba->mbox_mem_pool);
        }
@@ -1493,7 +1593,7 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
         * FCF discovery, no need to restart FCF discovery.
         */
        if ((phba->link_state  >= LPFC_LINK_UP) &&
-               (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan))
+           (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan))
                return 0;
 
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
@@ -1517,14 +1617,14 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
                lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
        } else {
                /*
-                * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS
+                * Do not continue FCF discovery and clear FCF_TS_INPROG
                 * flag
                 */
                lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
                                "2833 Stop FCF discovery process due to link "
                                "state change (x%x)\n", phba->link_state);
                spin_lock_irq(&phba->hbalock);
-               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+               phba->hba_flag &= ~(FCF_TS_INPROG | FCF_RR_INPROG);
                phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | FCF_DISCOVERY);
                spin_unlock_irq(&phba->hbalock);
        }
@@ -1728,6 +1828,65 @@ lpfc_sli4_fcf_record_match(struct lpfc_hba *phba,
        return true;
 }
 
+/**
+ * lpfc_sli4_fcf_rr_next_proc - processing next roundrobin fcf
+ * @vport: Pointer to vport object.
+ * @fcf_index: index to next fcf.
+ *
+ * This function processing the roundrobin fcf failover to next fcf index.
+ * When this function is invoked, there will be a current fcf registered
+ * for flogi.
+ * Return: 0 for continue retrying flogi on currently registered fcf;
+ *         1 for stop flogi on currently registered fcf;
+ */
+int lpfc_sli4_fcf_rr_next_proc(struct lpfc_vport *vport, uint16_t fcf_index)
+{
+       struct lpfc_hba *phba = vport->phba;
+       int rc;
+
+       if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) {
+               spin_lock_irq(&phba->hbalock);
+               if (phba->hba_flag & HBA_DEVLOSS_TMO) {
+                       spin_unlock_irq(&phba->hbalock);
+                       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                                       "2872 Devloss tmo with no eligible "
+                                       "FCF, unregister in-use FCF (x%x) "
+                                       "and rescan FCF table\n",
+                                       phba->fcf.current_rec.fcf_indx);
+                       lpfc_unregister_fcf_rescan(phba);
+                       goto stop_flogi_current_fcf;
+               }
+               /* Mark the end to FLOGI roundrobin failover */
+               phba->hba_flag &= ~FCF_RR_INPROG;
+               /* Allow action to new fcf asynchronous event */
+               phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE);
+               spin_unlock_irq(&phba->hbalock);
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                               "2865 No FCF available, stop roundrobin FCF "
+                               "failover and change port state:x%x/x%x\n",
+                               phba->pport->port_state, LPFC_VPORT_UNKNOWN);
+               phba->pport->port_state = LPFC_VPORT_UNKNOWN;
+               goto stop_flogi_current_fcf;
+       } else {
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_ELS,
+                               "2794 Try FLOGI roundrobin FCF failover to "
+                               "(x%x)\n", fcf_index);
+               rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba, fcf_index);
+               if (rc)
+                       lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
+                                       "2761 FLOGI roundrobin FCF failover "
+                                       "failed (rc:x%x) to read FCF (x%x)\n",
+                                       rc, phba->fcf.current_rec.fcf_indx);
+               else
+                       goto stop_flogi_current_fcf;
+       }
+       return 0;
+
+stop_flogi_current_fcf:
+       lpfc_can_disctmo(vport);
+       return 1;
+}
+
 /**
  * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler.
  * @phba: pointer to lpfc hba data structure.
@@ -1756,7 +1915,7 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
        int rc;
 
        /* If there is pending FCoE event restart FCF table scan */
-       if (lpfc_check_pending_fcoe_event(phba, 0)) {
+       if (lpfc_check_pending_fcoe_event(phba, LPFC_SKIP_UNREG_FCF)) {
                lpfc_sli4_mbox_cmd_free(phba, mboxq);
                return;
        }
@@ -1765,12 +1924,12 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
        new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq,
                                                      &next_fcf_index);
        if (!new_fcf_record) {
-               lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
+               lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
                                "2765 Mailbox command READ_FCF_RECORD "
                                "failed to retrieve a FCF record.\n");
                /* Let next new FCF event trigger fast failover */
                spin_lock_irq(&phba->hbalock);
-               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+               phba->hba_flag &= ~FCF_TS_INPROG;
                spin_unlock_irq(&phba->hbalock);
                lpfc_sli4_mbox_cmd_free(phba, mboxq);
                return;
@@ -1787,13 +1946,12 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
        /*
         * If the fcf record does not match with connect list entries
         * read the next entry; otherwise, this is an eligible FCF
-        * record for round robin FCF failover.
+        * record for roundrobin FCF failover.
         */
        if (!rc) {
                lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
-                               "2781 FCF record (x%x) failed FCF "
-                               "connection list check, fcf_avail:x%x, "
-                               "fcf_valid:x%x\n",
+                               "2781 FCF (x%x) failed connection "
+                               "list check: (x%x/x%x)\n",
                                bf_get(lpfc_fcf_record_fcf_index,
                                       new_fcf_record),
                                bf_get(lpfc_fcf_record_fcf_avail,
@@ -1803,6 +1961,16 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                if ((phba->fcf.fcf_flag & FCF_IN_USE) &&
                    lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec,
                    new_fcf_record, LPFC_FCOE_IGNORE_VID)) {
+                       if (bf_get(lpfc_fcf_record_fcf_index, new_fcf_record) !=
+                           phba->fcf.current_rec.fcf_indx) {
+                               lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
+                                       "2862 FCF (x%x) matches property "
+                                       "of in-use FCF (x%x)\n",
+                                       bf_get(lpfc_fcf_record_fcf_index,
+                                              new_fcf_record),
+                                       phba->fcf.current_rec.fcf_indx);
+                               goto read_next_fcf;
+                       }
                        /*
                         * In case the current in-use FCF record becomes
                         * invalid/unavailable during FCF discovery that
@@ -1813,9 +1981,8 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                            !(phba->fcf.fcf_flag & FCF_REDISC_FOV)) {
                                lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
                                                "2835 Invalid in-use FCF "
-                                               "record (x%x) reported, "
-                                               "entering fast FCF failover "
-                                               "mode scanning.\n",
+                                               "(x%x), enter FCF failover "
+                                               "table scan.\n",
                                                phba->fcf.current_rec.fcf_indx);
                                spin_lock_irq(&phba->hbalock);
                                phba->fcf.fcf_flag |= FCF_REDISC_FOV;
@@ -1844,22 +2011,29 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
        if (phba->fcf.fcf_flag & FCF_IN_USE) {
                if (lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec,
                    new_fcf_record, vlan_id)) {
-                       phba->fcf.fcf_flag |= FCF_AVAILABLE;
-                       if (phba->fcf.fcf_flag & FCF_REDISC_PEND)
-                               /* Stop FCF redisc wait timer if pending */
-                               __lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
-                       else if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
-                               /* If in fast failover, mark it's completed */
-                               phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
-                       spin_unlock_irq(&phba->hbalock);
-                       lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                                       "2836 The new FCF record (x%x) "
-                                       "matches the in-use FCF record "
-                                       "(x%x)\n",
-                                       phba->fcf.current_rec.fcf_indx,
+                       if (bf_get(lpfc_fcf_record_fcf_index, new_fcf_record) ==
+                           phba->fcf.current_rec.fcf_indx) {
+                               phba->fcf.fcf_flag |= FCF_AVAILABLE;
+                               if (phba->fcf.fcf_flag & FCF_REDISC_PEND)
+                                       /* Stop FCF redisc wait timer */
+                                       __lpfc_sli4_stop_fcf_redisc_wait_timer(
+                                                                       phba);
+                               else if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
+                                       /* Fast failover, mark completed */
+                                       phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
+                               spin_unlock_irq(&phba->hbalock);
+                               lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                                               "2836 New FCF matches in-use "
+                                               "FCF (x%x)\n",
+                                               phba->fcf.current_rec.fcf_indx);
+                               goto out;
+                       } else
+                               lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
+                                       "2863 New FCF (x%x) matches "
+                                       "property of in-use FCF (x%x)\n",
                                        bf_get(lpfc_fcf_record_fcf_index,
-                                              new_fcf_record));
-                       goto out;
+                                              new_fcf_record),
+                                       phba->fcf.current_rec.fcf_indx);
                }
                /*
                 * Read next FCF record from HBA searching for the matching
@@ -1953,8 +2127,8 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
         */
        if (fcf_rec) {
                lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                               "2840 Update current FCF record "
-                               "with initial FCF record (x%x)\n",
+                               "2840 Update initial FCF candidate "
+                               "with FCF (x%x)\n",
                                bf_get(lpfc_fcf_record_fcf_index,
                                       new_fcf_record));
                __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record,
@@ -1984,20 +2158,28 @@ read_next_fcf:
                         */
                        if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) {
                                lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
-                                              "2782 No suitable FCF record "
-                                              "found during this round of "
-                                              "post FCF rediscovery scan: "
-                                              "fcf_evt_tag:x%x, fcf_index: "
-                                              "x%x\n",
+                                              "2782 No suitable FCF found: "
+                                              "(x%x/x%x)\n",
                                               phba->fcoe_eventtag_at_fcf_scan,
                                               bf_get(lpfc_fcf_record_fcf_index,
                                                      new_fcf_record));
+                               spin_lock_irq(&phba->hbalock);
+                               if (phba->hba_flag & HBA_DEVLOSS_TMO) {
+                                       phba->hba_flag &= ~FCF_TS_INPROG;
+                                       spin_unlock_irq(&phba->hbalock);
+                                       /* Unregister in-use FCF and rescan */
+                                       lpfc_printf_log(phba, KERN_INFO,
+                                                       LOG_FIP,
+                                                       "2864 On devloss tmo "
+                                                       "unreg in-use FCF and "
+                                                       "rescan FCF table\n");
+                                       lpfc_unregister_fcf_rescan(phba);
+                                       return;
+                               }
                                /*
-                                * Let next new FCF event trigger fast
-                                * failover
+                                * Let next new FCF event trigger fast failover
                                 */
-                               spin_lock_irq(&phba->hbalock);
-                               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+                               phba->hba_flag &= ~FCF_TS_INPROG;
                                spin_unlock_irq(&phba->hbalock);
                                return;
                        }
@@ -2015,9 +2197,8 @@ read_next_fcf:
 
                        /* Replace in-use record with the new record */
                        lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                                       "2842 Replace the current in-use "
-                                       "FCF record (x%x) with failover FCF "
-                                       "record (x%x)\n",
+                                       "2842 Replace in-use FCF (x%x) "
+                                       "with failover FCF (x%x)\n",
                                        phba->fcf.current_rec.fcf_indx,
                                        phba->fcf.failover_rec.fcf_indx);
                        memcpy(&phba->fcf.current_rec,
@@ -2029,15 +2210,8 @@ read_next_fcf:
                         * FCF failover.
                         */
                        spin_lock_irq(&phba->hbalock);
-                       phba->fcf.fcf_flag &=
-                                       ~(FCF_REDISC_FOV | FCF_REDISC_RRU);
+                       phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
                        spin_unlock_irq(&phba->hbalock);
-                       /*
-                        * Set up the initial registered FCF index for FLOGI
-                        * round robin FCF failover.
-                        */
-                       phba->fcf.fcf_rr_init_indx =
-                                       phba->fcf.failover_rec.fcf_indx;
                        /* Register to the new FCF record */
                        lpfc_register_fcf(phba);
                } else {
@@ -2069,28 +2243,6 @@ read_next_fcf:
                                                LPFC_FCOE_FCF_GET_FIRST);
                                return;
                        }
-
-                       /*
-                        * Otherwise, initial scan or post linkdown rescan,
-                        * register with the best FCF record found so far
-                        * through the FCF scanning process.
-                        */
-
-                       /*
-                        * Mark the initial FCF discovery completed and
-                        * the start of the first round of the roundrobin
-                        * FCF failover.
-                        */
-                       spin_lock_irq(&phba->hbalock);
-                       phba->fcf.fcf_flag &=
-                                       ~(FCF_INIT_DISC | FCF_REDISC_RRU);
-                       spin_unlock_irq(&phba->hbalock);
-                       /*
-                        * Set up the initial registered FCF index for FLOGI
-                        * round robin FCF failover
-                        */
-                       phba->fcf.fcf_rr_init_indx =
-                                       phba->fcf.current_rec.fcf_indx;
                        /* Register to the new FCF record */
                        lpfc_register_fcf(phba);
                }
@@ -2106,11 +2258,11 @@ out:
 }
 
 /**
- * lpfc_mbx_cmpl_fcf_rr_read_fcf_rec - fcf round robin read_fcf mbox cmpl hdler
+ * lpfc_mbx_cmpl_fcf_rr_read_fcf_rec - fcf roundrobin read_fcf mbox cmpl hdler
  * @phba: pointer to lpfc hba data structure.
  * @mboxq: pointer to mailbox object.
  *
- * This is the callback function for FLOGI failure round robin FCF failover
+ * This is the callback function for FLOGI failure roundrobin FCF failover
  * read FCF record mailbox command from the eligible FCF record bmask for
  * performing the failover. If the FCF read back is not valid/available, it
  * fails through to retrying FLOGI to the currently registered FCF again.
@@ -2125,17 +2277,18 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
 {
        struct fcf_record *new_fcf_record;
        uint32_t boot_flag, addr_mode;
-       uint16_t next_fcf_index;
+       uint16_t next_fcf_index, fcf_index;
        uint16_t current_fcf_index;
        uint16_t vlan_id;
+       int rc;
 
-       /* If link state is not up, stop the round robin failover process */
+       /* If link state is not up, stop the roundrobin failover process */
        if (phba->link_state < LPFC_LINK_UP) {
                spin_lock_irq(&phba->hbalock);
                phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+               phba->hba_flag &= ~FCF_RR_INPROG;
                spin_unlock_irq(&phba->hbalock);
-               lpfc_sli4_mbox_cmd_free(phba, mboxq);
-               return;
+               goto out;
        }
 
        /* Parse the FCF record from the non-embedded mailbox command */
@@ -2145,23 +2298,47 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
                lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
                                "2766 Mailbox command READ_FCF_RECORD "
                                "failed to retrieve a FCF record.\n");
-               goto out;
+               goto error_out;
        }
 
        /* Get the needed parameters from FCF record */
-       lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
-                                &addr_mode, &vlan_id);
+       rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag,
+                                     &addr_mode, &vlan_id);
 
        /* Log the FCF record information if turned on */
        lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id,
                                      next_fcf_index);
 
+       fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
+       if (!rc) {
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                               "2848 Remove ineligible FCF (x%x) from "
+                               "from roundrobin bmask\n", fcf_index);
+               /* Clear roundrobin bmask bit for ineligible FCF */
+               lpfc_sli4_fcf_rr_index_clear(phba, fcf_index);
+               /* Perform next round of roundrobin FCF failover */
+               fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
+               rc = lpfc_sli4_fcf_rr_next_proc(phba->pport, fcf_index);
+               if (rc)
+                       goto out;
+               goto error_out;
+       }
+
+       if (fcf_index == phba->fcf.current_rec.fcf_indx) {
+               lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
+                               "2760 Perform FLOGI roundrobin FCF failover: "
+                               "FCF (x%x) back to FCF (x%x)\n",
+                               phba->fcf.current_rec.fcf_indx, fcf_index);
+               /* Wait 500 ms before retrying FLOGI to current FCF */
+               msleep(500);
+               lpfc_initial_flogi(phba->pport);
+               goto out;
+       }
+
        /* Upload new FCF record to the failover FCF record */
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                       "2834 Update the current FCF record (x%x) "
-                       "with the next FCF record (x%x)\n",
-                       phba->fcf.failover_rec.fcf_indx,
-                       bf_get(lpfc_fcf_record_fcf_index, new_fcf_record));
+                       "2834 Update current FCF (x%x) with new FCF (x%x)\n",
+                       phba->fcf.failover_rec.fcf_indx, fcf_index);
        spin_lock_irq(&phba->hbalock);
        __lpfc_update_fcf_record(phba, &phba->fcf.failover_rec,
                                 new_fcf_record, addr_mode, vlan_id,
@@ -2178,14 +2355,13 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
               sizeof(struct lpfc_fcf_rec));
 
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                       "2783 FLOGI round robin FCF failover from FCF "
-                       "(x%x) to FCF (x%x).\n",
-                       current_fcf_index,
-                       bf_get(lpfc_fcf_record_fcf_index, new_fcf_record));
+                       "2783 Perform FLOGI roundrobin FCF failover: FCF "
+                       "(x%x) to FCF (x%x)\n", current_fcf_index, fcf_index);
 
+error_out:
+       lpfc_register_fcf(phba);
 out:
        lpfc_sli4_mbox_cmd_free(phba, mboxq);
-       lpfc_register_fcf(phba);
 }
 
 /**
@@ -2194,10 +2370,10 @@ out:
  * @mboxq: pointer to mailbox object.
  *
  * This is the callback function of read FCF record mailbox command for
- * updating the eligible FCF bmask for FLOGI failure round robin FCF
+ * updating the eligible FCF bmask for FLOGI failure roundrobin FCF
  * failover when a new FCF event happened. If the FCF read back is
  * valid/available and it passes the connection list check, it updates
- * the bmask for the eligible FCF record for round robin failover.
+ * the bmask for the eligible FCF record for roundrobin failover.
  */
 void
 lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
@@ -2639,7 +2815,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
                 * and get the FCF Table.
                 */
                spin_lock_irq(&phba->hbalock);
-               if (phba->hba_flag & FCF_DISC_INPROGRESS) {
+               if (phba->hba_flag & FCF_TS_INPROG) {
                        spin_unlock_irq(&phba->hbalock);
                        return;
                }
@@ -3906,6 +4082,11 @@ lpfc_unreg_all_rpis(struct lpfc_vport *vport)
        LPFC_MBOXQ_t     *mbox;
        int rc;
 
+       if (phba->sli_rev == LPFC_SLI_REV4) {
+               lpfc_sli4_unreg_all_rpis(vport);
+               return;
+       }
+
        mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (mbox) {
                lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox);
@@ -3992,6 +4173,16 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        }
 
        spin_lock_irq(&phba->hbalock);
+       /* Cleanup REG_LOGIN completions which are not yet processed */
+       list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) {
+               if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) ||
+                       (ndlp != (struct lpfc_nodelist *) mb->context2))
+                       continue;
+
+               mb->context2 = NULL;
+               mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+       }
+
        list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
                if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
                    (ndlp == (struct lpfc_nodelist *) mb->context2)) {
@@ -5170,6 +5361,8 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba)
                        if (ndlp)
                                lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
                        lpfc_cleanup_pending_mbox(vports[i]);
+                       if (phba->sli_rev == LPFC_SLI_REV4)
+                               lpfc_sli4_unreg_all_rpis(vports[i]);
                        lpfc_mbx_unreg_vpi(vports[i]);
                        shost = lpfc_shost_from_vport(vports[i]);
                        spin_lock_irq(shost->host_lock);
index a631647051d99dc3cb53226ffd7602efe2cbfd19..9b833345646525c52b736f4f388e18f3f18695c4 100644 (file)
@@ -861,6 +861,47 @@ typedef struct  _RPS_RSP { /* Structure is in Big Endian format */
        uint32_t crcCnt;
 } RPS_RSP;
 
+struct RLS {                   /* Structure is in Big Endian format */
+       uint32_t rls;
+#define rls_rsvd_SHIFT         24
+#define rls_rsvd_MASK          0x000000ff
+#define rls_rsvd_WORD          rls
+#define rls_did_SHIFT          0
+#define rls_did_MASK           0x00ffffff
+#define rls_did_WORD           rls
+};
+
+struct  RLS_RSP {              /* Structure is in Big Endian format */
+       uint32_t linkFailureCnt;
+       uint32_t lossSyncCnt;
+       uint32_t lossSignalCnt;
+       uint32_t primSeqErrCnt;
+       uint32_t invalidXmitWord;
+       uint32_t crcCnt;
+};
+
+struct RTV_RSP {               /* Structure is in Big Endian format */
+       uint32_t ratov;
+       uint32_t edtov;
+       uint32_t qtov;
+#define qtov_rsvd0_SHIFT       28
+#define qtov_rsvd0_MASK                0x0000000f
+#define qtov_rsvd0_WORD                qtov            /* reserved */
+#define qtov_edtovres_SHIFT    27
+#define qtov_edtovres_MASK     0x00000001
+#define qtov_edtovres_WORD     qtov            /* E_D_TOV Resolution */
+#define qtov__rsvd1_SHIFT      19
+#define qtov_rsvd1_MASK                0x0000003f
+#define qtov_rsvd1_WORD                qtov            /* reserved */
+#define qtov_rttov_SHIFT       18
+#define qtov_rttov_MASK                0x00000001
+#define qtov_rttov_WORD                qtov            /* R_T_TOV value */
+#define qtov_rsvd2_SHIFT       0
+#define qtov_rsvd2_MASK                0x0003ffff
+#define qtov_rsvd2_WORD                qtov            /* reserved */
+};
+
+
 typedef struct  _RPL {         /* Structure is in Big Endian format */
        uint32_t maxsize;
        uint32_t index;
index bbdcf96800f619e952bdcb64df043bf789caf68e..6e4bc34e1d0d30028f2aaae15e615f5a0d067cd5 100644 (file)
@@ -424,79 +424,6 @@ struct lpfc_rcqe {
 #define FCOE_SOFn3     0x36
 };
 
-struct lpfc_wqe_generic{
-       struct ulp_bde64 bde;
-       uint32_t word3;
-       uint32_t word4;
-       uint32_t word5;
-       uint32_t word6;
-#define lpfc_wqe_gen_context_SHIFT     16
-#define lpfc_wqe_gen_context_MASK      0x0000FFFF
-#define lpfc_wqe_gen_context_WORD      word6
-#define lpfc_wqe_gen_xri_SHIFT         0
-#define lpfc_wqe_gen_xri_MASK          0x0000FFFF
-#define lpfc_wqe_gen_xri_WORD          word6
-       uint32_t word7;
-#define lpfc_wqe_gen_lnk_SHIFT         23
-#define lpfc_wqe_gen_lnk_MASK          0x00000001
-#define lpfc_wqe_gen_lnk_WORD          word7
-#define lpfc_wqe_gen_erp_SHIFT         22
-#define lpfc_wqe_gen_erp_MASK          0x00000001
-#define lpfc_wqe_gen_erp_WORD          word7
-#define lpfc_wqe_gen_pu_SHIFT          20
-#define lpfc_wqe_gen_pu_MASK           0x00000003
-#define lpfc_wqe_gen_pu_WORD           word7
-#define lpfc_wqe_gen_class_SHIFT       16
-#define lpfc_wqe_gen_class_MASK                0x00000007
-#define lpfc_wqe_gen_class_WORD                word7
-#define lpfc_wqe_gen_command_SHIFT     8
-#define lpfc_wqe_gen_command_MASK      0x000000FF
-#define lpfc_wqe_gen_command_WORD      word7
-#define lpfc_wqe_gen_status_SHIFT      4
-#define lpfc_wqe_gen_status_MASK       0x0000000F
-#define lpfc_wqe_gen_status_WORD       word7
-#define lpfc_wqe_gen_ct_SHIFT          2
-#define lpfc_wqe_gen_ct_MASK           0x00000003
-#define lpfc_wqe_gen_ct_WORD           word7
-       uint32_t abort_tag;
-       uint32_t word9;
-#define lpfc_wqe_gen_request_tag_SHIFT 0
-#define lpfc_wqe_gen_request_tag_MASK  0x0000FFFF
-#define lpfc_wqe_gen_request_tag_WORD  word9
-       uint32_t word10;
-#define lpfc_wqe_gen_ccp_SHIFT         24
-#define lpfc_wqe_gen_ccp_MASK          0x000000FF
-#define lpfc_wqe_gen_ccp_WORD          word10
-#define lpfc_wqe_gen_ccpe_SHIFT                23
-#define lpfc_wqe_gen_ccpe_MASK         0x00000001
-#define lpfc_wqe_gen_ccpe_WORD         word10
-#define lpfc_wqe_gen_pv_SHIFT          19
-#define lpfc_wqe_gen_pv_MASK           0x00000001
-#define lpfc_wqe_gen_pv_WORD           word10
-#define lpfc_wqe_gen_pri_SHIFT         16
-#define lpfc_wqe_gen_pri_MASK          0x00000007
-#define lpfc_wqe_gen_pri_WORD          word10
-       uint32_t word11;
-#define lpfc_wqe_gen_cq_id_SHIFT       16
-#define lpfc_wqe_gen_cq_id_MASK                0x0000FFFF
-#define lpfc_wqe_gen_cq_id_WORD                word11
-#define LPFC_WQE_CQ_ID_DEFAULT 0xffff
-#define lpfc_wqe_gen_wqec_SHIFT                7
-#define lpfc_wqe_gen_wqec_MASK         0x00000001
-#define lpfc_wqe_gen_wqec_WORD         word11
-#define ELS_ID_FLOGI 3
-#define ELS_ID_FDISC 2
-#define ELS_ID_LOGO  1
-#define ELS_ID_DEFAULT 0
-#define lpfc_wqe_gen_els_id_SHIFT      4
-#define lpfc_wqe_gen_els_id_MASK       0x00000003
-#define lpfc_wqe_gen_els_id_WORD       word11
-#define lpfc_wqe_gen_cmd_type_SHIFT    0
-#define lpfc_wqe_gen_cmd_type_MASK     0x0000000F
-#define lpfc_wqe_gen_cmd_type_WORD     word11
-       uint32_t payload[4];
-};
-
 struct lpfc_rqe {
        uint32_t address_hi;
        uint32_t address_lo;
@@ -2279,9 +2206,36 @@ struct wqe_common {
 #define wqe_reqtag_MASK       0x0000FFFF
 #define wqe_reqtag_WORD       word9
 #define wqe_rcvoxid_SHIFT     16
-#define wqe_rcvoxid_MASK       0x0000FFFF
-#define wqe_rcvoxid_WORD       word9
+#define wqe_rcvoxid_MASK      0x0000FFFF
+#define wqe_rcvoxid_WORD      word9
        uint32_t word10;
+#define wqe_ebde_cnt_SHIFT    0
+#define wqe_ebde_cnt_MASK     0x00000007
+#define wqe_ebde_cnt_WORD     word10
+#define wqe_lenloc_SHIFT      7
+#define wqe_lenloc_MASK       0x00000003
+#define wqe_lenloc_WORD       word10
+#define LPFC_WQE_LENLOC_NONE           0
+#define LPFC_WQE_LENLOC_WORD3  1
+#define LPFC_WQE_LENLOC_WORD12 2
+#define LPFC_WQE_LENLOC_WORD4  3
+#define wqe_qosd_SHIFT        9
+#define wqe_qosd_MASK         0x00000001
+#define wqe_qosd_WORD         word10
+#define wqe_xbl_SHIFT         11
+#define wqe_xbl_MASK          0x00000001
+#define wqe_xbl_WORD          word10
+#define wqe_iod_SHIFT         13
+#define wqe_iod_MASK          0x00000001
+#define wqe_iod_WORD          word10
+#define LPFC_WQE_IOD_WRITE     0
+#define LPFC_WQE_IOD_READ      1
+#define wqe_dbde_SHIFT        14
+#define wqe_dbde_MASK         0x00000001
+#define wqe_dbde_WORD         word10
+#define wqe_wqes_SHIFT        15
+#define wqe_wqes_MASK         0x00000001
+#define wqe_wqes_WORD         word10
 #define wqe_pri_SHIFT         16
 #define wqe_pri_MASK          0x00000007
 #define wqe_pri_WORD          word10
@@ -2295,18 +2249,26 @@ struct wqe_common {
 #define wqe_ccpe_MASK         0x00000001
 #define wqe_ccpe_WORD         word10
 #define wqe_ccp_SHIFT         24
-#define wqe_ccp_MASK         0x000000ff
-#define wqe_ccp_WORD         word10
+#define wqe_ccp_MASK          0x000000ff
+#define wqe_ccp_WORD          word10
        uint32_t word11;
-#define wqe_cmd_type_SHIFT  0
-#define wqe_cmd_type_MASK   0x0000000f
-#define wqe_cmd_type_WORD   word11
-#define wqe_wqec_SHIFT      7
-#define wqe_wqec_MASK       0x00000001
-#define wqe_wqec_WORD       word11
-#define wqe_cqid_SHIFT      16
-#define wqe_cqid_MASK       0x0000ffff
-#define wqe_cqid_WORD       word11
+#define wqe_cmd_type_SHIFT    0
+#define wqe_cmd_type_MASK     0x0000000f
+#define wqe_cmd_type_WORD     word11
+#define wqe_els_id_SHIFT      4
+#define wqe_els_id_MASK       0x00000003
+#define wqe_els_id_WORD       word11
+#define LPFC_ELS_ID_FLOGI      3
+#define LPFC_ELS_ID_FDISC      2
+#define LPFC_ELS_ID_LOGO       1
+#define LPFC_ELS_ID_DEFAULT    0
+#define wqe_wqec_SHIFT        7
+#define wqe_wqec_MASK         0x00000001
+#define wqe_wqec_WORD         word11
+#define wqe_cqid_SHIFT        16
+#define wqe_cqid_MASK         0x0000ffff
+#define wqe_cqid_WORD         word11
+#define LPFC_WQE_CQ_ID_DEFAULT 0xffff
 };
 
 struct wqe_did {
@@ -2325,6 +2287,15 @@ struct wqe_did {
 #define wqe_xmit_bls_xo_WORD          word5
 };
 
+struct lpfc_wqe_generic{
+       struct ulp_bde64 bde;
+       uint32_t word3;
+       uint32_t word4;
+       uint32_t word5;
+       struct wqe_common wqe_com;
+       uint32_t payload[4];
+};
+
 struct els_request64_wqe {
        struct ulp_bde64 bde;
        uint32_t payload_len;
@@ -2356,9 +2327,9 @@ struct els_request64_wqe {
 
 struct xmit_els_rsp64_wqe {
        struct ulp_bde64 bde;
-       uint32_t rsvd3;
+       uint32_t response_payload_len;
        uint32_t rsvd4;
-       struct wqe_did  wqe_dest;
+       struct wqe_did wqe_dest;
        struct wqe_common wqe_com; /* words 6-11 */
        uint32_t rsvd_12_15[4];
 };
@@ -2427,7 +2398,7 @@ struct wqe_rctl_dfctl {
 
 struct xmit_seq64_wqe {
        struct ulp_bde64 bde;
-       uint32_t paylaod_offset;
+       uint32_t rsvd3;
        uint32_t relative_offset;
        struct wqe_rctl_dfctl wge_ctl;
        struct wqe_common wqe_com; /* words 6-11 */
@@ -2437,7 +2408,7 @@ struct xmit_seq64_wqe {
 };
 struct xmit_bcast64_wqe {
        struct ulp_bde64 bde;
-       uint32_t paylaod_len;
+       uint32_t seq_payload_len;
        uint32_t rsvd4;
        struct wqe_rctl_dfctl wge_ctl; /* word 5 */
        struct wqe_common wqe_com;     /* words 6-11 */
@@ -2446,8 +2417,8 @@ struct xmit_bcast64_wqe {
 
 struct gen_req64_wqe {
        struct ulp_bde64 bde;
-       uint32_t command_len;
-       uint32_t payload_len;
+       uint32_t request_payload_len;
+       uint32_t relative_offset;
        struct wqe_rctl_dfctl wge_ctl; /* word 5 */
        struct wqe_common wqe_com;     /* words 6-11 */
        uint32_t rsvd_12_15[4];
@@ -2480,7 +2451,7 @@ struct abort_cmd_wqe {
 
 struct fcp_iwrite64_wqe {
        struct ulp_bde64 bde;
-       uint32_t payload_len;
+       uint32_t payload_offset_len;
        uint32_t total_xfer_len;
        uint32_t initial_xfer_len;
        struct wqe_common wqe_com;     /* words 6-11 */
@@ -2489,7 +2460,7 @@ struct fcp_iwrite64_wqe {
 
 struct fcp_iread64_wqe {
        struct ulp_bde64 bde;
-       uint32_t payload_len;          /* word 3 */
+       uint32_t payload_offset_len;   /* word 3 */
        uint32_t total_xfer_len;       /* word 4 */
        uint32_t rsrvd5;               /* word 5 */
        struct wqe_common wqe_com;     /* words 6-11 */
@@ -2497,10 +2468,12 @@ struct fcp_iread64_wqe {
 };
 
 struct fcp_icmnd64_wqe {
-       struct ulp_bde64 bde;    /* words 0-2 */
-       uint32_t rsrvd[3];             /* words 3-5 */
+       struct ulp_bde64 bde;          /* words 0-2 */
+       uint32_t rsrvd3;               /* word 3 */
+       uint32_t rsrvd4;               /* word 4 */
+       uint32_t rsrvd5;               /* word 5 */
        struct wqe_common wqe_com;     /* words 6-11 */
-       uint32_t rsvd_12_15[4];         /* word 12-15 */
+       uint32_t rsvd_12_15[4];        /* word 12-15 */
 };
 
 
index 295c7ddb36c11fa72eaa6626aa7203ac4fb1eabf..b3065791f30333b9667dcb0f9d3d222facb76fc0 100644 (file)
@@ -813,6 +813,7 @@ lpfc_hba_down_post_s3(struct lpfc_hba *phba)
 
        return 0;
 }
+
 /**
  * lpfc_hba_down_post_s4 - Perform lpfc uninitialization after HBA reset
  * @phba: pointer to lpfc HBA data structure.
@@ -2234,10 +2235,9 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport)
 void
 __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
 {
-       /* Clear pending FCF rediscovery wait and failover in progress flags */
-       phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND |
-                               FCF_DEAD_DISC |
-                               FCF_ACVL_DISC);
+       /* Clear pending FCF rediscovery wait flag */
+       phba->fcf.fcf_flag &= ~FCF_REDISC_PEND;
+
        /* Now, try to stop the timer */
        del_timer(&phba->fcf.redisc_wait);
 }
@@ -2261,6 +2261,8 @@ lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
                return;
        }
        __lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
+       /* Clear failover in progress flags */
+       phba->fcf.fcf_flag &= ~(FCF_DEAD_DISC | FCF_ACVL_DISC);
        spin_unlock_irq(&phba->hbalock);
 }
 
@@ -2935,8 +2937,7 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr)
        phba->fcf.fcf_flag |= FCF_REDISC_EVT;
        spin_unlock_irq(&phba->hbalock);
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                       "2776 FCF rediscover wait timer expired, post "
-                       "a worker thread event for FCF table scan\n");
+                       "2776 FCF rediscover quiescent timer expired\n");
        /* wake up worker thread */
        lpfc_worker_wake_up(phba);
 }
@@ -3311,35 +3312,34 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                if (event_type == LPFC_FCOE_EVENT_TYPE_NEW_FCF)
                        lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
                                        LOG_DISCOVERY,
-                                       "2546 New FCF found event: "
-                                       "evt_tag:x%x, fcf_index:x%x\n",
+                                       "2546 New FCF event, evt_tag:x%x, "
+                                       "index:x%x\n",
                                        acqe_fcoe->event_tag,
                                        acqe_fcoe->index);
                else
                        lpfc_printf_log(phba, KERN_WARNING, LOG_FIP |
                                        LOG_DISCOVERY,
-                                       "2788 FCF parameter modified event: "
-                                       "evt_tag:x%x, fcf_index:x%x\n",
+                                       "2788 FCF param modified event, "
+                                       "evt_tag:x%x, index:x%x\n",
                                        acqe_fcoe->event_tag,
                                        acqe_fcoe->index);
                if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
                        /*
                         * During period of FCF discovery, read the FCF
                         * table record indexed by the event to update
-                        * FCF round robin failover eligible FCF bmask.
+                        * FCF roundrobin failover eligible FCF bmask.
                         */
                        lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
                                        LOG_DISCOVERY,
-                                       "2779 Read new FCF record with "
-                                       "fcf_index:x%x for updating FCF "
-                                       "round robin failover bmask\n",
+                                       "2779 Read FCF (x%x) for updating "
+                                       "roundrobin FCF failover bmask\n",
                                        acqe_fcoe->index);
                        rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
                }
 
                /* If the FCF discovery is in progress, do nothing. */
                spin_lock_irq(&phba->hbalock);
-               if (phba->hba_flag & FCF_DISC_INPROGRESS) {
+               if (phba->hba_flag & FCF_TS_INPROG) {
                        spin_unlock_irq(&phba->hbalock);
                        break;
                }
@@ -3358,15 +3358,15 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
 
                /* Otherwise, scan the entire FCF table and re-discover SAN */
                lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
-                               "2770 Start FCF table scan due to new FCF "
-                               "event: evt_tag:x%x, fcf_index:x%x\n",
+                               "2770 Start FCF table scan per async FCF "
+                               "event, evt_tag:x%x, index:x%x\n",
                                acqe_fcoe->event_tag, acqe_fcoe->index);
                rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
                                                     LPFC_FCOE_FCF_GET_FIRST);
                if (rc)
                        lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
                                        "2547 Issue FCF scan read FCF mailbox "
-                                       "command failed 0x%x\n", rc);
+                                       "command failed (x%x)\n", rc);
                break;
 
        case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
@@ -3378,9 +3378,8 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
 
        case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
                lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
-                       "2549 FCF disconnected from network index 0x%x"
-                       " tag 0x%x\n", acqe_fcoe->index,
-                       acqe_fcoe->event_tag);
+                       "2549 FCF (x%x) disconnected from network, "
+                       "tag:x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
                /*
                 * If we are in the middle of FCF failover process, clear
                 * the corresponding FCF bit in the roundrobin bitmap.
@@ -3494,9 +3493,8 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                        spin_unlock_irq(&phba->hbalock);
                        lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
                                        LOG_DISCOVERY,
-                                       "2773 Start FCF fast failover due "
-                                       "to CVL event: evt_tag:x%x\n",
-                                       acqe_fcoe->event_tag);
+                                       "2773 Start FCF failover per CVL, "
+                                       "evt_tag:x%x\n", acqe_fcoe->event_tag);
                        rc = lpfc_sli4_redisc_fcf_table(phba);
                        if (rc) {
                                lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
@@ -3646,8 +3644,7 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba)
 
        /* Scan FCF table from the first entry to re-discover SAN */
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
-                       "2777 Start FCF table scan after FCF "
-                       "rediscovery quiescent period over\n");
+                       "2777 Start post-quiescent FCF table scan\n");
        rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
        if (rc)
                lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
@@ -4165,7 +4162,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
                goto out_free_active_sgl;
        }
 
-       /* Allocate eligible FCF bmask memory for FCF round robin failover */
+       /* Allocate eligible FCF bmask memory for FCF roundrobin failover */
        longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG;
        phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long),
                                         GFP_KERNEL);
@@ -7270,6 +7267,51 @@ lpfc_sli4_unset_hba(struct lpfc_hba *phba)
        return;
 }
 
+/**
+ * lpfc_sli4_xri_exchange_busy_wait - Wait for device XRI exchange busy
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called in the SLI4 code path to wait for completion
+ * of device's XRIs exchange busy. It will check the XRI exchange busy
+ * on outstanding FCP and ELS I/Os every 10ms for up to 10 seconds; after
+ * that, it will check the XRI exchange busy on outstanding FCP and ELS
+ * I/Os every 30 seconds, log error message, and wait forever. Only when
+ * all XRI exchange busy complete, the driver unload shall proceed with
+ * invoking the function reset ioctl mailbox command to the CNA and the
+ * the rest of the driver unload resource release.
+ **/
+static void
+lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba)
+{
+       int wait_time = 0;
+       int fcp_xri_cmpl = list_empty(&phba->sli4_hba.lpfc_abts_scsi_buf_list);
+       int els_xri_cmpl = list_empty(&phba->sli4_hba.lpfc_abts_els_sgl_list);
+
+       while (!fcp_xri_cmpl || !els_xri_cmpl) {
+               if (wait_time > LPFC_XRI_EXCH_BUSY_WAIT_TMO) {
+                       if (!fcp_xri_cmpl)
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                               "2877 FCP XRI exchange busy "
+                                               "wait time: %d seconds.\n",
+                                               wait_time/1000);
+                       if (!els_xri_cmpl)
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                               "2878 ELS XRI exchange busy "
+                                               "wait time: %d seconds.\n",
+                                               wait_time/1000);
+                       msleep(LPFC_XRI_EXCH_BUSY_WAIT_T2);
+                       wait_time += LPFC_XRI_EXCH_BUSY_WAIT_T2;
+               } else {
+                       msleep(LPFC_XRI_EXCH_BUSY_WAIT_T1);
+                       wait_time += LPFC_XRI_EXCH_BUSY_WAIT_T1;
+               }
+               fcp_xri_cmpl =
+                       list_empty(&phba->sli4_hba.lpfc_abts_scsi_buf_list);
+               els_xri_cmpl =
+                       list_empty(&phba->sli4_hba.lpfc_abts_els_sgl_list);
+       }
+}
+
 /**
  * lpfc_sli4_hba_unset - Unset the fcoe hba
  * @phba: Pointer to HBA context object.
@@ -7315,6 +7357,12 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
                spin_unlock_irq(&phba->hbalock);
        }
 
+       /* Abort all iocbs associated with the hba */
+       lpfc_sli_hba_iocb_abort(phba);
+
+       /* Wait for completion of device XRI exchange busy */
+       lpfc_sli4_xri_exchange_busy_wait(phba);
+
        /* Disable PCI subsystem interrupt */
        lpfc_sli4_disable_intr(phba);
 
index 0dfa310cd609318cb0c772f85ea344acdef2c5ea..62d0957e1d4c7dd29add28778f640af952e56b47 100644 (file)
@@ -796,6 +796,34 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
        return;
 }
 
+/**
+ * lpfc_sli4_unreg_all_rpis - unregister all RPIs for a vport on SLI4 HBA.
+ * @vport: pointer to a vport object.
+ *
+ * This routine sends mailbox command to unregister all active RPIs for
+ * a vport.
+ **/
+void
+lpfc_sli4_unreg_all_rpis(struct lpfc_vport *vport)
+{
+       struct lpfc_hba  *phba  = vport->phba;
+       LPFC_MBOXQ_t     *mbox;
+       int rc;
+
+       mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (mbox) {
+               lpfc_unreg_login(phba, vport->vpi,
+                       vport->vpi + phba->vpi_base, mbox);
+               mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000 ;
+               mbox->vport = vport;
+               mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+               mbox->context1 = NULL;
+               rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+               if (rc == MBX_NOT_FINISHED)
+                       mempool_free(mbox, phba->mbox_mem_pool);
+       }
+}
+
 /**
  * lpfc_reg_vpi - Prepare a mailbox command for registering vport identifier
  * @phba: pointer to lpfc hba data structure.
index 3a658953486cf9a1e73027c9be828a0c12be5e41..f64b65a770b8df3b3f0a3ba47decc0512a8df0a7 100644 (file)
@@ -169,6 +169,7 @@ lpfc_update_stats(struct lpfc_hba *phba, struct  lpfc_scsi_buf *lpfc_cmd)
        spin_lock_irqsave(shost->host_lock, flags);
        if (!vport->stat_data_enabled ||
                vport->stat_data_blocked ||
+               !pnode ||
                !pnode->lat_data ||
                (phba->bucket_type == LPFC_NO_BUCKET)) {
                spin_unlock_irqrestore(shost->host_lock, flags);
@@ -2040,6 +2041,9 @@ lpfc_send_scsi_error_event(struct lpfc_hba *phba, struct lpfc_vport *vport,
        struct lpfc_nodelist *pnode = lpfc_cmd->rdata->pnode;
        unsigned long flags;
 
+       if (!pnode || !NLP_CHK_NODE_ACT(pnode))
+               return;
+
        /* If there is queuefull or busy condition send a scsi event */
        if ((cmnd->result == SAM_STAT_TASK_SET_FULL) ||
                (cmnd->result == SAM_STAT_BUSY)) {
@@ -3226,10 +3230,11 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
        struct lpfc_scsi_buf *lpfc_cmd;
        struct lpfc_iocbq *iocbq;
        struct lpfc_iocbq *iocbqrsp;
+       struct lpfc_nodelist *pnode = rdata->pnode;
        int ret;
        int status;
 
-       if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode))
+       if (!pnode || !NLP_CHK_NODE_ACT(pnode))
                return FAILED;
 
        lpfc_cmd = lpfc_get_scsi_buf(phba);
@@ -3256,7 +3261,7 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
                         "0702 Issue %s to TGT %d LUN %d "
                         "rpi x%x nlp_flag x%x\n",
                         lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id,
-                        rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag);
+                        pnode->nlp_rpi, pnode->nlp_flag);
 
        status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING,
                                          iocbq, iocbqrsp, lpfc_cmd->timeout);
index 0d1e187b005ddd366b0545fee2356d1b43df9994..554efa6623f4edab7154e3f1ad23e5be845260c6 100644 (file)
@@ -95,7 +95,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe)
                return -ENOMEM;
        /* set consumption flag every once in a while */
        if (!((q->host_index + 1) % LPFC_RELEASE_NOTIFICATION_INTERVAL))
-               bf_set(lpfc_wqe_gen_wqec, &wqe->generic, 1);
+               bf_set(wqe_wqec, &wqe->generic.wqe_com, 1);
 
        lpfc_sli_pcimem_bcopy(wqe, temp_wqe, q->entry_size);
 
@@ -1735,6 +1735,7 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        struct lpfc_vport  *vport = pmb->vport;
        struct lpfc_dmabuf *mp;
        struct lpfc_nodelist *ndlp;
+       struct Scsi_Host *shost;
        uint16_t rpi, vpi;
        int rc;
 
@@ -1746,7 +1747,8 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        }
 
        if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) &&
-           (phba->sli_rev == LPFC_SLI_REV4))
+           (phba->sli_rev == LPFC_SLI_REV4) &&
+           (pmb->u.mb.un.varUnregLogin.rsvd1 == 0x0))
                lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi);
 
        /*
@@ -1765,16 +1767,14 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
                        return;
        }
 
-       /* Unreg VPI, if the REG_VPI succeed after VLink failure */
        if ((pmb->u.mb.mbxCommand == MBX_REG_VPI) &&
                !(phba->pport->load_flag & FC_UNLOADING) &&
                !pmb->u.mb.mbxStatus) {
-               lpfc_unreg_vpi(phba, pmb->u.mb.un.varRegVpi.vpi, pmb);
-               pmb->vport = vport;
-               pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-               rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
-               if (rc != MBX_NOT_FINISHED)
-                       return;
+               shost = lpfc_shost_from_vport(vport);
+               spin_lock_irq(shost->host_lock);
+               vport->vpi_state |= LPFC_VPI_REGISTERED;
+               vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
+               spin_unlock_irq(shost->host_lock);
        }
 
        if (pmb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
@@ -5921,7 +5921,7 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
  * lpfc_sli4_scmd_to_wqidx_distr - scsi command to SLI4 WQ index distribution
  * @phba: Pointer to HBA context object.
  *
- * This routine performs a round robin SCSI command to SLI4 FCP WQ index
+ * This routine performs a roundrobin SCSI command to SLI4 FCP WQ index
  * distribution.  This is called by __lpfc_sli_issue_iocb_s4() with the hbalock
  * held.
  *
@@ -5965,7 +5965,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
        uint16_t abrt_iotag;
        struct lpfc_iocbq *abrtiocbq;
        struct ulp_bde64 *bpl = NULL;
-       uint32_t els_id = ELS_ID_DEFAULT;
+       uint32_t els_id = LPFC_ELS_ID_DEFAULT;
        int numBdes, i;
        struct ulp_bde64 bde;
 
@@ -5982,7 +5982,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
        memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe));
        abort_tag = (uint32_t) iocbq->iotag;
        xritag = iocbq->sli4_xritag;
-       wqe->words[7] = 0; /* The ct field has moved so reset */
+       wqe->generic.wqe_com.word7 = 0; /* The ct field has moved so reset */
        /* words0-2 bpl convert bde */
        if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) {
                numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize /
@@ -6033,109 +6033,117 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
                 * contains the FCFI and remote N_Port_ID is
                 * in word 5.
                 */
-
                ct = ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l);
-               bf_set(lpfc_wqe_gen_context, &wqe->generic,
-                               iocbq->iocb.ulpContext);
-
-               bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct);
-               bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
+               bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
+                      iocbq->iocb.ulpContext);
+               bf_set(wqe_ct, &wqe->els_req.wqe_com, ct);
+               bf_set(wqe_pu, &wqe->els_req.wqe_com, 0);
                /* CCP CCPE PV PRI in word10 were set in the memcpy */
-
                if (command_type == ELS_COMMAND_FIP) {
                        els_id = ((iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK)
                                        >> LPFC_FIP_ELS_ID_SHIFT);
                }
-               bf_set(lpfc_wqe_gen_els_id, &wqe->generic, els_id);
-
+               bf_set(wqe_els_id, &wqe->els_req.wqe_com, els_id);
+               bf_set(wqe_dbde, &wqe->els_req.wqe_com, 1);
+               bf_set(wqe_iod, &wqe->els_req.wqe_com, LPFC_WQE_IOD_READ);
+               bf_set(wqe_qosd, &wqe->els_req.wqe_com, 1);
+               bf_set(wqe_lenloc, &wqe->els_req.wqe_com, LPFC_WQE_LENLOC_NONE);
+               bf_set(wqe_ebde_cnt, &wqe->els_req.wqe_com, 0);
        break;
        case CMD_XMIT_SEQUENCE64_CX:
-               bf_set(lpfc_wqe_gen_context, &wqe->generic,
-                                       iocbq->iocb.un.ulpWord[3]);
-               wqe->generic.word3 = 0;
-               bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext);
+               bf_set(wqe_ctxt_tag, &wqe->xmit_sequence.wqe_com,
+                      iocbq->iocb.un.ulpWord[3]);
+               bf_set(wqe_rcvoxid, &wqe->xmit_sequence.wqe_com,
+                      iocbq->iocb.ulpContext);
                /* The entire sequence is transmitted for this IOCB */
                xmit_len = total_len;
                cmnd = CMD_XMIT_SEQUENCE64_CR;
        case CMD_XMIT_SEQUENCE64_CR:
-               /* word3 iocb=io_tag32 wqe=payload_offset */
-               /* payload offset used for multilpe outstanding
-                * sequences on the same exchange
-                */
-               wqe->words[3] = 0;
+               /* word3 iocb=io_tag32 wqe=reserved */
+               wqe->xmit_sequence.rsvd3 = 0;
                /* word4 relative_offset memcpy */
                /* word5 r_ctl/df_ctl memcpy */
-               bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
+               bf_set(wqe_pu, &wqe->xmit_sequence.wqe_com, 0);
+               bf_set(wqe_dbde, &wqe->xmit_sequence.wqe_com, 1);
+               bf_set(wqe_iod, &wqe->xmit_sequence.wqe_com,
+                      LPFC_WQE_IOD_WRITE);
+               bf_set(wqe_lenloc, &wqe->xmit_sequence.wqe_com,
+                      LPFC_WQE_LENLOC_WORD12);
+               bf_set(wqe_ebde_cnt, &wqe->xmit_sequence.wqe_com, 0);
                wqe->xmit_sequence.xmit_len = xmit_len;
                command_type = OTHER_COMMAND;
        break;
        case CMD_XMIT_BCAST64_CN:
-               /* word3 iocb=iotag32 wqe=payload_len */
-               wqe->words[3] = 0; /* no definition for this in wqe */
+               /* word3 iocb=iotag32 wqe=seq_payload_len */
+               wqe->xmit_bcast64.seq_payload_len = xmit_len;
                /* word4 iocb=rsvd wqe=rsvd */
                /* word5 iocb=rctl/type/df_ctl wqe=rctl/type/df_ctl memcpy */
                /* word6 iocb=ctxt_tag/io_tag wqe=ctxt_tag/xri */
-               bf_set(lpfc_wqe_gen_ct, &wqe->generic,
+               bf_set(wqe_ct, &wqe->xmit_bcast64.wqe_com,
                        ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
+               bf_set(wqe_dbde, &wqe->xmit_bcast64.wqe_com, 1);
+               bf_set(wqe_iod, &wqe->xmit_bcast64.wqe_com, LPFC_WQE_IOD_WRITE);
+               bf_set(wqe_lenloc, &wqe->xmit_bcast64.wqe_com,
+                      LPFC_WQE_LENLOC_WORD3);
+               bf_set(wqe_ebde_cnt, &wqe->xmit_bcast64.wqe_com, 0);
        break;
        case CMD_FCP_IWRITE64_CR:
                command_type = FCP_COMMAND_DATA_OUT;
-               /* The struct for wqe fcp_iwrite has 3 fields that are somewhat
-                * confusing.
-                * word3 is payload_len: byte offset to the sgl entry for the
-                * fcp_command.
-                * word4 is total xfer len, same as the IOCB->ulpParameter.
-                * word5 is initial xfer len 0 = wait for xfer-ready
-                */
-
-               /* Always wait for xfer-ready before sending data */
-               wqe->fcp_iwrite.initial_xfer_len = 0;
-               /* word 4 (xfer length) should have been set on the memcpy */
-
-       /* allow write to fall through to read */
+               /* word3 iocb=iotag wqe=payload_offset_len */
+               /* Add the FCP_CMD and FCP_RSP sizes to get the offset */
+               wqe->fcp_iwrite.payload_offset_len =
+                       xmit_len + sizeof(struct fcp_rsp);
+               /* word4 iocb=parameter wqe=total_xfer_length memcpy */
+               /* word5 iocb=initial_xfer_len wqe=initial_xfer_len memcpy */
+               bf_set(wqe_erp, &wqe->fcp_iwrite.wqe_com,
+                      iocbq->iocb.ulpFCP2Rcvy);
+               bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS);
+               /* Always open the exchange */
+               bf_set(wqe_xc, &wqe->fcp_iwrite.wqe_com, 0);
+               bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1);
+               bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE);
+               bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com,
+                      LPFC_WQE_LENLOC_WORD4);
+               bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0);
+               bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU);
+       break;
        case CMD_FCP_IREAD64_CR:
-               /* FCP_CMD is always the 1st sgl entry */
-               wqe->fcp_iread.payload_len =
+               /* word3 iocb=iotag wqe=payload_offset_len */
+               /* Add the FCP_CMD and FCP_RSP sizes to get the offset */
+               wqe->fcp_iread.payload_offset_len =
                        xmit_len + sizeof(struct fcp_rsp);
-
-               /* word 4 (xfer length) should have been set on the memcpy */
-
-               bf_set(lpfc_wqe_gen_erp, &wqe->generic,
-                       iocbq->iocb.ulpFCP2Rcvy);
-               bf_set(lpfc_wqe_gen_lnk, &wqe->generic, iocbq->iocb.ulpXS);
-               /* The XC bit and the XS bit are similar. The driver never
-                * tracked whether or not the exchange was previouslly open.
-                * XC = Exchange create, 0 is create. 1 is already open.
-                * XS = link cmd: 1 do not close the exchange after command.
-                * XS = 0 close exchange when command completes.
-                * The only time we would not set the XC bit is when the XS bit
-                * is set and we are sending our 2nd or greater command on
-                * this exchange.
-                */
+               /* word4 iocb=parameter wqe=total_xfer_length memcpy */
+               /* word5 iocb=initial_xfer_len wqe=initial_xfer_len memcpy */
+               bf_set(wqe_erp, &wqe->fcp_iread.wqe_com,
+                      iocbq->iocb.ulpFCP2Rcvy);
+               bf_set(wqe_lnk, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpXS);
                /* Always open the exchange */
                bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0);
-
-               wqe->words[10] &= 0xffff0000; /* zero out ebde count */
-               bf_set(lpfc_wqe_gen_pu, &wqe->generic, iocbq->iocb.ulpPU);
-               break;
+               bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1);
+               bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ);
+               bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com,
+                      LPFC_WQE_LENLOC_WORD4);
+               bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0);
+               bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU);
+       break;
        case CMD_FCP_ICMND64_CR:
+               /* word3 iocb=IO_TAG wqe=reserved */
+               wqe->fcp_icmd.rsrvd3 = 0;
+               bf_set(wqe_pu, &wqe->fcp_icmd.wqe_com, 0);
                /* Always open the exchange */
-               bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0);
-
-               wqe->words[4] = 0;
-               wqe->words[10] &= 0xffff0000; /* zero out ebde count */
-               bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
+               bf_set(wqe_xc, &wqe->fcp_icmd.wqe_com, 0);
+               bf_set(wqe_dbde, &wqe->fcp_icmd.wqe_com, 1);
+               bf_set(wqe_iod, &wqe->fcp_icmd.wqe_com, LPFC_WQE_IOD_WRITE);
+               bf_set(wqe_qosd, &wqe->fcp_icmd.wqe_com, 1);
+               bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com,
+                      LPFC_WQE_LENLOC_NONE);
+               bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0);
        break;
        case CMD_GEN_REQUEST64_CR:
-               /* word3 command length is described as byte offset to the
-                * rsp_data. Would always be 16, sizeof(struct sli4_sge)
-                * sgl[0] = cmnd
-                * sgl[1] = rsp.
-                *
-                */
-               wqe->gen_req.command_len = xmit_len;
-               /* Word4 parameter  copied in the memcpy */
-               /* Word5 [rctl, type, df_ctl, la] copied in memcpy */
+               /* word3 iocb=IO_TAG wqe=request_payload_len */
+               wqe->gen_req.request_payload_len = xmit_len;
+               /* word4 iocb=parameter wqe=relative_offset memcpy */
+               /* word5 [rctl, type, df_ctl, la] copied in memcpy */
                /* word6 context tag copied in memcpy */
                if (iocbq->iocb.ulpCt_h  || iocbq->iocb.ulpCt_l) {
                        ct = ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l);
@@ -6144,31 +6152,39 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
                                ct, iocbq->iocb.ulpCommand);
                        return IOCB_ERROR;
                }
-               bf_set(lpfc_wqe_gen_ct, &wqe->generic, 0);
-               bf_set(wqe_tmo, &wqe->gen_req.wqe_com,
-                       iocbq->iocb.ulpTimeout);
-
-               bf_set(lpfc_wqe_gen_pu, &wqe->generic, iocbq->iocb.ulpPU);
+               bf_set(wqe_ct, &wqe->gen_req.wqe_com, 0);
+               bf_set(wqe_tmo, &wqe->gen_req.wqe_com, iocbq->iocb.ulpTimeout);
+               bf_set(wqe_pu, &wqe->gen_req.wqe_com, iocbq->iocb.ulpPU);
+               bf_set(wqe_dbde, &wqe->gen_req.wqe_com, 1);
+               bf_set(wqe_iod, &wqe->gen_req.wqe_com, LPFC_WQE_IOD_READ);
+               bf_set(wqe_qosd, &wqe->gen_req.wqe_com, 1);
+               bf_set(wqe_lenloc, &wqe->gen_req.wqe_com, LPFC_WQE_LENLOC_NONE);
+               bf_set(wqe_ebde_cnt, &wqe->gen_req.wqe_com, 0);
                command_type = OTHER_COMMAND;
        break;
        case CMD_XMIT_ELS_RSP64_CX:
                /* words0-2 BDE memcpy */
-               /* word3 iocb=iotag32 wqe=rsvd */
-               wqe->words[3] = 0;
+               /* word3 iocb=iotag32 wqe=response_payload_len */
+               wqe->xmit_els_rsp.response_payload_len = xmit_len;
                /* word4 iocb=did wge=rsvd. */
-               wqe->words[4] = 0;
+               wqe->xmit_els_rsp.rsvd4 = 0;
                /* word5 iocb=rsvd wge=did */
                bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest,
                         iocbq->iocb.un.elsreq64.remoteID);
-
-               bf_set(lpfc_wqe_gen_ct, &wqe->generic,
-                       ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
-
-               bf_set(lpfc_wqe_gen_pu, &wqe->generic, iocbq->iocb.ulpPU);
-               bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext);
+               bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com,
+                      ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
+               bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU);
+               bf_set(wqe_rcvoxid, &wqe->xmit_els_rsp.wqe_com,
+                      iocbq->iocb.ulpContext);
                if (!iocbq->iocb.ulpCt_h && iocbq->iocb.ulpCt_l)
-                       bf_set(lpfc_wqe_gen_context, &wqe->generic,
+                       bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com,
                               iocbq->vport->vpi + phba->vpi_base);
+               bf_set(wqe_dbde, &wqe->xmit_els_rsp.wqe_com, 1);
+               bf_set(wqe_iod, &wqe->xmit_els_rsp.wqe_com, LPFC_WQE_IOD_WRITE);
+               bf_set(wqe_qosd, &wqe->xmit_els_rsp.wqe_com, 1);
+               bf_set(wqe_lenloc, &wqe->xmit_els_rsp.wqe_com,
+                      LPFC_WQE_LENLOC_WORD3);
+               bf_set(wqe_ebde_cnt, &wqe->xmit_els_rsp.wqe_com, 0);
                command_type = OTHER_COMMAND;
        break;
        case CMD_CLOSE_XRI_CN:
@@ -6193,15 +6209,19 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
                else
                        bf_set(abort_cmd_ia, &wqe->abort_cmd, 0);
                bf_set(abort_cmd_criteria, &wqe->abort_cmd, T_XRI_TAG);
-               wqe->words[5] = 0;
-               bf_set(lpfc_wqe_gen_ct, &wqe->generic,
+               /* word5 iocb=CONTEXT_TAG|IO_TAG wqe=reserved */
+               wqe->abort_cmd.rsrvd5 = 0;
+               bf_set(wqe_ct, &wqe->abort_cmd.wqe_com,
                        ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
                abort_tag = iocbq->iocb.un.acxri.abortIoTag;
                /*
                 * The abort handler will send us CMD_ABORT_XRI_CN or
                 * CMD_CLOSE_XRI_CN and the fw only accepts CMD_ABORT_XRI_CX
                 */
-               bf_set(lpfc_wqe_gen_command, &wqe->generic, CMD_ABORT_XRI_CX);
+               bf_set(wqe_cmnd, &wqe->abort_cmd.wqe_com, CMD_ABORT_XRI_CX);
+               bf_set(wqe_qosd, &wqe->abort_cmd.wqe_com, 1);
+               bf_set(wqe_lenloc, &wqe->abort_cmd.wqe_com,
+                      LPFC_WQE_LENLOC_NONE);
                cmnd = CMD_ABORT_XRI_CX;
                command_type = OTHER_COMMAND;
                xritag = 0;
@@ -6235,18 +6255,14 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
                bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1);
                bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com,
                       iocbq->iocb.ulpContext);
+               bf_set(wqe_qosd, &wqe->xmit_bls_rsp.wqe_com, 1);
+               bf_set(wqe_lenloc, &wqe->xmit_bls_rsp.wqe_com,
+                      LPFC_WQE_LENLOC_NONE);
                /* Overwrite the pre-set comnd type with OTHER_COMMAND */
                command_type = OTHER_COMMAND;
        break;
        case CMD_XRI_ABORTED_CX:
        case CMD_CREATE_XRI_CR: /* Do we expect to use this? */
-               /* words0-2 are all 0's no bde */
-               /* word3 and word4 are rsvrd */
-               wqe->words[3] = 0;
-               wqe->words[4] = 0;
-               /* word5 iocb=rsvd wge=did */
-               /* There is no remote port id in the IOCB? */
-               /* Let this fall through and fail */
        case CMD_IOCB_FCP_IBIDIR64_CR: /* bidirectional xfer */
        case CMD_FCP_TSEND64_CX: /* Target mode send xfer-ready */
        case CMD_FCP_TRSP64_CX: /* Target mode rcv */
@@ -6257,16 +6273,14 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
                                iocbq->iocb.ulpCommand);
                return IOCB_ERROR;
        break;
-
        }
-       bf_set(lpfc_wqe_gen_xri, &wqe->generic, xritag);
-       bf_set(lpfc_wqe_gen_request_tag, &wqe->generic, iocbq->iotag);
-       wqe->generic.abort_tag = abort_tag;
-       bf_set(lpfc_wqe_gen_cmd_type, &wqe->generic, command_type);
-       bf_set(lpfc_wqe_gen_command, &wqe->generic, cmnd);
-       bf_set(lpfc_wqe_gen_class, &wqe->generic, iocbq->iocb.ulpClass);
-       bf_set(lpfc_wqe_gen_cq_id, &wqe->generic, LPFC_WQE_CQ_ID_DEFAULT);
-
+       bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag);
+       bf_set(wqe_reqtag, &wqe->generic.wqe_com, iocbq->iotag);
+       wqe->generic.wqe_com.abort_tag = abort_tag;
+       bf_set(wqe_cmd_type, &wqe->generic.wqe_com, command_type);
+       bf_set(wqe_cmnd, &wqe->generic.wqe_com, cmnd);
+       bf_set(wqe_class, &wqe->generic.wqe_com, iocbq->iocb.ulpClass);
+       bf_set(wqe_cqid, &wqe->generic.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
        return 0;
 }
 
@@ -7257,25 +7271,26 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 }
 
 /**
- * lpfc_sli_issue_abort_iotag - Abort function for a command iocb
+ * lpfc_sli_abort_iotag_issue - Issue abort for a command iocb
  * @phba: Pointer to HBA context object.
  * @pring: Pointer to driver SLI ring object.
  * @cmdiocb: Pointer to driver command iocb object.
  *
- * This function issues an abort iocb for the provided command
- * iocb. This function is called with hbalock held.
- * The function returns 0 when it fails due to memory allocation
- * failure or when the command iocb is an abort request.
+ * This function issues an abort iocb for the provided command iocb down to
+ * the port. Other than the case the outstanding command iocb is an abort
+ * request, this function issues abort out unconditionally. This function is
+ * called with hbalock held. The function returns 0 when it fails due to
+ * memory allocation failure or when the command iocb is an abort request.
  **/
-int
-lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+static int
+lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                           struct lpfc_iocbq *cmdiocb)
 {
        struct lpfc_vport *vport = cmdiocb->vport;
        struct lpfc_iocbq *abtsiocbp;
        IOCB_t *icmd = NULL;
        IOCB_t *iabt = NULL;
-       int retval = IOCB_ERROR;
+       int retval;
 
        /*
         * There are certain command types we don't want to abort.  And we
@@ -7288,18 +7303,6 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
            (cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0)
                return 0;
 
-       /* If we're unloading, don't abort iocb on the ELS ring, but change the
-        * callback so that nothing happens when it finishes.
-        */
-       if ((vport->load_flag & FC_UNLOADING) &&
-           (pring->ringno == LPFC_ELS_RING)) {
-               if (cmdiocb->iocb_flag & LPFC_IO_FABRIC)
-                       cmdiocb->fabric_iocb_cmpl = lpfc_ignore_els_cmpl;
-               else
-                       cmdiocb->iocb_cmpl = lpfc_ignore_els_cmpl;
-               goto abort_iotag_exit;
-       }
-
        /* issue ABTS for this IOCB based on iotag */
        abtsiocbp = __lpfc_sli_get_iocbq(phba);
        if (abtsiocbp == NULL)
@@ -7344,6 +7347,63 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 
        if (retval)
                __lpfc_sli_release_iocbq(phba, abtsiocbp);
+
+       /*
+        * Caller to this routine should check for IOCB_ERROR
+        * and handle it properly.  This routine no longer removes
+        * iocb off txcmplq and call compl in case of IOCB_ERROR.
+        */
+       return retval;
+}
+
+/**
+ * lpfc_sli_issue_abort_iotag - Abort function for a command iocb
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @cmdiocb: Pointer to driver command iocb object.
+ *
+ * This function issues an abort iocb for the provided command iocb. In case
+ * of unloading, the abort iocb will not be issued to commands on the ELS
+ * ring. Instead, the callback function shall be changed to those commands
+ * so that nothing happens when them finishes. This function is called with
+ * hbalock held. The function returns 0 when the command iocb is an abort
+ * request.
+ **/
+int
+lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+                          struct lpfc_iocbq *cmdiocb)
+{
+       struct lpfc_vport *vport = cmdiocb->vport;
+       int retval = IOCB_ERROR;
+       IOCB_t *icmd = NULL;
+
+       /*
+        * There are certain command types we don't want to abort.  And we
+        * don't want to abort commands that are already in the process of
+        * being aborted.
+        */
+       icmd = &cmdiocb->iocb;
+       if (icmd->ulpCommand == CMD_ABORT_XRI_CN ||
+           icmd->ulpCommand == CMD_CLOSE_XRI_CN ||
+           (cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0)
+               return 0;
+
+       /*
+        * If we're unloading, don't abort iocb on the ELS ring, but change
+        * the callback so that nothing happens when it finishes.
+        */
+       if ((vport->load_flag & FC_UNLOADING) &&
+           (pring->ringno == LPFC_ELS_RING)) {
+               if (cmdiocb->iocb_flag & LPFC_IO_FABRIC)
+                       cmdiocb->fabric_iocb_cmpl = lpfc_ignore_els_cmpl;
+               else
+                       cmdiocb->iocb_cmpl = lpfc_ignore_els_cmpl;
+               goto abort_iotag_exit;
+       }
+
+       /* Now, we try to issue the abort to the cmdiocb out */
+       retval = lpfc_sli_abort_iotag_issue(phba, pring, cmdiocb);
+
 abort_iotag_exit:
        /*
         * Caller to this routine should check for IOCB_ERROR
@@ -7353,6 +7413,62 @@ abort_iotag_exit:
        return retval;
 }
 
+/**
+ * lpfc_sli_iocb_ring_abort - Unconditionally abort all iocbs on an iocb ring
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * This function aborts all iocbs in the given ring and frees all the iocb
+ * objects in txq. This function issues abort iocbs unconditionally for all
+ * the iocb commands in txcmplq. The iocbs in the txcmplq is not guaranteed
+ * to complete before the return of this function. The caller is not required
+ * to hold any locks.
+ **/
+static void
+lpfc_sli_iocb_ring_abort(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
+{
+       LIST_HEAD(completions);
+       struct lpfc_iocbq *iocb, *next_iocb;
+
+       if (pring->ringno == LPFC_ELS_RING)
+               lpfc_fabric_abort_hba(phba);
+
+       spin_lock_irq(&phba->hbalock);
+
+       /* Take off all the iocbs on txq for cancelling */
+       list_splice_init(&pring->txq, &completions);
+       pring->txq_cnt = 0;
+
+       /* Next issue ABTS for everything on the txcmplq */
+       list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list)
+               lpfc_sli_abort_iotag_issue(phba, pring, iocb);
+
+       spin_unlock_irq(&phba->hbalock);
+
+       /* Cancel all the IOCBs from the completions list */
+       lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
+                             IOERR_SLI_ABORTED);
+}
+
+/**
+ * lpfc_sli_hba_iocb_abort - Abort all iocbs to an hba.
+ * @phba: pointer to lpfc HBA data structure.
+ *
+ * This routine will abort all pending and outstanding iocbs to an HBA.
+ **/
+void
+lpfc_sli_hba_iocb_abort(struct lpfc_hba *phba)
+{
+       struct lpfc_sli *psli = &phba->sli;
+       struct lpfc_sli_ring *pring;
+       int i;
+
+       for (i = 0; i < psli->num_rings; i++) {
+               pring = &psli->ring[i];
+               lpfc_sli_iocb_ring_abort(phba, pring);
+       }
+}
+
 /**
  * lpfc_sli_validate_fcp_iocb - find commands associated with a vport or LUN
  * @iocbq: Pointer to driver iocb object.
@@ -12242,13 +12358,15 @@ lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index)
        /* Issue the mailbox command asynchronously */
        mboxq->vport = phba->pport;
        mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec;
+
+       spin_lock_irq(&phba->hbalock);
+       phba->hba_flag |= FCF_TS_INPROG;
+       spin_unlock_irq(&phba->hbalock);
+
        rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
        if (rc == MBX_NOT_FINISHED)
                error = -EIO;
        else {
-               spin_lock_irq(&phba->hbalock);
-               phba->hba_flag |= FCF_DISC_INPROGRESS;
-               spin_unlock_irq(&phba->hbalock);
                /* Reset eligible FCF count for new scan */
                if (fcf_index == LPFC_FCOE_FCF_GET_FIRST)
                        phba->fcf.eligible_fcf_cnt = 0;
@@ -12258,21 +12376,21 @@ fail_fcf_scan:
        if (error) {
                if (mboxq)
                        lpfc_sli4_mbox_cmd_free(phba, mboxq);
-               /* FCF scan failed, clear FCF_DISC_INPROGRESS flag */
+               /* FCF scan failed, clear FCF_TS_INPROG flag */
                spin_lock_irq(&phba->hbalock);
-               phba->hba_flag &= ~FCF_DISC_INPROGRESS;
+               phba->hba_flag &= ~FCF_TS_INPROG;
                spin_unlock_irq(&phba->hbalock);
        }
        return error;
 }
 
 /**
- * lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for round robin fcf.
+ * lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for roundrobin fcf.
  * @phba: pointer to lpfc hba data structure.
  * @fcf_index: FCF table entry offset.
  *
  * This routine is invoked to read an FCF record indicated by @fcf_index
- * and to use it for FLOGI round robin FCF failover.
+ * and to use it for FLOGI roundrobin FCF failover.
  *
  * Return 0 if the mailbox command is submitted sucessfully, none 0
  * otherwise.
@@ -12318,7 +12436,7 @@ fail_fcf_read:
  * @fcf_index: FCF table entry offset.
  *
  * This routine is invoked to read an FCF record indicated by @fcf_index to
- * determine whether it's eligible for FLOGI round robin failover list.
+ * determine whether it's eligible for FLOGI roundrobin failover list.
  *
  * Return 0 if the mailbox command is submitted sucessfully, none 0
  * otherwise.
@@ -12364,7 +12482,7 @@ fail_fcf_read:
  *
  * This routine is to get the next eligible FCF record index in a round
  * robin fashion. If the next eligible FCF record index equals to the
- * initial round robin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF)
+ * initial roundrobin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF)
  * shall be returned, otherwise, the next eligible FCF record's index
  * shall be returned.
  **/
@@ -12392,28 +12510,10 @@ lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
                return LPFC_FCOE_FCF_NEXT_NONE;
        }
 
-       /* Check roundrobin failover index bmask stop condition */
-       if (next_fcf_index == phba->fcf.fcf_rr_init_indx) {
-               if (!(phba->fcf.fcf_flag & FCF_REDISC_RRU)) {
-                       lpfc_printf_log(phba, KERN_WARNING, LOG_FIP,
-                                       "2847 Round robin failover FCF index "
-                                       "search hit stop condition:x%x\n",
-                                       next_fcf_index);
-                       return LPFC_FCOE_FCF_NEXT_NONE;
-               }
-               /* The roundrobin failover index bmask updated, start over */
-               lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                               "2848 Round robin failover FCF index bmask "
-                               "updated, start over\n");
-               spin_lock_irq(&phba->hbalock);
-               phba->fcf.fcf_flag &= ~FCF_REDISC_RRU;
-               spin_unlock_irq(&phba->hbalock);
-               return phba->fcf.fcf_rr_init_indx;
-       }
-
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                       "2845 Get next round robin failover "
-                       "FCF index x%x\n", next_fcf_index);
+                       "2845 Get next roundrobin failover FCF (x%x)\n",
+                       next_fcf_index);
+
        return next_fcf_index;
 }
 
@@ -12422,7 +12522,7 @@ lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba)
  * @phba: pointer to lpfc hba data structure.
  *
  * This routine sets the FCF record index in to the eligible bmask for
- * round robin failover search. It checks to make sure that the index
+ * roundrobin failover search. It checks to make sure that the index
  * does not go beyond the range of the driver allocated bmask dimension
  * before setting the bit.
  *
@@ -12434,22 +12534,16 @@ lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index)
 {
        if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
                lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
-                               "2610 HBA FCF index reached driver's "
-                               "book keeping dimension: fcf_index:%d, "
-                               "driver_bmask_max:%d\n",
+                               "2610 FCF (x%x) reached driver's book "
+                               "keeping dimension:x%x\n",
                                fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
                return -EINVAL;
        }
        /* Set the eligible FCF record index bmask */
        set_bit(fcf_index, phba->fcf.fcf_rr_bmask);
 
-       /* Set the roundrobin index bmask updated */
-       spin_lock_irq(&phba->hbalock);
-       phba->fcf.fcf_flag |= FCF_REDISC_RRU;
-       spin_unlock_irq(&phba->hbalock);
-
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                       "2790 Set FCF index x%x to round robin failover "
+                       "2790 Set FCF (x%x) to roundrobin FCF failover "
                        "bmask\n", fcf_index);
 
        return 0;
@@ -12460,7 +12554,7 @@ lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index)
  * @phba: pointer to lpfc hba data structure.
  *
  * This routine clears the FCF record index from the eligible bmask for
- * round robin failover search. It checks to make sure that the index
+ * roundrobin failover search. It checks to make sure that the index
  * does not go beyond the range of the driver allocated bmask dimension
  * before clearing the bit.
  **/
@@ -12469,9 +12563,8 @@ lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index)
 {
        if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) {
                lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
-                               "2762 HBA FCF index goes beyond driver's "
-                               "book keeping dimension: fcf_index:%d, "
-                               "driver_bmask_max:%d\n",
+                               "2762 FCF (x%x) reached driver's book "
+                               "keeping dimension:x%x\n",
                                fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX);
                return;
        }
@@ -12479,7 +12572,7 @@ lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index)
        clear_bit(fcf_index, phba->fcf.fcf_rr_bmask);
 
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                       "2791 Clear FCF index x%x from round robin failover "
+                       "2791 Clear FCF (x%x) from roundrobin failover "
                        "bmask\n", fcf_index);
 }
 
@@ -12530,8 +12623,7 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
                }
        } else {
                lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                               "2775 Start FCF rediscovery quiescent period "
-                               "wait timer before scaning FCF table\n");
+                               "2775 Start FCF rediscover quiescent timer\n");
                /*
                 * Start FCF rediscovery wait timer for pending FCF
                 * before rescan FCF record table.
index a0ca572ec28be4a4105a08f4360459aa8f091abf..c4483feb8b71a32a4198175ac91a0c142a647e61 100644 (file)
  *******************************************************************/
 
 #define LPFC_ACTIVE_MBOX_WAIT_CNT               100
+#define LPFC_XRI_EXCH_BUSY_WAIT_TMO            10000
+#define LPFC_XRI_EXCH_BUSY_WAIT_T1             10
+#define LPFC_XRI_EXCH_BUSY_WAIT_T2              30000
 #define LPFC_RELEASE_NOTIFICATION_INTERVAL     32
 #define LPFC_GET_QE_REL_INT                    32
 #define LPFC_RPI_LOW_WATER_MARK                        10
 
+#define LPFC_UNREG_FCF                          1
+#define LPFC_SKIP_UNREG_FCF                     0
+
 /* Amount of time in seconds for waiting FCF rediscovery to complete */
 #define LPFC_FCF_REDISCOVER_WAIT_TMO           2000 /* msec */
 
@@ -163,9 +169,8 @@ struct lpfc_fcf {
 #define FCF_REDISC_PEND        0x80 /* FCF rediscovery pending */
 #define FCF_REDISC_EVT 0x100 /* FCF rediscovery event to worker thread */
 #define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */
-#define FCF_REDISC_RRU 0x400 /* Roundrobin bitmap updated */
+#define FCF_REDISC_PROG (FCF_REDISC_PEND | FCF_REDISC_EVT)
        uint32_t addr_mode;
-       uint16_t fcf_rr_init_indx;
        uint32_t eligible_fcf_cnt;
        struct lpfc_fcf_rec current_rec;
        struct lpfc_fcf_rec failover_rec;
index f93120e4c7961e632e6fb79c9aa2ee28ad029e38..7a1b5b112a0bca1c26481063875576430a7ac664 100644 (file)
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.17"
+#define LPFC_DRIVER_VERSION "8.3.18"
 #define LPFC_DRIVER_NAME               "lpfc"
 #define LPFC_SP_DRIVER_HANDLER_NAME    "lpfc:sp"
 #define LPFC_FP_DRIVER_HANDLER_NAME    "lpfc:fp"
index d3c9cdee292b11cdcf44cd9b163bec3e7749814d..eb29d508513148653fb492df24cee9ab0b14cb17 100644 (file)
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.04.17.1-rc1
+ * Version     : v00.00.04.31-rc1
  *
  * Authors:
  *     (email-id : megaraidlinux@lsi.com)
@@ -56,6 +56,15 @@ module_param_named(poll_mode_io, poll_mode_io, int, 0);
 MODULE_PARM_DESC(poll_mode_io,
        "Complete cmds from IO path, (default=0)");
 
+/*
+ * Number of sectors per IO command
+ * Will be set in megasas_init_mfi if user does not provide
+ */
+static unsigned int max_sectors;
+module_param_named(max_sectors, max_sectors, int, 0);
+MODULE_PARM_DESC(max_sectors,
+       "Maximum number of sectors per IO command");
+
 MODULE_LICENSE("GPL");
 MODULE_VERSION(MEGASAS_VERSION);
 MODULE_AUTHOR("megaraidlinux@lsi.com");
@@ -103,6 +112,7 @@ static int megasas_poll_wait_aen;
 static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
 static u32 support_poll_for_event;
 static u32 megasas_dbg_lvl;
+static u32 support_device_change;
 
 /* define lock for aen poll */
 spinlock_t poll_aen_lock;
@@ -718,6 +728,10 @@ static int
 megasas_check_reset_gen2(struct megasas_instance *instance,
                struct megasas_register_set __iomem *regs)
 {
+       if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
+               return 1;
+       }
+
        return 0;
 }
 
@@ -930,6 +944,7 @@ megasas_make_sgl_skinny(struct megasas_instance *instance,
                        mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
                        mfi_sgl->sge_skinny[i].phys_addr =
                                                sg_dma_address(os_sgl);
+                       mfi_sgl->sge_skinny[i].flag = 0;
                }
        }
        return sge_count;
@@ -1557,6 +1572,28 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
        }
 }
 
+static void
+megasas_internal_reset_defer_cmds(struct megasas_instance *instance);
+
+static void
+process_fw_state_change_wq(struct work_struct *work);
+
+void megasas_do_ocr(struct megasas_instance *instance)
+{
+       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
+       (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
+       (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
+               *instance->consumer     = MEGASAS_ADPRESET_INPROG_SIGN;
+       }
+       instance->instancet->disable_intr(instance->reg_set);
+       instance->adprecovery   = MEGASAS_ADPRESET_SM_INFAULT;
+       instance->issuepend_done = 0;
+
+       atomic_set(&instance->fw_outstanding, 0);
+       megasas_internal_reset_defer_cmds(instance);
+       process_fw_state_change_wq(&instance->work_init);
+}
+
 /**
  * megasas_wait_for_outstanding -      Wait for all outstanding cmds
  * @instance:                          Adapter soft state
@@ -1574,6 +1611,8 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
        unsigned long flags;
        struct list_head clist_local;
        struct megasas_cmd *reset_cmd;
+       u32 fw_state;
+       u8 kill_adapter_flag;
 
        spin_lock_irqsave(&instance->hba_lock, flags);
        adprecovery = instance->adprecovery;
@@ -1659,7 +1698,45 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
                msleep(1000);
        }
 
-       if (atomic_read(&instance->fw_outstanding)) {
+       i = 0;
+       kill_adapter_flag = 0;
+       do {
+               fw_state = instance->instancet->read_fw_status_reg(
+                                       instance->reg_set) & MFI_STATE_MASK;
+               if ((fw_state == MFI_STATE_FAULT) &&
+                       (instance->disableOnlineCtrlReset == 0)) {
+                       if (i == 3) {
+                               kill_adapter_flag = 2;
+                               break;
+                       }
+                       megasas_do_ocr(instance);
+                       kill_adapter_flag = 1;
+
+                       /* wait for 1 secs to let FW finish the pending cmds */
+                       msleep(1000);
+               }
+               i++;
+       } while (i <= 3);
+
+       if (atomic_read(&instance->fw_outstanding) &&
+                                       !kill_adapter_flag) {
+               if (instance->disableOnlineCtrlReset == 0) {
+
+                       megasas_do_ocr(instance);
+
+                       /* wait for 5 secs to let FW finish the pending cmds */
+                       for (i = 0; i < wait_time; i++) {
+                               int outstanding =
+                                       atomic_read(&instance->fw_outstanding);
+                               if (!outstanding)
+                                       return SUCCESS;
+                               msleep(1000);
+                       }
+               }
+       }
+
+       if (atomic_read(&instance->fw_outstanding) ||
+                                       (kill_adapter_flag == 2)) {
                printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n");
                /*
                * Send signal to FW to stop processing any pending cmds.
@@ -2669,6 +2746,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
                        return -ENOMEM;
                }
 
+               memset(cmd->frame, 0, total_sz);
                cmd->frame->io.context = cmd->index;
                cmd->frame->io.pad_0 = 0;
        }
@@ -3585,6 +3663,27 @@ static int megasas_io_attach(struct megasas_instance *instance)
                        instance->max_fw_cmds - MEGASAS_INT_CMDS;
        host->this_id = instance->init_id;
        host->sg_tablesize = instance->max_num_sge;
+       /*
+        * Check if the module parameter value for max_sectors can be used
+        */
+       if (max_sectors && max_sectors < instance->max_sectors_per_req)
+               instance->max_sectors_per_req = max_sectors;
+       else {
+               if (max_sectors) {
+                       if (((instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
+                               (instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0079GEN2)) &&
+                               (max_sectors <= MEGASAS_MAX_SECTORS)) {
+                               instance->max_sectors_per_req = max_sectors;
+                       } else {
+                       printk(KERN_INFO "megasas: max_sectors should be > 0"
+                               "and <= %d (or < 1MB for GEN2 controller)\n",
+                               instance->max_sectors_per_req);
+                       }
+               }
+       }
+
        host->max_sectors = instance->max_sectors_per_req;
        host->cmd_per_lun = 128;
        host->max_channel = MEGASAS_MAX_CHANNELS - 1;
@@ -4658,6 +4757,15 @@ megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
 static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
                        megasas_sysfs_show_support_poll_for_event, NULL);
 
+ static ssize_t
+megasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf)
+{
+       return sprintf(buf, "%u\n", support_device_change);
+}
+
+static DRIVER_ATTR(support_device_change, S_IRUGO,
+                       megasas_sysfs_show_support_device_change, NULL);
+
 static ssize_t
 megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
 {
@@ -4978,6 +5086,7 @@ static int __init megasas_init(void)
               MEGASAS_EXT_VERSION);
 
        support_poll_for_event = 2;
+       support_device_change = 1;
 
        memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
 
@@ -5026,8 +5135,17 @@ static int __init megasas_init(void)
        if (rval)
                goto err_dcf_poll_mode_io;
 
+       rval = driver_create_file(&megasas_pci_driver.driver,
+                               &driver_attr_support_device_change);
+       if (rval)
+               goto err_dcf_support_device_change;
+
        return rval;
 
+err_dcf_support_device_change:
+       driver_remove_file(&megasas_pci_driver.driver,
+                 &driver_attr_poll_mode_io);
+
 err_dcf_poll_mode_io:
        driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_dbg_lvl);
@@ -5057,6 +5175,10 @@ static void __exit megasas_exit(void)
                           &driver_attr_poll_mode_io);
        driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_dbg_lvl);
+       driver_remove_file(&megasas_pci_driver.driver,
+                       &driver_attr_support_poll_for_event);
+       driver_remove_file(&megasas_pci_driver.driver,
+                       &driver_attr_support_device_change);
        driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_release_date);
        driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
index 16a4f68a34b0db0fa48145eb42c0f90aae25ec07..ad16f5e600462955bec5c5e4878119a4093f1ae7 100644 (file)
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                        "00.00.04.17.1-rc1"
-#define MEGASAS_RELDATE                        "Oct. 29, 2009"
-#define MEGASAS_EXT_VERSION            "Thu. Oct. 29, 11:41:51 PST 2009"
+#define MEGASAS_VERSION                        "00.00.04.31-rc1"
+#define MEGASAS_RELDATE                        "May 3, 2010"
+#define MEGASAS_EXT_VERSION            "Mon. May 3, 11:41:51 PST 2010"
 
 /*
  * Device IDs
@@ -706,6 +706,7 @@ struct megasas_ctrl_info {
 #define MEGASAS_MAX_LD_IDS                     (MEGASAS_MAX_LD_CHANNELS * \
                                                MEGASAS_MAX_DEV_PER_CHANNEL)
 
+#define MEGASAS_MAX_SECTORS                    (2*1024)
 #define MEGASAS_DBG_LVL                                1
 
 #define MEGASAS_FW_BUSY                                1
index e88bbdde49c5066b4bfb9fa2d8b5822115777cd8..0433ea6f27c9c2db97c464ca238afce39ebd0fcb 100644 (file)
@@ -452,10 +452,6 @@ void osd_end_request(struct osd_request *or)
 {
        struct request *rq = or->request;
 
-       _osd_free_seg(or, &or->set_attr);
-       _osd_free_seg(or, &or->enc_get_attr);
-       _osd_free_seg(or, &or->get_attr);
-
        if (rq) {
                if (rq->next_rq) {
                        _put_request(rq->next_rq);
@@ -464,6 +460,12 @@ void osd_end_request(struct osd_request *or)
 
                _put_request(rq);
        }
+
+       _osd_free_seg(or, &or->get_attr);
+       _osd_free_seg(or, &or->enc_get_attr);
+       _osd_free_seg(or, &or->set_attr);
+       _osd_free_seg(or, &or->cdb_cont);
+
        _osd_request_free(or);
 }
 EXPORT_SYMBOL(osd_end_request);
@@ -547,6 +549,12 @@ static int _osd_realloc_seg(struct osd_request *or,
        return 0;
 }
 
+static int _alloc_cdb_cont(struct osd_request *or, unsigned total_bytes)
+{
+       OSD_DEBUG("total_bytes=%d\n", total_bytes);
+       return _osd_realloc_seg(or, &or->cdb_cont, total_bytes);
+}
+
 static int _alloc_set_attr_list(struct osd_request *or,
        const struct osd_attr *oa, unsigned nelem, unsigned add_bytes)
 {
@@ -885,6 +893,199 @@ int osd_req_read_kern(struct osd_request *or,
 }
 EXPORT_SYMBOL(osd_req_read_kern);
 
+static int _add_sg_continuation_descriptor(struct osd_request *or,
+       const struct osd_sg_entry *sglist, unsigned numentries, u64 *len)
+{
+       struct osd_sg_continuation_descriptor *oscd;
+       u32 oscd_size;
+       unsigned i;
+       int ret;
+
+       oscd_size = sizeof(*oscd) + numentries * sizeof(oscd->entries[0]);
+
+       if (!or->cdb_cont.total_bytes) {
+               /* First time, jump over the header, we will write to:
+                *      cdb_cont.buff + cdb_cont.total_bytes
+                */
+               or->cdb_cont.total_bytes =
+                               sizeof(struct osd_continuation_segment_header);
+       }
+
+       ret = _alloc_cdb_cont(or, or->cdb_cont.total_bytes + oscd_size);
+       if (unlikely(ret))
+               return ret;
+
+       oscd = or->cdb_cont.buff + or->cdb_cont.total_bytes;
+       oscd->hdr.type = cpu_to_be16(SCATTER_GATHER_LIST);
+       oscd->hdr.pad_length = 0;
+       oscd->hdr.length = cpu_to_be32(oscd_size - sizeof(*oscd));
+
+       *len = 0;
+       /* copy the sg entries and convert to network byte order */
+       for (i = 0; i < numentries; i++) {
+               oscd->entries[i].offset = cpu_to_be64(sglist[i].offset);
+               oscd->entries[i].len    = cpu_to_be64(sglist[i].len);
+               *len += sglist[i].len;
+       }
+
+       or->cdb_cont.total_bytes += oscd_size;
+       OSD_DEBUG("total_bytes=%d oscd_size=%d numentries=%d\n",
+                 or->cdb_cont.total_bytes, oscd_size, numentries);
+       return 0;
+}
+
+static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key)
+{
+       struct request_queue *req_q = osd_request_queue(or->osd_dev);
+       struct bio *bio;
+       struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
+       struct osd_continuation_segment_header *cont_seg_hdr;
+
+       if (!or->cdb_cont.total_bytes)
+               return 0;
+
+       cont_seg_hdr = or->cdb_cont.buff;
+       cont_seg_hdr->format = CDB_CONTINUATION_FORMAT_V2;
+       cont_seg_hdr->service_action = cdbh->varlen_cdb.service_action;
+
+       /* create a bio for continuation segment */
+       bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes,
+                          GFP_KERNEL);
+       if (unlikely(!bio))
+               return -ENOMEM;
+
+       bio->bi_rw |= REQ_WRITE;
+
+       /* integrity check the continuation before the bio is linked
+        * with the other data segments since the continuation
+        * integrity is separate from the other data segments.
+        */
+       osd_sec_sign_data(cont_seg_hdr->integrity_check, bio, cap_key);
+
+       cdbh->v2.cdb_continuation_length = cpu_to_be32(or->cdb_cont.total_bytes);
+
+       /* we can't use _req_append_segment, because we need to link in the
+        * continuation bio to the head of the bio list - the
+        * continuation segment (if it exists) is always the first segment in
+        * the out data buffer.
+        */
+       bio->bi_next = or->out.bio;
+       or->out.bio = bio;
+       or->out.total_bytes += or->cdb_cont.total_bytes;
+
+       return 0;
+}
+
+/* osd_req_write_sg: Takes a @bio that points to the data out buffer and an
+ * @sglist that has the scatter gather entries. Scatter-gather enables a write
+ * of multiple none-contiguous areas of an object, in a single call. The extents
+ * may overlap and/or be in any order. The only constrain is that:
+ *     total_bytes(sglist) >= total_bytes(bio)
+ */
+int osd_req_write_sg(struct osd_request *or,
+       const struct osd_obj_id *obj, struct bio *bio,
+       const struct osd_sg_entry *sglist, unsigned numentries)
+{
+       u64 len;
+       int ret = _add_sg_continuation_descriptor(or, sglist, numentries, &len);
+
+       if (ret)
+               return ret;
+       osd_req_write(or, obj, 0, bio, len);
+
+       return 0;
+}
+EXPORT_SYMBOL(osd_req_write_sg);
+
+/* osd_req_read_sg: Read multiple extents of an object into @bio
+ * See osd_req_write_sg
+ */
+int osd_req_read_sg(struct osd_request *or,
+       const struct osd_obj_id *obj, struct bio *bio,
+       const struct osd_sg_entry *sglist, unsigned numentries)
+{
+       u64 len;
+       int ret = _add_sg_continuation_descriptor(or, sglist, numentries, &len);
+
+       if (ret)
+               return ret;
+       osd_req_read(or, obj, 0, bio, len);
+
+       return 0;
+}
+EXPORT_SYMBOL(osd_req_read_sg);
+
+/* SG-list write/read Kern API
+ *
+ * osd_req_{write,read}_sg_kern takes an array of @buff pointers and an array
+ * of sg_entries. @numentries indicates how many pointers and sg_entries there
+ * are.  By requiring an array of buff pointers. This allows a caller to do a
+ * single write/read and scatter into multiple buffers.
+ * NOTE: Each buffer + len should not cross a page boundary.
+ */
+static struct bio *_create_sg_bios(struct osd_request *or,
+       void **buff, const struct osd_sg_entry *sglist, unsigned numentries)
+{
+       struct request_queue *q = osd_request_queue(or->osd_dev);
+       struct bio *bio;
+       unsigned i;
+
+       bio = bio_kmalloc(GFP_KERNEL, numentries);
+       if (unlikely(!bio)) {
+               OSD_DEBUG("Faild to allocate BIO size=%u\n", numentries);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       for (i = 0; i < numentries; i++) {
+               unsigned offset = offset_in_page(buff[i]);
+               struct page *page = virt_to_page(buff[i]);
+               unsigned len = sglist[i].len;
+               unsigned added_len;
+
+               BUG_ON(offset + len > PAGE_SIZE);
+               added_len = bio_add_pc_page(q, bio, page, len, offset);
+               if (unlikely(len != added_len)) {
+                       OSD_DEBUG("bio_add_pc_page len(%d) != added_len(%d)\n",
+                                 len, added_len);
+                       bio_put(bio);
+                       return ERR_PTR(-ENOMEM);
+               }
+       }
+
+       return bio;
+}
+
+int osd_req_write_sg_kern(struct osd_request *or,
+       const struct osd_obj_id *obj, void **buff,
+       const struct osd_sg_entry *sglist, unsigned numentries)
+{
+       struct bio *bio = _create_sg_bios(or, buff, sglist, numentries);
+       if (IS_ERR(bio))
+               return PTR_ERR(bio);
+
+       bio->bi_rw |= REQ_WRITE;
+       osd_req_write_sg(or, obj, bio, sglist, numentries);
+
+       return 0;
+}
+EXPORT_SYMBOL(osd_req_write_sg_kern);
+
+int osd_req_read_sg_kern(struct osd_request *or,
+       const struct osd_obj_id *obj, void **buff,
+       const struct osd_sg_entry *sglist, unsigned numentries)
+{
+       struct bio *bio = _create_sg_bios(or, buff, sglist, numentries);
+       if (IS_ERR(bio))
+               return PTR_ERR(bio);
+
+       osd_req_read_sg(or, obj, bio, sglist, numentries);
+
+       return 0;
+}
+EXPORT_SYMBOL(osd_req_read_sg_kern);
+
+
+
 void osd_req_get_attributes(struct osd_request *or,
        const struct osd_obj_id *obj)
 {
@@ -1218,17 +1419,18 @@ int osd_req_add_get_attr_page(struct osd_request *or,
        or->get_attr.buff = attar_page;
        or->get_attr.total_bytes = max_page_len;
 
-       or->set_attr.buff = set_one_attr->val_ptr;
-       or->set_attr.total_bytes = set_one_attr->len;
-
        cdbh->attrs_page.get_attr_page = cpu_to_be32(page_id);
        cdbh->attrs_page.get_attr_alloc_length = cpu_to_be32(max_page_len);
-       /* ocdb->attrs_page.get_attr_offset; */
+
+       if (!set_one_attr || !set_one_attr->attr_page)
+               return 0; /* The set is optional */
+
+       or->set_attr.buff = set_one_attr->val_ptr;
+       or->set_attr.total_bytes = set_one_attr->len;
 
        cdbh->attrs_page.set_attr_page = cpu_to_be32(set_one_attr->attr_page);
        cdbh->attrs_page.set_attr_id = cpu_to_be32(set_one_attr->attr_id);
        cdbh->attrs_page.set_attr_length = cpu_to_be32(set_one_attr->len);
-       /* ocdb->attrs_page.set_attr_offset; */
        return 0;
 }
 EXPORT_SYMBOL(osd_req_add_get_attr_page);
@@ -1248,11 +1450,14 @@ static int _osd_req_finalize_attr_page(struct osd_request *or)
        if (ret)
                return ret;
 
+       if (or->set_attr.total_bytes == 0)
+               return 0;
+
        /* set one value */
        cdbh->attrs_page.set_attr_offset =
                osd_req_encode_offset(or, or->out.total_bytes, &out_padding);
 
-       ret = _req_append_segment(or, out_padding, &or->enc_get_attr, NULL,
+       ret = _req_append_segment(or, out_padding, &or->set_attr, NULL,
                                  &or->out);
        return ret;
 }
@@ -1276,7 +1481,8 @@ static inline void osd_sec_parms_set_in_offset(bool is_v1,
 }
 
 static int _osd_req_finalize_data_integrity(struct osd_request *or,
-       bool has_in, bool has_out, u64 out_data_bytes, const u8 *cap_key)
+       bool has_in, bool has_out, struct bio *out_data_bio, u64 out_data_bytes,
+       const u8 *cap_key)
 {
        struct osd_security_parameters *sec_parms = _osd_req_sec_params(or);
        int ret;
@@ -1307,7 +1513,7 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or,
                or->out.last_seg = NULL;
 
                /* they are now all chained to request sign them all together */
-               osd_sec_sign_data(&or->out_data_integ, or->out.req->bio,
+               osd_sec_sign_data(&or->out_data_integ, out_data_bio,
                                  cap_key);
        }
 
@@ -1403,6 +1609,8 @@ int osd_finalize_request(struct osd_request *or,
 {
        struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
        bool has_in, has_out;
+        /* Save for data_integrity without the cdb_continuation */
+       struct bio *out_data_bio = or->out.bio;
        u64 out_data_bytes = or->out.total_bytes;
        int ret;
 
@@ -1418,9 +1626,14 @@ int osd_finalize_request(struct osd_request *or,
        osd_set_caps(&or->cdb, cap);
 
        has_in = or->in.bio || or->get_attr.total_bytes;
-       has_out = or->out.bio || or->set_attr.total_bytes ||
-               or->enc_get_attr.total_bytes;
+       has_out = or->out.bio || or->cdb_cont.total_bytes ||
+               or->set_attr.total_bytes || or->enc_get_attr.total_bytes;
 
+       ret = _osd_req_finalize_cdb_cont(or, cap_key);
+       if (ret) {
+               OSD_DEBUG("_osd_req_finalize_cdb_cont failed\n");
+               return ret;
+       }
        ret = _init_blk_request(or, has_in, has_out);
        if (ret) {
                OSD_DEBUG("_init_blk_request failed\n");
@@ -1458,7 +1671,8 @@ int osd_finalize_request(struct osd_request *or,
        }
 
        ret = _osd_req_finalize_data_integrity(or, has_in, has_out,
-                                              out_data_bytes, cap_key);
+                                              out_data_bio, out_data_bytes,
+                                              cap_key);
        if (ret)
                return ret;
 
index 4b8765785aeb0cb3020acdb51b1b0218e42bac34..cf89091e4c3d3befec59b89425792dcad23e2a87 100644 (file)
@@ -1594,10 +1594,12 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
        cfg_entry = &ccn_hcam->cfg_entry;
        fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
 
-       pmcraid_info
-               ("CCN(%x): %x type: %x lost: %x flags: %x res: %x:%x:%x:%x\n",
+       pmcraid_info("CCN(%x): %x timestamp: %llx type: %x lost: %x flags: %x \
+                res: %x:%x:%x:%x\n",
                 pinstance->ccn.hcam->ilid,
                 pinstance->ccn.hcam->op_code,
+               ((pinstance->ccn.hcam->timestamp1) |
+               ((pinstance->ccn.hcam->timestamp2 & 0xffffffffLL) << 32)),
                 pinstance->ccn.hcam->notification_type,
                 pinstance->ccn.hcam->notification_lost,
                 pinstance->ccn.hcam->flags,
@@ -1850,6 +1852,7 @@ static void pmcraid_process_ccn(struct pmcraid_cmd *cmd)
  *   none
  */
 static void pmcraid_initiate_reset(struct pmcraid_instance *);
+static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd);
 
 static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
 {
@@ -1881,6 +1884,10 @@ static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
                                               lock_flags);
                        return;
                }
+               if (fd_ioasc == PMCRAID_IOASC_TIME_STAMP_OUT_OF_SYNC) {
+                       pinstance->timestamp_error = 1;
+                       pmcraid_set_timestamp(cmd);
+               }
        } else {
                dev_info(&pinstance->pdev->dev,
                        "Host RCB(LDN) failed with IOASC: 0x%08X\n", ioasc);
@@ -3363,7 +3370,7 @@ static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen)
        sg_size = buflen;
 
        for (i = 0; i < num_elem; i++) {
-               page = alloc_pages(GFP_KERNEL|GFP_DMA, order);
+               page = alloc_pages(GFP_KERNEL|GFP_DMA|__GFP_ZERO, order);
                if (!page) {
                        for (j = i - 1; j >= 0; j--)
                                __free_pages(sg_page(&scatterlist[j]), order);
@@ -3739,6 +3746,7 @@ static long pmcraid_ioctl_passthrough(
        unsigned long request_buffer;
        unsigned long request_offset;
        unsigned long lock_flags;
+       void *ioasa;
        u32 ioasc;
        int request_size;
        int buffer_size;
@@ -3780,6 +3788,11 @@ static long pmcraid_ioctl_passthrough(
        rc = __copy_from_user(buffer,
                             (struct pmcraid_passthrough_ioctl_buffer *) arg,
                             sizeof(struct pmcraid_passthrough_ioctl_buffer));
+
+       ioasa =
+       (void *)(arg +
+               offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa));
+
        if (rc) {
                pmcraid_err("ioctl: can't copy passthrough buffer\n");
                rc = -EFAULT;
@@ -3947,22 +3960,14 @@ static long pmcraid_ioctl_passthrough(
        }
 
 out_handle_response:
-       /* If the command failed for any reason, copy entire IOASA buffer and
-        * return IOCTL success. If copying IOASA to user-buffer fails, return
+       /* copy entire IOASA buffer and return IOCTL success.
+        * If copying IOASA to user-buffer fails, return
         * EFAULT
         */
-       if (PMCRAID_IOASC_SENSE_KEY(le32_to_cpu(cmd->ioa_cb->ioasa.ioasc))) {
-               void *ioasa =
-                   (void *)(arg +
-                   offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa));
-
-               pmcraid_info("command failed with %x\n",
-                            le32_to_cpu(cmd->ioa_cb->ioasa.ioasc));
-               if (copy_to_user(ioasa, &cmd->ioa_cb->ioasa,
-                                sizeof(struct pmcraid_ioasa))) {
-                       pmcraid_err("failed to copy ioasa buffer to user\n");
-                       rc = -EFAULT;
-               }
+       if (copy_to_user(ioasa, &cmd->ioa_cb->ioasa,
+               sizeof(struct pmcraid_ioasa))) {
+               pmcraid_err("failed to copy ioasa buffer to user\n");
+               rc = -EFAULT;
        }
 
        /* If the data transfer was from device, copy the data onto user
@@ -5147,6 +5152,16 @@ static void pmcraid_release_buffers(struct pmcraid_instance *pinstance)
                pinstance->inq_data = NULL;
                pinstance->inq_data_baddr = 0;
        }
+
+       if (pinstance->timestamp_data != NULL) {
+               pci_free_consistent(pinstance->pdev,
+                                   sizeof(struct pmcraid_timestamp_data),
+                                   pinstance->timestamp_data,
+                                   pinstance->timestamp_data_baddr);
+
+               pinstance->timestamp_data = NULL;
+               pinstance->timestamp_data_baddr = 0;
+       }
 }
 
 /**
@@ -5205,6 +5220,20 @@ static int __devinit pmcraid_init_buffers(struct pmcraid_instance *pinstance)
                return -ENOMEM;
        }
 
+       /* allocate DMAable memory for set timestamp data buffer */
+       pinstance->timestamp_data = pci_alloc_consistent(
+                                       pinstance->pdev,
+                                       sizeof(struct pmcraid_timestamp_data),
+                                       &pinstance->timestamp_data_baddr);
+
+       if (pinstance->timestamp_data == NULL) {
+               pmcraid_err("couldn't allocate DMA memory for \
+                               set time_stamp \n");
+               pmcraid_release_buffers(pinstance);
+               return -ENOMEM;
+       }
+
+
        /* Initialize all the command blocks and add them to free pool. No
         * need to lock (free_pool_lock) as this is done in initialization
         * itself
@@ -5609,6 +5638,68 @@ static void pmcraid_set_supported_devs(struct pmcraid_cmd *cmd)
        return;
 }
 
+/**
+ * pmcraid_set_timestamp - set the timestamp to IOAFP
+ *
+ * @cmd: pointer to pmcraid_cmd structure
+ *
+ * Return Value
+ *  0 for success or non-zero for failure cases
+ */
+static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd)
+{
+       struct pmcraid_instance *pinstance = cmd->drv_inst;
+       struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
+       __be32 time_stamp_len = cpu_to_be32(PMCRAID_TIMESTAMP_LEN);
+       struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+
+       struct timeval tv;
+       __le64 timestamp;
+
+       do_gettimeofday(&tv);
+       timestamp = tv.tv_sec * 1000;
+
+       pinstance->timestamp_data->timestamp[0] = (__u8)(timestamp);
+       pinstance->timestamp_data->timestamp[1] = (__u8)((timestamp) >> 8);
+       pinstance->timestamp_data->timestamp[2] = (__u8)((timestamp) >> 16);
+       pinstance->timestamp_data->timestamp[3] = (__u8)((timestamp) >> 24);
+       pinstance->timestamp_data->timestamp[4] = (__u8)((timestamp) >> 32);
+       pinstance->timestamp_data->timestamp[5] = (__u8)((timestamp)  >> 40);
+
+       pmcraid_reinit_cmdblk(cmd);
+       ioarcb->request_type = REQ_TYPE_SCSI;
+       ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
+       ioarcb->cdb[0] = PMCRAID_SCSI_SET_TIMESTAMP;
+       ioarcb->cdb[1] = PMCRAID_SCSI_SERVICE_ACTION;
+       memcpy(&(ioarcb->cdb[6]), &time_stamp_len, sizeof(time_stamp_len));
+
+       ioarcb->ioadl_bus_addr = cpu_to_le64((cmd->ioa_cb_bus_addr) +
+                                       offsetof(struct pmcraid_ioarcb,
+                                               add_data.u.ioadl[0]));
+       ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
+       ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
+
+       ioarcb->request_flags0 |= NO_LINK_DESCS;
+       ioarcb->request_flags0 |= TRANSFER_DIR_WRITE;
+       ioarcb->data_transfer_length =
+               cpu_to_le32(sizeof(struct pmcraid_timestamp_data));
+       ioadl = &(ioarcb->add_data.u.ioadl[0]);
+       ioadl->flags = IOADL_FLAGS_LAST_DESC;
+       ioadl->address = cpu_to_le64(pinstance->timestamp_data_baddr);
+       ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_timestamp_data));
+
+       if (!pinstance->timestamp_error) {
+               pinstance->timestamp_error = 0;
+               pmcraid_send_cmd(cmd, pmcraid_set_supported_devs,
+                        PMCRAID_INTERNAL_TIMEOUT, pmcraid_timeout_handler);
+       } else {
+               pmcraid_send_cmd(cmd, pmcraid_return_cmd,
+                        PMCRAID_INTERNAL_TIMEOUT, pmcraid_timeout_handler);
+               return;
+       }
+}
+
+
 /**
  * pmcraid_init_res_table - Initialize the resource table
  * @cmd:  pointer to pmcraid command struct
@@ -5720,7 +5811,7 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
 
        /* release the resource list lock */
        spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
-       pmcraid_set_supported_devs(cmd);
+       pmcraid_set_timestamp(cmd);
 }
 
 /**
@@ -6054,10 +6145,10 @@ out_init:
 static void __exit pmcraid_exit(void)
 {
        pmcraid_netlink_release();
-       class_destroy(pmcraid_class);
        unregister_chrdev_region(MKDEV(pmcraid_major, 0),
                                 PMCRAID_MAX_ADAPTERS);
        pci_unregister_driver(&pmcraid_driver);
+       class_destroy(pmcraid_class);
 }
 
 module_init(pmcraid_init);
index 6cfa0145a1d7f088ea41926c400154bfcd0b989d..1134279604e805780f84607c523bbdd647685f24 100644 (file)
@@ -42,7 +42,7 @@
  */
 #define PMCRAID_DRIVER_NAME            "PMC MaxRAID"
 #define PMCRAID_DEVFILE                        "pmcsas"
-#define PMCRAID_DRIVER_VERSION         "2.0.2"
+#define PMCRAID_DRIVER_VERSION         "2.0.3"
 #define PMCRAID_DRIVER_DATE            __DATE__
 
 #define PMCRAID_FW_VERSION_1           0x002
 #define PMCRAID_IOASC_IR_INVALID_RESOURCE_HANDLE        0x05250000
 #define PMCRAID_IOASC_AC_TERMINATED_BY_HOST            0x0B5A0000
 #define PMCRAID_IOASC_UA_BUS_WAS_RESET                 0x06290000
+#define PMCRAID_IOASC_TIME_STAMP_OUT_OF_SYNC           0x06908B00
 #define PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER                0x06298000
 
 /* Driver defined IOASCs */
@@ -561,6 +562,17 @@ struct pmcraid_inquiry_data {
        __u8    reserved3[16];
 };
 
+#define PMCRAID_TIMESTAMP_LEN          12
+#define PMCRAID_REQ_TM_STR_LEN         6
+#define PMCRAID_SCSI_SET_TIMESTAMP     0xA4
+#define PMCRAID_SCSI_SERVICE_ACTION    0x0F
+
+struct pmcraid_timestamp_data {
+       __u8 reserved1[4];
+       __u8 timestamp[PMCRAID_REQ_TM_STR_LEN];         /* current time value */
+       __u8 reserved2[2];
+};
+
 /* pmcraid_cmd - LLD representation of SCSI command */
 struct pmcraid_cmd {
 
@@ -568,7 +580,6 @@ struct pmcraid_cmd {
        struct pmcraid_control_block *ioa_cb;
        dma_addr_t ioa_cb_bus_addr;
        dma_addr_t dma_handle;
-       u8 *sense_buffer;
 
        /* pointer to mid layer structure of SCSI commands */
        struct scsi_cmnd *scsi_cmd;
@@ -705,6 +716,9 @@ struct pmcraid_instance {
        struct pmcraid_inquiry_data *inq_data;
        dma_addr_t  inq_data_baddr;
 
+       struct pmcraid_timestamp_data *timestamp_data;
+       dma_addr_t  timestamp_data_baddr;
+
        /* size of configuration table entry, varies based on the firmware */
        u32     config_table_entry_size;
 
@@ -791,6 +805,7 @@ struct pmcraid_instance {
 #define SHUTDOWN_NONE               0x0
 #define SHUTDOWN_NORMAL             0x1
 #define SHUTDOWN_ABBREV             0x2
+       u32 timestamp_error:1; /* indicate set timestamp for out of sync */
 
 };
 
@@ -1056,10 +1071,10 @@ struct pmcraid_passthrough_ioctl_buffer {
 #define PMCRAID_PASSTHROUGH_IOCTL    'F'
 
 #define DRV_IOCTL(n, size) \
-    _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_DRIVER_IOCTL, (n), (size))
+       _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_DRIVER_IOCTL, (n), (size))
 
 #define FMW_IOCTL(n, size) \
-    _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_PASSTHROUGH_IOCTL,  (n), (size))
+       _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_PASSTHROUGH_IOCTL,  (n), (size))
 
 /*
  * _ARGSIZE: macro that gives size of the argument type passed to an IOCTL cmd.
index 2ff4342ae362ecfae79b03f86ec460a08dc40888..bc8194f74625f923b16b05a88faa3b6bb63ffb2e 100644 (file)
@@ -1538,6 +1538,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
        if (!fcport)
                return;
 
+       /* Now that the rport has been deleted, set the fcport state to
+          FCS_DEVICE_DEAD */
+       atomic_set(&fcport->state, FCS_DEVICE_DEAD);
+
        /*
         * Transport has effectively 'deleted' the rport, clear
         * all local references.
index fdfbf83a63309316c394bf360d189c8bae7a9b33..31a4121a2be1651543d97cd99be7534c86a6acb9 100644 (file)
@@ -1306,6 +1306,125 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
        return rval;
 }
 
+static int
+qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, struct qla_hw_data *ha,
+       uint8_t is_update)
+{
+       uint32_t start = 0;
+       int valid = 0;
+
+       bsg_job->reply->reply_payload_rcv_len = 0;
+
+       if (unlikely(pci_channel_offline(ha->pdev)))
+               return -EINVAL;
+
+       start = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+       if (start > ha->optrom_size)
+               return -EINVAL;
+
+       if (ha->optrom_state != QLA_SWAITING)
+               return -EBUSY;
+
+       ha->optrom_region_start = start;
+
+       if (is_update) {
+               if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
+                       valid = 1;
+               else if (start == (ha->flt_region_boot * 4) ||
+                   start == (ha->flt_region_fw * 4))
+                       valid = 1;
+               else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
+                   IS_QLA8XXX_TYPE(ha))
+                       valid = 1;
+               if (!valid) {
+                       qla_printk(KERN_WARNING, ha,
+                           "Invalid start region 0x%x/0x%x.\n",
+                           start, bsg_job->request_payload.payload_len);
+                       return -EINVAL;
+               }
+
+               ha->optrom_region_size = start +
+                   bsg_job->request_payload.payload_len > ha->optrom_size ?
+                   ha->optrom_size - start :
+                   bsg_job->request_payload.payload_len;
+               ha->optrom_state = QLA_SWRITING;
+       } else {
+               ha->optrom_region_size = start +
+                   bsg_job->reply_payload.payload_len > ha->optrom_size ?
+                   ha->optrom_size - start :
+                   bsg_job->reply_payload.payload_len;
+               ha->optrom_state = QLA_SREADING;
+       }
+
+       ha->optrom_buffer = vmalloc(ha->optrom_region_size);
+       if (!ha->optrom_buffer) {
+               qla_printk(KERN_WARNING, ha,
+                   "Read: Unable to allocate memory for optrom retrieval "
+                   "(%x).\n", ha->optrom_region_size);
+
+               ha->optrom_state = QLA_SWAITING;
+               return -ENOMEM;
+       }
+
+       memset(ha->optrom_buffer, 0, ha->optrom_region_size);
+       return 0;
+}
+
+static int
+qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
+{
+       struct Scsi_Host *host = bsg_job->shost;
+       scsi_qla_host_t *vha = shost_priv(host);
+       struct qla_hw_data *ha = vha->hw;
+       int rval = 0;
+
+       rval = qla2x00_optrom_setup(bsg_job, ha, 0);
+       if (rval)
+               return rval;
+
+       ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
+           ha->optrom_region_start, ha->optrom_region_size);
+
+       sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
+           bsg_job->reply_payload.sg_cnt, ha->optrom_buffer,
+           ha->optrom_region_size);
+
+       bsg_job->reply->reply_payload_rcv_len = ha->optrom_region_size;
+       bsg_job->reply->result = DID_OK;
+       vfree(ha->optrom_buffer);
+       ha->optrom_buffer = NULL;
+       ha->optrom_state = QLA_SWAITING;
+       bsg_job->job_done(bsg_job);
+       return rval;
+}
+
+static int
+qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
+{
+       struct Scsi_Host *host = bsg_job->shost;
+       scsi_qla_host_t *vha = shost_priv(host);
+       struct qla_hw_data *ha = vha->hw;
+       int rval = 0;
+
+       rval = qla2x00_optrom_setup(bsg_job, ha, 1);
+       if (rval)
+               return rval;
+
+       sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+           bsg_job->request_payload.sg_cnt, ha->optrom_buffer,
+           ha->optrom_region_size);
+
+       ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
+           ha->optrom_region_start, ha->optrom_region_size);
+
+       bsg_job->reply->result = DID_OK;
+       vfree(ha->optrom_buffer);
+       ha->optrom_buffer = NULL;
+       ha->optrom_state = QLA_SWAITING;
+       bsg_job->job_done(bsg_job);
+       return rval;
+}
+
 static int
 qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
 {
@@ -1328,6 +1447,12 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
        case QL_VND_FCP_PRIO_CFG_CMD:
                return qla24xx_proc_fcp_prio_cfg_cmd(bsg_job);
 
+       case QL_VND_READ_FLASH:
+               return qla2x00_read_optrom(bsg_job);
+
+       case QL_VND_UPDATE_FLASH:
+               return qla2x00_update_optrom(bsg_job);
+
        default:
                bsg_job->reply->result = (DID_ERROR << 16);
                bsg_job->job_done(bsg_job);
index cc7c52f87a11a3332868ccf2bfac3d9aae31c9d2..074a999c7017a8cd05c4763c49042e464177b2f8 100644 (file)
@@ -14,6 +14,8 @@
 #define QL_VND_A84_MGMT_CMD    0x04
 #define QL_VND_IIDMA           0x05
 #define QL_VND_FCP_PRIO_CFG_CMD        0x06
+#define QL_VND_READ_FLASH      0x07
+#define QL_VND_UPDATE_FLASH    0x08
 
 /* BSG definations for interpreting CommandSent field */
 #define INT_DEF_LB_LOOPBACK_CMD         0
index e1d3ad40a946cc4c206a0755053bfcc67fa60ac2..3a22effced5fa1a94996582b9fd13ccf151d8861 100644 (file)
@@ -1700,9 +1700,7 @@ typedef struct fc_port {
        atomic_t state;
        uint32_t flags;
 
-       int port_login_retry_count;
        int login_retry;
-       atomic_t port_down_timer;
 
        struct fc_rport *rport, *drport;
        u32 supported_classes;
index c33dec827e1ecd3dde4742d67f44f0afe694b83f..9382a816c133104e45108dff7e4a0a2ced2271b8 100644 (file)
@@ -92,6 +92,7 @@ extern int ql2xshiftctondsd;
 extern int ql2xdbwr;
 extern int ql2xdontresethba;
 extern int ql2xasynctmfenable;
+extern int ql2xgffidenable;
 extern int ql2xenabledif;
 extern int ql2xenablehba_err_chk;
 extern int ql2xtargetreset;
index 3cafbef40737e55f99d815060f9d22566efe080c..259f511374933cb4d7463098c26e746809e75d1b 100644 (file)
@@ -71,7 +71,7 @@ qla2x00_ctx_sp_free(srb_t *sp)
        struct srb_iocb *iocb = ctx->u.iocb_cmd;
        struct scsi_qla_host *vha = sp->fcport->vha;
 
-       del_timer_sync(&iocb->timer);
+       del_timer(&iocb->timer);
        kfree(iocb);
        kfree(ctx);
        mempool_free(sp, sp->fcport->vha->hw->srb_mempool);
@@ -1344,6 +1344,13 @@ cont_alloc:
                qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for "
                    "firmware dump!!!\n", dump_size / 1024);
 
+               if (ha->fce) {
+                       dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce,
+                           ha->fce_dma);
+                       ha->fce = NULL;
+                       ha->fce_dma = 0;
+               }
+
                if (ha->eft) {
                        dma_free_coherent(&ha->pdev->dev, eft_size, ha->eft,
                            ha->eft_dma);
@@ -1818,14 +1825,14 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
                qla2x00_init_response_q_entries(rsp);
        }
 
-       spin_lock_irqsave(&ha->vport_slock, flags);
+       spin_lock(&ha->vport_slock);
        /* Clear RSCN queue. */
        list_for_each_entry(vp, &ha->vp_list, list) {
                vp->rscn_in_ptr = 0;
                vp->rscn_out_ptr = 0;
        }
 
-       spin_unlock_irqrestore(&ha->vport_slock, flags);
+       spin_unlock(&ha->vport_slock);
 
        ha->isp_ops->config_rings(vha);
 
@@ -2916,21 +2923,13 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
 void
 qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
 {
-       struct qla_hw_data *ha = vha->hw;
-
        fcport->vha = vha;
        fcport->login_retry = 0;
-       fcport->port_login_retry_count = ha->port_down_retry_count *
-           PORT_RETRY_TIME;
-       atomic_set(&fcport->port_down_timer, ha->port_down_retry_count *
-           PORT_RETRY_TIME);
        fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
 
        qla2x00_iidma_fcport(vha, fcport);
-
-       atomic_set(&fcport->state, FCS_ONLINE);
-
        qla2x00_reg_remote_port(vha, fcport);
+       atomic_set(&fcport->state, FCS_ONLINE);
 }
 
 /*
@@ -3292,8 +3291,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
                        continue;
 
                /* Bypass ports whose FCP-4 type is not FCP_SCSI */
-               if (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
-                   new_fcport->fc4_type != FC4_TYPE_UNKNOWN)
+               if (ql2xgffidenable &&
+                   (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
+                   new_fcport->fc4_type != FC4_TYPE_UNKNOWN))
                        continue;
 
                /* Locate matching device in database. */
index 579f02854665a41ab8ae7cdfa0e53155fbcbd374..5f94430b42f03974fda76e9f1f969cedbf3e9047 100644 (file)
@@ -992,8 +992,8 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
        ha = vha->hw;
 
        DEBUG18(printk(KERN_DEBUG
-           "%s(%ld): Executing cmd sp %p, pid=%ld, prot_op=%u.\n", __func__,
-           vha->host_no, sp, cmd->serial_number, scsi_get_prot_op(sp->cmd)));
+           "%s(%ld): Executing cmd sp %p, prot_op=%u.\n", __func__,
+           vha->host_no, sp, scsi_get_prot_op(sp->cmd)));
 
        cmd_pkt->vp_index = sp->fcport->vp_idx;
 
index e0e43d9e7ed130346d27f86c7f60b933c2fea6cf..1f06ddd9bdd10cdbe6526de1deaaab194a19118e 100644 (file)
@@ -1240,12 +1240,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
        case LSC_SCODE_NPORT_USED:
                data[0] = MBS_LOOP_ID_USED;
                break;
-       case LSC_SCODE_CMD_FAILED:
-               if ((iop[1] & 0xff) == 0x05) {
-                       data[0] = MBS_NOT_LOGGED_IN;
-                       break;
-               }
-               /* Fall through. */
        default:
                data[0] = MBS_COMMAND_ERROR;
                break;
@@ -1431,9 +1425,8 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
                rsp->status_srb = sp;
 
        DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) "
-           "cmd=%p pid=%ld\n", __func__, sp->fcport->vha->host_no,
-           cp->device->channel, cp->device->id, cp->device->lun, cp,
-           cp->serial_number));
+           "cmd=%p\n", __func__, sp->fcport->vha->host_no,
+           cp->device->channel, cp->device->id, cp->device->lun, cp));
        if (sense_len)
                DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, sense_len));
 }
@@ -1757,6 +1750,8 @@ check_scsi_status:
        case CS_INCOMPLETE:
        case CS_PORT_UNAVAILABLE:
        case CS_TIMEOUT:
+       case CS_RESET:
+
                /*
                 * We are going to have the fc class block the rport
                 * while we try to recover so instruct the mid layer
@@ -1781,10 +1776,6 @@ check_scsi_status:
                        qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
                break;
 
-       case CS_RESET:
-               cp->result = DID_TRANSPORT_DISRUPTED << 16;
-               break;
-
        case CS_ABORTED:
                cp->result = DID_RESET << 16;
                break;
@@ -1801,10 +1792,10 @@ out:
        if (logit)
                DEBUG2(qla_printk(KERN_INFO, ha,
                    "scsi(%ld:%d:%d) FCP command status: 0x%x-0x%x (0x%x) "
-                   "oxid=0x%x ser=0x%lx cdb=%02x%02x%02x len=0x%x "
+                   "oxid=0x%x cdb=%02x%02x%02x len=0x%x "
                    "rsp_info=0x%x resid=0x%x fw_resid=0x%x\n", vha->host_no,
                    cp->device->id, cp->device->lun, comp_status, scsi_status,
-                   cp->result, ox_id, cp->serial_number, cp->cmnd[0],
+                   cp->result, ox_id, cp->cmnd[0],
                    cp->cmnd[1], cp->cmnd[2], scsi_bufflen(cp), rsp_info_len,
                    resid_len, fw_resid_len));
 
index 800ea926975236214c2846e4aa8b18ad12ebd56c..1830e6e973155684234710e129e564f82176ce2d 100644 (file)
@@ -160,6 +160,11 @@ MODULE_PARM_DESC(ql2xtargetreset,
                 "Enable target reset."
                 "Default is 1 - use hw defaults.");
 
+int ql2xgffidenable;
+module_param(ql2xgffidenable, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xgffidenable,
+               "Enables GFF_ID checks of port type. "
+               "Default is 0 - Do not use GFF_ID information.");
 
 int ql2xasynctmfenable;
 module_param(ql2xasynctmfenable, int, S_IRUGO|S_IRUSR);
@@ -255,6 +260,7 @@ static void qla2x00_rst_aen(scsi_qla_host_t *);
 
 static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t,
        struct req_que **, struct rsp_que **);
+static void qla2x00_free_fw_dump(struct qla_hw_data *);
 static void qla2x00_mem_free(struct qla_hw_data *);
 static void qla2x00_sp_free_dma(srb_t *);
 
@@ -539,6 +545,7 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        srb_t *sp;
        int rval;
 
+       spin_unlock_irq(vha->host->host_lock);
        if (ha->flags.eeh_busy) {
                if (ha->flags.pci_channel_io_perm_failure)
                        cmd->result = DID_NO_CONNECT << 16;
@@ -553,10 +560,6 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
                goto qc24_fail_command;
        }
 
-       /* Close window on fcport/rport state-transitioning. */
-       if (fcport->drport)
-               goto qc24_target_busy;
-
        if (!vha->flags.difdix_supported &&
                scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) {
                        DEBUG2(qla_printk(KERN_ERR, ha,
@@ -567,15 +570,14 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        }
        if (atomic_read(&fcport->state) != FCS_ONLINE) {
                if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
-                   atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
+                       atomic_read(&fcport->state) == FCS_DEVICE_LOST ||
+                       atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
                        cmd->result = DID_NO_CONNECT << 16;
                        goto qc24_fail_command;
                }
                goto qc24_target_busy;
        }
 
-       spin_unlock_irq(vha->host->host_lock);
-
        sp = qla2x00_get_new_sp(base_vha, fcport, cmd, done);
        if (!sp)
                goto qc24_host_busy_lock;
@@ -597,9 +599,11 @@ qc24_host_busy_lock:
        return SCSI_MLQUEUE_HOST_BUSY;
 
 qc24_target_busy:
+       spin_lock_irq(vha->host->host_lock);
        return SCSI_MLQUEUE_TARGET_BUSY;
 
 qc24_fail_command:
+       spin_lock_irq(vha->host->host_lock);
        done(cmd);
 
        return 0;
@@ -824,81 +828,58 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 {
        scsi_qla_host_t *vha = shost_priv(cmd->device->host);
        srb_t *sp;
-       int ret, i;
+       int ret;
        unsigned int id, lun;
-       unsigned long serial;
        unsigned long flags;
        int wait = 0;
        struct qla_hw_data *ha = vha->hw;
-       struct req_que *req = vha->req;
-       srb_t *spt;
-       int got_ref = 0;
 
        fc_block_scsi_eh(cmd);
 
        if (!CMD_SP(cmd))
                return SUCCESS;
 
-       ret = SUCCESS;
-
        id = cmd->device->id;
        lun = cmd->device->lun;
-       serial = cmd->serial_number;
-       spt = (srb_t *) CMD_SP(cmd);
-       if (!spt)
-               return SUCCESS;
 
-       /* Check active list for command command. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
-       for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
-               sp = req->outstanding_cmds[i];
-
-               if (sp == NULL)
-                       continue;
-               if ((sp->ctx) && !(sp->flags & SRB_FCP_CMND_DMA_VALID) &&
-                   !IS_PROT_IO(sp))
-                       continue;
-               if (sp->cmd != cmd)
-                       continue;
+       sp = (srb_t *) CMD_SP(cmd);
+       if (!sp) {
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               return SUCCESS;
+       }
 
-               DEBUG2(printk("%s(%ld): aborting sp %p from RISC."
-               " pid=%ld.\n", __func__, vha->host_no, sp, serial));
+       DEBUG2(printk("%s(%ld): aborting sp %p from RISC.",
+           __func__, vha->host_no, sp));
 
-               /* Get a reference to the sp and drop the lock.*/
-               sp_get(sp);
-               got_ref++;
+       /* Get a reference to the sp and drop the lock.*/
+       sp_get(sp);
 
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
-               if (ha->isp_ops->abort_command(sp)) {
-                       DEBUG2(printk("%s(%ld): abort_command "
-                       "mbx failed.\n", __func__, vha->host_no));
-                       ret = FAILED;
-               } else {
-                       DEBUG3(printk("%s(%ld): abort_command "
-                       "mbx success.\n", __func__, vha->host_no));
-                       wait = 1;
-               }
-               spin_lock_irqsave(&ha->hardware_lock, flags);
-               break;
-       }
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       if (ha->isp_ops->abort_command(sp)) {
+               DEBUG2(printk("%s(%ld): abort_command "
+               "mbx failed.\n", __func__, vha->host_no));
+               ret = FAILED;
+       } else {
+               DEBUG3(printk("%s(%ld): abort_command "
+               "mbx success.\n", __func__, vha->host_no));
+               wait = 1;
+       }
+       qla2x00_sp_compl(ha, sp);
 
        /* Wait for the command to be returned. */
        if (wait) {
                if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) {
                        qla_printk(KERN_ERR, ha,
-                           "scsi(%ld:%d:%d): Abort handler timed out -- %lx "
-                           "%x.\n", vha->host_no, id, lun, serial, ret);
+                           "scsi(%ld:%d:%d): Abort handler timed out -- %x.\n",
+                           vha->host_no, id, lun, ret);
                        ret = FAILED;
                }
        }
 
-       if (got_ref)
-               qla2x00_sp_compl(ha, sp);
-
        qla_printk(KERN_INFO, ha,
-           "scsi(%ld:%d:%d): Abort command issued -- %d %lx %x.\n",
-           vha->host_no, id, lun, wait, serial, ret);
+           "scsi(%ld:%d:%d): Abort command issued -- %d %x.\n",
+           vha->host_no, id, lun, wait, ret);
 
        return ret;
 }
@@ -1043,13 +1024,11 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
        fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
        int ret = FAILED;
        unsigned int id, lun;
-       unsigned long serial;
 
        fc_block_scsi_eh(cmd);
 
        id = cmd->device->id;
        lun = cmd->device->lun;
-       serial = cmd->serial_number;
 
        if (!fcport)
                return ret;
@@ -1104,14 +1083,12 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
        struct qla_hw_data *ha = vha->hw;
        int ret = FAILED;
        unsigned int id, lun;
-       unsigned long serial;
        scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
 
        fc_block_scsi_eh(cmd);
 
        id = cmd->device->id;
        lun = cmd->device->lun;
-       serial = cmd->serial_number;
 
        if (!fcport)
                return ret;
@@ -1974,6 +1951,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ha->bars = bars;
        ha->mem_only = mem_only;
        spin_lock_init(&ha->hardware_lock);
+       spin_lock_init(&ha->vport_slock);
 
        /* Set ISP-type information. */
        qla2x00_set_isp_flags(ha);
@@ -2341,6 +2319,42 @@ probe_out:
        return ret;
 }
 
+static void
+qla2x00_shutdown(struct pci_dev *pdev)
+{
+       scsi_qla_host_t *vha;
+       struct qla_hw_data  *ha;
+
+       vha = pci_get_drvdata(pdev);
+       ha = vha->hw;
+
+       /* Turn-off FCE trace */
+       if (ha->flags.fce_enabled) {
+               qla2x00_disable_fce_trace(vha, NULL, NULL);
+               ha->flags.fce_enabled = 0;
+       }
+
+       /* Turn-off EFT trace */
+       if (ha->eft)
+               qla2x00_disable_eft_trace(vha);
+
+       /* Stop currently executing firmware. */
+       qla2x00_try_to_stop_firmware(vha);
+
+       /* Turn adapter off line */
+       vha->flags.online = 0;
+
+       /* turn-off interrupts on the card */
+       if (ha->interrupts_on) {
+               vha->flags.init_done = 0;
+               ha->isp_ops->disable_intrs(ha);
+       }
+
+       qla2x00_free_irqs(vha);
+
+       qla2x00_free_fw_dump(ha);
+}
+
 static void
 qla2x00_remove_one(struct pci_dev *pdev)
 {
@@ -2597,12 +2611,12 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
                if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
                        continue;
                if (atomic_read(&fcport->state) == FCS_ONLINE) {
+                       atomic_set(&fcport->state, FCS_DEVICE_LOST);
                        if (defer)
                                qla2x00_schedule_rport_del(vha, fcport, defer);
                        else if (vha->vp_idx == fcport->vp_idx)
                                qla2x00_schedule_rport_del(vha, fcport, defer);
                }
-               atomic_set(&fcport->state, FCS_DEVICE_LOST);
        }
 }
 
@@ -2830,28 +2844,48 @@ fail:
 }
 
 /*
-* qla2x00_mem_free
-*      Frees all adapter allocated memory.
+* qla2x00_free_fw_dump
+*      Frees fw dump stuff.
 *
 * Input:
-*      ha = adapter block pointer.
+*      ha = adapter block pointer.
 */
 static void
-qla2x00_mem_free(struct qla_hw_data *ha)
+qla2x00_free_fw_dump(struct qla_hw_data *ha)
 {
-       if (ha->srb_mempool)
-               mempool_destroy(ha->srb_mempool);
-
        if (ha->fce)
                dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce,
-               ha->fce_dma);
+                   ha->fce_dma);
 
        if (ha->fw_dump) {
                if (ha->eft)
                        dma_free_coherent(&ha->pdev->dev,
-                       ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma);
+                           ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma);
                vfree(ha->fw_dump);
        }
+       ha->fce = NULL;
+       ha->fce_dma = 0;
+       ha->eft = NULL;
+       ha->eft_dma = 0;
+       ha->fw_dump = NULL;
+       ha->fw_dumped = 0;
+       ha->fw_dump_reading = 0;
+}
+
+/*
+* qla2x00_mem_free
+*      Frees all adapter allocated memory.
+*
+* Input:
+*      ha = adapter block pointer.
+*/
+static void
+qla2x00_mem_free(struct qla_hw_data *ha)
+{
+       qla2x00_free_fw_dump(ha);
+
+       if (ha->srb_mempool)
+               mempool_destroy(ha->srb_mempool);
 
        if (ha->dcbx_tlv)
                dma_free_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE,
@@ -2925,8 +2959,6 @@ qla2x00_mem_free(struct qla_hw_data *ha)
 
        ha->srb_mempool = NULL;
        ha->ctx_mempool = NULL;
-       ha->eft = NULL;
-       ha->eft_dma = 0;
        ha->sns_cmd = NULL;
        ha->sns_cmd_dma = 0;
        ha->ct_sns = NULL;
@@ -2946,10 +2978,6 @@ qla2x00_mem_free(struct qla_hw_data *ha)
 
        ha->gid_list = NULL;
        ha->gid_list_dma = 0;
-
-       ha->fw_dump = NULL;
-       ha->fw_dumped = 0;
-       ha->fw_dump_reading = 0;
 }
 
 struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
@@ -3547,11 +3575,9 @@ void
 qla2x00_timer(scsi_qla_host_t *vha)
 {
        unsigned long   cpu_flags = 0;
-       fc_port_t       *fcport;
        int             start_dpc = 0;
        int             index;
        srb_t           *sp;
-       int             t;
        uint16_t        w;
        struct qla_hw_data *ha = vha->hw;
        struct req_que *req;
@@ -3567,34 +3593,6 @@ qla2x00_timer(scsi_qla_host_t *vha)
        /* Hardware read to raise pending EEH errors during mailbox waits. */
        if (!pci_channel_offline(ha->pdev))
                pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
-       /*
-        * Ports - Port down timer.
-        *
-        * Whenever, a port is in the LOST state we start decrementing its port
-        * down timer every second until it reaches zero. Once  it reaches zero
-        * the port it marked DEAD.
-        */
-       t = 0;
-       list_for_each_entry(fcport, &vha->vp_fcports, list) {
-               if (fcport->port_type != FCT_TARGET)
-                       continue;
-
-               if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
-
-                       if (atomic_read(&fcport->port_down_timer) == 0)
-                               continue;
-
-                       if (atomic_dec_and_test(&fcport->port_down_timer) != 0)
-                               atomic_set(&fcport->state, FCS_DEVICE_DEAD);
-
-                       DEBUG(printk("scsi(%ld): fcport-%d - port retry count: "
-                           "%d remaining\n",
-                           vha->host_no,
-                           t, atomic_read(&fcport->port_down_timer)));
-               }
-               t++;
-       } /* End of for fcport  */
-
 
        /* Loop down handler. */
        if (atomic_read(&vha->loop_down_timer) > 0 &&
@@ -4079,6 +4077,7 @@ static struct pci_driver qla2xxx_pci_driver = {
        .id_table       = qla2xxx_pci_tbl,
        .probe          = qla2x00_probe_one,
        .remove         = qla2x00_remove_one,
+       .shutdown       = qla2x00_shutdown,
        .err_handler    = &qla2xxx_err_handler,
 };
 
index cbceb0ebabf7c41888ec091ab77f61e1c9b20f48..edcf048215dd18326181a8cdca07acf3198b3cb3 100644 (file)
@@ -30,3 +30,104 @@ void qla4xxx_dump_buffer(void *b, uint32_t size)
        printk(KERN_INFO "\n");
 }
 
+void qla4xxx_dump_registers(struct scsi_qla_host *ha)
+{
+       uint8_t i;
+
+       if (is_qla8022(ha)) {
+               for (i = 1; i < MBOX_REG_COUNT; i++)
+                       printk(KERN_INFO "mailbox[%d]     = 0x%08X\n",
+                           i, readl(&ha->qla4_8xxx_reg->mailbox_in[i]));
+               return;
+       }
+
+       for (i = 0; i < MBOX_REG_COUNT; i++) {
+               printk(KERN_INFO "0x%02X mailbox[%d]      = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, mailbox[i]), i,
+                   readw(&ha->reg->mailbox[i]));
+       }
+
+       printk(KERN_INFO "0x%02X flash_address            = 0x%08X\n",
+           (uint8_t) offsetof(struct isp_reg, flash_address),
+           readw(&ha->reg->flash_address));
+       printk(KERN_INFO "0x%02X flash_data               = 0x%08X\n",
+           (uint8_t) offsetof(struct isp_reg, flash_data),
+           readw(&ha->reg->flash_data));
+       printk(KERN_INFO "0x%02X ctrl_status              = 0x%08X\n",
+           (uint8_t) offsetof(struct isp_reg, ctrl_status),
+           readw(&ha->reg->ctrl_status));
+
+       if (is_qla4010(ha)) {
+               printk(KERN_INFO "0x%02X nvram            = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u1.isp4010.nvram),
+                   readw(&ha->reg->u1.isp4010.nvram));
+       } else if (is_qla4022(ha) | is_qla4032(ha)) {
+               printk(KERN_INFO "0x%02X intr_mask        = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u1.isp4022.intr_mask),
+                   readw(&ha->reg->u1.isp4022.intr_mask));
+               printk(KERN_INFO "0x%02X nvram            = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u1.isp4022.nvram),
+                   readw(&ha->reg->u1.isp4022.nvram));
+               printk(KERN_INFO "0x%02X semaphore        = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u1.isp4022.semaphore),
+                   readw(&ha->reg->u1.isp4022.semaphore));
+       }
+       printk(KERN_INFO "0x%02X req_q_in                 = 0x%08X\n",
+           (uint8_t) offsetof(struct isp_reg, req_q_in),
+           readw(&ha->reg->req_q_in));
+       printk(KERN_INFO "0x%02X rsp_q_out                = 0x%08X\n",
+           (uint8_t) offsetof(struct isp_reg, rsp_q_out),
+           readw(&ha->reg->rsp_q_out));
+
+       if (is_qla4010(ha)) {
+               printk(KERN_INFO "0x%02X ext_hw_conf      = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u2.isp4010.ext_hw_conf),
+                   readw(&ha->reg->u2.isp4010.ext_hw_conf));
+               printk(KERN_INFO "0x%02X port_ctrl        = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u2.isp4010.port_ctrl),
+                   readw(&ha->reg->u2.isp4010.port_ctrl));
+               printk(KERN_INFO "0x%02X port_status      = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u2.isp4010.port_status),
+                   readw(&ha->reg->u2.isp4010.port_status));
+               printk(KERN_INFO "0x%02X req_q_out        = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u2.isp4010.req_q_out),
+                   readw(&ha->reg->u2.isp4010.req_q_out));
+               printk(KERN_INFO "0x%02X gp_out           = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_out),
+                   readw(&ha->reg->u2.isp4010.gp_out));
+               printk(KERN_INFO "0x%02X gp_in            = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_in),
+                   readw(&ha->reg->u2.isp4010.gp_in));
+               printk(KERN_INFO "0x%02X port_err_status  = 0x%08X\n", (uint8_t)
+                   offsetof(struct isp_reg, u2.isp4010.port_err_status),
+                   readw(&ha->reg->u2.isp4010.port_err_status));
+       } else if (is_qla4022(ha) | is_qla4032(ha)) {
+               printk(KERN_INFO "Page 0 Registers:\n");
+               printk(KERN_INFO "0x%02X ext_hw_conf      = 0x%08X\n", (uint8_t)
+                   offsetof(struct isp_reg, u2.isp4022.p0.ext_hw_conf),
+                   readw(&ha->reg->u2.isp4022.p0.ext_hw_conf));
+               printk(KERN_INFO "0x%02X port_ctrl        = 0x%08X\n", (uint8_t)
+                   offsetof(struct isp_reg, u2.isp4022.p0.port_ctrl),
+                   readw(&ha->reg->u2.isp4022.p0.port_ctrl));
+               printk(KERN_INFO "0x%02X port_status      = 0x%08X\n", (uint8_t)
+                   offsetof(struct isp_reg, u2.isp4022.p0.port_status),
+                   readw(&ha->reg->u2.isp4022.p0.port_status));
+               printk(KERN_INFO "0x%02X gp_out           = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_out),
+                   readw(&ha->reg->u2.isp4022.p0.gp_out));
+               printk(KERN_INFO "0x%02X gp_in            = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_in),
+                   readw(&ha->reg->u2.isp4022.p0.gp_in));
+               printk(KERN_INFO "0x%02X port_err_status  = 0x%08X\n", (uint8_t)
+                   offsetof(struct isp_reg, u2.isp4022.p0.port_err_status),
+                   readw(&ha->reg->u2.isp4022.p0.port_err_status));
+               printk(KERN_INFO "Page 1 Registers:\n");
+               writel(HOST_MEM_CFG_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT),
+                   &ha->reg->ctrl_status);
+               printk(KERN_INFO "0x%02X req_q_out        = 0x%08X\n",
+                   (uint8_t) offsetof(struct isp_reg, u2.isp4022.p1.req_q_out),
+                   readw(&ha->reg->u2.isp4022.p1.req_q_out));
+               writel(PORT_CTRL_STAT_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT),
+                   &ha->reg->ctrl_status);
+       }
+}
index 9dc0a6616edd566656154413a96f41043e886447..0f3bfc3da5cf6670287393bb4ca64baee59db2e4 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
+#include <linux/aer.h>
 
 #include <net/tcp.h>
 #include <scsi/scsi.h>
 #include "ql4_dbg.h"
 #include "ql4_nx.h"
 
-#if defined(CONFIG_PCIEAER)
-#include <linux/aer.h>
-#else
-/* AER releated */
-static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
-{
-       return -EINVAL;
-}
-static inline int pci_disable_pcie_error_reporting(struct pci_dev *dev)
-{
-       return -EINVAL;
-}
-static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
-{
-       return -EINVAL;
-}
-#endif
-
 #ifndef PCI_DEVICE_ID_QLOGIC_ISP4010
 #define PCI_DEVICE_ID_QLOGIC_ISP4010   0x4010
 #endif
@@ -179,6 +162,7 @@ static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
 #define IOCB_TOV_MARGIN                        10
 #define RELOGIN_TOV                    18
 #define ISNS_DEREG_TOV                 5
+#define HBA_ONLINE_TOV                 30
 
 #define MAX_RESET_HA_RETRIES           2
 
index 0336c6db8cb3b338a15bf42608dcdfc1c12c8bfd..5e757d7fff7dc4eb0ae23d01ec93c4b6550d1ce6 100644 (file)
@@ -416,6 +416,8 @@ struct qla_flt_region {
 #define MBOX_ASTS_IPV6_ND_PREFIX_IGNORED       0x802C
 #define MBOX_ASTS_IPV6_LCL_PREFIX_IGNORED      0x802D
 #define MBOX_ASTS_ICMPV6_ERROR_MSG_RCVD                0x802E
+#define MBOX_ASTS_TXSCVR_INSERTED              0x8130
+#define MBOX_ASTS_TXSCVR_REMOVED               0x8131
 
 #define ISNS_EVENT_DATA_RECEIVED               0x0000
 #define ISNS_EVENT_CONNECTION_OPENED           0x0001
@@ -446,6 +448,7 @@ struct addr_ctrl_blk {
 #define         FWOPT_SESSION_MODE               0x0040
 #define         FWOPT_INITIATOR_MODE             0x0020
 #define         FWOPT_TARGET_MODE                0x0010
+#define         FWOPT_ENABLE_CRBDB               0x8000
 
        uint16_t exec_throttle; /* 04-05 */
        uint8_t zio_count;      /* 06 */
index 95a26fb1626c8c21af2473cc02c75fa654de08ce..6575a47501e57667f3f7c8dc2cae73c7c7fb5876 100644 (file)
@@ -94,6 +94,7 @@ void qla4xxx_process_response_queue(struct scsi_qla_host *ha);
 void qla4xxx_wake_dpc(struct scsi_qla_host *ha);
 void qla4xxx_get_conn_event_log(struct scsi_qla_host *ha);
 void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha);
+void qla4xxx_dump_registers(struct scsi_qla_host *ha);
 
 void qla4_8xxx_pci_config(struct scsi_qla_host *);
 int qla4_8xxx_iospace_config(struct scsi_qla_host *ha);
index 4c9be77ee70b81a21a9bda19cd8116b3352bed98..dc01fa3da5d11be799f2c826bc324424e2bd3b76 100644 (file)
@@ -1207,8 +1207,8 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
                        break;
 
                DEBUG2(printk(KERN_INFO "scsi%ld: %s: Waiting for boot "
-                             "firmware to complete... ctrl_sts=0x%x\n",
-                             ha->host_no, __func__, ctrl_status));
+                   "firmware to complete... ctrl_sts=0x%x, remaining=%ld\n",
+                   ha->host_no, __func__, ctrl_status, max_wait_time));
 
                msleep_interruptible(250);
        } while (!time_after_eq(jiffies, max_wait_time));
@@ -1459,6 +1459,12 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
 exit_init_online:
        set_bit(AF_ONLINE, &ha->flags);
 exit_init_hba:
+       if (is_qla8022(ha) && (status == QLA_ERROR)) {
+               /* Since interrupts are registered in start_firmware for
+                * 82xx, release them here if initialize_adapter fails */
+               qla4xxx_free_irqs(ha);
+       }
+
        DEBUG2(printk("scsi%ld: initialize adapter: %s\n", ha->host_no,
            status == QLA_ERROR ? "FAILED" : "SUCCEDED"));
        return status;
index 4ef9ba112ee87ecd55e4815a6572db9d9bf43106..5ae49fd8784639c8802e24c8ce210fd0f9cf1ee0 100644 (file)
@@ -202,19 +202,11 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
 void qla4_8xxx_queue_iocb(struct scsi_qla_host *ha)
 {
        uint32_t dbval = 0;
-       unsigned long wtime;
 
        dbval = 0x14 | (ha->func_num << 5);
        dbval = dbval | (0 << 8) | (ha->request_in << 16);
-       writel(dbval, (unsigned long __iomem *)ha->nx_db_wr_ptr);
-       wmb();
 
-       wtime = jiffies + (2 * HZ);
-       while (readl((void __iomem *)ha->nx_db_rd_ptr) != dbval &&
-           !time_after_eq(jiffies, wtime)) {
-               writel(dbval, (unsigned long __iomem *)ha->nx_db_wr_ptr);
-               wmb();
-       }
+       qla4_8xxx_wr_32(ha, ha->nx_db_wr_ptr, ha->request_in);
 }
 
 /**
index 2a1ab63f3eb0165de7a147be1eeef222c0b03e9a..7c33fd5943d50315a22ac5ff64de69799fe795a2 100644 (file)
@@ -72,7 +72,7 @@ qla4xxx_status_cont_entry(struct scsi_qla_host *ha,
 {
        struct srb *srb = ha->status_srb;
        struct scsi_cmnd *cmd;
-       uint8_t sense_len;
+       uint16_t sense_len;
 
        if (srb == NULL)
                return;
@@ -487,6 +487,8 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
                case MBOX_ASTS_SYSTEM_ERROR:
                        /* Log Mailbox registers */
                        ql4_printk(KERN_INFO, ha, "%s: System Err\n", __func__);
+                       qla4xxx_dump_registers(ha);
+
                        if (ql4xdontresethba) {
                                DEBUG2(printk("scsi%ld: %s:Don't Reset HBA\n",
                                    ha->host_no, __func__));
@@ -621,6 +623,18 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
                        }
                        break;
 
+               case MBOX_ASTS_TXSCVR_INSERTED:
+                       DEBUG2(printk(KERN_WARNING
+                           "scsi%ld: AEN %04x Transceiver"
+                           " inserted\n",  ha->host_no, mbox_sts[0]));
+                       break;
+
+               case MBOX_ASTS_TXSCVR_REMOVED:
+                       DEBUG2(printk(KERN_WARNING
+                           "scsi%ld: AEN %04x Transceiver"
+                           " removed\n",  ha->host_no, mbox_sts[0]));
+                       break;
+
                default:
                        DEBUG2(printk(KERN_WARNING
                                      "scsi%ld: AEN %04x UNKNOWN\n",
index 90021704d8cac0e37a30c2b788e8f40a17875229..2d2f9c879bfd57994366e050f9a82bc2541a4030 100644 (file)
@@ -299,6 +299,10 @@ qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
 {
        memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
        memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
+
+       if (is_qla8022(ha))
+               qla4_8xxx_wr_32(ha, ha->nx_db_wr_ptr, 0);
+
        mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
        mbox_cmd[1] = 0;
        mbox_cmd[2] = LSDW(init_fw_cb_dma);
@@ -472,6 +476,11 @@ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
        init_fw_cb->fw_options |=
                __constant_cpu_to_le16(FWOPT_SESSION_MODE |
                                       FWOPT_INITIATOR_MODE);
+
+       if (is_qla8022(ha))
+               init_fw_cb->fw_options |=
+                   __constant_cpu_to_le16(FWOPT_ENABLE_CRBDB);
+
        init_fw_cb->fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
 
        if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma)
@@ -592,7 +601,7 @@ int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
        }
 
        ql4_printk(KERN_INFO, ha, "%ld firmare IOCBs available (%d).\n",
-           ha->host_no, mbox_cmd[2]);
+           ha->host_no, mbox_sts[2]);
 
        return QLA_SUCCESS;
 }
index 449256f2c5f8dc213226e2a81fa44e85eab18990..474b10d713647ea8aafde7a9057a49450bcf99e9 100644 (file)
@@ -839,8 +839,11 @@ qla4_8xxx_rom_lock(struct scsi_qla_host *ha)
                done = qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK));
                if (done == 1)
                        break;
-               if (timeout >= qla4_8xxx_rom_lock_timeout)
+               if (timeout >= qla4_8xxx_rom_lock_timeout) {
+                       ql4_printk(KERN_WARNING, ha,
+                           "%s: Failed to acquire rom lock", __func__);
                        return -1;
+               }
 
                timeout++;
 
@@ -1078,21 +1081,6 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
        return 0;
 }
 
-static int qla4_8xxx_check_for_bad_spd(struct scsi_qla_host *ha)
-{
-       u32 val = 0;
-       val = qla4_8xxx_rd_32(ha, BOOT_LOADER_DIMM_STATUS) ;
-       val &= QLA82XX_BOOT_LOADER_MN_ISSUE;
-       if (val & QLA82XX_PEG_TUNE_MN_SPD_ZEROED) {
-               printk("Memory DIMM SPD not programmed.  Assumed valid.\n");
-               return 1;
-       } else if (val) {
-               printk("Memory DIMM type incorrect.  Info:%08X.\n", val);
-               return 2;
-       }
-       return 0;
-}
-
 static int
 qla4_8xxx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
 {
@@ -1377,8 +1365,6 @@ static int qla4_8xxx_cmdpeg_ready(struct scsi_qla_host *ha, int pegtune_val)
 
                } while (--retries);
 
-               qla4_8xxx_check_for_bad_spd(ha);
-
                if (!retries) {
                        pegtune_val = qla4_8xxx_rd_32(ha,
                                QLA82XX_ROMUSB_GLB_PEGTUNE_DONE);
@@ -1540,14 +1526,31 @@ qla4_8xxx_try_start_fw(struct scsi_qla_host *ha)
        ql4_printk(KERN_INFO, ha,
            "FW: Attempting to load firmware from flash...\n");
        rval = qla4_8xxx_start_firmware(ha, ha->hw.flt_region_fw);
-       if (rval == QLA_SUCCESS)
-               return rval;
 
-       ql4_printk(KERN_ERR, ha, "FW: Load firmware from flash FAILED...\n");
+       if (rval != QLA_SUCCESS) {
+               ql4_printk(KERN_ERR, ha, "FW: Load firmware from flash"
+                   " FAILED...\n");
+               return rval;
+       }
 
        return rval;
 }
 
+static void qla4_8xxx_rom_lock_recovery(struct scsi_qla_host *ha)
+{
+       if (qla4_8xxx_rom_lock(ha)) {
+               /* Someone else is holding the lock. */
+               dev_info(&ha->pdev->dev, "Resetting rom_lock\n");
+       }
+
+       /*
+        * Either we got the lock, or someone
+        * else died while holding it.
+        * In either case, unlock.
+        */
+       qla4_8xxx_rom_unlock(ha);
+}
+
 /**
  * qla4_8xxx_device_bootstrap - Initialize device, set DEV_READY, start fw
  * @ha: pointer to adapter structure
@@ -1557,11 +1560,12 @@ qla4_8xxx_try_start_fw(struct scsi_qla_host *ha)
 static int
 qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
 {
-       int rval, i, timeout;
+       int rval = QLA_ERROR;
+       int i, timeout;
        uint32_t old_count, count;
+       int need_reset = 0, peg_stuck = 1;
 
-       if (qla4_8xxx_need_reset(ha))
-               goto dev_initialize;
+       need_reset = qla4_8xxx_need_reset(ha);
 
        old_count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
 
@@ -1570,12 +1574,30 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
                if (timeout) {
                        qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
                           QLA82XX_DEV_FAILED);
-                       return QLA_ERROR;
+                       return rval;
                }
 
                count = qla4_8xxx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
                if (count != old_count)
+                       peg_stuck = 0;
+       }
+
+       if (need_reset) {
+               /* We are trying to perform a recovery here. */
+               if (peg_stuck)
+                       qla4_8xxx_rom_lock_recovery(ha);
+               goto dev_initialize;
+       } else  {
+               /* Start of day for this ha context. */
+               if (peg_stuck) {
+                       /* Either we are the first or recovery in progress. */
+                       qla4_8xxx_rom_lock_recovery(ha);
+                       goto dev_initialize;
+               } else {
+                       /* Firmware already running. */
+                       rval = QLA_SUCCESS;
                        goto dev_ready;
+               }
        }
 
 dev_initialize:
@@ -1601,7 +1623,7 @@ dev_ready:
        ql4_printk(KERN_INFO, ha, "HW State: READY\n");
        qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_READY);
 
-       return QLA_SUCCESS;
+       return rval;
 }
 
 /**
@@ -1764,20 +1786,9 @@ int qla4_8xxx_load_risc(struct scsi_qla_host *ha)
        int retval;
        retval = qla4_8xxx_device_state_handler(ha);
 
-       if (retval == QLA_SUCCESS &&
-           !test_bit(AF_INIT_DONE, &ha->flags)) {
+       if (retval == QLA_SUCCESS && !test_bit(AF_INIT_DONE, &ha->flags))
                retval = qla4xxx_request_irqs(ha);
-               if (retval != QLA_SUCCESS) {
-                       ql4_printk(KERN_WARNING, ha,
-                           "Failed to reserve interrupt %d already in use.\n",
-                           ha->pdev->irq);
-               } else {
-                       set_bit(AF_IRQ_ATTACHED, &ha->flags);
-                       ha->host->irq = ha->pdev->irq;
-                       ql4_printk(KERN_INFO, ha, "%s: irq %d attached\n",
-                           __func__, ha->pdev->irq);
-               }
-       }
+
        return retval;
 }
 
index 931ad3f1e918c12b1289839d8ea9a8d556658475..ff689bf530071a1978fe85bce5e56082b2570e8b 100644 (file)
@@ -24,7 +24,6 @@
 
 #define CRB_CMDPEG_STATE               QLA82XX_REG(0x50)
 #define CRB_RCVPEG_STATE               QLA82XX_REG(0x13c)
-#define BOOT_LOADER_DIMM_STATUS                QLA82XX_REG(0x54)
 #define CRB_DMA_SHIFT                  QLA82XX_REG(0xcc)
 
 #define QLA82XX_HW_H0_CH_HUB_ADR       0x05
 # define QLA82XX_CAM_RAM_BASE  (QLA82XX_CRB_CAM + 0x02000)
 # define QLA82XX_CAM_RAM(reg)  (QLA82XX_CAM_RAM_BASE + (reg))
 
-#define QLA82XX_PEG_TUNE_MN_SPD_ZEROED 0x80000000
-#define QLA82XX_BOOT_LOADER_MN_ISSUE   0xff00ffff
 #define QLA82XX_PORT_MODE_ADDR         (QLA82XX_CAM_RAM(0x24))
 #define QLA82XX_PEG_HALT_STATUS1       (QLA82XX_CAM_RAM(0xa8))
 #define QLA82XX_PEG_HALT_STATUS2       (QLA82XX_CAM_RAM(0xac))
 #define QLA82XX_PEG_ALIVE_COUNTER      (QLA82XX_CAM_RAM(0xb0))
+#define QLA82XX_CAM_RAM_DB1            (QLA82XX_CAM_RAM(0x1b0))
+#define QLA82XX_CAM_RAM_DB2            (QLA82XX_CAM_RAM(0x1b4))
 
 #define HALT_STATUS_UNRECOVERABLE      0x80000000
 #define HALT_STATUS_RECOVERABLE                0x40000000
index 370d40ff15296ff8c1c19f3294a011ba94450b75..f4cd846abf6dcf77dc7d6bd7a855437ba6a1868f 100644 (file)
@@ -167,8 +167,6 @@ static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session)
                              "of (%d) secs exhausted, marking device DEAD.\n",
                              ha->host_no, __func__, ddb_entry->fw_ddb_index,
                              QL4_SESS_RECOVERY_TMO));
-
-               qla4xxx_wake_dpc(ha);
        }
 }
 
@@ -573,10 +571,6 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha)
                if (ha->nx_pcibase)
                        iounmap(
                            (struct device_reg_82xx __iomem *)ha->nx_pcibase);
-
-               if (ha->nx_db_wr_ptr)
-                       iounmap(
-                           (struct device_reg_82xx __iomem *)ha->nx_db_wr_ptr);
        } else if (ha->reg)
                iounmap(ha->reg);
        pci_release_regions(ha->pdev);
@@ -692,7 +686,9 @@ static void qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
                        qla4xxx_wake_dpc(ha);
                        qla4xxx_mailbox_premature_completion(ha);
                }
-       }
+       } else
+               ha->seconds_since_last_heartbeat = 0;
+
        ha->fw_heartbeat_counter = fw_heartbeat_counter;
 }
 
@@ -885,7 +881,13 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha)
                /* Find a command that hasn't completed. */
                for (index = 0; index < ha->host->can_queue; index++) {
                        cmd = scsi_host_find_tag(ha->host, index);
-                       if (cmd != NULL)
+                       /*
+                        * We cannot just check if the index is valid,
+                        * becase if we are run from the scsi eh, then
+                        * the scsi/block layer is going to prevent
+                        * the tag from being released.
+                        */
+                       if (cmd != NULL && CMD_SP(cmd))
                                break;
                }
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -937,11 +939,14 @@ int qla4xxx_soft_reset(struct scsi_qla_host *ha)
 {
        uint32_t max_wait_time;
        unsigned long flags = 0;
-       int status = QLA_ERROR;
+       int status;
        uint32_t ctrl_status;
 
-       qla4xxx_hw_reset(ha);
+       status = qla4xxx_hw_reset(ha);
+       if (status != QLA_SUCCESS)
+               return status;
 
+       status = QLA_ERROR;
        /* Wait until the Network Reset Intr bit is cleared */
        max_wait_time = RESET_INTR_TOV;
        do {
@@ -1101,7 +1106,8 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
                    ha->host_no, __func__));
                status = ha->isp_ops->reset_firmware(ha);
                if (status == QLA_SUCCESS) {
-                       qla4xxx_cmd_wait(ha);
+                       if (!test_bit(AF_FW_RECOVERY, &ha->flags))
+                               qla4xxx_cmd_wait(ha);
                        ha->isp_ops->disable_intrs(ha);
                        qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
                        qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
@@ -1118,7 +1124,8 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
         * or if stop_firmware fails for ISP-82xx.
         * This is the default case for ISP-4xxx */
        if (!is_qla8022(ha) || reset_chip) {
-               qla4xxx_cmd_wait(ha);
+               if (!test_bit(AF_FW_RECOVERY, &ha->flags))
+                       qla4xxx_cmd_wait(ha);
                qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
                qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
                DEBUG2(ql4_printk(KERN_INFO, ha,
@@ -1471,24 +1478,10 @@ int qla4_8xxx_iospace_config(struct scsi_qla_host *ha)
        db_base = pci_resource_start(pdev, 4);  /* doorbell is on bar 4 */
        db_len = pci_resource_len(pdev, 4);
 
-       /* mapping of doorbell write pointer */
-       ha->nx_db_wr_ptr = (unsigned long)ioremap(db_base +
-           (ha->pdev->devfn << 12), 4);
-       if (!ha->nx_db_wr_ptr) {
-               printk(KERN_ERR
-                   "cannot remap MMIO doorbell-write (%s), aborting\n",
-                   pci_name(pdev));
-               goto iospace_error_exit;
-       }
-       /* mapping of doorbell read pointer */
-       ha->nx_db_rd_ptr = (uint8_t *) ha->nx_pcibase + (512 * 1024) +
-           (ha->pdev->devfn * 8);
-       if (!ha->nx_db_rd_ptr)
-               printk(KERN_ERR
-                   "cannot remap MMIO doorbell-read (%s), aborting\n",
-                   pci_name(pdev));
-       return 0;
+       ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 :
+           QLA82XX_CAM_RAM_DB2);
 
+       return 0;
 iospace_error_exit:
        return -ENOMEM;
 }
@@ -1960,13 +1953,11 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha)
 {
        unsigned long wait_online;
 
-       wait_online = jiffies + (30 * HZ);
+       wait_online = jiffies + (HBA_ONLINE_TOV * HZ);
        while (time_before(jiffies, wait_online)) {
 
                if (adapter_up(ha))
                        return QLA_SUCCESS;
-               else if (ha->retry_reset_ha_cnt == 0)
-                       return QLA_ERROR;
 
                msleep(2000);
        }
@@ -2021,6 +2012,7 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)
        unsigned int id = cmd->device->id;
        unsigned int lun = cmd->device->lun;
        unsigned long serial = cmd->serial_number;
+       unsigned long flags;
        struct srb *srb = NULL;
        int ret = SUCCESS;
        int wait = 0;
@@ -2029,12 +2021,14 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)
            "scsi%ld:%d:%d: Abort command issued cmd=%p, pid=%ld\n",
            ha->host_no, id, lun, cmd, serial);
 
+       spin_lock_irqsave(&ha->hardware_lock, flags);
        srb = (struct srb *) CMD_SP(cmd);
-
-       if (!srb)
+       if (!srb) {
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
                return SUCCESS;
-
+       }
        kref_get(&srb->srb_ref);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        if (qla4xxx_abort_task(ha, srb) != QLA_SUCCESS) {
                DEBUG3(printk("scsi%ld:%d:%d: Abort_task mbx failed.\n",
@@ -2267,6 +2261,8 @@ qla4xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
                qla4xxx_mailbox_premature_completion(ha);
                qla4xxx_free_irqs(ha);
                pci_disable_device(pdev);
+               /* Return back all IOs */
+               qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
                return PCI_ERS_RESULT_NEED_RESET;
        case pci_channel_io_perm_failure:
                set_bit(AF_EEH_BUSY, &ha->flags);
@@ -2290,17 +2286,13 @@ qla4xxx_pci_mmio_enabled(struct pci_dev *pdev)
        if (!is_aer_supported(ha))
                return PCI_ERS_RESULT_NONE;
 
-       if (test_bit(AF_FW_RECOVERY, &ha->flags)) {
-               ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: firmware hang  -- "
-                   "mmio_enabled\n", ha->host_no, __func__);
-               return PCI_ERS_RESULT_NEED_RESET;
-       } else
-               return PCI_ERS_RESULT_RECOVERED;
+       return PCI_ERS_RESULT_RECOVERED;
 }
 
-uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
+static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
 {
        uint32_t rval = QLA_ERROR;
+       uint32_t ret = 0;
        int fn;
        struct pci_dev *other_pdev = NULL;
 
@@ -2312,7 +2304,6 @@ uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
                clear_bit(AF_ONLINE, &ha->flags);
                qla4xxx_mark_all_devices_missing(ha);
                qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
-               qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
        }
 
        fn = PCI_FUNC(ha->pdev->devfn);
@@ -2375,7 +2366,16 @@ uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
                        /* Clear driver state register */
                        qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0);
                        qla4_8xxx_set_drv_active(ha);
-                       ha->isp_ops->enable_intrs(ha);
+                       ret = qla4xxx_request_irqs(ha);
+                       if (ret) {
+                               ql4_printk(KERN_WARNING, ha, "Failed to "
+                                   "reserve interrupt %d already in use.\n",
+                                   ha->pdev->irq);
+                               rval = QLA_ERROR;
+                       } else {
+                               ha->isp_ops->enable_intrs(ha);
+                               rval = QLA_SUCCESS;
+                       }
                }
                qla4_8xxx_idc_unlock(ha);
        } else {
@@ -2387,8 +2387,18 @@ uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
                        clear_bit(AF_FW_RECOVERY, &ha->flags);
                        rval = qla4xxx_initialize_adapter(ha,
                            PRESERVE_DDB_LIST);
-                       if (rval == QLA_SUCCESS)
-                               ha->isp_ops->enable_intrs(ha);
+                       if (rval == QLA_SUCCESS) {
+                               ret = qla4xxx_request_irqs(ha);
+                               if (ret) {
+                                       ql4_printk(KERN_WARNING, ha, "Failed to"
+                                           " reserve interrupt %d already in"
+                                           " use.\n", ha->pdev->irq);
+                                       rval = QLA_ERROR;
+                               } else {
+                                       ha->isp_ops->enable_intrs(ha);
+                                       rval = QLA_SUCCESS;
+                               }
+                       }
                        qla4_8xxx_idc_lock(ha);
                        qla4_8xxx_set_drv_active(ha);
                        qla4_8xxx_idc_unlock(ha);
@@ -2430,12 +2440,7 @@ qla4xxx_pci_slot_reset(struct pci_dev *pdev)
                goto exit_slot_reset;
        }
 
-       ret = qla4xxx_request_irqs(ha);
-       if (ret) {
-               ql4_printk(KERN_WARNING, ha, "Failed to reserve interrupt %d"
-                   " already in use.\n", pdev->irq);
-               goto exit_slot_reset;
-       }
+       ha->isp_ops->disable_intrs(ha);
 
        if (is_qla8022(ha)) {
                if (qla4_8xxx_error_recovery(ha) == QLA_SUCCESS) {
index a77b973f2cbc607c60c510b8f1e58ae048fb3c42..9bfacf4ed1371f30a557ac99250feb8e2d3f0987 100644 (file)
@@ -5,4 +5,4 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 
-#define QLA4XXX_DRIVER_VERSION "5.02.00-k3"
+#define QLA4XXX_DRIVER_VERSION "5.02.00-k4"
index 1de30eb83bb097664056209ec6d06a470385b76d..f3cf924a2cd96f8c322e53d6012c8397c99f8a58 100644 (file)
@@ -320,19 +320,11 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
                                    "changed. The Linux SCSI layer does not "
                                    "automatically adjust these parameters.\n");
 
-               if (scmd->request->cmd_flags & REQ_HARDBARRIER)
-                       /*
-                        * barrier requests should always retry on UA
-                        * otherwise block will get a spurious error
-                        */
-                       return NEEDS_RETRY;
-               else
-                       /*
-                        * for normal (non barrier) commands, pass the
-                        * UA upwards for a determination in the
-                        * completion functions
-                        */
-                       return SUCCESS;
+               /*
+                * Pass the UA upwards for a determination in the completion
+                * functions.
+                */
+               return SUCCESS;
 
                /* these three are not supported */
        case COPY_ABORTED:
index 8041fe1ab179c2c2e77386726b8082c05643b187..eafeeda6e1942b7deda691f940c0f10efddee390 100644 (file)
@@ -2438,7 +2438,8 @@ scsi_internal_device_unblock(struct scsi_device *sdev)
                sdev->sdev_state = SDEV_RUNNING;
        else if (sdev->sdev_state == SDEV_CREATED_BLOCK)
                sdev->sdev_state = SDEV_CREATED;
-       else
+       else if (sdev->sdev_state != SDEV_CANCEL &&
+                sdev->sdev_state != SDEV_OFFLINE)
                return -EINVAL;
 
        spin_lock_irqsave(q->queue_lock, flags);
index 20ad59dff730289dd3d05768574e8695ea407109..76ee2e784f75085660524fa35143804659735dbd 100644 (file)
@@ -964,10 +964,11 @@ static void __scsi_remove_target(struct scsi_target *starget)
        list_for_each_entry(sdev, &shost->__devices, siblings) {
                if (sdev->channel != starget->channel ||
                    sdev->id != starget->id ||
-                   sdev->sdev_state == SDEV_DEL)
+                   scsi_device_get(sdev))
                        continue;
                spin_unlock_irqrestore(shost->host_lock, flags);
                scsi_remove_device(sdev);
+               scsi_device_put(sdev);
                spin_lock_irqsave(shost->host_lock, flags);
                goto restart;
        }
index 57d1e3e1bd4478548f89ef9f3a472ee4418c71b3..b9ab3a590e4b4fd891865a1f9d3d5f3cb55d9dc5 100644 (file)
@@ -258,6 +258,28 @@ sd_show_protection_type(struct device *dev, struct device_attribute *attr,
        return snprintf(buf, 20, "%u\n", sdkp->protection_type);
 }
 
+static ssize_t
+sd_show_protection_mode(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       struct scsi_disk *sdkp = to_scsi_disk(dev);
+       struct scsi_device *sdp = sdkp->device;
+       unsigned int dif, dix;
+
+       dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type);
+       dix = scsi_host_dix_capable(sdp->host, sdkp->protection_type);
+
+       if (!dix && scsi_host_dix_capable(sdp->host, SD_DIF_TYPE0_PROTECTION)) {
+               dif = 0;
+               dix = 1;
+       }
+
+       if (!dif && !dix)
+               return snprintf(buf, 20, "none\n");
+
+       return snprintf(buf, 20, "%s%u\n", dix ? "dix" : "dif", dif);
+}
+
 static ssize_t
 sd_show_app_tag_own(struct device *dev, struct device_attribute *attr,
                    char *buf)
@@ -285,6 +307,7 @@ static struct device_attribute sd_disk_attrs[] = {
        __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop,
               sd_store_manage_start_stop),
        __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL),
+       __ATTR(protection_mode, S_IRUGO, sd_show_protection_mode, NULL),
        __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL),
        __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL),
        __ATTR_NULL,
index cbb38c5197fad67299f32a36792ab1fc5cdeec3e..3cd8ffbad5776dbcee289f1465022602e3897199 100644 (file)
@@ -324,6 +324,15 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot)
                        return CDS_NO_DISC;
        }
 
+       /*
+        * SK/ASC/ASCQ of 2/4/2 means "initialization required"
+        * Using CD_TRAY_OPEN results in an START_STOP_UNIT to close
+        * the tray, which resolves the initialization requirement.
+        */
+       if (scsi_sense_valid(&sshdr) && sshdr.sense_key == NOT_READY
+                       && sshdr.asc == 0x04 && sshdr.ascq == 0x02)
+               return CDS_TRAY_OPEN;
+
        /*
         * 0x04 is format in progress .. but there must be a disc present!
         */
index 53be4d35a0aa171dde05ca5628d53a2b422443c7..842e3b2a02b1ceb35ecdf45ee172cd35d116a82c 100644 (file)
@@ -2285,6 +2285,8 @@ static struct pciserial_board pci_boards[] __devinitdata = {
 
 static const struct pci_device_id softmodem_blacklist[] = {
        { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */
+       { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */
+       { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */
 };
 
 /*
@@ -2863,6 +2865,9 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL,
                0, 0,
                pbn_b0_4_1152000 },
+       {       PCI_VENDOR_ID_OXSEMI, 0x9505,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_b0_bt_2_921600 },
 
                /*
                 * The below card is a little controversial since it is the
index a9eff2b18eab25ed0fb797f3e0a97be8e2b913c0..19cac9f610fd9aa154a976b44410f5bf8187f94f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
+#include <linux/dma-mapping.h>
 
 #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
        defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
 #include <asm/gpio.h>
 #include <mach/bfin_serial_5xx.h>
 
-#ifdef CONFIG_SERIAL_BFIN_DMA
-#include <linux/dma-mapping.h>
+#include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/cacheflush.h>
-#endif
 
 #ifdef CONFIG_SERIAL_BFIN_MODULE
 # undef CONFIG_EARLY_PRINTK
@@ -360,7 +359,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
                UART_PUT_CHAR(uart, xmit->buf[xmit->tail]);
                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
                uart->port.icount.tx++;
-               SSYNC();
        }
 
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
@@ -688,6 +686,13 @@ static int bfin_serial_startup(struct uart_port *port)
 
 # ifdef CONFIG_BF54x
        {
+               /*
+                * UART2 and UART3 on BF548 share interrupt PINs and DMA
+                * controllers with SPORT2 and SPORT3. UART rx and tx
+                * interrupts are generated in PIO mode only when configure
+                * their peripheral mapping registers properly, which means
+                * request corresponding DMA channels in PIO mode as well.
+                */
                unsigned uart_dma_ch_rx, uart_dma_ch_tx;
 
                switch (uart->port.irq) {
@@ -734,8 +739,7 @@ static int bfin_serial_startup(struct uart_port *port)
                        IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
                        IRQF_DISABLED, "BFIN_UART_CTS", uart)) {
                        uart->cts_pin = -1;
-                       pr_info("Unable to attach BlackFin UART CTS interrupt.\
-                                So, disable it.\n");
+                       pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n");
                }
        }
        if (uart->rts_pin >= 0) {
@@ -747,8 +751,7 @@ static int bfin_serial_startup(struct uart_port *port)
        if (request_irq(uart->status_irq,
                bfin_serial_mctrl_cts_int,
                IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) {
-               pr_info("Unable to attach BlackFin UART Modem \
-                       Status interrupt.\n");
+               pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n");
        }
 
        /* CTS RTS PINs are negative assertive. */
@@ -846,6 +849,8 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
        if (termios->c_cflag & CMSPAR)
                lcr |= STP;
 
+       spin_lock_irqsave(&uart->port.lock, flags);
+
        port->read_status_mask = OE;
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= (FE | PE);
@@ -875,8 +880,6 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
        if (termios->c_line != N_IRDA)
                quot -= ANOMALY_05000230;
 
-       spin_lock_irqsave(&uart->port.lock, flags);
-
        UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
 
        /* Disable UART */
@@ -1321,6 +1324,14 @@ struct console __init *bfin_earlyserial_init(unsigned int port,
        struct bfin_serial_port *uart;
        struct ktermios t;
 
+#ifdef CONFIG_SERIAL_BFIN_CONSOLE
+       /*
+        * If we are using early serial, don't let the normal console rewind
+        * log buffer, since that causes things to be printed multiple times
+        */
+       bfin_serial_console.flags &= ~CON_PRINTBUFFER;
+#endif
+
        if (port == -1 || port >= nr_active_ports)
                port = 0;
        bfin_serial_init_ports();
index c856905bb3bdfc3105ac5eff30de5aad2160c265..fa62578fcd20f572dbd391b614e47f246250b978 100644 (file)
@@ -1411,11 +1411,12 @@ e100_enable_rs485(struct tty_struct *tty, struct serial_rs485 *r)
                       CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1);
 #endif
 
-       info->rs485.flags = r->flags;
-       if (r->delay_rts_before_send >= 1000)
+       info->rs485 = *r;
+
+       /* Maximum delay before RTS equal to 1000 */
+       if (info->rs485.delay_rts_before_send >= 1000)
                info->rs485.delay_rts_before_send = 1000;
-       else
-               info->rs485.delay_rts_before_send = r->delay_rts_before_send;
+
 /*     printk("rts: on send = %i, after = %i, enabled = %i",
                    info->rs485.rts_on_send,
                    info->rs485.rts_after_sent,
@@ -3234,9 +3235,9 @@ rs_write(struct tty_struct *tty,
                e100_disable_rx(info);
                e100_enable_rx_irq(info);
 #endif
-
-               if (info->rs485.delay_rts_before_send > 0)
-                       msleep(info->rs485.delay_rts_before_send);
+               if ((info->rs485.flags & SER_RS485_RTS_BEFORE_SEND) &&
+                       (info->rs485.delay_rts_before_send > 0))
+                               msleep(info->rs485.delay_rts_before_send);
        }
 #endif /* CONFIG_ETRAX_RS485 */
 
@@ -3694,6 +3695,11 @@ rs_ioctl(struct tty_struct *tty, struct file * file,
 
                rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send;
                rs485data.flags = 0;
+               if (rs485data.delay_rts_before_send != 0)
+                       rs485data.flags |= SER_RS485_RTS_BEFORE_SEND;
+               else
+                       rs485data.flags &= ~(SER_RS485_RTS_BEFORE_SEND);
+
                if (rs485ctrl.enabled)
                        rs485data.flags |= SER_RS485_ENABLED;
                else
@@ -3731,7 +3737,7 @@ rs_ioctl(struct tty_struct *tty, struct file * file,
                /* This is the ioctl to get RS485 data from user-space */
                if (copy_to_user((struct serial_rs485 *) arg,
                                        rs485data,
-                                       sizeof(serial_rs485)))
+                                       sizeof(struct serial_rs485)))
                        return -EFAULT;
                break;
        }
@@ -4527,6 +4533,7 @@ static int __init rs_init(void)
                /* Set sane defaults */
                info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND);
                info->rs485.flags |= SER_RS485_RTS_AFTER_SEND;
+               info->rs485.flags &= ~(SER_RS485_RTS_BEFORE_SEND);
                info->rs485.delay_rts_before_send = 0;
                info->rs485.flags &= ~(SER_RS485_ENABLED);
 #endif
index d4b711c9a416c79bbfd242a248a51d3589eb2a15..3374618300af87c16ac3ef6a674e9cb650e62f8c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/vt_kern.h>
+#include <linux/input.h>
 
 #define MAX_CONFIG_LEN         40
 
@@ -37,6 +38,61 @@ static struct tty_driver     *kgdb_tty_driver;
 static int                     kgdb_tty_line;
 
 #ifdef CONFIG_KDB_KEYBOARD
+static int kgdboc_reset_connect(struct input_handler *handler,
+                               struct input_dev *dev,
+                               const struct input_device_id *id)
+{
+       input_reset_device(dev);
+
+       /* Retrun an error - we do not want to bind, just to reset */
+       return -ENODEV;
+}
+
+static void kgdboc_reset_disconnect(struct input_handle *handle)
+{
+       /* We do not expect anyone to actually bind to us */
+       BUG();
+}
+
+static const struct input_device_id kgdboc_reset_ids[] = {
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+       },
+       { }
+};
+
+static struct input_handler kgdboc_reset_handler = {
+       .connect        = kgdboc_reset_connect,
+       .disconnect     = kgdboc_reset_disconnect,
+       .name           = "kgdboc_reset",
+       .id_table       = kgdboc_reset_ids,
+};
+
+static DEFINE_MUTEX(kgdboc_reset_mutex);
+
+static void kgdboc_restore_input_helper(struct work_struct *dummy)
+{
+       /*
+        * We need to take a mutex to prevent several instances of
+        * this work running on different CPUs so they don't try
+        * to register again already registered handler.
+        */
+       mutex_lock(&kgdboc_reset_mutex);
+
+       if (input_register_handler(&kgdboc_reset_handler) == 0)
+               input_unregister_handler(&kgdboc_reset_handler);
+
+       mutex_unlock(&kgdboc_reset_mutex);
+}
+
+static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
+
+static void kgdboc_restore_input(void)
+{
+       schedule_work(&kgdboc_restore_input_work);
+}
+
 static int kgdboc_register_kbd(char **cptr)
 {
        if (strncmp(*cptr, "kbd", 3) == 0) {
@@ -64,10 +120,12 @@ static void kgdboc_unregister_kbd(void)
                        i--;
                }
        }
+       flush_work_sync(&kgdboc_restore_input_work);
 }
 #else /* ! CONFIG_KDB_KEYBOARD */
 #define kgdboc_register_kbd(x) 0
 #define kgdboc_unregister_kbd()
+#define kgdboc_restore_input()
 #endif /* ! CONFIG_KDB_KEYBOARD */
 
 static int kgdboc_option_setup(char *opt)
@@ -231,6 +289,7 @@ static void kgdboc_post_exp_handler(void)
                dbg_restore_graphics = 0;
                con_debug_leave();
        }
+       kgdboc_restore_input();
 }
 
 static struct kgdb_io kgdboc_io_ops = {
index fd0d1b98901c2a0c13cc925e078139be079d1f43..cb12a8e1466b3d8cfe2ad13833d150eaaca90bc3 100644 (file)
@@ -90,8 +90,8 @@ struct clk_rate_round_data {
 static long clk_rate_round_helper(struct clk_rate_round_data *rounder)
 {
        unsigned long rate_error, rate_error_prev = ~0UL;
-       unsigned long rate_best_fit = rounder->rate;
        unsigned long highest, lowest, freq;
+       long rate_best_fit = -ENOENT;
        int i;
 
        highest = 0;
@@ -146,7 +146,7 @@ long clk_rate_table_round(struct clk *clk,
        };
 
        if (clk->nr_freqs < 1)
-               return 0;
+               return -ENOSYS;
 
        return clk_rate_round_helper(&table_round);
 }
@@ -541,6 +541,98 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL_GPL(clk_round_rate);
 
+long clk_round_parent(struct clk *clk, unsigned long target,
+                     unsigned long *best_freq, unsigned long *parent_freq,
+                     unsigned int div_min, unsigned int div_max)
+{
+       struct cpufreq_frequency_table *freq, *best = NULL;
+       unsigned long error = ULONG_MAX, freq_high, freq_low, div;
+       struct clk *parent = clk_get_parent(clk);
+
+       if (!parent) {
+               *parent_freq = 0;
+               *best_freq = clk_round_rate(clk, target);
+               return abs(target - *best_freq);
+       }
+
+       for (freq = parent->freq_table; freq->frequency != CPUFREQ_TABLE_END;
+            freq++) {
+               if (freq->frequency == CPUFREQ_ENTRY_INVALID)
+                       continue;
+
+               if (unlikely(freq->frequency / target <= div_min - 1)) {
+                       unsigned long freq_max;
+
+                       freq_max = (freq->frequency + div_min / 2) / div_min;
+                       if (error > target - freq_max) {
+                               error = target - freq_max;
+                               best = freq;
+                               if (best_freq)
+                                       *best_freq = freq_max;
+                       }
+
+                       pr_debug("too low freq %u, error %lu\n", freq->frequency,
+                                target - freq_max);
+
+                       if (!error)
+                               break;
+
+                       continue;
+               }
+
+               if (unlikely(freq->frequency / target >= div_max)) {
+                       unsigned long freq_min;
+
+                       freq_min = (freq->frequency + div_max / 2) / div_max;
+                       if (error > freq_min - target) {
+                               error = freq_min - target;
+                               best = freq;
+                               if (best_freq)
+                                       *best_freq = freq_min;
+                       }
+
+                       pr_debug("too high freq %u, error %lu\n", freq->frequency,
+                                freq_min - target);
+
+                       if (!error)
+                               break;
+
+                       continue;
+               }
+
+               div = freq->frequency / target;
+               freq_high = freq->frequency / div;
+               freq_low = freq->frequency / (div + 1);
+
+               if (freq_high - target < error) {
+                       error = freq_high - target;
+                       best = freq;
+                       if (best_freq)
+                               *best_freq = freq_high;
+               }
+
+               if (target - freq_low < error) {
+                       error = target - freq_low;
+                       best = freq;
+                       if (best_freq)
+                               *best_freq = freq_low;
+               }
+
+               pr_debug("%u / %lu = %lu, / %lu = %lu, best %lu, parent %u\n",
+                        freq->frequency, div, freq_high, div + 1, freq_low,
+                        *best_freq, best->frequency);
+
+               if (!error)
+                       break;
+       }
+
+       if (parent_freq)
+               *parent_freq = best->frequency;
+
+       return error;
+}
+EXPORT_SYMBOL_GPL(clk_round_parent);
+
 #ifdef CONFIG_PM
 static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)
 {
index 873a99ff8f64a454a505d1838be751dad20ae181..e5e9e6735f7d62e3d585505de7be4fe379fbbd40 100644 (file)
@@ -79,7 +79,7 @@ static void __init intc_register_irq(struct intc_desc *desc,
         * Register the IRQ position with the global IRQ map, then insert
         * it in to the radix tree.
         */
-       irq_reserve_irqs(irq, 1);
+       irq_reserve_irq(irq);
 
        raw_spin_lock_irqsave(&intc_big_lock, flags);
        radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq));
index 4187cce20ffdc9cd0997b276e2f5e8dc020e2519..a3677c9dfe36e3fa6ebcac37bee81af58d9ece5c 100644 (file)
@@ -60,5 +60,5 @@ void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs)
        int i;
 
        for (i = 0; i < nr_vecs; i++)
-               irq_reserve_irqs(evt2irq(vectors[i].vect), 1);
+               irq_reserve_irq(evt2irq(vectors[i].vect));
 }
index e5bf5d3c698e2f15a1ea16f31a4dad38312e6c08..4e0ff7181164c34eb603cd1b03e7633e34f681b3 100644 (file)
@@ -215,7 +215,7 @@ restart:
                entry = radix_tree_deref_slot((void **)entries[i]);
                if (unlikely(!entry))
                        continue;
-               if (unlikely(entry == RADIX_TREE_RETRY))
+               if (radix_tree_deref_retry(entry))
                        goto restart;
 
                irq = create_irq();
index b5a78a1f4421a0c19aa8735bd49f076fd8f91b46..709c836607de23636e6c567a38833cceff752b08 100644 (file)
 #include <linux/spi/spi.h>
 #include <linux/of_spi.h>
 
-
-/* SPI bustype and spi_master class are registered after board init code
- * provides the SPI device tables, ensuring that both are present by the
- * time controller driver registration causes spi_devices to "enumerate".
- */
 static void spidev_release(struct device *dev)
 {
        struct spi_device       *spi = to_spi_device(dev);
@@ -202,11 +197,16 @@ EXPORT_SYMBOL_GPL(spi_register_driver);
 
 struct boardinfo {
        struct list_head        list;
-       unsigned                n_board_info;
-       struct spi_board_info   board_info[0];
+       struct spi_board_info   board_info;
 };
 
 static LIST_HEAD(board_list);
+static LIST_HEAD(spi_master_list);
+
+/*
+ * Used to protect add/del opertion for board_info list and
+ * spi_master list, and their matching process
+ */
 static DEFINE_MUTEX(board_lock);
 
 /**
@@ -300,16 +300,16 @@ int spi_add_device(struct spi_device *spi)
         */
        status = spi_setup(spi);
        if (status < 0) {
-               dev_err(dev, "can't %s %s, status %d\n",
-                               "setup", dev_name(&spi->dev), status);
+               dev_err(dev, "can't setup %s, status %d\n",
+                               dev_name(&spi->dev), status);
                goto done;
        }
 
        /* Device may be bound to an active driver when this returns */
        status = device_add(&spi->dev);
        if (status < 0)
-               dev_err(dev, "can't %s %s, status %d\n",
-                               "add", dev_name(&spi->dev), status);
+               dev_err(dev, "can't add %s, status %d\n",
+                               dev_name(&spi->dev), status);
        else
                dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev));
 
@@ -371,6 +371,20 @@ struct spi_device *spi_new_device(struct spi_master *master,
 }
 EXPORT_SYMBOL_GPL(spi_new_device);
 
+static void spi_match_master_to_boardinfo(struct spi_master *master,
+                               struct spi_board_info *bi)
+{
+       struct spi_device *dev;
+
+       if (master->bus_num != bi->bus_num)
+               return;
+
+       dev = spi_new_device(master, bi);
+       if (!dev)
+               dev_err(master->dev.parent, "can't create new device for %s\n",
+                       bi->modalias);
+}
+
 /**
  * spi_register_board_info - register SPI devices for a given board
  * @info: array of chip descriptors
@@ -393,43 +407,25 @@ EXPORT_SYMBOL_GPL(spi_new_device);
 int __init
 spi_register_board_info(struct spi_board_info const *info, unsigned n)
 {
-       struct boardinfo        *bi;
+       struct boardinfo *bi;
+       int i;
 
-       bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL);
+       bi = kzalloc(n * sizeof(*bi), GFP_KERNEL);
        if (!bi)
                return -ENOMEM;
-       bi->n_board_info = n;
-       memcpy(bi->board_info, info, n * sizeof *info);
 
-       mutex_lock(&board_lock);
-       list_add_tail(&bi->list, &board_list);
-       mutex_unlock(&board_lock);
-       return 0;
-}
+       for (i = 0; i < n; i++, bi++, info++) {
+               struct spi_master *master;
 
-/* FIXME someone should add support for a __setup("spi", ...) that
- * creates board info from kernel command lines
- */
-
-static void scan_boardinfo(struct spi_master *master)
-{
-       struct boardinfo        *bi;
-
-       mutex_lock(&board_lock);
-       list_for_each_entry(bi, &board_list, list) {
-               struct spi_board_info   *chip = bi->board_info;
-               unsigned                n;
-
-               for (n = bi->n_board_info; n > 0; n--, chip++) {
-                       if (chip->bus_num != master->bus_num)
-                               continue;
-                       /* NOTE: this relies on spi_new_device to
-                        * issue diagnostics when given bogus inputs
-                        */
-                       (void) spi_new_device(master, chip);
-               }
+               memcpy(&bi->board_info, info, sizeof(*info));
+               mutex_lock(&board_lock);
+               list_add_tail(&bi->list, &board_list);
+               list_for_each_entry(master, &spi_master_list, list)
+                       spi_match_master_to_boardinfo(master, &bi->board_info);
+               mutex_unlock(&board_lock);
        }
-       mutex_unlock(&board_lock);
+
+       return 0;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -512,6 +508,7 @@ int spi_register_master(struct spi_master *master)
 {
        static atomic_t         dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
        struct device           *dev = master->dev.parent;
+       struct boardinfo        *bi;
        int                     status = -ENODEV;
        int                     dynamic = 0;
 
@@ -547,8 +544,12 @@ int spi_register_master(struct spi_master *master)
        dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev),
                        dynamic ? " (dynamic)" : "");
 
-       /* populate children from any spi device tables */
-       scan_boardinfo(master);
+       mutex_lock(&board_lock);
+       list_add_tail(&master->list, &spi_master_list);
+       list_for_each_entry(bi, &board_list, list)
+               spi_match_master_to_boardinfo(master, &bi->board_info);
+       mutex_unlock(&board_lock);
+
        status = 0;
 
        /* Register devices from the device tree */
@@ -579,7 +580,12 @@ void spi_unregister_master(struct spi_master *master)
 {
        int dummy;
 
-       dummy = device_for_each_child(&master->dev, NULL, __unregister);
+       mutex_lock(&board_lock);
+       list_del(&master->list);
+       mutex_unlock(&board_lock);
+
+       dummy = device_for_each_child(master->dev.parent, &master->dev,
+                                       __unregister);
        device_unregister(&master->dev);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_master);
@@ -652,7 +658,7 @@ int spi_setup(struct spi_device *spi)
         */
        bad_bits = spi->mode & ~spi->master->mode_bits;
        if (bad_bits) {
-               dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
+               dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
                        bad_bits);
                return -EINVAL;
        }
index ab483a0ec6d05b7738ab85aed075ee0a293598bf..3f223511127b56c9a6800743991aea342e5e2e92 100644 (file)
@@ -504,6 +504,15 @@ static irqreturn_t bfin_spi_dma_irq_handler(int irq, void *dev_id)
                "in dma_irq_handler dmastat:0x%x spistat:0x%x\n",
                dmastat, spistat);
 
+       if (drv_data->rx != NULL) {
+               u16 cr = read_CTRL(drv_data);
+               /* discard old RX data and clear RXS */
+               bfin_spi_dummy_read(drv_data);
+               write_CTRL(drv_data, cr & ~BIT_CTL_ENABLE); /* Disable SPI */
+               write_CTRL(drv_data, cr & ~BIT_CTL_TIMOD); /* Restore State */
+               write_STAT(drv_data, BIT_STAT_CLR); /* Clear Status */
+       }
+
        clear_dma_irqstat(drv_data->dma_channel);
 
        /*
@@ -1099,12 +1108,15 @@ static int bfin_spi_setup(struct spi_device *spi)
        }
 
        if (chip->chip_select_num >= MAX_CTRL_CS) {
-               ret = gpio_request(chip->cs_gpio, spi->modalias);
-               if (ret) {
-                       dev_err(&spi->dev, "gpio_request() error\n");
-                       goto pin_error;
+               /* Only request on first setup */
+               if (spi_get_ctldata(spi) == NULL) {
+                       ret = gpio_request(chip->cs_gpio, spi->modalias);
+                       if (ret) {
+                               dev_err(&spi->dev, "gpio_request() error\n");
+                               goto pin_error;
+                       }
+                       gpio_direction_output(chip->cs_gpio, 1);
                }
-               gpio_direction_output(chip->cs_gpio, 1);
        }
 
        dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n",
index f9c9c8a397db10ab028fca13ef8be45ceb09be51..5eafdf435550fb307d9423c602a50f78be0ca471 100644 (file)
@@ -87,8 +87,6 @@ source "drivers/staging/rtl8712/Kconfig"
 
 source "drivers/staging/frontier/Kconfig"
 
-source "drivers/staging/dream/Kconfig"
-
 source "drivers/staging/pohmelfs/Kconfig"
 
 source "drivers/staging/autofs/Kconfig"
index a85074f8321b436e7cc255d60e2c0dc26a8d701c..a97a955c094bc8aa0f8142917f2ece87ecb01eac 100644 (file)
@@ -28,7 +28,6 @@ obj-$(CONFIG_RTL8192E)                += rtl8192e/
 obj-$(CONFIG_R8712U)           += rtl8712/
 obj-$(CONFIG_SPECTRA)          += spectra/
 obj-$(CONFIG_TRANZPORT)                += frontier/
-obj-$(CONFIG_DREAM)            += dream/
 obj-$(CONFIG_POHMELFS)         += pohmelfs/
 obj-$(CONFIG_AUTOFS_FS)                += autofs/
 obj-$(CONFIG_IDE_PHISON)       += phison/
index ae2cdf48b74c76d09808554e7b30a761fece63e8..8a5caa30b85f30afb0502c379064bcd2b8d44b89 100644 (file)
@@ -102,7 +102,7 @@ config AR600x_BT_RESET_PIN
 
 config ATH6KL_CFG80211
        bool "CFG80211 support"
-       depends on ATH6K_LEGACY
+       depends on ATH6K_LEGACY && CFG80211
        help
        Enables support for CFG80211 APIs. The default option is to use WEXT. Even with this option enabled, WEXT is not explicitly disabled and the onus of not exercising WEXT lies on the application(s) running in the user space.
 
index 22c6c6659f5b5f9a004ed25ae4543e01c200380b..ee8b47746a155ece0fbc559803a40ecb71e6f21b 100644 (file)
@@ -285,9 +285,9 @@ A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_I
     do {
         
             /* check if host supports scatter requests and it meets our requirements */
-        if (device->func->card->host->max_hw_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
+        if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n",
-                    device->func->card->host->max_hw_segs, MAX_SCATTER_ENTRIES_PER_REQ));
+                    device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ));
             status = A_ENOTSUP;
             break;    
         }
index c5a6d6c1673502b0ae4c8543a7dfd0fd9a04ac32..a659f7047373efcca83a010b05dbd999546b6566 100644 (file)
@@ -1126,7 +1126,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A
         if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) {
             A_UINT32 param;
 
-            status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(((A_UINT32)fw_entry->data) + board_data_size), board_ext_data_size);
+            status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(fw_entry->data + board_data_size), board_ext_data_size);
 
             if (status != A_OK) {
                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
@@ -3030,7 +3030,8 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
         A_UINT8 csumDest=0;
         A_UINT8 csum=skb->ip_summed;
         if(csumOffload && (csum==CHECKSUM_PARTIAL)){
-            csumStart=skb->csum_start-(skb->network_header-skb->head)+sizeof(ATH_LLC_SNAP_HDR);
+            csumStart = (skb->head + skb->csum_start - skb_network_header(skb) +
+                        sizeof(ATH_LLC_SNAP_HDR));
             csumDest=skb->csum_offset+csumStart;
         }
 #endif
index c196098f0859c2aa1c60df2d2c9dcc1bd5957110..6b8eeea475cf4e9e5a59f9b0d821121229d4cea5 100644 (file)
@@ -198,8 +198,8 @@ int ar6000_htc_raw_open(AR_SOFTC_T *ar)
         
     for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
         /* Initialize the data structures */
-        init_MUTEX(&arRaw->raw_htc_read_sem[streamID]);
-        init_MUTEX(&arRaw->raw_htc_write_sem[streamID]);
+       sema_init(&arRaw->raw_htc_read_sem[streamID], 1);
+       sema_init(&arRaw->raw_htc_write_sem[streamID], 1);
         init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]);
         init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]);
 
index c94ad29eeb4dcdb13a70b5b3bdba73a0345221e4..7269d0a1d61852e5319fba93538caf4aabb14873 100644 (file)
@@ -808,7 +808,7 @@ ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status)
 
 static int
 ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
-                      A_UINT8 key_index, const A_UINT8 *mac_addr,
+                      A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr,
                       struct key_params *params)
 {
     AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
@@ -901,7 +901,7 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 
 static int
 ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
-                      A_UINT8 key_index, const A_UINT8 *mac_addr)
+                      A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr)
 {
     AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
 
@@ -936,7 +936,8 @@ ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
 
 static int
 ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
-                      A_UINT8 key_index, const A_UINT8 *mac_addr, void *cookie,
+                      A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr,
+                      void *cookie,
                       void (*callback)(void *cookie, struct key_params*))
 {
     AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
diff --git a/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h b/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h b/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h
deleted file mode 100644 (file)
index e69de29..0000000
index 765c72f42976ef9d30440d59814b568cb4fd5c1f..5e4b372ea663169f9680d3c20eecf40ad0d4c54b 100644 (file)
 #include <linux/init.h>
 #include "autofs_i.h"
 
-static int autofs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *autofs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, autofs_fill_super, mnt);
+       return mount_nodev(fs_type, flags, data, autofs_fill_super);
 }
 
 static struct file_system_type autofs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "autofs",
-       .get_sb         = autofs_get_sb,
+       .mount          = autofs_mount,
        .kill_sb        = autofs_kill_sb,
 };
 
index 80cfa866958504692a45b2c6aaf29e936dc97d72..b68a7e5173be9279b44fbe5ce4f574b847c832b3 100644 (file)
@@ -165,7 +165,7 @@ static void update_mac_addresses(struct batman_if *batman_if)
               batman_if->net_dev->dev_addr, ETH_ALEN);
 }
 
-static void check_known_mac_addr(uint8_t *addr)
+static void check_known_mac_addr(struct net_device *net_dev)
 {
        struct batman_if *batman_if;
 
@@ -175,11 +175,16 @@ static void check_known_mac_addr(uint8_t *addr)
                    (batman_if->if_status != IF_TO_BE_ACTIVATED))
                        continue;
 
-               if (!compare_orig(batman_if->net_dev->dev_addr, addr))
+               if (batman_if->net_dev == net_dev)
+                       continue;
+
+               if (!compare_orig(batman_if->net_dev->dev_addr,
+                                 net_dev->dev_addr))
                        continue;
 
                pr_warning("The newly added mac address (%pM) already exists "
-                          "on: %s\n", addr, batman_if->net_dev->name);
+                          "on: %s\n", net_dev->dev_addr,
+                          batman_if->net_dev->name);
                pr_warning("It is strongly recommended to keep mac addresses "
                           "unique to avoid problems!\n");
        }
@@ -430,7 +435,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
        atomic_set(&batman_if->refcnt, 0);
        hardif_hold(batman_if);
 
-       check_known_mac_addr(batman_if->net_dev->dev_addr);
+       check_known_mac_addr(batman_if->net_dev);
 
        spin_lock(&if_list_lock);
        list_add_tail_rcu(&batman_if->list, &if_list);
@@ -515,7 +520,7 @@ static int hard_if_event(struct notifier_block *this,
                        goto out;
                }
 
-               check_known_mac_addr(batman_if->net_dev->dev_addr);
+               check_known_mac_addr(batman_if->net_dev);
                update_mac_addresses(batman_if);
 
                bat_priv = netdev_priv(batman_if->soft_iface);
index 90102631330b883ad1f3df3bc45f3494b7f06d91..657b69e6b9573595e80fb42e9c69849ac701d7c6 100644 (file)
@@ -1000,10 +1000,10 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
 
 /* find a suitable router for this originator, and use
  * bonding if possible. */
-struct neigh_node *find_router(struct orig_node *orig_node,
+struct neigh_node *find_router(struct bat_priv *bat_priv,
+                              struct orig_node *orig_node,
                               struct batman_if *recv_if)
 {
-       struct bat_priv *bat_priv;
        struct orig_node *primary_orig_node;
        struct orig_node *router_orig;
        struct neigh_node *router, *first_candidate, *best_router;
@@ -1019,13 +1019,9 @@ struct neigh_node *find_router(struct orig_node *orig_node,
        /* without bonding, the first node should
         * always choose the default router. */
 
-       if (!recv_if)
-               return orig_node->router;
-
-       bat_priv = netdev_priv(recv_if->soft_iface);
        bonding_enabled = atomic_read(&bat_priv->bonding_enabled);
 
-       if (!bonding_enabled)
+       if ((!recv_if) && (!bonding_enabled))
                return orig_node->router;
 
        router_orig = orig_node->router->orig_node;
@@ -1154,7 +1150,7 @@ static int route_unicast_packet(struct sk_buff *skb,
        orig_node = ((struct orig_node *)
                     hash_find(bat_priv->orig_hash, unicast_packet->dest));
 
-       router = find_router(orig_node, recv_if);
+       router = find_router(bat_priv, orig_node, recv_if);
 
        if (!router) {
                spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
index 06ea99df37064fd30c2d04d19ce60337d70f9455..92674c8d9c030c96b7da1bf39ee2c31eeae33688 100644 (file)
@@ -38,8 +38,8 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if);
 int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if);
 int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if);
 int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if);
-struct neigh_node *find_router(struct orig_node *orig_node,
-               struct batman_if *recv_if);
+struct neigh_node *find_router(struct bat_priv *bat_priv,
+               struct orig_node *orig_node, struct batman_if *recv_if);
 void update_bonding_candidates(struct bat_priv *bat_priv,
                               struct orig_node *orig_node);
 
index 0dac50d69c03c13b0dec25f95c93dae2f93ddd45..0459413ff67ff73a06f822038385d1005dee11b5 100644 (file)
@@ -224,7 +224,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
        if (!orig_node)
                orig_node = transtable_search(bat_priv, ethhdr->h_dest);
 
-       router = find_router(orig_node, NULL);
+       router = find_router(bat_priv, orig_node, NULL);
 
        if (!router)
                goto unlock;
index 77fdfe24d9990df393df9cc85b5ac95f27feb61f..fead9c56162e1f629648ca1a8d94aca0887e8cc1 100644 (file)
@@ -1001,13 +1001,15 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                }
 #endif
                case IOCTL_BE_BUCKET_SIZE:
-                       Adapter->BEBucketSize = *(PULONG)arg;
-                       Status = STATUS_SUCCESS;
+                       Status = 0;
+                       if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg))
+                               Status = -EFAULT;
                        break;
 
                case IOCTL_RTPS_BUCKET_SIZE:
-                       Adapter->rtPSBucketSize = *(PULONG)arg;
-                       Status = STATUS_SUCCESS;
+                       Status = 0;
+                       if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg))
+                               Status = -EFAULT;
                        break;
                case IOCTL_CHIP_RESET:
            {
@@ -1028,11 +1030,15 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                case IOCTL_QOS_THRESHOLD:
                {
                        USHORT uiLoopIndex;
-                       for(uiLoopIndex = 0 ; uiLoopIndex < NO_OF_QUEUES ; uiLoopIndex++)
-                       {
-                               Adapter->PackInfo[uiLoopIndex].uiThreshold = *(PULONG)arg;
+
+                       Status = 0;
+                       for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
+                               if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold,
+                                               (unsigned long __user *)arg)) {
+                                       Status = -EFAULT;
+                                       break;
+                               }
                        }
-                       Status = STATUS_SUCCESS;
                        break;
                }
 
@@ -1093,7 +1099,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                }
                case IOCTL_BCM_GET_CURRENT_STATUS:
                {
-                       LINK_STATE *plink_state = NULL;
+                       LINK_STATE plink_state;
+
                        /* Copy Ioctl Buffer structure */
                        if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
                        {
@@ -1101,13 +1108,19 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                                Status = -EFAULT;
                                break;
                        }
-                       plink_state = (LINK_STATE*)arg;
-                       plink_state->bIdleMode = (UCHAR)Adapter->IdleMode;
-                       plink_state->bShutdownMode = Adapter->bShutStatus;
-                       plink_state->ucLinkStatus = (UCHAR)Adapter->LinkStatus;
-                       if(copy_to_user(IoBuffer.OutputBuffer,
-                               (PUCHAR)plink_state, (UINT)IoBuffer.OutputLength))
-                       {
+                       if (IoBuffer.OutputLength != sizeof(plink_state)) {
+                               Status = -EINVAL;
+                               break;
+                       }
+
+                       if (copy_from_user(&plink_state, (void __user *)arg, sizeof(plink_state))) {
+                               Status = -EFAULT;
+                               break;
+                       }
+                       plink_state.bIdleMode = (UCHAR)Adapter->IdleMode;
+                       plink_state.bShutdownMode = Adapter->bShutStatus;
+                       plink_state.ucLinkStatus = (UCHAR)Adapter->LinkStatus;
+                       if (copy_to_user(IoBuffer.OutputBuffer, &plink_state, IoBuffer.OutputLength)) {
                                BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n");
                                Status = -EFAULT;
                                break;
@@ -1331,7 +1344,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
                                                BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status);
                                                return -EFAULT;
                                        }
-                                       uiSectorSize = *((PUINT)(IoBuffer.InputBuffer)); /* FIXME: unchecked __user access */
+                                       if (get_user(uiSectorSize, (unsigned int __user *)IoBuffer.InputBuffer))
+                                               return -EFAULT;
+
                                        if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE))
                                        {
 
index c3ba9bb9b11678695f16f3448ba16961c2fa84d2..c8f1cf1b440963280241229906452d227b3e9ad4 100644 (file)
@@ -90,5 +90,5 @@ Contact Info:
 =============
 Brett Rudley   brudley@broadcom.com
 Henry Ptasinski henryp@broadcom.com
-Nohee Ko       noheek@broadcom.com
+Dowan Kim      dowan@broadcom.com
 
index 8803d300b5311b307d7112f0cbc649e7d55a89e4..dbf904184899884c825dab5e1e290c962e5dad25 100644 (file)
@@ -45,5 +45,5 @@ Contact
 =====
 Brett Rudley <brudley@broadcom.com>
 Henry Ptasinski <henryp@broadcom.com>
-Nohee Ko <noheek@broadcom.com>
+Dowan Kim <dowan@broadcom.com>
 
index e5357875661f5227a4cdd81dbd3f6b2e53e20fb4..9335f02029aa3351b3360ea624188cc6a589883a 100644 (file)
@@ -1929,7 +1929,7 @@ dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
                goto fail;
 
        net->netdev_ops = NULL;
-       init_MUTEX(&dhd->proto_sem);
+       sema_init(&dhd->proto_sem, 1);
        /* Initialize other structure content */
        init_waitqueue_head(&dhd->ioctl_resp_wait);
        init_waitqueue_head(&dhd->ctrl_wait);
@@ -1977,7 +1977,7 @@ dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
        dhd->timer.function = dhd_watchdog;
 
        /* Initialize thread based operation and lock */
-       init_MUTEX(&dhd->sdsem);
+       sema_init(&dhd->sdsem, 1);
        if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0))
                dhd->threads_only = true;
        else
@@ -2222,8 +2222,6 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
        ASSERT(net);
 
        ASSERT(!net->netdev_ops);
-       net->netdev_ops = &dhd_ops_virt;
-
        net->netdev_ops = &dhd_ops_pri;
 
        /*
index 3f29488d9c7279c6ba79ad604d6fbb22b9a59a5a..ea0825238d53fd847be7dd6351da1011d26e9b8c 100644 (file)
@@ -95,12 +95,12 @@ static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
                                            struct net_device *dev,
                                            u8 key_idx);
 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
-                                u8 key_idx, const u8 *mac_addr,
+                                u8 key_idx, bool pairwise, const u8 *mac_addr,
                                 struct key_params *params);
 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
-                                u8 key_idx, const u8 *mac_addr);
+                                u8 key_idx, bool pairwise, const u8 *mac_addr);
 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
-                                u8 key_idx, const u8 *mac_addr,
+                                u8 key_idx, bool pairwise, const u8 *mac_addr,
                                 void *cookie, void (*callback) (void *cookie,
                                                                 struct
                                                                 key_params *
@@ -1615,7 +1615,7 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
 
 static s32
 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
-                   u8 key_idx, const u8 *mac_addr,
+                   u8 key_idx, bool pairwise, const u8 *mac_addr,
                    struct key_params *params)
 {
        struct wl_wsec_key key;
@@ -1700,7 +1700,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 
 static s32
 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
-                   u8 key_idx, const u8 *mac_addr)
+                   u8 key_idx, bool pairwise, const u8 *mac_addr)
 {
        struct wl_wsec_key key;
        s32 err = 0;
@@ -1756,7 +1756,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
 
 static s32
 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
-                   u8 key_idx, const u8 *mac_addr, void *cookie,
+                   u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
                    void (*callback) (void *cookie, struct key_params * params))
 {
        struct key_params params;
index ad635ee7758e2aca45e3d6cb5d60d67c19c48618..d060377629ac2fc69320a17600a1371b201dec40 100644 (file)
@@ -866,7 +866,7 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs,
        spin_lock_init(&wl->rpcq_lock);
        spin_lock_init(&wl->txq_lock);
 
-       init_MUTEX(&wl->sem);
+       sema_init(&wl->sem, 1);
 #else
        spin_lock_init(&wl->lock);
        spin_lock_init(&wl->isr_lock);
index 0560a74515125c6668e225ab433987b91dd4e365..06059850dae2e3d2b7a4d06e16a9337c2cfefab4 100644 (file)
@@ -262,7 +262,7 @@ struct dt9812_usb_cmd {
 
 #define DT9812_NUM_SLOTS       16
 
-static DECLARE_MUTEX(dt9812_mutex);
+static DEFINE_SEMAPHORE(dt9812_mutex);
 
 static const struct usb_device_id dt9812_table[] = {
        {USB_DEVICE(0x0867, 0x9812)},
index 6131e2dd0591ba60b38c6b7cc755e326e5382123..1f177a67ff114f9098f3bcdb282068978c6567e3 100644 (file)
@@ -315,7 +315,7 @@ struct usbduxsub {
  */
 static struct usbduxsub usbduxsub[NUMUSBDUX];
 
-static DECLARE_MUTEX(start_stop_sem);
+static DEFINE_SEMAPHORE(start_stop_sem);
 
 /*
  * Stops the data acquision
@@ -2367,7 +2367,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
        dev_dbg(dev, "comedi_: usbdux: "
                "usbduxsub[%d] is ready to connect to comedi.\n", index);
 
-       init_MUTEX(&(usbduxsub[index].sem));
+       sema_init(&(usbduxsub[index].sem), 1);
        /* save a pointer to the usb device */
        usbduxsub[index].usbdev = udev;
 
index 0a164a9a66c3b0024890b61a76e0178abf576023..5b15e6df54e653cb4f7e815979c0c7f645722a23 100644 (file)
@@ -199,7 +199,7 @@ struct usbduxfastsub_s {
  */
 static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST];
 
-static DECLARE_MUTEX(start_stop_sem);
+static DEFINE_SEMAPHORE(start_stop_sem);
 
 /*
  * bulk transfers to usbduxfast
@@ -1504,7 +1504,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
               "connect to comedi.\n", index);
 #endif
 
-       init_MUTEX(&(usbduxfastsub[index].sem));
+       sema_init(&(usbduxfastsub[index].sem), 1);
        /* save a pointer to the usb device */
        usbduxfastsub[index].usbdev = udev;
 
index 933ae4c8cb9a6467b63f2d576e2b008b86c95ae8..0e740b8dafc3781d8ac9afb55a6c8ffb0b596d40 100644 (file)
@@ -3184,13 +3184,9 @@ static int cpia_open(struct file *file)
                goto oops;
        }
 
-       err = -EINTR;
-       if(signal_pending(current))
-               goto oops;
-
        /* Set ownership of /proc/cpia/videoX to current user */
        if(cam->proc_entry)
-               cam->proc_entry->uid = current_uid();
+               cam->proc_entry->uid = current_euid();
 
        /* set mark for loading first frame uncompressed */
        cam->first_frame = 1;
diff --git a/drivers/staging/dream/Kconfig b/drivers/staging/dream/Kconfig
deleted file mode 100644 (file)
index 0c30b19..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-config DREAM
-       tristate "HTC Dream support"
-       depends on MACH_TROUT
-
-if DREAM
-
-source "drivers/staging/dream/camera/Kconfig"
-
-config INPUT_GPIO
-       tristate "GPIO driver support"
-       help
-         Say Y here if you want to support gpio based keys, wheels etc...
-endif
diff --git a/drivers/staging/dream/Makefile b/drivers/staging/dream/Makefile
deleted file mode 100644 (file)
index 87de1a5..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-ccflags-y:=-Idrivers/staging/dream/include
-obj-$(CONFIG_MSM_ADSP)         += qdsp5/
-obj-$(CONFIG_MSM_CAMERA)       += camera/
-obj-$(CONFIG_INPUT_GPIO)       += gpio_axis.o gpio_event.o gpio_input.o gpio_matrix.o gpio_output.o
-
diff --git a/drivers/staging/dream/TODO b/drivers/staging/dream/TODO
deleted file mode 100644 (file)
index dcd3ba8..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-
-* camera driver uses old V4L API
-
-* coding style in some places is lacking
-
-* gpio_input.c has some features matrix_keypad lacks. They should be
-merged to gpio_input, with gpio_input.c removed
-
-* pmem provides interface for userspace. Needs to be reviewed at least.
-
-* it is probably possible to simplify touchscreen driver using threaded_irq's.
-
-* touchscreen driver should be switched to oficial multitouch API
diff --git a/drivers/staging/dream/camera/Kconfig b/drivers/staging/dream/camera/Kconfig
deleted file mode 100644 (file)
index bfb6d24..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-comment "Qualcomm MSM Camera And Video"
-
-menuconfig MSM_CAMERA
-       bool "Qualcomm MSM camera and video capture support"
-       depends on ARCH_MSM && VIDEO_V4L2_COMMON
-       help
-         Say Y here to enable selecting the video adapters for
-         Qualcomm msm camera and video encoding
-
-config MSM_CAMERA_DEBUG
-       bool "Qualcomm MSM camera debugging with printk"
-       depends on MSM_CAMERA
-       help
-         Enable printk() debug for msm camera
-
-config MSM_CAMERA_FLASH
-       bool "Qualcomm MSM camera flash support"
-       depends on MSM_CAMERA && BROKEN
-       ---help---
-         Enable support for LED flash for msm camera
-
-
-comment "Camera Sensor Selection"
-config MT9T013
-       bool "Sensor mt9t013 (BAYER 3M)"
-       depends on MSM_CAMERA
-       ---help---
-         MICRON 3M Bayer Sensor with AutoFocus
-
-config MT9D112
-       bool "Sensor mt9d112 (YUV 2M)"
-       depends on MSM_CAMERA
-       ---help---
-         MICRON 2M YUV Sensor
-
-config MT9P012
-       bool "Sensor mt9p012 (BAYER 5M)"
-       depends on MSM_CAMERA
-       ---help---
-         MICRON 5M Bayer Sensor with Autofocus
-
-config S5K3E2FX
-       bool "Sensor s5k3e2fx (Samsung 5M)"
-       depends on MSM_CAMERA
-       ---help---
-         Samsung 5M with Autofocus
diff --git a/drivers/staging/dream/camera/Makefile b/drivers/staging/dream/camera/Makefile
deleted file mode 100644 (file)
index 03711dc..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-ccflags-y:=-Idrivers/staging/dream/include
-obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
-obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
-obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o
-obj-$(CONFIG_MSM_CAMERA) += msm_camera.o msm_v4l2.o
-obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o
-obj-$(CONFIG_ARCH_MSM) += msm_vfe7x.o msm_io7x.o
-obj-$(CONFIG_ARCH_QSD) += msm_vfe8x.o msm_vfe8x_proc.o msm_io8x.o
diff --git a/drivers/staging/dream/camera/msm_camera.c b/drivers/staging/dream/camera/msm_camera.c
deleted file mode 100644 (file)
index de4ab61..0000000
+++ /dev/null
@@ -1,2181 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-/* FIXME: most allocations need not be GFP_ATOMIC */
-/* FIXME: management of mutexes */
-/* FIXME: msm_pmem_region_lookup return values */
-/* FIXME: way too many copy to/from user */
-/* FIXME: does region->active mean free */
-/* FIXME: check limits on command lenghts passed from userspace */
-/* FIXME: __msm_release: which queues should we flush when opencnt != 0 */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <mach/board.h>
-
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/uaccess.h>
-#include <linux/android_pmem.h>
-#include <linux/poll.h>
-#include <media/msm_camera.h>
-#include <mach/camera.h>
-
-#define MSM_MAX_CAMERA_SENSORS 5
-
-#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
-                               __func__, __LINE__, ((to) ? "to" : "from"))
-#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
-#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
-
-static struct class *msm_class;
-static dev_t msm_devno;
-static LIST_HEAD(msm_sensors);
-
-#define __CONTAINS(r, v, l, field) ({                          \
-       typeof(r) __r = r;                                      \
-       typeof(v) __v = v;                                      \
-       typeof(v) __e = __v + l;                                \
-       int res = __v >= __r->field &&                          \
-               __e <= __r->field + __r->len;                   \
-       res;                                                    \
-})
-
-#define CONTAINS(r1, r2, field) ({                             \
-       typeof(r2) __r2 = r2;                                   \
-       __CONTAINS(r1, __r2->field, __r2->len, field);          \
-})
-
-#define IN_RANGE(r, v, field) ({                               \
-       typeof(r) __r = r;                                      \
-       typeof(v) __vv = v;                                     \
-       int res = ((__vv >= __r->field) &&                      \
-               (__vv < (__r->field + __r->len)));              \
-       res;                                                    \
-})
-
-#define OVERLAPS(r1, r2, field) ({                             \
-       typeof(r1) __r1 = r1;                                   \
-       typeof(r2) __r2 = r2;                                   \
-       typeof(__r2->field) __v = __r2->field;                  \
-       typeof(__v) __e = __v + __r2->len - 1;                  \
-       int res = (IN_RANGE(__r1, __v, field) ||                \
-                  IN_RANGE(__r1, __e, field));                 \
-       res;                                                    \
-})
-
-#define MSM_DRAIN_QUEUE_NOSYNC(sync, name) do {                        \
-       struct msm_queue_cmd *qcmd = NULL;                      \
-       CDBG("%s: draining queue "#name"\n", __func__);         \
-       while (!list_empty(&(sync)->name)) {                    \
-               qcmd = list_first_entry(&(sync)->name,          \
-                       struct msm_queue_cmd, list);            \
-               list_del_init(&qcmd->list);                     \
-               kfree(qcmd);                                    \
-       };                                                      \
-} while (0)
-
-#define MSM_DRAIN_QUEUE(sync, name) do {                       \
-       unsigned long flags;                                    \
-       spin_lock_irqsave(&(sync)->name##_lock, flags);         \
-       MSM_DRAIN_QUEUE_NOSYNC(sync, name);                     \
-       spin_unlock_irqrestore(&(sync)->name##_lock, flags);    \
-} while (0)
-
-static int check_overlap(struct hlist_head *ptype,
-                       unsigned long paddr,
-                       unsigned long len)
-{
-       struct msm_pmem_region *region;
-       struct msm_pmem_region t = { .paddr = paddr, .len = len };
-       struct hlist_node *node;
-
-       hlist_for_each_entry(region, node, ptype, list) {
-               if (CONTAINS(region, &t, paddr) ||
-                               CONTAINS(&t, region, paddr) ||
-                               OVERLAPS(region, &t, paddr)) {
-                       printk(KERN_ERR
-                               " region (PHYS %p len %ld)"
-                               " clashes with registered region"
-                               " (paddr %p len %ld)\n",
-                               (void *)t.paddr, t.len,
-                               (void *)region->paddr, region->len);
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-static int msm_pmem_table_add(struct hlist_head *ptype,
-       struct msm_pmem_info *info)
-{
-       struct file *file;
-       unsigned long paddr;
-       unsigned long vstart;
-       unsigned long len;
-       int rc;
-       struct msm_pmem_region *region;
-
-       rc = get_pmem_file(info->fd, &paddr, &vstart, &len, &file);
-       if (rc < 0) {
-               pr_err("msm_pmem_table_add: get_pmem_file fd %d error %d\n",
-                       info->fd, rc);
-               return rc;
-       }
-
-       if (check_overlap(ptype, paddr, len) < 0)
-               return -EINVAL;
-
-       CDBG("%s: type = %d, paddr = 0x%lx, vaddr = 0x%lx\n",
-               __func__,
-               info->type, paddr, (unsigned long)info->vaddr);
-
-       region = kmalloc(sizeof(*region), GFP_KERNEL);
-       if (!region)
-               return -ENOMEM;
-
-       INIT_HLIST_NODE(&region->list);
-
-       region->type = info->type;
-       region->vaddr = info->vaddr;
-       region->paddr = paddr;
-       region->len = len;
-       region->file = file;
-       region->y_off = info->y_off;
-       region->cbcr_off = info->cbcr_off;
-       region->fd = info->fd;
-       region->active = info->active;
-
-       hlist_add_head(&(region->list), ptype);
-
-       return 0;
-}
-
-/* return of 0 means failure */
-static uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
-       int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount)
-{
-       struct msm_pmem_region *region;
-       struct msm_pmem_region *regptr;
-       struct hlist_node *node, *n;
-
-       uint8_t rc = 0;
-
-       regptr = reg;
-
-       hlist_for_each_entry_safe(region, node, n, ptype, list) {
-               if (region->type == pmem_type && region->active) {
-                       *regptr = *region;
-                       rc += 1;
-                       if (rc >= maxcount)
-                               break;
-                       regptr++;
-               }
-       }
-
-       return rc;
-}
-
-static unsigned long msm_pmem_frame_ptov_lookup(struct msm_sync *sync,
-               unsigned long pyaddr,
-               unsigned long pcbcraddr,
-               uint32_t *yoff, uint32_t *cbcroff, int *fd)
-{
-       struct msm_pmem_region *region;
-       struct hlist_node *node, *n;
-
-       hlist_for_each_entry_safe(region, node, n, &sync->frame, list) {
-               if (pyaddr == (region->paddr + region->y_off) &&
-                               pcbcraddr == (region->paddr +
-                                               region->cbcr_off) &&
-                               region->active) {
-                       /* offset since we could pass vaddr inside
-                        * a registerd pmem buffer
-                        */
-                       *yoff = region->y_off;
-                       *cbcroff = region->cbcr_off;
-                       *fd = region->fd;
-                       region->active = 0;
-                       return (unsigned long)(region->vaddr);
-               }
-       }
-
-       return 0;
-}
-
-static unsigned long msm_pmem_stats_ptov_lookup(struct msm_sync *sync,
-               unsigned long addr, int *fd)
-{
-       struct msm_pmem_region *region;
-       struct hlist_node *node, *n;
-
-       hlist_for_each_entry_safe(region, node, n, &sync->stats, list) {
-               if (addr == region->paddr && region->active) {
-                       /* offset since we could pass vaddr inside a
-                        * registered pmem buffer */
-                       *fd = region->fd;
-                       region->active = 0;
-                       return (unsigned long)(region->vaddr);
-               }
-       }
-
-       return 0;
-}
-
-static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync,
-               unsigned long buffer,
-               uint32_t yoff, uint32_t cbcroff, int fd)
-{
-       struct msm_pmem_region *region;
-       struct hlist_node *node, *n;
-
-       hlist_for_each_entry_safe(region,
-               node, n, &sync->frame, list) {
-               if (((unsigned long)(region->vaddr) == buffer) &&
-                               (region->y_off == yoff) &&
-                               (region->cbcr_off == cbcroff) &&
-                               (region->fd == fd) &&
-                               (region->active == 0)) {
-
-                       region->active = 1;
-                       return region->paddr;
-               }
-       }
-
-       return 0;
-}
-
-static unsigned long msm_pmem_stats_vtop_lookup(
-               struct msm_sync *sync,
-               unsigned long buffer,
-               int fd)
-{
-       struct msm_pmem_region *region;
-       struct hlist_node *node, *n;
-
-       hlist_for_each_entry_safe(region, node, n, &sync->stats, list) {
-               if (((unsigned long)(region->vaddr) == buffer) &&
-                               (region->fd == fd) && region->active == 0) {
-                       region->active = 1;
-                       return region->paddr;
-               }
-       }
-
-       return 0;
-}
-
-static int __msm_pmem_table_del(struct msm_sync *sync,
-               struct msm_pmem_info *pinfo)
-{
-       int rc = 0;
-       struct msm_pmem_region *region;
-       struct hlist_node *node, *n;
-
-       switch (pinfo->type) {
-       case MSM_PMEM_OUTPUT1:
-       case MSM_PMEM_OUTPUT2:
-       case MSM_PMEM_THUMBAIL:
-       case MSM_PMEM_MAINIMG:
-       case MSM_PMEM_RAW_MAINIMG:
-               hlist_for_each_entry_safe(region, node, n,
-                       &sync->frame, list) {
-
-                       if (pinfo->type == region->type &&
-                                       pinfo->vaddr == region->vaddr &&
-                                       pinfo->fd == region->fd) {
-                               hlist_del(node);
-                               put_pmem_file(region->file);
-                               kfree(region);
-                       }
-               }
-               break;
-
-       case MSM_PMEM_AEC_AWB:
-       case MSM_PMEM_AF:
-               hlist_for_each_entry_safe(region, node, n,
-                       &sync->stats, list) {
-
-                       if (pinfo->type == region->type &&
-                                       pinfo->vaddr == region->vaddr &&
-                                       pinfo->fd == region->fd) {
-                               hlist_del(node);
-                               put_pmem_file(region->file);
-                               kfree(region);
-                       }
-               }
-               break;
-
-       default:
-               rc = -EINVAL;
-               break;
-       }
-
-       return rc;
-}
-
-static int msm_pmem_table_del(struct msm_sync *sync, void __user *arg)
-{
-       struct msm_pmem_info info;
-
-       if (copy_from_user(&info, arg, sizeof(info))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       return __msm_pmem_table_del(sync, &info);
-}
-
-static int __msm_get_frame(struct msm_sync *sync,
-               struct msm_frame *frame)
-{
-       unsigned long flags;
-       int rc = 0;
-
-       struct msm_queue_cmd *qcmd = NULL;
-       struct msm_vfe_phy_info *pphy;
-
-       spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
-       if (!list_empty(&sync->prev_frame_q)) {
-               qcmd = list_first_entry(&sync->prev_frame_q,
-                       struct msm_queue_cmd, list);
-               list_del_init(&qcmd->list);
-       }
-       spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
-
-       if (!qcmd) {
-               pr_err("%s: no preview frame.\n", __func__);
-               return -EAGAIN;
-       }
-
-       pphy = (struct msm_vfe_phy_info *)(qcmd->command);
-
-       frame->buffer =
-               msm_pmem_frame_ptov_lookup(sync,
-                       pphy->y_phy,
-                       pphy->cbcr_phy, &(frame->y_off),
-                       &(frame->cbcr_off), &(frame->fd));
-       if (!frame->buffer) {
-               pr_err("%s: cannot get frame, invalid lookup address "
-                       "y=%x cbcr=%x offset=%d\n",
-                       __func__,
-                       pphy->y_phy,
-                       pphy->cbcr_phy,
-                       frame->y_off);
-               rc = -EINVAL;
-       }
-
-       CDBG("__msm_get_frame: y=0x%x, cbcr=0x%x, qcmd=0x%x, virt_addr=0x%x\n",
-               pphy->y_phy, pphy->cbcr_phy, (int) qcmd, (int) frame->buffer);
-
-       kfree(qcmd);
-       return rc;
-}
-
-static int msm_get_frame(struct msm_sync *sync, void __user *arg)
-{
-       int rc = 0;
-       struct msm_frame frame;
-
-       if (copy_from_user(&frame,
-                               arg,
-                               sizeof(struct msm_frame))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       rc = __msm_get_frame(sync, &frame);
-       if (rc < 0)
-               return rc;
-
-       if (sync->croplen) {
-               if (frame.croplen > sync->croplen) {
-                       pr_err("msm_get_frame: invalid frame croplen %d\n",
-                               frame.croplen);
-                       return -EINVAL;
-               }
-
-               if (copy_to_user((void *)frame.cropinfo,
-                               sync->cropinfo,
-                               sync->croplen)) {
-                       ERR_COPY_TO_USER();
-                       return -EFAULT;
-               }
-       }
-
-       if (copy_to_user((void *)arg,
-                               &frame, sizeof(struct msm_frame))) {
-               ERR_COPY_TO_USER();
-               rc = -EFAULT;
-       }
-
-       CDBG("Got frame!!!\n");
-
-       return rc;
-}
-
-static int msm_enable_vfe(struct msm_sync *sync, void __user *arg)
-{
-       int rc = -EIO;
-       struct camera_enable_cmd cfg;
-
-       if (copy_from_user(&cfg,
-                       arg,
-                       sizeof(struct camera_enable_cmd))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       if (sync->vfefn.vfe_enable)
-               rc = sync->vfefn.vfe_enable(&cfg);
-
-       CDBG("msm_enable_vfe: returned rc = %d\n", rc);
-       return rc;
-}
-
-static int msm_disable_vfe(struct msm_sync *sync, void __user *arg)
-{
-       int rc = -EIO;
-       struct camera_enable_cmd cfg;
-
-       if (copy_from_user(&cfg,
-                       arg,
-                       sizeof(struct camera_enable_cmd))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       if (sync->vfefn.vfe_disable)
-               rc = sync->vfefn.vfe_disable(&cfg, NULL);
-
-       CDBG("msm_disable_vfe: returned rc = %d\n", rc);
-       return rc;
-}
-
-static struct msm_queue_cmd *__msm_control(struct msm_sync *sync,
-               struct msm_control_device_queue *queue,
-               struct msm_queue_cmd *qcmd,
-               int timeout)
-{
-       unsigned long flags;
-       int rc;
-
-       spin_lock_irqsave(&sync->msg_event_q_lock, flags);
-       list_add_tail(&qcmd->list, &sync->msg_event_q);
-       /* wake up config thread */
-       wake_up(&sync->msg_event_wait);
-       spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
-
-       if (!queue)
-               return NULL;
-
-       /* wait for config status */
-       rc = wait_event_interruptible_timeout(
-                       queue->ctrl_status_wait,
-                       !list_empty_careful(&queue->ctrl_status_q),
-                       timeout);
-       if (list_empty_careful(&queue->ctrl_status_q)) {
-               if (!rc)
-                       rc = -ETIMEDOUT;
-               if (rc < 0) {
-                       pr_err("msm_control: wait_event error %d\n", rc);
-#if 0
-                       /* This is a bit scary.  If we time out too early, we
-                        * will free qcmd at the end of this function, and the
-                        * dsp may do the same when it does respond, so we
-                        * remove the message from the source queue.
-                        */
-                       pr_err("%s: error waiting for ctrl_status_q: %d\n",
-                               __func__, rc);
-                       spin_lock_irqsave(&sync->msg_event_q_lock, flags);
-                       list_del_init(&qcmd->list);
-                       spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
-#endif
-                       return ERR_PTR(rc);
-               }
-       }
-
-       /* control command status is ready */
-       spin_lock_irqsave(&queue->ctrl_status_q_lock, flags);
-       BUG_ON(list_empty(&queue->ctrl_status_q));
-       qcmd = list_first_entry(&queue->ctrl_status_q,
-                       struct msm_queue_cmd, list);
-       list_del_init(&qcmd->list);
-       spin_unlock_irqrestore(&queue->ctrl_status_q_lock, flags);
-
-       return qcmd;
-}
-
-static int msm_control(struct msm_control_device *ctrl_pmsm,
-                       int block,
-                       void __user *arg)
-{
-       int rc = 0;
-
-       struct msm_sync *sync = ctrl_pmsm->pmsm->sync;
-       struct msm_ctrl_cmd udata, *ctrlcmd;
-       struct msm_queue_cmd *qcmd = NULL, *qcmd_temp;
-
-       if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) {
-               ERR_COPY_FROM_USER();
-               rc = -EFAULT;
-               goto end;
-       }
-
-       qcmd = kmalloc(sizeof(struct msm_queue_cmd) +
-                               sizeof(struct msm_ctrl_cmd) + udata.length,
-                               GFP_KERNEL);
-       if (!qcmd) {
-               pr_err("msm_control: cannot allocate buffer\n");
-               rc = -ENOMEM;
-               goto end;
-       }
-
-       qcmd->type = MSM_CAM_Q_CTRL;
-       qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1);
-       *ctrlcmd = udata;
-       ctrlcmd->value = ctrlcmd + 1;
-
-       if (udata.length) {
-               if (copy_from_user(ctrlcmd->value,
-                               udata.value, udata.length)) {
-                       ERR_COPY_FROM_USER();
-                       rc = -EFAULT;
-                       goto end;
-               }
-       }
-
-       if (!block) {
-               /* qcmd will be set to NULL */
-               qcmd = __msm_control(sync, NULL, qcmd, 0);
-               goto end;
-       }
-
-       qcmd_temp = __msm_control(sync,
-                                 &ctrl_pmsm->ctrl_q,
-                                 qcmd, MAX_SCHEDULE_TIMEOUT);
-
-       if (IS_ERR(qcmd_temp)) {
-               rc = PTR_ERR(qcmd_temp);
-               goto end;
-       }
-       qcmd = qcmd_temp;
-
-       if (qcmd->command) {
-               void __user *to = udata.value;
-               udata = *(struct msm_ctrl_cmd *)qcmd->command;
-               if (udata.length > 0) {
-                       if (copy_to_user(to,
-                                        udata.value,
-                                        udata.length)) {
-                               ERR_COPY_TO_USER();
-                               rc = -EFAULT;
-                               goto end;
-                       }
-               }
-               udata.value = to;
-
-               if (copy_to_user((void *)arg, &udata,
-                               sizeof(struct msm_ctrl_cmd))) {
-                       ERR_COPY_TO_USER();
-                       rc = -EFAULT;
-                       goto end;
-               }
-       }
-
-end:
-       /* Note: if we get here as a result of an error, we will free the
-        * qcmd that we kmalloc() in this function.  When we come here as
-        * a result of a successful completion, we are freeing the qcmd that
-        * we dequeued from queue->ctrl_status_q.
-        */
-       kfree(qcmd);
-
-       CDBG("msm_control: end rc = %d\n", rc);
-       return rc;
-}
-
-static int msm_get_stats(struct msm_sync *sync, void __user *arg)
-{
-       unsigned long flags;
-       int timeout;
-       int rc = 0;
-
-       struct msm_stats_event_ctrl se;
-
-       struct msm_queue_cmd *qcmd = NULL;
-       struct msm_ctrl_cmd  *ctrl = NULL;
-       struct msm_vfe_resp  *data = NULL;
-       struct msm_stats_buf stats;
-
-       if (copy_from_user(&se, arg,
-                       sizeof(struct msm_stats_event_ctrl))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       timeout = (int)se.timeout_ms;
-
-       CDBG("msm_get_stats timeout %d\n", timeout);
-       rc = wait_event_interruptible_timeout(
-                       sync->msg_event_wait,
-                       !list_empty_careful(&sync->msg_event_q),
-                       msecs_to_jiffies(timeout));
-       if (list_empty_careful(&sync->msg_event_q)) {
-               if (rc == 0)
-                       rc = -ETIMEDOUT;
-               if (rc < 0) {
-                       pr_err("msm_get_stats error %d\n", rc);
-                       return rc;
-               }
-       }
-       CDBG("msm_get_stats returned from wait: %d\n", rc);
-
-       spin_lock_irqsave(&sync->msg_event_q_lock, flags);
-       BUG_ON(list_empty(&sync->msg_event_q));
-       qcmd = list_first_entry(&sync->msg_event_q,
-                       struct msm_queue_cmd, list);
-       list_del_init(&qcmd->list);
-       spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
-
-       CDBG("=== received from DSP === %d\n", qcmd->type);
-
-       switch (qcmd->type) {
-       case MSM_CAM_Q_VFE_EVT:
-       case MSM_CAM_Q_VFE_MSG:
-               data = (struct msm_vfe_resp *)(qcmd->command);
-
-               /* adsp event and message */
-               se.resptype = MSM_CAM_RESP_STAT_EVT_MSG;
-
-               /* 0 - msg from aDSP, 1 - event from mARM */
-               se.stats_event.type   = data->evt_msg.type;
-               se.stats_event.msg_id = data->evt_msg.msg_id;
-               se.stats_event.len    = data->evt_msg.len;
-
-               CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type);
-               CDBG("length = %d\n", se.stats_event.len);
-               CDBG("msg_id = %d\n", se.stats_event.msg_id);
-
-               if ((data->type == VFE_MSG_STATS_AF) ||
-                               (data->type == VFE_MSG_STATS_WE)) {
-
-                       stats.buffer =
-                       msm_pmem_stats_ptov_lookup(sync,
-                                       data->phy.sbuf_phy,
-                                       &(stats.fd));
-                       if (!stats.buffer) {
-                               pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
-                                       __func__);
-                               rc = -EINVAL;
-                               goto failure;
-                       }
-
-                       if (copy_to_user((void *)(se.stats_event.data),
-                                       &stats,
-                                       sizeof(struct msm_stats_buf))) {
-                               ERR_COPY_TO_USER();
-                               rc = -EFAULT;
-                               goto failure;
-                       }
-               } else if ((data->evt_msg.len > 0) &&
-                               (data->type == VFE_MSG_GENERAL)) {
-                       if (copy_to_user((void *)(se.stats_event.data),
-                                       data->evt_msg.data,
-                                       data->evt_msg.len)) {
-                               ERR_COPY_TO_USER();
-                               rc = -EFAULT;
-                       }
-               } else if (data->type == VFE_MSG_OUTPUT1 ||
-                       data->type == VFE_MSG_OUTPUT2) {
-                       if (copy_to_user((void *)(se.stats_event.data),
-                                       data->extdata,
-                                       data->extlen)) {
-                               ERR_COPY_TO_USER();
-                               rc = -EFAULT;
-                       }
-               } else if (data->type == VFE_MSG_SNAPSHOT && sync->pict_pp) {
-                       struct msm_postproc buf;
-                       struct msm_pmem_region region;
-                       buf.fmnum = msm_pmem_region_lookup(&sync->frame,
-                                       MSM_PMEM_MAINIMG,
-                                       &region, 1);
-                       if (buf.fmnum == 1) {
-                               buf.fmain.buffer = (unsigned long)region.vaddr;
-                               buf.fmain.y_off  = region.y_off;
-                               buf.fmain.cbcr_off = region.cbcr_off;
-                               buf.fmain.fd = region.fd;
-                       } else {
-                               buf.fmnum = msm_pmem_region_lookup(&sync->frame,
-                                               MSM_PMEM_RAW_MAINIMG,
-                                               &region, 1);
-                               if (buf.fmnum == 1) {
-                                       buf.fmain.path = MSM_FRAME_PREV_2;
-                                       buf.fmain.buffer =
-                                               (unsigned long)region.vaddr;
-                                       buf.fmain.fd = region.fd;
-                               } else {
-                                       pr_err("%s: pmem lookup failed\n",
-                                               __func__);
-                                       rc = -EINVAL;
-                               }
-                       }
-
-                       if (copy_to_user((void *)(se.stats_event.data), &buf,
-                                       sizeof(buf))) {
-                               ERR_COPY_TO_USER();
-                               rc = -EFAULT;
-                               goto failure;
-                       }
-                       CDBG("snapshot copy_to_user!\n");
-               }
-               break;
-
-       case MSM_CAM_Q_CTRL:
-               /* control command from control thread */
-               ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
-
-               CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type);
-               CDBG("length = %d\n", ctrl->length);
-
-               if (ctrl->length > 0) {
-                       if (copy_to_user((void *)(se.ctrl_cmd.value),
-                                               ctrl->value,
-                                               ctrl->length)) {
-                               ERR_COPY_TO_USER();
-                               rc = -EFAULT;
-                               goto failure;
-                       }
-               }
-
-               se.resptype = MSM_CAM_RESP_CTRL;
-
-               /* what to control */
-               se.ctrl_cmd.type = ctrl->type;
-               se.ctrl_cmd.length = ctrl->length;
-               se.ctrl_cmd.resp_fd = ctrl->resp_fd;
-               break;
-
-       case MSM_CAM_Q_V4L2_REQ:
-               /* control command from v4l2 client */
-               ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
-
-               CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type);
-               CDBG("length = %d\n", ctrl->length);
-
-               if (ctrl->length > 0) {
-                       if (copy_to_user((void *)(se.ctrl_cmd.value),
-                                       ctrl->value, ctrl->length)) {
-                               ERR_COPY_TO_USER();
-                               rc = -EFAULT;
-                               goto failure;
-                       }
-               }
-
-               /* 2 tells config thread this is v4l2 request */
-               se.resptype = MSM_CAM_RESP_V4L2;
-
-               /* what to control */
-               se.ctrl_cmd.type   = ctrl->type;
-               se.ctrl_cmd.length = ctrl->length;
-               break;
-
-       default:
-               rc = -EFAULT;
-               goto failure;
-       } /* switch qcmd->type */
-
-       if (copy_to_user((void *)arg, &se, sizeof(se))) {
-               ERR_COPY_TO_USER();
-               rc = -EFAULT;
-       }
-
-failure:
-       kfree(qcmd);
-
-       CDBG("msm_get_stats: %d\n", rc);
-       return rc;
-}
-
-static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm,
-               void __user *arg)
-{
-       unsigned long flags;
-       int rc = 0;
-
-       struct msm_ctrl_cmd udata, *ctrlcmd;
-       struct msm_queue_cmd *qcmd = NULL;
-
-       if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) {
-               ERR_COPY_FROM_USER();
-               rc = -EFAULT;
-               goto end;
-       }
-
-       qcmd = kmalloc(sizeof(struct msm_queue_cmd) +
-                       sizeof(struct msm_ctrl_cmd) + udata.length,
-                       GFP_KERNEL);
-       if (!qcmd) {
-               rc = -ENOMEM;
-               goto end;
-       }
-
-       qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1);
-       *ctrlcmd = udata;
-       if (udata.length > 0) {
-               ctrlcmd->value = ctrlcmd + 1;
-               if (copy_from_user(ctrlcmd->value,
-                                       (void *)udata.value,
-                                       udata.length)) {
-                       ERR_COPY_FROM_USER();
-                       rc = -EFAULT;
-                       kfree(qcmd);
-                       goto end;
-               }
-       } else
-               ctrlcmd->value = NULL;
-
-end:
-       CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc);
-       if (rc == 0) {
-               /* wake up control thread */
-               spin_lock_irqsave(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags);
-               list_add_tail(&qcmd->list, &ctrl_pmsm->ctrl_q.ctrl_status_q);
-               wake_up(&ctrl_pmsm->ctrl_q.ctrl_status_wait);
-               spin_unlock_irqrestore(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags);
-       }
-
-       return rc;
-}
-
-static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
-{
-       struct msm_vfe_cfg_cmd cfgcmd;
-       struct msm_pmem_region region[8];
-       struct axidata axi_data;
-       void *data = NULL;
-       int rc = -EIO;
-
-       memset(&axi_data, 0, sizeof(axi_data));
-
-       if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       switch (cfgcmd.cmd_type) {
-       case CMD_STATS_ENABLE:
-               axi_data.bufnum1 =
-                       msm_pmem_region_lookup(&sync->stats,
-                                       MSM_PMEM_AEC_AWB, &region[0],
-                                       NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
-               if (!axi_data.bufnum1) {
-                       pr_err("%s: pmem region lookup error\n", __func__);
-                       return -EINVAL;
-               }
-               axi_data.region = &region[0];
-               data = &axi_data;
-               break;
-       case CMD_STATS_AF_ENABLE:
-               axi_data.bufnum1 =
-                       msm_pmem_region_lookup(&sync->stats,
-                                       MSM_PMEM_AF, &region[0],
-                                       NUM_AF_STAT_OUTPUT_BUFFERS);
-               if (!axi_data.bufnum1) {
-                       pr_err("%s: pmem region lookup error\n", __func__);
-                       return -EINVAL;
-               }
-               axi_data.region = &region[0];
-               data = &axi_data;
-               break;
-       case CMD_GENERAL:
-       case CMD_STATS_DISABLE:
-               break;
-       default:
-               pr_err("%s: unknown command type %d\n",
-                       __func__, cfgcmd.cmd_type);
-               return -EINVAL;
-       }
-
-
-       if (sync->vfefn.vfe_config)
-               rc = sync->vfefn.vfe_config(&cfgcmd, data);
-
-       return rc;
-}
-
-static int msm_frame_axi_cfg(struct msm_sync *sync,
-               struct msm_vfe_cfg_cmd *cfgcmd)
-{
-       int rc = -EIO;
-       struct axidata axi_data;
-       void *data = &axi_data;
-       struct msm_pmem_region region[8];
-       int pmem_type;
-
-       memset(&axi_data, 0, sizeof(axi_data));
-
-       switch (cfgcmd->cmd_type) {
-       case CMD_AXI_CFG_OUT1:
-               pmem_type = MSM_PMEM_OUTPUT1;
-               axi_data.bufnum1 =
-                       msm_pmem_region_lookup(&sync->frame, pmem_type,
-                               &region[0], 8);
-               if (!axi_data.bufnum1) {
-                       pr_err("%s: pmem region lookup error\n", __func__);
-                       return -EINVAL;
-               }
-               break;
-
-       case CMD_AXI_CFG_OUT2:
-               pmem_type = MSM_PMEM_OUTPUT2;
-               axi_data.bufnum2 =
-                       msm_pmem_region_lookup(&sync->frame, pmem_type,
-                               &region[0], 8);
-               if (!axi_data.bufnum2) {
-                       pr_err("%s: pmem region lookup error\n", __func__);
-                       return -EINVAL;
-               }
-               break;
-
-       case CMD_AXI_CFG_SNAP_O1_AND_O2:
-               pmem_type = MSM_PMEM_THUMBAIL;
-               axi_data.bufnum1 =
-                       msm_pmem_region_lookup(&sync->frame, pmem_type,
-                               &region[0], 8);
-               if (!axi_data.bufnum1) {
-                       pr_err("%s: pmem region lookup error\n", __func__);
-                       return -EINVAL;
-               }
-
-               pmem_type = MSM_PMEM_MAINIMG;
-               axi_data.bufnum2 =
-                       msm_pmem_region_lookup(&sync->frame, pmem_type,
-                               &region[axi_data.bufnum1], 8);
-               if (!axi_data.bufnum2) {
-                       pr_err("%s: pmem region lookup error\n", __func__);
-                       return -EINVAL;
-               }
-               break;
-
-       case CMD_RAW_PICT_AXI_CFG:
-               pmem_type = MSM_PMEM_RAW_MAINIMG;
-               axi_data.bufnum2 =
-                       msm_pmem_region_lookup(&sync->frame, pmem_type,
-                               &region[0], 8);
-               if (!axi_data.bufnum2) {
-                       pr_err("%s: pmem region lookup error\n", __func__);
-                       return -EINVAL;
-               }
-               break;
-
-       case CMD_GENERAL:
-               data = NULL;
-               break;
-
-       default:
-               pr_err("%s: unknown command type %d\n",
-                       __func__, cfgcmd->cmd_type);
-               return -EINVAL;
-       }
-
-       axi_data.region = &region[0];
-
-       /* send the AXI configuration command to driver */
-       if (sync->vfefn.vfe_config)
-               rc = sync->vfefn.vfe_config(cfgcmd, data);
-
-       return rc;
-}
-
-static int msm_get_sensor_info(struct msm_sync *sync, void __user *arg)
-{
-       int rc = 0;
-       struct msm_camsensor_info info;
-       struct msm_camera_sensor_info *sdata;
-
-       if (copy_from_user(&info,
-                       arg,
-                       sizeof(struct msm_camsensor_info))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       sdata = sync->pdev->dev.platform_data;
-       CDBG("sensor_name %s\n", sdata->sensor_name);
-
-       memcpy(&info.name[0],
-               sdata->sensor_name,
-               MAX_SENSOR_NAME);
-       info.flash_enabled = sdata->flash_type != MSM_CAMERA_FLASH_NONE;
-
-       /* copy back to user space */
-       if (copy_to_user((void *)arg,
-                       &info,
-                       sizeof(struct msm_camsensor_info))) {
-               ERR_COPY_TO_USER();
-               rc = -EFAULT;
-       }
-
-       return rc;
-}
-
-static int __msm_put_frame_buf(struct msm_sync *sync,
-               struct msm_frame *pb)
-{
-       unsigned long pphy;
-       struct msm_vfe_cfg_cmd cfgcmd;
-
-       int rc = -EIO;
-
-       pphy = msm_pmem_frame_vtop_lookup(sync,
-               pb->buffer,
-               pb->y_off, pb->cbcr_off, pb->fd);
-
-       if (pphy != 0) {
-               CDBG("rel: vaddr = 0x%lx, paddr = 0x%lx\n",
-                       pb->buffer, pphy);
-               cfgcmd.cmd_type = CMD_FRAME_BUF_RELEASE;
-               cfgcmd.value    = (void *)pb;
-               if (sync->vfefn.vfe_config)
-                       rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
-       } else {
-               pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
-                       __func__);
-               rc = -EINVAL;
-       }
-
-       return rc;
-}
-
-static int msm_put_frame_buffer(struct msm_sync *sync, void __user *arg)
-{
-       struct msm_frame buf_t;
-
-       if (copy_from_user(&buf_t,
-                               arg,
-                               sizeof(struct msm_frame))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       return __msm_put_frame_buf(sync, &buf_t);
-}
-
-static int __msm_register_pmem(struct msm_sync *sync,
-               struct msm_pmem_info *pinfo)
-{
-       int rc = 0;
-
-       switch (pinfo->type) {
-       case MSM_PMEM_OUTPUT1:
-       case MSM_PMEM_OUTPUT2:
-       case MSM_PMEM_THUMBAIL:
-       case MSM_PMEM_MAINIMG:
-       case MSM_PMEM_RAW_MAINIMG:
-               rc = msm_pmem_table_add(&sync->frame, pinfo);
-               break;
-
-       case MSM_PMEM_AEC_AWB:
-       case MSM_PMEM_AF:
-               rc = msm_pmem_table_add(&sync->stats, pinfo);
-               break;
-
-       default:
-               rc = -EINVAL;
-               break;
-       }
-
-       return rc;
-}
-
-static int msm_register_pmem(struct msm_sync *sync, void __user *arg)
-{
-       struct msm_pmem_info info;
-
-       if (copy_from_user(&info, arg, sizeof(info))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       return __msm_register_pmem(sync, &info);
-}
-
-static int msm_stats_axi_cfg(struct msm_sync *sync,
-               struct msm_vfe_cfg_cmd *cfgcmd)
-{
-       int rc = -EIO;
-       struct axidata axi_data;
-       void *data = &axi_data;
-
-       struct msm_pmem_region region[3];
-       int pmem_type = MSM_PMEM_MAX;
-
-       memset(&axi_data, 0, sizeof(axi_data));
-
-       switch (cfgcmd->cmd_type) {
-       case CMD_STATS_AXI_CFG:
-               pmem_type = MSM_PMEM_AEC_AWB;
-               break;
-       case CMD_STATS_AF_AXI_CFG:
-               pmem_type = MSM_PMEM_AF;
-               break;
-       case CMD_GENERAL:
-               data = NULL;
-               break;
-       default:
-               pr_err("%s: unknown command type %d\n",
-                       __func__, cfgcmd->cmd_type);
-               return -EINVAL;
-       }
-
-       if (cfgcmd->cmd_type != CMD_GENERAL) {
-               axi_data.bufnum1 =
-                       msm_pmem_region_lookup(&sync->stats, pmem_type,
-                               &region[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
-               if (!axi_data.bufnum1) {
-                       pr_err("%s: pmem region lookup error\n", __func__);
-                       return -EINVAL;
-               }
-               axi_data.region = &region[0];
-       }
-
-       /* send the AEC/AWB STATS configuration command to driver */
-       if (sync->vfefn.vfe_config)
-               rc = sync->vfefn.vfe_config(cfgcmd, &axi_data);
-
-       return rc;
-}
-
-static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg)
-{
-       int rc = -EIO;
-
-       struct msm_stats_buf buf;
-       unsigned long pphy;
-       struct msm_vfe_cfg_cmd cfgcmd;
-
-       if (copy_from_user(&buf, arg,
-                               sizeof(struct msm_stats_buf))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       CDBG("msm_put_stats_buffer\n");
-       pphy = msm_pmem_stats_vtop_lookup(sync, buf.buffer, buf.fd);
-
-       if (pphy != 0) {
-               if (buf.type == STAT_AEAW)
-                       cfgcmd.cmd_type = CMD_STATS_BUF_RELEASE;
-               else if (buf.type == STAT_AF)
-                       cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
-               else {
-                       pr_err("%s: invalid buf type %d\n",
-                               __func__,
-                               buf.type);
-                       rc = -EINVAL;
-                       goto put_done;
-               }
-
-               cfgcmd.value = (void *)&buf;
-
-               if (sync->vfefn.vfe_config) {
-                       rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
-                       if (rc < 0)
-                               pr_err("msm_put_stats_buffer: "\
-                                       "vfe_config err %d\n", rc);
-               } else
-                       pr_err("msm_put_stats_buffer: vfe_config is NULL\n");
-       } else {
-               pr_err("msm_put_stats_buffer: NULL physical address\n");
-               rc = -EINVAL;
-       }
-
-put_done:
-       return rc;
-}
-
-static int msm_axi_config(struct msm_sync *sync, void __user *arg)
-{
-       struct msm_vfe_cfg_cmd cfgcmd;
-
-       if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       switch (cfgcmd.cmd_type) {
-       case CMD_AXI_CFG_OUT1:
-       case CMD_AXI_CFG_OUT2:
-       case CMD_AXI_CFG_SNAP_O1_AND_O2:
-       case CMD_RAW_PICT_AXI_CFG:
-               return msm_frame_axi_cfg(sync, &cfgcmd);
-
-       case CMD_STATS_AXI_CFG:
-       case CMD_STATS_AF_AXI_CFG:
-               return msm_stats_axi_cfg(sync, &cfgcmd);
-
-       default:
-               pr_err("%s: unknown command type %d\n",
-                       __func__,
-                       cfgcmd.cmd_type);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int __msm_get_pic(struct msm_sync *sync, struct msm_ctrl_cmd *ctrl)
-{
-       unsigned long flags;
-       int rc = 0;
-       int tm;
-
-       struct msm_queue_cmd *qcmd = NULL;
-
-       tm = (int)ctrl->timeout_ms;
-
-       rc = wait_event_interruptible_timeout(
-                       sync->pict_frame_wait,
-                       !list_empty_careful(&sync->pict_frame_q),
-                       msecs_to_jiffies(tm));
-       if (list_empty_careful(&sync->pict_frame_q)) {
-               if (rc == 0)
-                       return -ETIMEDOUT;
-               if (rc < 0) {
-                       pr_err("msm_camera_get_picture, rc = %d\n", rc);
-                       return rc;
-               }
-       }
-
-       spin_lock_irqsave(&sync->pict_frame_q_lock, flags);
-       BUG_ON(list_empty(&sync->pict_frame_q));
-       qcmd = list_first_entry(&sync->pict_frame_q,
-                       struct msm_queue_cmd, list);
-       list_del_init(&qcmd->list);
-       spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags);
-
-       if (qcmd->command != NULL) {
-               struct msm_ctrl_cmd *q =
-                       (struct msm_ctrl_cmd *)qcmd->command;
-               ctrl->type = q->type;
-               ctrl->status = q->status;
-       } else {
-               ctrl->type = -1;
-               ctrl->status = -1;
-       }
-
-       kfree(qcmd);
-       return rc;
-}
-
-static int msm_get_pic(struct msm_sync *sync, void __user *arg)
-{
-       struct msm_ctrl_cmd ctrlcmd_t;
-       int rc;
-
-       if (copy_from_user(&ctrlcmd_t,
-                               arg,
-                               sizeof(struct msm_ctrl_cmd))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       rc = __msm_get_pic(sync, &ctrlcmd_t);
-       if (rc < 0)
-               return rc;
-
-       if (sync->croplen) {
-               if (ctrlcmd_t.length < sync->croplen) {
-                       pr_err("msm_get_pic: invalid len %d\n",
-                               ctrlcmd_t.length);
-                       return -EINVAL;
-               }
-               if (copy_to_user(ctrlcmd_t.value,
-                               sync->cropinfo,
-                               sync->croplen)) {
-                       ERR_COPY_TO_USER();
-                       return -EFAULT;
-               }
-       }
-
-       if (copy_to_user((void *)arg,
-               &ctrlcmd_t,
-               sizeof(struct msm_ctrl_cmd))) {
-               ERR_COPY_TO_USER();
-               return -EFAULT;
-       }
-       return 0;
-}
-
-static int msm_set_crop(struct msm_sync *sync, void __user *arg)
-{
-       struct crop_info crop;
-
-       if (copy_from_user(&crop,
-                               arg,
-                               sizeof(struct crop_info))) {
-               ERR_COPY_FROM_USER();
-               return -EFAULT;
-       }
-
-       if (!sync->croplen) {
-               sync->cropinfo = kmalloc(crop.len, GFP_KERNEL);
-               if (!sync->cropinfo)
-                       return -ENOMEM;
-       } else if (sync->croplen < crop.len)
-               return -EINVAL;
-
-       if (copy_from_user(sync->cropinfo,
-                               crop.info,
-                               crop.len)) {
-               ERR_COPY_FROM_USER();
-               kfree(sync->cropinfo);
-               return -EFAULT;
-       }
-
-       sync->croplen = crop.len;
-
-       return 0;
-}
-
-static int msm_pict_pp_done(struct msm_sync *sync, void __user *arg)
-{
-       struct msm_ctrl_cmd udata;
-       struct msm_ctrl_cmd *ctrlcmd = NULL;
-       struct msm_queue_cmd *qcmd = NULL;
-       unsigned long flags;
-       int rc = 0;
-
-       if (!sync->pict_pp)
-               return -EINVAL;
-
-       if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) {
-               ERR_COPY_FROM_USER();
-               rc = -EFAULT;
-               goto pp_fail;
-       }
-
-       qcmd = kmalloc(sizeof(struct msm_queue_cmd) +
-                       sizeof(struct msm_ctrl_cmd),
-                       GFP_KERNEL);
-       if (!qcmd) {
-               rc = -ENOMEM;
-               goto pp_fail;
-       }
-
-       qcmd->type = MSM_CAM_Q_VFE_MSG;
-       qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1);
-       memset(ctrlcmd, 0, sizeof(struct msm_ctrl_cmd));
-       ctrlcmd->type = udata.type;
-       ctrlcmd->status = udata.status;
-
-       spin_lock_irqsave(&sync->pict_frame_q_lock, flags);
-       list_add_tail(&qcmd->list, &sync->pict_frame_q);
-       spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags);
-       wake_up(&sync->pict_frame_wait);
-
-pp_fail:
-       return rc;
-}
-
-static long msm_ioctl_common(struct msm_device *pmsm,
-               unsigned int cmd,
-               void __user *argp)
-{
-       CDBG("msm_ioctl_common\n");
-       switch (cmd) {
-       case MSM_CAM_IOCTL_REGISTER_PMEM:
-               return msm_register_pmem(pmsm->sync, argp);
-       case MSM_CAM_IOCTL_UNREGISTER_PMEM:
-               return msm_pmem_table_del(pmsm->sync, argp);
-       default:
-               return -EINVAL;
-       }
-}
-
-static long msm_ioctl_config(struct file *filep, unsigned int cmd,
-       unsigned long arg)
-{
-       int rc = -EINVAL;
-       void __user *argp = (void __user *)arg;
-       struct msm_device *pmsm = filep->private_data;
-
-       CDBG("msm_ioctl_config cmd = %d\n", _IOC_NR(cmd));
-
-       switch (cmd) {
-       case MSM_CAM_IOCTL_GET_SENSOR_INFO:
-               rc = msm_get_sensor_info(pmsm->sync, argp);
-               break;
-
-       case MSM_CAM_IOCTL_CONFIG_VFE:
-               /* Coming from config thread for update */
-               rc = msm_config_vfe(pmsm->sync, argp);
-               break;
-
-       case MSM_CAM_IOCTL_GET_STATS:
-               /* Coming from config thread wait
-                * for vfe statistics and control requests */
-               rc = msm_get_stats(pmsm->sync, argp);
-               break;
-
-       case MSM_CAM_IOCTL_ENABLE_VFE:
-               /* This request comes from control thread:
-                * enable either QCAMTASK or VFETASK */
-               rc = msm_enable_vfe(pmsm->sync, argp);
-               break;
-
-       case MSM_CAM_IOCTL_DISABLE_VFE:
-               /* This request comes from control thread:
-                * disable either QCAMTASK or VFETASK */
-               rc = msm_disable_vfe(pmsm->sync, argp);
-               break;
-
-       case MSM_CAM_IOCTL_VFE_APPS_RESET:
-               msm_camio_vfe_blk_reset();
-               rc = 0;
-               break;
-
-       case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER:
-               rc = msm_put_stats_buffer(pmsm->sync, argp);
-               break;
-
-       case MSM_CAM_IOCTL_AXI_CONFIG:
-               rc = msm_axi_config(pmsm->sync, argp);
-               break;
-
-       case MSM_CAM_IOCTL_SET_CROP:
-               rc = msm_set_crop(pmsm->sync, argp);
-               break;
-
-       case MSM_CAM_IOCTL_PICT_PP: {
-               uint8_t enable;
-               if (copy_from_user(&enable, argp, sizeof(enable))) {
-                       ERR_COPY_FROM_USER();
-                       rc = -EFAULT;
-               } else {
-                       pmsm->sync->pict_pp = enable;
-                       rc = 0;
-               }
-               break;
-       }
-
-       case MSM_CAM_IOCTL_PICT_PP_DONE:
-               rc = msm_pict_pp_done(pmsm->sync, argp);
-               break;
-
-       case MSM_CAM_IOCTL_SENSOR_IO_CFG:
-               rc = pmsm->sync->sctrl.s_config(argp);
-               break;
-
-       case MSM_CAM_IOCTL_FLASH_LED_CFG: {
-               uint32_t led_state;
-               if (copy_from_user(&led_state, argp, sizeof(led_state))) {
-                       ERR_COPY_FROM_USER();
-                       rc = -EFAULT;
-               } else
-                       rc = msm_camera_flash_set_led_state(led_state);
-               break;
-       }
-
-       default:
-               rc = msm_ioctl_common(pmsm, cmd, argp);
-               break;
-       }
-
-       CDBG("msm_ioctl_config cmd = %d DONE\n", _IOC_NR(cmd));
-       return rc;
-}
-
-static int msm_unblock_poll_frame(struct msm_sync *);
-
-static long msm_ioctl_frame(struct file *filep, unsigned int cmd,
-       unsigned long arg)
-{
-       int rc = -EINVAL;
-       void __user *argp = (void __user *)arg;
-       struct msm_device *pmsm = filep->private_data;
-
-
-       switch (cmd) {
-       case MSM_CAM_IOCTL_GETFRAME:
-               /* Coming from frame thread to get frame
-                * after SELECT is done */
-               rc = msm_get_frame(pmsm->sync, argp);
-               break;
-       case MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER:
-               rc = msm_put_frame_buffer(pmsm->sync, argp);
-               break;
-       case MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME:
-               rc = msm_unblock_poll_frame(pmsm->sync);
-               break;
-       default:
-               break;
-       }
-
-       return rc;
-}
-
-
-static long msm_ioctl_control(struct file *filep, unsigned int cmd,
-       unsigned long arg)
-{
-       int rc = -EINVAL;
-       void __user *argp = (void __user *)arg;
-       struct msm_control_device *ctrl_pmsm = filep->private_data;
-       struct msm_device *pmsm = ctrl_pmsm->pmsm;
-
-       switch (cmd) {
-       case MSM_CAM_IOCTL_CTRL_COMMAND:
-               /* Coming from control thread, may need to wait for
-                * command status */
-               rc = msm_control(ctrl_pmsm, 1, argp);
-               break;
-       case MSM_CAM_IOCTL_CTRL_COMMAND_2:
-               /* Sends a message, returns immediately */
-               rc = msm_control(ctrl_pmsm, 0, argp);
-               break;
-       case MSM_CAM_IOCTL_CTRL_CMD_DONE:
-               /* Config thread calls the control thread to notify it
-                * of the result of a MSM_CAM_IOCTL_CTRL_COMMAND.
-                */
-               rc = msm_ctrl_cmd_done(ctrl_pmsm, argp);
-               break;
-       case MSM_CAM_IOCTL_GET_PICTURE:
-               rc = msm_get_pic(pmsm->sync, argp);
-               break;
-       default:
-               rc = msm_ioctl_common(pmsm, cmd, argp);
-               break;
-       }
-
-       return rc;
-}
-
-static int __msm_release(struct msm_sync *sync)
-{
-       struct msm_pmem_region *region;
-       struct hlist_node *hnode;
-       struct hlist_node *n;
-
-       mutex_lock(&sync->lock);
-       if (sync->opencnt)
-               sync->opencnt--;
-
-       if (!sync->opencnt) {
-               /* need to clean up system resource */
-               if (sync->vfefn.vfe_release)
-                       sync->vfefn.vfe_release(sync->pdev);
-
-               if (sync->cropinfo) {
-                       kfree(sync->cropinfo);
-                       sync->cropinfo = NULL;
-                       sync->croplen = 0;
-               }
-
-               hlist_for_each_entry_safe(region, hnode, n,
-                               &sync->frame, list) {
-                       hlist_del(hnode);
-                       put_pmem_file(region->file);
-                       kfree(region);
-               }
-
-               hlist_for_each_entry_safe(region, hnode, n,
-                               &sync->stats, list) {
-                       hlist_del(hnode);
-                       put_pmem_file(region->file);
-                       kfree(region);
-               }
-
-               MSM_DRAIN_QUEUE(sync, msg_event_q);
-               MSM_DRAIN_QUEUE(sync, prev_frame_q);
-               MSM_DRAIN_QUEUE(sync, pict_frame_q);
-
-               sync->sctrl.s_release();
-
-               sync->apps_id = NULL;
-               CDBG("msm_release completed!\n");
-       }
-       mutex_unlock(&sync->lock);
-
-       return 0;
-}
-
-static int msm_release_config(struct inode *node, struct file *filep)
-{
-       int rc;
-       struct msm_device *pmsm = filep->private_data;
-       printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name);
-       rc = __msm_release(pmsm->sync);
-       atomic_set(&pmsm->opened, 0);
-       return rc;
-}
-
-static int msm_release_control(struct inode *node, struct file *filep)
-{
-       int rc;
-       struct msm_control_device *ctrl_pmsm = filep->private_data;
-       struct msm_device *pmsm = ctrl_pmsm->pmsm;
-       printk(KERN_INFO "msm_camera: RELEASE %s\n",
-                                       filep->f_path.dentry->d_name.name);
-       rc = __msm_release(pmsm->sync);
-       if (!rc) {
-               MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q);
-               MSM_DRAIN_QUEUE(pmsm->sync, pict_frame_q);
-       }
-       kfree(ctrl_pmsm);
-       return rc;
-}
-
-static int msm_release_frame(struct inode *node, struct file *filep)
-{
-       int rc;
-       struct msm_device *pmsm = filep->private_data;
-       printk(KERN_INFO "msm_camera: RELEASE %s\n",
-                                       filep->f_path.dentry->d_name.name);
-       rc = __msm_release(pmsm->sync);
-       if (!rc) {
-               MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q);
-               atomic_set(&pmsm->opened, 0);
-       }
-       return rc;
-}
-
-static int msm_unblock_poll_frame(struct msm_sync *sync)
-{
-       unsigned long flags;
-       CDBG("msm_unblock_poll_frame\n");
-       spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
-       sync->unblock_poll_frame = 1;
-       wake_up(&sync->prev_frame_wait);
-       spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
-       return 0;
-}
-
-static unsigned int __msm_poll_frame(struct msm_sync *sync,
-               struct file *filep,
-               struct poll_table_struct *pll_table)
-{
-       int rc = 0;
-       unsigned long flags;
-
-       poll_wait(filep, &sync->prev_frame_wait, pll_table);
-
-       spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
-       if (!list_empty_careful(&sync->prev_frame_q))
-               /* frame ready */
-               rc = POLLIN | POLLRDNORM;
-       if (sync->unblock_poll_frame) {
-               CDBG("%s: sync->unblock_poll_frame is true\n", __func__);
-               rc |= POLLPRI;
-               sync->unblock_poll_frame = 0;
-       }
-       spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
-
-       return rc;
-}
-
-static unsigned int msm_poll_frame(struct file *filep,
-       struct poll_table_struct *pll_table)
-{
-       struct msm_device *pmsm = filep->private_data;
-       return __msm_poll_frame(pmsm->sync, filep, pll_table);
-}
-
-/*
- * This function executes in interrupt context.
- */
-
-static void *msm_vfe_sync_alloc(int size,
-                       void *syncdata __attribute__((unused)))
-{
-       struct msm_queue_cmd *qcmd =
-               kmalloc(sizeof(struct msm_queue_cmd) + size, GFP_ATOMIC);
-       return qcmd ? qcmd + 1 : NULL;
-}
-
-/*
- * This function executes in interrupt context.
- */
-
-static void msm_vfe_sync(struct msm_vfe_resp *vdata,
-               enum msm_queue qtype, void *syncdata)
-{
-       struct msm_queue_cmd *qcmd = NULL;
-       struct msm_queue_cmd *qcmd_frame = NULL;
-       struct msm_vfe_phy_info *fphy;
-
-       unsigned long flags;
-       struct msm_sync *sync = (struct msm_sync *)syncdata;
-       if (!sync) {
-               pr_err("msm_camera: no context in dsp callback.\n");
-               return;
-       }
-
-       qcmd = ((struct msm_queue_cmd *)vdata) - 1;
-       qcmd->type = qtype;
-
-       if (qtype == MSM_CAM_Q_VFE_MSG) {
-               switch (vdata->type) {
-               case VFE_MSG_OUTPUT1:
-               case VFE_MSG_OUTPUT2:
-                       qcmd_frame =
-                               kmalloc(sizeof(struct msm_queue_cmd) +
-                                       sizeof(struct msm_vfe_phy_info),
-                                       GFP_ATOMIC);
-                       if (!qcmd_frame)
-                               goto mem_fail;
-                       fphy = (struct msm_vfe_phy_info *)(qcmd_frame + 1);
-                       *fphy = vdata->phy;
-
-                       qcmd_frame->type = MSM_CAM_Q_VFE_MSG;
-                       qcmd_frame->command = fphy;
-
-                       CDBG("qcmd_frame= 0x%x phy_y= 0x%x, phy_cbcr= 0x%x\n",
-                               (int) qcmd_frame, fphy->y_phy, fphy->cbcr_phy);
-
-                       spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
-                       list_add_tail(&qcmd_frame->list, &sync->prev_frame_q);
-                       wake_up(&sync->prev_frame_wait);
-                       spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
-                       CDBG("woke up frame thread\n");
-                       break;
-               case VFE_MSG_SNAPSHOT:
-                       if (sync->pict_pp)
-                               break;
-
-                       CDBG("snapshot pp = %d\n", sync->pict_pp);
-                       qcmd_frame =
-                               kmalloc(sizeof(struct msm_queue_cmd),
-                                       GFP_ATOMIC);
-                       if (!qcmd_frame)
-                               goto mem_fail;
-                       qcmd_frame->type = MSM_CAM_Q_VFE_MSG;
-                       qcmd_frame->command = NULL;
-                               spin_lock_irqsave(&sync->pict_frame_q_lock,
-                               flags);
-                       list_add_tail(&qcmd_frame->list, &sync->pict_frame_q);
-                       wake_up(&sync->pict_frame_wait);
-                       spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags);
-                       CDBG("woke up picture thread\n");
-                       break;
-               default:
-                       CDBG("%s: qtype = %d not handled\n",
-                               __func__, vdata->type);
-                       break;
-               }
-       }
-
-       qcmd->command = (void *)vdata;
-       CDBG("vdata->type = %d\n", vdata->type);
-
-       spin_lock_irqsave(&sync->msg_event_q_lock, flags);
-       list_add_tail(&qcmd->list, &sync->msg_event_q);
-       wake_up(&sync->msg_event_wait);
-       spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
-       CDBG("woke up config thread\n");
-       return;
-
-mem_fail:
-       kfree(qcmd);
-}
-
-static struct msm_vfe_callback msm_vfe_s = {
-       .vfe_resp = msm_vfe_sync,
-       .vfe_alloc = msm_vfe_sync_alloc,
-};
-
-static int __msm_open(struct msm_sync *sync, const char *const apps_id)
-{
-       int rc = 0;
-
-       mutex_lock(&sync->lock);
-       if (sync->apps_id && strcmp(sync->apps_id, apps_id)) {
-               pr_err("msm_camera(%s): sensor %s is already opened for %s\n",
-                       apps_id,
-                       sync->sdata->sensor_name,
-                       sync->apps_id);
-               rc = -EBUSY;
-               goto msm_open_done;
-       }
-
-       sync->apps_id = apps_id;
-
-       if (!sync->opencnt) {
-
-               msm_camvfe_fn_init(&sync->vfefn, sync);
-               if (sync->vfefn.vfe_init) {
-                       rc = sync->vfefn.vfe_init(&msm_vfe_s,
-                               sync->pdev);
-                       if (rc < 0) {
-                               pr_err("vfe_init failed at %d\n", rc);
-                               goto msm_open_done;
-                       }
-                       rc = sync->sctrl.s_init(sync->sdata);
-                       if (rc < 0) {
-                               pr_err("sensor init failed: %d\n", rc);
-                               goto msm_open_done;
-                       }
-               } else {
-                       pr_err("no sensor init func\n");
-                       rc = -ENODEV;
-                       goto msm_open_done;
-               }
-
-               if (rc >= 0) {
-                       INIT_HLIST_HEAD(&sync->frame);
-                       INIT_HLIST_HEAD(&sync->stats);
-                       sync->unblock_poll_frame = 0;
-               }
-       }
-       sync->opencnt++;
-
-msm_open_done:
-       mutex_unlock(&sync->lock);
-       return rc;
-}
-
-static int msm_open_common(struct inode *inode, struct file *filep,
-                          int once)
-{
-       int rc;
-       struct msm_device *pmsm =
-               container_of(inode->i_cdev, struct msm_device, cdev);
-
-       CDBG("msm_camera: open %s\n", filep->f_path.dentry->d_name.name);
-
-       if (atomic_cmpxchg(&pmsm->opened, 0, 1) && once) {
-               pr_err("msm_camera: %s is already opened.\n",
-                       filep->f_path.dentry->d_name.name);
-               return -EBUSY;
-       }
-
-       rc = nonseekable_open(inode, filep);
-       if (rc < 0) {
-               pr_err("msm_open: nonseekable_open error %d\n", rc);
-               return rc;
-       }
-
-       rc = __msm_open(pmsm->sync, MSM_APPS_ID_PROP);
-       if (rc < 0)
-               return rc;
-
-       filep->private_data = pmsm;
-
-       CDBG("msm_open() open: rc = %d\n", rc);
-       return rc;
-}
-
-static int msm_open(struct inode *inode, struct file *filep)
-{
-       return msm_open_common(inode, filep, 1);
-}
-
-static int msm_open_control(struct inode *inode, struct file *filep)
-{
-       int rc;
-
-       struct msm_control_device *ctrl_pmsm =
-               kmalloc(sizeof(struct msm_control_device), GFP_KERNEL);
-       if (!ctrl_pmsm)
-               return -ENOMEM;
-
-       rc = msm_open_common(inode, filep, 0);
-       if (rc < 0) {
-               kfree(ctrl_pmsm);
-               return rc;
-       }
-
-       ctrl_pmsm->pmsm = filep->private_data;
-       filep->private_data = ctrl_pmsm;
-       spin_lock_init(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock);
-       INIT_LIST_HEAD(&ctrl_pmsm->ctrl_q.ctrl_status_q);
-       init_waitqueue_head(&ctrl_pmsm->ctrl_q.ctrl_status_wait);
-
-       CDBG("msm_open() open: rc = %d\n", rc);
-       return rc;
-}
-
-static int __msm_v4l2_control(struct msm_sync *sync,
-               struct msm_ctrl_cmd *out)
-{
-       int rc = 0;
-
-       struct msm_queue_cmd *qcmd = NULL, *rcmd = NULL;
-       struct msm_ctrl_cmd *ctrl;
-       struct msm_control_device_queue FIXME;
-
-       /* wake up config thread, 4 is for V4L2 application */
-       qcmd = kmalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
-       if (!qcmd) {
-               pr_err("msm_control: cannot allocate buffer\n");
-               rc = -ENOMEM;
-               goto end;
-       }
-       qcmd->type = MSM_CAM_Q_V4L2_REQ;
-       qcmd->command = out;
-
-       rcmd = __msm_control(sync, &FIXME, qcmd, out->timeout_ms);
-       if (IS_ERR(rcmd)) {
-               rc = PTR_ERR(rcmd);
-               goto end;
-       }
-
-       ctrl = (struct msm_ctrl_cmd *)(rcmd->command);
-       /* FIXME: we should just set out->length = ctrl->length; */
-       BUG_ON(out->length < ctrl->length);
-       memcpy(out->value, ctrl->value, ctrl->length);
-
-end:
-       kfree(rcmd);
-       CDBG("__msm_v4l2_control: end rc = %d\n", rc);
-       return rc;
-}
-
-static const struct file_operations msm_fops_config = {
-       .owner = THIS_MODULE,
-       .open = msm_open,
-       .unlocked_ioctl = msm_ioctl_config,
-       .release = msm_release_config,
-       .llseek = no_llseek,
-};
-
-static const struct file_operations msm_fops_control = {
-       .owner = THIS_MODULE,
-       .open = msm_open_control,
-       .unlocked_ioctl = msm_ioctl_control,
-       .release = msm_release_control,
-       .llseek = no_llseek,
-};
-
-static const struct file_operations msm_fops_frame = {
-       .owner = THIS_MODULE,
-       .open = msm_open,
-       .unlocked_ioctl = msm_ioctl_frame,
-       .release = msm_release_frame,
-       .poll = msm_poll_frame,
-       .llseek = no_llseek,
-};
-
-static int msm_setup_cdev(struct msm_device *msm,
-                       int node,
-                       dev_t devno,
-                       const char *suffix,
-                       const struct file_operations *fops)
-{
-       int rc = -ENODEV;
-
-       struct device *device =
-               device_create(msm_class, NULL,
-                       devno, NULL,
-                       "%s%d", suffix, node);
-
-       if (IS_ERR(device)) {
-               rc = PTR_ERR(device);
-               pr_err("msm_camera: error creating device: %d\n", rc);
-               return rc;
-       }
-
-       cdev_init(&msm->cdev, fops);
-       msm->cdev.owner = THIS_MODULE;
-
-       rc = cdev_add(&msm->cdev, devno, 1);
-       if (rc < 0) {
-               pr_err("msm_camera: error adding cdev: %d\n", rc);
-               device_destroy(msm_class, devno);
-               return rc;
-       }
-
-       return rc;
-}
-
-static int msm_tear_down_cdev(struct msm_device *msm, dev_t devno)
-{
-       cdev_del(&msm->cdev);
-       device_destroy(msm_class, devno);
-       return 0;
-}
-
-int msm_v4l2_register(struct msm_v4l2_driver *drv)
-{
-       /* FIXME: support multiple sensors */
-       if (list_empty(&msm_sensors))
-               return -ENODEV;
-
-       drv->sync = list_first_entry(&msm_sensors, struct msm_sync, list);
-       drv->open      = __msm_open;
-       drv->release   = __msm_release;
-       drv->ctrl      = __msm_v4l2_control;
-       drv->reg_pmem  = __msm_register_pmem;
-       drv->get_frame = __msm_get_frame;
-       drv->put_frame = __msm_put_frame_buf;
-       drv->get_pict  = __msm_get_pic;
-       drv->drv_poll  = __msm_poll_frame;
-
-       return 0;
-}
-EXPORT_SYMBOL(msm_v4l2_register);
-
-int msm_v4l2_unregister(struct msm_v4l2_driver *drv)
-{
-       drv->sync = NULL;
-       return 0;
-}
-EXPORT_SYMBOL(msm_v4l2_unregister);
-
-static int msm_sync_init(struct msm_sync *sync,
-               struct platform_device *pdev,
-               int (*sensor_probe)(const struct msm_camera_sensor_info *,
-                               struct msm_sensor_ctrl *))
-{
-       int rc = 0;
-       struct msm_sensor_ctrl sctrl;
-       sync->sdata = pdev->dev.platform_data;
-
-       spin_lock_init(&sync->msg_event_q_lock);
-       INIT_LIST_HEAD(&sync->msg_event_q);
-       init_waitqueue_head(&sync->msg_event_wait);
-
-       spin_lock_init(&sync->prev_frame_q_lock);
-       INIT_LIST_HEAD(&sync->prev_frame_q);
-       init_waitqueue_head(&sync->prev_frame_wait);
-
-       spin_lock_init(&sync->pict_frame_q_lock);
-       INIT_LIST_HEAD(&sync->pict_frame_q);
-       init_waitqueue_head(&sync->pict_frame_wait);
-
-       rc = msm_camio_probe_on(pdev);
-       if (rc < 0)
-               return rc;
-       rc = sensor_probe(sync->sdata, &sctrl);
-       if (rc >= 0) {
-               sync->pdev = pdev;
-               sync->sctrl = sctrl;
-       }
-       msm_camio_probe_off(pdev);
-       if (rc < 0) {
-               pr_err("msm_camera: failed to initialize %s\n",
-                       sync->sdata->sensor_name);
-               return rc;
-       }
-
-       sync->opencnt = 0;
-       mutex_init(&sync->lock);
-       CDBG("initialized %s\n", sync->sdata->sensor_name);
-       return rc;
-}
-
-static int msm_sync_destroy(struct msm_sync *sync)
-{
-       return 0;
-}
-
-static int msm_device_init(struct msm_device *pmsm,
-               struct msm_sync *sync,
-               int node)
-{
-       int dev_num = 3 * node;
-       int rc = msm_setup_cdev(pmsm, node,
-               MKDEV(MAJOR(msm_devno), dev_num),
-               "control", &msm_fops_control);
-       if (rc < 0) {
-               pr_err("error creating control node: %d\n", rc);
-               return rc;
-       }
-
-       rc = msm_setup_cdev(pmsm + 1, node,
-               MKDEV(MAJOR(msm_devno), dev_num + 1),
-               "config", &msm_fops_config);
-       if (rc < 0) {
-               pr_err("error creating config node: %d\n", rc);
-               msm_tear_down_cdev(pmsm, MKDEV(MAJOR(msm_devno),
-                               dev_num));
-               return rc;
-       }
-
-       rc = msm_setup_cdev(pmsm + 2, node,
-               MKDEV(MAJOR(msm_devno), dev_num + 2),
-               "frame", &msm_fops_frame);
-       if (rc < 0) {
-               pr_err("error creating frame node: %d\n", rc);
-               msm_tear_down_cdev(pmsm,
-                       MKDEV(MAJOR(msm_devno), dev_num));
-               msm_tear_down_cdev(pmsm + 1,
-                       MKDEV(MAJOR(msm_devno), dev_num + 1));
-               return rc;
-       }
-
-       atomic_set(&pmsm[0].opened, 0);
-       atomic_set(&pmsm[1].opened, 0);
-       atomic_set(&pmsm[2].opened, 0);
-
-       pmsm[0].sync = sync;
-       pmsm[1].sync = sync;
-       pmsm[2].sync = sync;
-
-       return rc;
-}
-
-int msm_camera_drv_start(struct platform_device *dev,
-               int (*sensor_probe)(const struct msm_camera_sensor_info *,
-                       struct msm_sensor_ctrl *))
-{
-       struct msm_device *pmsm = NULL;
-       struct msm_sync *sync;
-       int rc = -ENODEV;
-       static int camera_node;
-
-       if (camera_node >= MSM_MAX_CAMERA_SENSORS) {
-               pr_err("msm_camera: too many camera sensors\n");
-               return rc;
-       }
-
-       if (!msm_class) {
-               /* There are three device nodes per sensor */
-               rc = alloc_chrdev_region(&msm_devno, 0,
-                               3 * MSM_MAX_CAMERA_SENSORS,
-                               "msm_camera");
-               if (rc < 0) {
-                       pr_err("msm_camera: failed to allocate chrdev: %d\n",
-                               rc);
-                       return rc;
-               }
-
-               msm_class = class_create(THIS_MODULE, "msm_camera");
-               if (IS_ERR(msm_class)) {
-                       rc = PTR_ERR(msm_class);
-                       pr_err("msm_camera: create device class failed: %d\n",
-                               rc);
-                       return rc;
-               }
-       }
-
-       pmsm = kzalloc(sizeof(struct msm_device) * 3 +
-                       sizeof(struct msm_sync), GFP_ATOMIC);
-       if (!pmsm)
-               return -ENOMEM;
-       sync = (struct msm_sync *)(pmsm + 3);
-
-       rc = msm_sync_init(sync, dev, sensor_probe);
-       if (rc < 0) {
-               kfree(pmsm);
-               return rc;
-       }
-
-       CDBG("setting camera node %d\n", camera_node);
-       rc = msm_device_init(pmsm, sync, camera_node);
-       if (rc < 0) {
-               msm_sync_destroy(sync);
-               kfree(pmsm);
-               return rc;
-       }
-
-       camera_node++;
-       list_add(&sync->list, &msm_sensors);
-       return rc;
-}
-EXPORT_SYMBOL(msm_camera_drv_start);
diff --git a/drivers/staging/dream/camera/msm_io7x.c b/drivers/staging/dream/camera/msm_io7x.c
deleted file mode 100644 (file)
index 55c020b..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2008-2009 QUALCOMM Incorporated
- */
-
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <mach/gpio.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-
-#define CAMIF_CFG_RMSK 0x1fffff
-#define CAM_SEL_BMSK 0x2
-#define CAM_PCLK_SRC_SEL_BMSK 0x60000
-#define CAM_PCLK_INVERT_BMSK 0x80000
-#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
-
-#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
-#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
-#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
-
-#define CAM_SEL_SHFT 0x1
-#define CAM_PCLK_SRC_SEL_SHFT 0x11
-#define CAM_PCLK_INVERT_SHFT 0x13
-#define CAM_PAD_REG_SW_RESET_SHFT 0x14
-
-#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
-#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
-#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
-#define APPS_RESET_OFFSET 0x00000210
-
-static struct clk *camio_vfe_mdc_clk;
-static struct clk *camio_mdc_clk;
-static struct clk *camio_vfe_clk;
-
-static struct msm_camera_io_ext camio_ext;
-static struct resource *appio, *mdcio;
-void __iomem *appbase, *mdcbase;
-
-static struct msm_camera_io_ext camio_ext;
-static struct resource *appio, *mdcio;
-void __iomem *appbase, *mdcbase;
-
-extern int clk_set_flags(struct clk *clk, unsigned long flags);
-
-int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
-{
-       int rc = -1;
-       struct clk *clk = NULL;
-
-       switch (clktype) {
-       case CAMIO_VFE_MDC_CLK:
-               clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk");
-               break;
-
-       case CAMIO_MDC_CLK:
-               clk = camio_mdc_clk = clk_get(NULL, "mdc_clk");
-               break;
-
-       case CAMIO_VFE_CLK:
-               clk = camio_vfe_clk = clk_get(NULL, "vfe_clk");
-               break;
-
-       default:
-               break;
-       }
-
-       if (!IS_ERR(clk)) {
-               clk_enable(clk);
-               rc = 0;
-       }
-
-       return rc;
-}
-
-int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
-{
-       int rc = -1;
-       struct clk *clk = NULL;
-
-       switch (clktype) {
-       case CAMIO_VFE_MDC_CLK:
-               clk = camio_vfe_mdc_clk;
-               break;
-
-       case CAMIO_MDC_CLK:
-               clk = camio_mdc_clk;
-               break;
-
-       case CAMIO_VFE_CLK:
-               clk = camio_vfe_clk;
-               break;
-
-       default:
-               break;
-       }
-
-       if (!IS_ERR(clk)) {
-               clk_disable(clk);
-               clk_put(clk);
-               rc = 0;
-       }
-
-       return rc;
-}
-
-void msm_camio_clk_rate_set(int rate)
-{
-       struct clk *clk = camio_vfe_clk;
-
-       if (clk != ERR_PTR(-ENOENT))
-               clk_set_rate(clk, rate);
-}
-
-int msm_camio_enable(struct platform_device *pdev)
-{
-       int rc = 0;
-       struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-       struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-       camio_ext = camdev->ioext;
-
-       appio = request_mem_region(camio_ext.appphy,
-               camio_ext.appsz, pdev->name);
-       if (!appio) {
-               rc = -EBUSY;
-               goto enable_fail;
-       }
-
-       appbase = ioremap(camio_ext.appphy,
-               camio_ext.appsz);
-       if (!appbase) {
-               rc = -ENOMEM;
-               goto apps_no_mem;
-       }
-
-       mdcio = request_mem_region(camio_ext.mdcphy,
-               camio_ext.mdcsz, pdev->name);
-       if (!mdcio) {
-               rc = -EBUSY;
-               goto mdc_busy;
-       }
-
-       mdcbase = ioremap(camio_ext.mdcphy,
-               camio_ext.mdcsz);
-       if (!mdcbase) {
-               rc = -ENOMEM;
-               goto mdc_no_mem;
-       }
-
-       camdev->camera_gpio_on();
-
-       msm_camio_clk_enable(CAMIO_VFE_CLK);
-       msm_camio_clk_enable(CAMIO_MDC_CLK);
-       msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
-       return 0;
-
-mdc_no_mem:
-       release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
-mdc_busy:
-       iounmap(appbase);
-apps_no_mem:
-       release_mem_region(camio_ext.appphy, camio_ext.appsz);
-enable_fail:
-       return rc;
-}
-
-void msm_camio_disable(struct platform_device *pdev)
-{
-       struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-       struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-       iounmap(mdcbase);
-       release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
-       iounmap(appbase);
-       release_mem_region(camio_ext.appphy, camio_ext.appsz);
-
-       camdev->camera_gpio_off();
-
-       msm_camio_clk_disable(CAMIO_VFE_CLK);
-       msm_camio_clk_disable(CAMIO_MDC_CLK);
-       msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
-}
-
-void msm_camio_camif_pad_reg_reset(void)
-{
-       uint32_t reg;
-       uint32_t mask, value;
-
-       /* select CLKRGM_VFE_SRC_CAM_VFE_SRC:  internal source */
-       msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-
-       mask = CAM_SEL_BMSK |
-               CAM_PCLK_SRC_SEL_BMSK |
-               CAM_PCLK_INVERT_BMSK;
-
-       value = 1 << CAM_SEL_SHFT |
-               3 << CAM_PCLK_SRC_SEL_SHFT |
-               0 << CAM_PCLK_INVERT_SHFT;
-
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-       mask = CAM_PAD_REG_SW_RESET_BMSK;
-       value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-       mask = CAM_PAD_REG_SW_RESET_BMSK;
-       value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-
-       msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
-       mdelay(10);
-}
-
-void msm_camio_vfe_blk_reset(void)
-{
-       uint32_t val;
-
-       val = readl(appbase + 0x00000210);
-       val |= 0x1;
-       writel(val, appbase + 0x00000210);
-       mdelay(10);
-
-       val = readl(appbase + 0x00000210);
-       val &= ~0x1;
-       writel(val, appbase + 0x00000210);
-       mdelay(10);
-}
-
-void msm_camio_camif_pad_reg_reset_2(void)
-{
-       uint32_t reg;
-       uint32_t mask, value;
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-       mask = CAM_PAD_REG_SW_RESET_BMSK;
-       value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-       mask = CAM_PAD_REG_SW_RESET_BMSK;
-       value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-}
-
-void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
-{
-       struct clk *clk = NULL;
-
-       clk = camio_vfe_clk;
-
-       if (clk != NULL && clk != ERR_PTR(-ENOENT)) {
-               switch (srctype) {
-               case MSM_CAMIO_CLK_SRC_INTERNAL:
-                       clk_set_flags(clk, 0x00000100 << 1);
-                       break;
-
-               case MSM_CAMIO_CLK_SRC_EXTERNAL:
-                       clk_set_flags(clk, 0x00000100);
-                       break;
-
-               default:
-                       break;
-               }
-       }
-}
-
-int msm_camio_probe_on(struct platform_device *pdev)
-{
-       struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-       struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-       camdev->camera_gpio_on();
-       return msm_camio_clk_enable(CAMIO_VFE_CLK);
-}
-
-int msm_camio_probe_off(struct platform_device *pdev)
-{
-       struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-       struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-       camdev->camera_gpio_off();
-       return msm_camio_clk_disable(CAMIO_VFE_CLK);
-}
diff --git a/drivers/staging/dream/camera/msm_io8x.c b/drivers/staging/dream/camera/msm_io8x.c
deleted file mode 100644 (file)
index 895161a..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (c) 2008-2009 QUALCOMM Incorporated
- */
-
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <mach/gpio.h>
-#include <mach/board.h>
-#include <mach/camera.h>
-
-#define CAMIF_CFG_RMSK 0x1fffff
-#define CAM_SEL_BMSK 0x2
-#define CAM_PCLK_SRC_SEL_BMSK 0x60000
-#define CAM_PCLK_INVERT_BMSK 0x80000
-#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
-
-#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
-#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
-#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
-
-#define CAM_SEL_SHFT 0x1
-#define CAM_PCLK_SRC_SEL_SHFT 0x11
-#define CAM_PCLK_INVERT_SHFT 0x13
-#define CAM_PAD_REG_SW_RESET_SHFT 0x14
-
-#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
-#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
-#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
-#define APPS_RESET_OFFSET 0x00000210
-
-static struct clk *camio_vfe_mdc_clk;
-static struct clk *camio_mdc_clk;
-static struct clk *camio_vfe_clk;
-static struct clk *camio_vfe_axi_clk;
-static struct msm_camera_io_ext camio_ext;
-static struct resource *appio, *mdcio;
-void __iomem *appbase, *mdcbase;
-
-extern int clk_set_flags(struct clk *clk, unsigned long flags);
-
-int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
-{
-       int rc = 0;
-       struct clk *clk = NULL;
-
-       switch (clktype) {
-       case CAMIO_VFE_MDC_CLK:
-               camio_vfe_mdc_clk =
-               clk = clk_get(NULL, "vfe_mdc_clk");
-               break;
-
-       case CAMIO_MDC_CLK:
-               camio_mdc_clk =
-               clk = clk_get(NULL, "mdc_clk");
-               break;
-
-       case CAMIO_VFE_CLK:
-               camio_vfe_clk =
-               clk = clk_get(NULL, "vfe_clk");
-               break;
-
-       case CAMIO_VFE_AXI_CLK:
-               camio_vfe_axi_clk =
-               clk = clk_get(NULL, "vfe_axi_clk");
-               break;
-
-       default:
-               break;
-       }
-
-       if (!IS_ERR(clk))
-               clk_enable(clk);
-       else
-               rc = -1;
-
-       return rc;
-}
-
-int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
-{
-       int rc = 0;
-       struct clk *clk = NULL;
-
-       switch (clktype) {
-       case CAMIO_VFE_MDC_CLK:
-               clk = camio_vfe_mdc_clk;
-               break;
-
-       case CAMIO_MDC_CLK:
-               clk = camio_mdc_clk;
-               break;
-
-       case CAMIO_VFE_CLK:
-               clk = camio_vfe_clk;
-               break;
-
-       case CAMIO_VFE_AXI_CLK:
-               clk = camio_vfe_axi_clk;
-               break;
-
-       default:
-               break;
-       }
-
-       if (!IS_ERR(clk)) {
-               clk_disable(clk);
-               clk_put(clk);
-       } else
-               rc = -1;
-
-       return rc;
-}
-
-void msm_camio_clk_rate_set(int rate)
-{
-       struct clk *clk = camio_vfe_mdc_clk;
-
-       /* TODO: check return */
-       clk_set_rate(clk, rate);
-}
-
-int msm_camio_enable(struct platform_device *pdev)
-{
-       int rc = 0;
-       struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-       struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-       camio_ext = camdev->ioext;
-
-       appio = request_mem_region(camio_ext.appphy,
-               camio_ext.appsz, pdev->name);
-       if (!appio) {
-               rc = -EBUSY;
-               goto enable_fail;
-       }
-
-       appbase = ioremap(camio_ext.appphy,
-               camio_ext.appsz);
-       if (!appbase) {
-               rc = -ENOMEM;
-               goto apps_no_mem;
-       }
-
-       mdcio = request_mem_region(camio_ext.mdcphy,
-               camio_ext.mdcsz, pdev->name);
-       if (!mdcio) {
-               rc = -EBUSY;
-               goto mdc_busy;
-       }
-
-       mdcbase = ioremap(camio_ext.mdcphy,
-               camio_ext.mdcsz);
-       if (!mdcbase) {
-               rc = -ENOMEM;
-               goto mdc_no_mem;
-       }
-
-       camdev->camera_gpio_on();
-
-       msm_camio_clk_enable(CAMIO_VFE_CLK);
-       msm_camio_clk_enable(CAMIO_MDC_CLK);
-       msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
-       msm_camio_clk_enable(CAMIO_VFE_AXI_CLK);
-       return 0;
-
-mdc_no_mem:
-       release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
-mdc_busy:
-       iounmap(appbase);
-apps_no_mem:
-       release_mem_region(camio_ext.appphy, camio_ext.appsz);
-enable_fail:
-       return rc;
-}
-
-void msm_camio_disable(struct platform_device *pdev)
-{
-       struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-       struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-       iounmap(mdcbase);
-       release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
-       iounmap(appbase);
-       release_mem_region(camio_ext.appphy, camio_ext.appsz);
-
-       camdev->camera_gpio_off();
-
-       msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
-       msm_camio_clk_disable(CAMIO_MDC_CLK);
-       msm_camio_clk_disable(CAMIO_VFE_CLK);
-       msm_camio_clk_disable(CAMIO_VFE_AXI_CLK);
-}
-
-void msm_camio_camif_pad_reg_reset(void)
-{
-       uint32_t reg;
-       uint32_t mask, value;
-
-       /* select CLKRGM_VFE_SRC_CAM_VFE_SRC:  internal source */
-       msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-
-       mask = CAM_SEL_BMSK |
-               CAM_PCLK_SRC_SEL_BMSK |
-               CAM_PCLK_INVERT_BMSK |
-               EXT_CAM_HSYNC_POL_SEL_BMSK |
-               EXT_CAM_VSYNC_POL_SEL_BMSK |
-               MDDI_CLK_CHICKEN_BIT_BMSK;
-
-       value = 1 << CAM_SEL_SHFT |
-               3 << CAM_PCLK_SRC_SEL_SHFT |
-               0 << CAM_PCLK_INVERT_SHFT |
-               0 << EXT_CAM_HSYNC_POL_SEL_SHFT |
-               0 << EXT_CAM_VSYNC_POL_SEL_SHFT |
-               0 << MDDI_CLK_CHICKEN_BIT_SHFT;
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-       mask = CAM_PAD_REG_SW_RESET_BMSK;
-       value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-       mask = CAM_PAD_REG_SW_RESET_BMSK;
-       value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-
-       msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
-
-       mdelay(10);
-
-       /* todo: check return */
-       if (camio_vfe_clk)
-               clk_set_rate(camio_vfe_clk, 96000000);
-}
-
-void msm_camio_vfe_blk_reset(void)
-{
-       uint32_t val;
-
-       val = readl(appbase + 0x00000210);
-       val |= 0x1;
-       writel(val, appbase + 0x00000210);
-       mdelay(10);
-
-       val = readl(appbase + 0x00000210);
-       val &= ~0x1;
-       writel(val, appbase + 0x00000210);
-       mdelay(10);
-}
-
-void msm_camio_camif_pad_reg_reset_2(void)
-{
-       uint32_t reg;
-       uint32_t mask, value;
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-       mask = CAM_PAD_REG_SW_RESET_BMSK;
-       value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-
-       reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
-       mask = CAM_PAD_REG_SW_RESET_BMSK;
-       value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
-       writel((reg & (~mask)) | (value & mask), mdcbase);
-       mdelay(10);
-}
-
-void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
-{
-       struct clk *clk = NULL;
-
-       clk = camio_vfe_clk;
-
-       if (clk != NULL) {
-               switch (srctype) {
-               case MSM_CAMIO_CLK_SRC_INTERNAL:
-                       clk_set_flags(clk, 0x00000100 << 1);
-                       break;
-
-               case MSM_CAMIO_CLK_SRC_EXTERNAL:
-                       clk_set_flags(clk, 0x00000100);
-                       break;
-
-               default:
-                       break;
-               }
-       }
-}
-
-void msm_camio_clk_axi_rate_set(int rate)
-{
-       struct clk *clk = camio_vfe_axi_clk;
-       /* todo: check return */
-       clk_set_rate(clk, rate);
-}
-
-int msm_camio_probe_on(struct platform_device *pdev)
-{
-       struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-       struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-       camdev->camera_gpio_on();
-       return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
-}
-
-int msm_camio_probe_off(struct platform_device *pdev)
-{
-       struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-       struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-       camdev->camera_gpio_off();
-       return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
-}
diff --git a/drivers/staging/dream/camera/msm_v4l2.c b/drivers/staging/dream/camera/msm_v4l2.c
deleted file mode 100644 (file)
index c276f2f..0000000
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- *
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- *
- */
-
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <media/v4l2-dev.h>
-#include <media/msm_camera.h>
-#include <mach/camera.h>
-#include <media/v4l2-ioctl.h>
-/*#include <linux/platform_device.h>*/
-
-#define MSM_V4L2_START_SNAPSHOT _IOWR('V', BASE_VIDIOC_PRIVATE+1, \
-      struct v4l2_buffer)
-
-#define MSM_V4L2_GET_PICTURE    _IOWR('V', BASE_VIDIOC_PRIVATE+2, \
-      struct v4l2_buffer)
-
-#define MSM_V4L2_DEVICE_NAME       "msm_v4l2"
-
-#define MSM_V4L2_PROC_NAME         "msm_v4l2"
-
-#define MSM_V4L2_DEVNUM_MPEG2       0
-#define MSM_V4L2_DEVNUM_YUV         20
-
-/* HVGA-P (portrait) and HVGA-L (landscape) */
-#define MSM_V4L2_WIDTH              480
-#define MSM_V4L2_HEIGHT             320
-
-#if 1
-#define D(fmt, args...) printk(KERN_INFO "msm_v4l2: " fmt, ##args)
-#else
-#define D(fmt, args...) do {} while (0)
-#endif
-
-#define PREVIEW_FRAMES_NUM 4
-
-struct msm_v4l2_device {
-       struct list_head read_queue;
-       struct v4l2_format current_cap_format;
-       struct v4l2_format current_pix_format;
-       struct video_device *pvdev;
-       struct msm_v4l2_driver   *drv;
-       uint8_t opencnt;
-
-       spinlock_t read_queue_lock;
-};
-
-static struct msm_v4l2_device *g_pmsm_v4l2_dev;
-
-
-static DEFINE_MUTEX(msm_v4l2_opencnt_lock);
-
-static int msm_v4l2_open(struct file *f)
-{
-       int rc = 0;
-       D("%s\n", __func__);
-       mutex_lock(&msm_v4l2_opencnt_lock);
-       if (!g_pmsm_v4l2_dev->opencnt) {
-               rc = g_pmsm_v4l2_dev->drv->open(
-                               g_pmsm_v4l2_dev->drv->sync,
-                               MSM_APPS_ID_V4L2);
-       }
-       g_pmsm_v4l2_dev->opencnt++;
-       mutex_unlock(&msm_v4l2_opencnt_lock);
-       return rc;
-}
-
-static int msm_v4l2_release(struct file *f)
-{
-       int rc = 0;
-       D("%s\n", __func__);
-       mutex_lock(&msm_v4l2_opencnt_lock);
-       if (!g_pmsm_v4l2_dev->opencnt) {
-               g_pmsm_v4l2_dev->opencnt--;
-               if (!g_pmsm_v4l2_dev->opencnt) {
-                       rc = g_pmsm_v4l2_dev->drv->release(
-                                       g_pmsm_v4l2_dev->drv->sync);
-               }
-       }
-       mutex_unlock(&msm_v4l2_opencnt_lock);
-       return rc;
-}
-
-static unsigned int msm_v4l2_poll(struct file *f, struct poll_table_struct *w)
-{
-       return g_pmsm_v4l2_dev->drv->drv_poll(g_pmsm_v4l2_dev->drv->sync, f, w);
-}
-
-static long msm_v4l2_ioctl(struct file *filep,
-                          unsigned int cmd, unsigned long arg)
-{
-       struct msm_ctrl_cmd *ctrlcmd;
-
-       D("msm_v4l2_ioctl, cmd = %d, %d\n", cmd, __LINE__);
-
-       switch (cmd) {
-       case MSM_V4L2_START_SNAPSHOT:
-
-               ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
-               if (!ctrlcmd) {
-                       CDBG("msm_v4l2_ioctl: cannot allocate buffer\n");
-                       return -ENOMEM;
-               }
-
-               ctrlcmd->length     = 0;
-               ctrlcmd->value      = NULL;
-               ctrlcmd->timeout_ms = 10000;
-
-               D("msm_v4l2_ioctl,  MSM_V4L2_START_SNAPSHOT v4l2 ioctl %d\n",
-               cmd);
-               ctrlcmd->type = MSM_V4L2_SNAPSHOT;
-               return g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync,
-                                                       ctrlcmd);
-
-       case MSM_V4L2_GET_PICTURE:
-               D("msm_v4l2_ioctl,  MSM_V4L2_GET_PICTURE v4l2 ioctl %d\n", cmd);
-               ctrlcmd = (struct msm_ctrl_cmd *)arg;
-               return g_pmsm_v4l2_dev->drv->get_pict(
-                               g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
-
-       default:
-               D("msm_v4l2_ioctl, standard v4l2 ioctl %d\n", cmd);
-               return video_ioctl2(filep, cmd, arg);
-       }
-}
-
-static void msm_v4l2_release_dev(struct video_device *d)
-{
-       D("%s\n", __func__);
-}
-
-static int msm_v4l2_querycap(struct file *f,
-                            void *pctx, struct v4l2_capability *pcaps)
-{
-       D("%s\n", __func__);
-       strncpy(pcaps->driver, MSM_APPS_ID_V4L2, sizeof(pcaps->driver));
-       strncpy(pcaps->card,
-               MSM_V4L2_DEVICE_NAME, sizeof(pcaps->card));
-       pcaps->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-       return 0;
-}
-
-static int msm_v4l2_s_std(struct file *f, void *pctx, v4l2_std_id *pnorm)
-{
-       D("%s\n", __func__);
-       return 0;
-}
-
-static int msm_v4l2_queryctrl(struct file *f,
-                               void *pctx, struct v4l2_queryctrl *pqctrl)
-{
-  int rc = 0;
-  struct msm_ctrl_cmd *ctrlcmd;
-
-       D("%s\n", __func__);
-
-       ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
-       if (!ctrlcmd) {
-               CDBG("msm_v4l2_queryctrl: cannot allocate buffer\n");
-               return -ENOMEM;
-       }
-
-       ctrlcmd->type       = MSM_V4L2_QUERY_CTRL;
-       ctrlcmd->length     = sizeof(struct v4l2_queryctrl);
-       ctrlcmd->value      = pqctrl;
-       ctrlcmd->timeout_ms = 10000;
-
-       rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
-       if (rc < 0)
-               return -1;
-
-       return ctrlcmd->status;
-}
-
-static int msm_v4l2_g_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
-{
-       int rc = 0;
-       struct msm_ctrl_cmd *ctrlcmd;
-
-       D("%s\n", __func__);
-
-       ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
-       if (!ctrlcmd) {
-               CDBG("msm_v4l2_g_ctrl: cannot allocate buffer\n");
-               return -ENOMEM;
-       }
-
-       ctrlcmd->type       = MSM_V4L2_GET_CTRL;
-       ctrlcmd->length     = sizeof(struct v4l2_control);
-       ctrlcmd->value      = c;
-       ctrlcmd->timeout_ms = 10000;
-
-       rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
-       if (rc < 0)
-               return -1;
-
-       return ctrlcmd->status;
-}
-
-static int msm_v4l2_s_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
-{
-       int rc = 0;
-       struct msm_ctrl_cmd *ctrlcmd;
-
-       ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
-       if (!ctrlcmd) {
-               CDBG("msm_v4l2_s_ctrl: cannot allocate buffer\n");
-               return -ENOMEM;
-       }
-
-       ctrlcmd->type       = MSM_V4L2_SET_CTRL;
-       ctrlcmd->length     = sizeof(struct v4l2_control);
-       ctrlcmd->value      = c;
-       ctrlcmd->timeout_ms = 10000;
-
-       D("%s\n", __func__);
-
-       rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
-       if (rc < 0)
-               return -1;
-
-       return ctrlcmd->status;
-}
-
-static int msm_v4l2_reqbufs(struct file *f,
-                           void *pctx, struct v4l2_requestbuffers *b)
-{
-       D("%s\n", __func__);
-       return 0;
-}
-
-static int msm_v4l2_querybuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
-{
-       struct msm_pmem_info pmem_buf;
-#if 0
-       __u32 width = 0;
-       __u32 height = 0;
-       __u32 y_size = 0;
-       __u32 y_pad = 0;
-
-       /* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.width; */
-       width = 640;
-       /* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.height; */
-       height = 480;
-
-       D("%s: width = %d, height = %d\n", __func__, width, height);
-
-       y_size = width * height;
-       y_pad = y_size % 4;
-#endif
-
-    __u32 y_pad = pb->bytesused % 4;
-
-       /* V4L2 videodev will do the copy_from_user. */
-
-       memset(&pmem_buf, 0, sizeof(struct msm_pmem_info));
-       pmem_buf.type = MSM_PMEM_OUTPUT2;
-       pmem_buf.vaddr = (void *)pb->m.userptr;
-       pmem_buf.y_off = 0;
-       pmem_buf.fd = (int)pb->reserved;
-       /* pmem_buf.cbcr_off = (y_size + y_pad); */
-    pmem_buf.cbcr_off = (pb->bytesused + y_pad);
-
-       g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync, &pmem_buf);
-
-       return 0;
-}
-
-static int msm_v4l2_qbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
-{
-    /*
-       __u32 y_size = 0;
-       __u32 y_pad = 0;
-       __u32 width = 0;
-       __u32 height = 0;
-    */
-
-       __u32 y_pad = 0;
-
-       struct msm_pmem_info meminfo;
-       struct msm_frame frame;
-       static int cnt;
-
-       if ((pb->flags >> 16) & 0x0001) {
-               /* this is for previwe */
-#if 0
-               width = 640;
-               height = 480;
-
-               /* V4L2 videodev will do the copy_from_user. */
-               D("%s: width = %d, height = %d\n", __func__, width, height);
-               y_size = width * height;
-               y_pad = y_size % 4;
-#endif
-
-               y_pad = pb->bytesused % 4;
-
-               if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
-                       /* this qbuf is actually for releasing */
-
-                       frame.buffer           = pb->m.userptr;
-                       frame.y_off            = 0;
-                       /* frame.cbcr_off = (y_size + y_pad); */
-                       frame.cbcr_off         = (pb->bytesused + y_pad);
-                       frame.fd               = pb->reserved;
-
-                       D("V4L2_BUF_TYPE_PRIVATE: pb->bytesused = %d \n",
-                       pb->bytesused);
-
-                       g_pmsm_v4l2_dev->drv->put_frame(
-                               g_pmsm_v4l2_dev->drv->sync,
-                               &frame);
-
-                       return 0;
-               }
-
-               D("V4L2_BUF_TYPE_VIDEO_CAPTURE: pb->bytesused = %d \n",
-               pb->bytesused);
-
-               meminfo.type             = MSM_PMEM_OUTPUT2;
-               meminfo.fd               = (int)pb->reserved;
-               meminfo.vaddr            = (void *)pb->m.userptr;
-               meminfo.y_off            = 0;
-               /* meminfo.cbcr_off = (y_size + y_pad); */
-               meminfo.cbcr_off         = (pb->bytesused + y_pad);
-               if (cnt == PREVIEW_FRAMES_NUM - 1)
-                       meminfo.active = 0;
-               else
-                       meminfo.active = 1;
-               cnt++;
-               g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
-                               &meminfo);
-       } else if ((pb->flags) & 0x0001) {
-               /* this is for snapshot */
-
-       __u32 y_size = 0;
-
-       if ((pb->flags >> 8) & 0x01) {
-
-               y_size = pb->bytesused;
-
-               meminfo.type = MSM_PMEM_THUMBAIL;
-       } else if ((pb->flags >> 9) & 0x01) {
-
-               y_size = pb->bytesused;
-
-               meminfo.type = MSM_PMEM_MAINIMG;
-       }
-
-       y_pad = y_size % 4;
-
-       meminfo.fd         = (int)pb->reserved;
-       meminfo.vaddr      = (void *)pb->m.userptr;
-       meminfo.y_off      = 0;
-       /* meminfo.cbcr_off = (y_size + y_pad); */
-       meminfo.cbcr_off   = (y_size + y_pad);
-       meminfo.active     = 1;
-       g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
-                                       &meminfo);
-       }
-
-       return 0;
-}
-
-static int msm_v4l2_dqbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
-{
-       struct msm_frame frame;
-       D("%s\n", __func__);
-
-       /* V4L2 videodev will do the copy_to_user. */
-       if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-
-               D("%s, %d\n", __func__, __LINE__);
-
-               g_pmsm_v4l2_dev->drv->get_frame(
-                       g_pmsm_v4l2_dev->drv->sync,
-                       &frame);
-
-               pb->type       = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-               pb->m.userptr  = (unsigned long)frame.buffer;  /* FIXME */
-               pb->reserved   = (int)frame.fd;
-               /* pb->length     = (int)frame.cbcr_off; */
-
-               pb->bytesused  = frame.cbcr_off;
-
-       } else if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
-               __u32 y_pad     = pb->bytesused % 4;
-
-               frame.buffer   = pb->m.userptr;
-               frame.y_off    = 0;
-               /* frame.cbcr_off = (y_size + y_pad); */
-               frame.cbcr_off = (pb->bytesused + y_pad);
-               frame.fd       = pb->reserved;
-
-               g_pmsm_v4l2_dev->drv->put_frame(
-                       g_pmsm_v4l2_dev->drv->sync,
-                       &frame);
-       }
-
-       return 0;
-}
-
-static int msm_v4l2_streamon(struct file *f, void *pctx, enum v4l2_buf_type i)
-{
-  struct msm_ctrl_cmd *ctrlcmd;
-
-       ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
-       if (!ctrlcmd) {
-               CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
-               return -ENOMEM;
-       }
-
-       ctrlcmd->type       = MSM_V4L2_STREAM_ON;
-       ctrlcmd->timeout_ms = 10000;
-       ctrlcmd->length     = 0;
-       ctrlcmd->value      = NULL;
-
-       D("%s\n", __func__);
-
-       g_pmsm_v4l2_dev->drv->ctrl(
-               g_pmsm_v4l2_dev->drv->sync,
-               ctrlcmd);
-
-       D("%s after drv->ctrl \n", __func__);
-
-       return 0;
-}
-
-static int msm_v4l2_streamoff(struct file *f, void *pctx, enum v4l2_buf_type i)
-{
-  struct msm_ctrl_cmd *ctrlcmd;
-
-       ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
-       if (!ctrlcmd) {
-               CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
-               return -ENOMEM;
-       }
-
-       ctrlcmd->type       = MSM_V4L2_STREAM_OFF;
-       ctrlcmd->timeout_ms = 10000;
-       ctrlcmd->length     = 0;
-       ctrlcmd->value      = NULL;
-
-
-       D("%s\n", __func__);
-
-       g_pmsm_v4l2_dev->drv->ctrl(
-               g_pmsm_v4l2_dev->drv->sync,
-               ctrlcmd);
-
-       return 0;
-}
-
-static int msm_v4l2_enum_fmt_overlay(struct file *f,
-                                    void *pctx, struct v4l2_fmtdesc *pfmtdesc)
-{
-       D("%s\n", __func__);
-       return 0;
-}
-
-static int msm_v4l2_enum_fmt_cap(struct file *f,
-                                void *pctx, struct v4l2_fmtdesc *pfmtdesc)
-{
-       D("%s\n", __func__);
-
-       switch (pfmtdesc->index) {
-       case 0:
-               pfmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-               pfmtdesc->flags = 0;
-               strncpy(pfmtdesc->description, "YUV 4:2:0",
-                       sizeof(pfmtdesc->description));
-               pfmtdesc->pixelformat = V4L2_PIX_FMT_YVU420;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int msm_v4l2_g_fmt_cap(struct file *f,
-                             void *pctx, struct v4l2_format *pfmt)
-{
-       D("%s\n", __func__);
-       pfmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
-       pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
-       pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
-       pfmt->fmt.pix.field = V4L2_FIELD_ANY;
-       pfmt->fmt.pix.bytesperline = 0;
-       pfmt->fmt.pix.sizeimage = 0;
-       pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
-       pfmt->fmt.pix.priv = 0;
-       return 0;
-}
-
-static int msm_v4l2_s_fmt_cap(struct file *f,
-                             void *pctx, struct v4l2_format *pfmt)
-{
-  struct msm_ctrl_cmd *ctrlcmd;
-
-       D("%s\n", __func__);
-
-       ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
-       if (!ctrlcmd) {
-               CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
-               return -ENOMEM;
-       }
-
-  ctrlcmd->type       = MSM_V4L2_VID_CAP_TYPE;
-  ctrlcmd->length     = sizeof(struct v4l2_format);
-  ctrlcmd->value      = pfmt;
-  ctrlcmd->timeout_ms = 10000;
-
-       if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-               kfree(ctrlcmd);
-               return -1;
-       }
-
-#if 0
-       /* FIXEME */
-       if (pfmt->fmt.pix.pixelformat != V4L2_PIX_FMT_YVU420) {
-               kfree(ctrlcmd);
-               return -EINVAL;
-       }
-#endif
-
-       /* Ok, but check other params, too. */
-
-#if 0
-       memcpy(&g_pmsm_v4l2_dev->current_pix_format.fmt.pix, pfmt,
-              sizeof(struct v4l2_format));
-#endif
-
-       g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
-
-       return 0;
-}
-
-static int msm_v4l2_g_fmt_overlay(struct file *f,
-                                 void *pctx, struct v4l2_format *pfmt)
-{
-       D("%s\n", __func__);
-       pfmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
-       pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
-       pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
-       pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
-       pfmt->fmt.pix.field = V4L2_FIELD_ANY;
-       pfmt->fmt.pix.bytesperline = 0;
-       pfmt->fmt.pix.sizeimage = 0;
-       pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
-       pfmt->fmt.pix.priv = 0;
-       return 0;
-}
-
-static int msm_v4l2_s_fmt_overlay(struct file *f,
-                                 void *pctx, struct v4l2_format *pfmt)
-{
-       D("%s\n", __func__);
-       return 0;
-}
-
-static int msm_v4l2_overlay(struct file *f, void *pctx, unsigned int i)
-{
-       D("%s\n", __func__);
-       return 0;
-}
-
-static int msm_v4l2_g_jpegcomp(struct file *f,
-                              void *pctx, struct v4l2_jpegcompression *pcomp)
-{
-       D("%s\n", __func__);
-       return 0;
-}
-
-static int msm_v4l2_s_jpegcomp(struct file *f,
-                              void *pctx, struct v4l2_jpegcompression *pcomp)
-{
-       D("%s\n", __func__);
-       return 0;
-}
-
-#ifdef CONFIG_PROC_FS
-int msm_v4l2_read_proc(char *pbuf, char **start, off_t offset,
-                      int count, int *eof, void *data)
-{
-       int len = 0;
-       len += snprintf(pbuf, strlen("stats\n") + 1, "stats\n");
-
-       if (g_pmsm_v4l2_dev) {
-               len += snprintf(pbuf, strlen("mode: ") + 1, "mode: ");
-
-               if (g_pmsm_v4l2_dev->current_cap_format.type
-                   == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-                       len += snprintf(pbuf, strlen("capture\n") + 1,
-                                       "capture\n");
-               else
-                       len += snprintf(pbuf, strlen("unknown\n") + 1,
-                                       "unknown\n");
-
-               len += snprintf(pbuf, 21, "resolution: %dx%d\n",
-                               g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
-                               width,
-                               g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
-                               height);
-
-               len += snprintf(pbuf,
-                               strlen("pixel format: ") + 1, "pixel format: ");
-               if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.pixelformat
-                   == V4L2_PIX_FMT_YVU420)
-                       len += snprintf(pbuf, strlen("yvu420\n") + 1,
-                                       "yvu420\n");
-               else
-                       len += snprintf(pbuf, strlen("unknown\n") + 1,
-                                       "unknown\n");
-
-               len += snprintf(pbuf, strlen("colorspace: ") + 1,
-                               "colorspace: ");
-               if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.colorspace
-                   == V4L2_COLORSPACE_JPEG)
-                       len += snprintf(pbuf, strlen("jpeg\n") + 1, "jpeg\n");
-               else
-                       len += snprintf(pbuf, strlen("unknown\n") + 1,
-                                       "unknown\n");
-       }
-
-       *eof = 1;
-       return len;
-}
-#endif
-
-static const struct v4l2_file_operations msm_v4l2_fops = {
-       .owner = THIS_MODULE,
-       .open = msm_v4l2_open,
-       .poll = msm_v4l2_poll,
-       .release = msm_v4l2_release,
-       .ioctl = msm_v4l2_ioctl,
-};
-
-static void msm_v4l2_dev_init(struct msm_v4l2_device *pmsm_v4l2_dev)
-{
-       pmsm_v4l2_dev->read_queue_lock =
-           __SPIN_LOCK_UNLOCKED(pmsm_v4l2_dev->read_queue_lock);
-       INIT_LIST_HEAD(&pmsm_v4l2_dev->read_queue);
-}
-
-static int msm_v4l2_try_fmt_cap(struct file *file,
-                                void *fh, struct v4l2_format *f)
-{
-       /* FIXME */
-       return 0;
-}
-
-static int mm_v4l2_try_fmt_type_private(struct file *file,
-                                        void *fh, struct v4l2_format *f)
-{
-       /* FIXME */
-       return 0;
-}
-
-/*
- * should the following structure be used instead of the code in the function?
- * static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
- *     .vidioc_querycap = ....
- * }
- */
-static const struct v4l2_ioctl_ops msm_ioctl_ops = {
-       .vidioc_querycap = msm_v4l2_querycap,
-       .vidioc_s_std = msm_v4l2_s_std,
-
-       .vidioc_queryctrl = msm_v4l2_queryctrl,
-       .vidioc_g_ctrl = msm_v4l2_g_ctrl,
-       .vidioc_s_ctrl = msm_v4l2_s_ctrl,
-
-       .vidioc_reqbufs = msm_v4l2_reqbufs,
-       .vidioc_querybuf = msm_v4l2_querybuf,
-       .vidioc_qbuf = msm_v4l2_qbuf,
-       .vidioc_dqbuf = msm_v4l2_dqbuf,
-
-       .vidioc_streamon = msm_v4l2_streamon,
-       .vidioc_streamoff = msm_v4l2_streamoff,
-
-       .vidioc_enum_fmt_vid_overlay = msm_v4l2_enum_fmt_overlay,
-       .vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt_cap,
-
-       .vidioc_try_fmt_vid_cap = msm_v4l2_try_fmt_cap,
-       .vidioc_try_fmt_type_private = mm_v4l2_try_fmt_type_private,
-
-       .vidioc_g_fmt_vid_cap = msm_v4l2_g_fmt_cap,
-       .vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt_cap,
-       .vidioc_g_fmt_vid_overlay = msm_v4l2_g_fmt_overlay,
-       .vidioc_s_fmt_vid_overlay = msm_v4l2_s_fmt_overlay,
-       .vidioc_overlay = msm_v4l2_overlay,
-
-       .vidioc_g_jpegcomp = msm_v4l2_g_jpegcomp,
-       .vidioc_s_jpegcomp = msm_v4l2_s_jpegcomp,
-};
-
-static int msm_v4l2_video_dev_init(struct video_device *pvd)
-{
-       strncpy(pvd->name, MSM_APPS_ID_V4L2, sizeof(pvd->name));
-       pvd->vfl_type = 1;
-       pvd->fops = &msm_v4l2_fops;
-       pvd->release = msm_v4l2_release_dev;
-       pvd->minor = -1;
-       pvd->ioctl_ops = &msm_ioctl_ops;
-       return msm_v4l2_register(g_pmsm_v4l2_dev->drv);
-}
-
-static int __init msm_v4l2_init(void)
-{
-       int rc = -ENOMEM;
-       struct video_device *pvdev = NULL;
-       struct msm_v4l2_device *pmsm_v4l2_dev = NULL;
-       D("%s\n", __func__);
-
-       pvdev = video_device_alloc();
-       if (pvdev == NULL)
-               return rc;
-
-       pmsm_v4l2_dev =
-               kzalloc(sizeof(struct msm_v4l2_device), GFP_KERNEL);
-       if (pmsm_v4l2_dev == NULL) {
-               video_device_release(pvdev);
-               return rc;
-       }
-
-       msm_v4l2_dev_init(pmsm_v4l2_dev);
-
-       g_pmsm_v4l2_dev = pmsm_v4l2_dev;
-       g_pmsm_v4l2_dev->pvdev = pvdev;
-
-       g_pmsm_v4l2_dev->drv =
-               kzalloc(sizeof(struct msm_v4l2_driver), GFP_KERNEL);
-       if (!g_pmsm_v4l2_dev->drv) {
-               video_device_release(pvdev);
-               kfree(pmsm_v4l2_dev);
-               return rc;
-       }
-
-       rc = msm_v4l2_video_dev_init(pvdev);
-       if (rc < 0) {
-               video_device_release(pvdev);
-               kfree(g_pmsm_v4l2_dev->drv);
-               kfree(pmsm_v4l2_dev);
-               return rc;
-       }
-
-       if (video_register_device(pvdev, VFL_TYPE_GRABBER,
-           MSM_V4L2_DEVNUM_YUV)) {
-               D("failed to register device\n");
-               video_device_release(pvdev);
-               kfree(g_pmsm_v4l2_dev);
-               g_pmsm_v4l2_dev = NULL;
-               return -ENOENT;
-       }
-#ifdef CONFIG_PROC_FS
-       create_proc_read_entry(MSM_V4L2_PROC_NAME,
-                              0, NULL, msm_v4l2_read_proc, NULL);
-#endif
-
-       return 0;
-}
-
-static void __exit msm_v4l2_exit(void)
-{
-       struct video_device *pvdev = g_pmsm_v4l2_dev->pvdev;
-       D("%s\n", __func__);
-#ifdef CONFIG_PROC_FS
-       remove_proc_entry(MSM_V4L2_PROC_NAME, NULL);
-#endif
-       video_unregister_device(pvdev);
-       video_device_release(pvdev);
-
-       msm_v4l2_unregister(g_pmsm_v4l2_dev->drv);
-
-       kfree(g_pmsm_v4l2_dev->drv);
-       g_pmsm_v4l2_dev->drv = NULL;
-
-       kfree(g_pmsm_v4l2_dev);
-       g_pmsm_v4l2_dev = NULL;
-}
-
-module_init(msm_v4l2_init);
-module_exit(msm_v4l2_exit);
-
-MODULE_DESCRIPTION("MSM V4L2 driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/dream/camera/msm_vfe7x.c b/drivers/staging/dream/camera/msm_vfe7x.c
deleted file mode 100644 (file)
index 198656a..0000000
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#include <linux/msm_adsp.h>
-#include <linux/uaccess.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/android_pmem.h>
-#include <linux/slab.h>
-#include <mach/msm_adsp.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include "msm_vfe7x.h"
-
-#define QDSP_CMDQUEUE QDSP_vfeCommandQueue
-
-#define VFE_RESET_CMD 0
-#define VFE_START_CMD 1
-#define VFE_STOP_CMD  2
-#define VFE_FRAME_ACK 20
-#define STATS_AF_ACK  21
-#define STATS_WE_ACK  22
-
-#define MSG_STOP_ACK  1
-#define MSG_SNAPSHOT  2
-#define MSG_OUTPUT1   6
-#define MSG_OUTPUT2   7
-#define MSG_STATS_AF  8
-#define MSG_STATS_WE  9
-
-static struct msm_adsp_module *qcam_mod;
-static struct msm_adsp_module *vfe_mod;
-static struct msm_vfe_callback *resp;
-static void *extdata;
-static uint32_t extlen;
-
-struct mutex vfe_lock;
-static void     *vfe_syncdata;
-static uint8_t vfestopped;
-
-static struct stop_event stopevent;
-
-static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo,
-               enum vfe_resp_msg type,
-               void *data, void **ext, int32_t *elen)
-{
-       switch (type) {
-       case VFE_MSG_OUTPUT1:
-       case VFE_MSG_OUTPUT2: {
-               pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
-               pinfo->cbcr_phy =
-                       ((struct vfe_endframe *)data)->cbcr_address;
-
-               CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
-                                pinfo->y_phy, pinfo->cbcr_phy);
-
-               ((struct vfe_frame_extra *)extdata)->bl_evencol =
-               ((struct vfe_endframe *)data)->blacklevelevencolumn;
-
-               ((struct vfe_frame_extra *)extdata)->bl_oddcol =
-               ((struct vfe_endframe *)data)->blackleveloddcolumn;
-
-               ((struct vfe_frame_extra *)extdata)->g_def_p_cnt =
-               ((struct vfe_endframe *)data)->greendefectpixelcount;
-
-               ((struct vfe_frame_extra *)extdata)->r_b_def_p_cnt =
-               ((struct vfe_endframe *)data)->redbluedefectpixelcount;
-
-               *ext  = extdata;
-               *elen = extlen;
-       }
-               break;
-
-       case VFE_MSG_STATS_AF:
-       case VFE_MSG_STATS_WE:
-               pinfo->sbuf_phy = *(uint32_t *)data;
-               break;
-
-       default:
-               break;
-       } /* switch */
-}
-
-static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
-               void (*getevent)(void *ptr, size_t len))
-{
-       uint32_t evt_buf[3];
-       struct msm_vfe_resp *rp;
-       void *data;
-
-       len = (id == (uint16_t)-1) ? 0 : len;
-       data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len, vfe_syncdata);
-
-       if (!data) {
-               pr_err("rp: cannot allocate buffer\n");
-               return;
-       }
-       rp = (struct msm_vfe_resp *)data;
-       rp->evt_msg.len = len;
-
-       if (id == ((uint16_t)-1)) {
-               /* event */
-               rp->type           = VFE_EVENT;
-               rp->evt_msg.type   = MSM_CAMERA_EVT;
-               getevent(evt_buf, sizeof(evt_buf));
-               rp->evt_msg.msg_id = evt_buf[0];
-               resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata);
-       } else {
-               /* messages */
-               rp->evt_msg.type   = MSM_CAMERA_MSG;
-               rp->evt_msg.msg_id = id;
-               rp->evt_msg.data = rp + 1;
-               getevent(rp->evt_msg.data, len);
-
-               switch (rp->evt_msg.msg_id) {
-               case MSG_SNAPSHOT:
-                       rp->type = VFE_MSG_SNAPSHOT;
-                       break;
-
-               case MSG_OUTPUT1:
-                       rp->type = VFE_MSG_OUTPUT1;
-                       vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT1,
-                               rp->evt_msg.data, &(rp->extdata),
-                               &(rp->extlen));
-                       break;
-
-               case MSG_OUTPUT2:
-                       rp->type = VFE_MSG_OUTPUT2;
-                       vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT2,
-                                       rp->evt_msg.data, &(rp->extdata),
-                                       &(rp->extlen));
-                       break;
-
-               case MSG_STATS_AF:
-                       rp->type = VFE_MSG_STATS_AF;
-                       vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
-                                       rp->evt_msg.data, NULL, NULL);
-                       break;
-
-               case MSG_STATS_WE:
-                       rp->type = VFE_MSG_STATS_WE;
-                       vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
-                                       rp->evt_msg.data, NULL, NULL);
-
-                       CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
-                       break;
-
-               case MSG_STOP_ACK:
-                       rp->type = VFE_MSG_GENERAL;
-                       stopevent.state = 1;
-                       wake_up(&stopevent.wait);
-                       break;
-
-
-               default:
-                       rp->type = VFE_MSG_GENERAL;
-                       break;
-               }
-               resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe_syncdata);
-       }
-}
-
-static struct msm_adsp_ops vfe_7x_sync = {
-       .event = vfe_7x_ops,
-};
-
-static int vfe_7x_enable(struct camera_enable_cmd *enable)
-{
-       int rc = -EFAULT;
-
-       if (!strcmp(enable->name, "QCAMTASK"))
-               rc = msm_adsp_enable(qcam_mod);
-       else if (!strcmp(enable->name, "VFETASK"))
-               rc = msm_adsp_enable(vfe_mod);
-
-       return rc;
-}
-
-static int vfe_7x_disable(struct camera_enable_cmd *enable,
-               struct platform_device *dev __attribute__((unused)))
-{
-       int rc = -EFAULT;
-
-       if (!strcmp(enable->name, "QCAMTASK"))
-               rc = msm_adsp_disable(qcam_mod);
-       else if (!strcmp(enable->name, "VFETASK"))
-               rc = msm_adsp_disable(vfe_mod);
-
-       return rc;
-}
-
-static int vfe_7x_stop(void)
-{
-       int rc = 0;
-       uint32_t stopcmd = VFE_STOP_CMD;
-       rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
-                               &stopcmd, sizeof(uint32_t));
-       if (rc < 0) {
-               CDBG("%s:%d: failed rc = %d \n", __func__, __LINE__, rc);
-               return rc;
-       }
-
-       stopevent.state = 0;
-       rc = wait_event_timeout(stopevent.wait,
-               stopevent.state != 0,
-               msecs_to_jiffies(stopevent.timeout));
-
-       return rc;
-}
-
-static void vfe_7x_release(struct platform_device *pdev)
-{
-       mutex_lock(&vfe_lock);
-       vfe_syncdata = NULL;
-       mutex_unlock(&vfe_lock);
-
-       if (!vfestopped) {
-               CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__);
-               vfe_7x_stop();
-       } else
-               vfestopped = 0;
-
-       msm_adsp_disable(qcam_mod);
-       msm_adsp_disable(vfe_mod);
-
-       msm_adsp_put(qcam_mod);
-       msm_adsp_put(vfe_mod);
-
-       msm_camio_disable(pdev);
-
-       kfree(extdata);
-       extlen = 0;
-}
-
-static int vfe_7x_init(struct msm_vfe_callback *presp,
-       struct platform_device *dev)
-{
-       int rc = 0;
-
-       init_waitqueue_head(&stopevent.wait);
-       stopevent.timeout = 200;
-       stopevent.state = 0;
-
-       if (presp && presp->vfe_resp)
-               resp = presp;
-       else
-               return -EFAULT;
-
-       /* Bring up all the required GPIOs and Clocks */
-       rc = msm_camio_enable(dev);
-       if (rc < 0)
-               return rc;
-
-       msm_camio_camif_pad_reg_reset();
-
-       extlen = sizeof(struct vfe_frame_extra);
-
-       extdata = kmalloc(extlen, GFP_ATOMIC);
-       if (!extdata) {
-               rc = -ENOMEM;
-               goto init_fail;
-       }
-
-       rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
-       if (rc) {
-               rc = -EBUSY;
-               goto get_qcam_fail;
-       }
-
-       rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
-       if (rc) {
-               rc = -EBUSY;
-               goto get_vfe_fail;
-       }
-
-       return 0;
-
-get_vfe_fail:
-       msm_adsp_put(qcam_mod);
-get_qcam_fail:
-       kfree(extdata);
-init_fail:
-       extlen = 0;
-       return rc;
-}
-
-static int vfe_7x_config_axi(int mode,
-       struct axidata *ad, struct axiout *ao)
-{
-       struct msm_pmem_region *regptr;
-       unsigned long *bptr;
-       int    cnt;
-
-       int rc = 0;
-
-       if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
-               regptr = ad->region;
-
-               CDBG("bufnum1 = %d\n", ad->bufnum1);
-               CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-                       regptr->paddr, regptr->y_off, regptr->cbcr_off);
-
-               bptr = &ao->output1buffer1_y_phy;
-               for (cnt = 0; cnt < ad->bufnum1; cnt++) {
-                       *bptr = regptr->paddr + regptr->y_off;
-                       bptr++;
-                       *bptr = regptr->paddr + regptr->cbcr_off;
-
-                       bptr++;
-                       regptr++;
-               }
-
-               regptr--;
-               for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
-                       *bptr = regptr->paddr + regptr->y_off;
-                       bptr++;
-                       *bptr = regptr->paddr + regptr->cbcr_off;
-                       bptr++;
-               }
-       } /* if OUTPUT1 or Both */
-
-       if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
-               regptr = &(ad->region[ad->bufnum1]);
-
-               CDBG("bufnum2 = %d\n", ad->bufnum2);
-               CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-                       regptr->paddr, regptr->y_off, regptr->cbcr_off);
-
-               bptr = &ao->output2buffer1_y_phy;
-               for (cnt = 0; cnt < ad->bufnum2; cnt++) {
-                       *bptr = regptr->paddr + regptr->y_off;
-                       bptr++;
-                       *bptr = regptr->paddr + regptr->cbcr_off;
-
-                       bptr++;
-                       regptr++;
-               }
-
-               regptr--;
-               for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
-                       *bptr = regptr->paddr + regptr->y_off;
-                       bptr++;
-                       *bptr = regptr->paddr + regptr->cbcr_off;
-                       bptr++;
-               }
-       }
-
-       return rc;
-}
-
-static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data)
-{
-       struct msm_pmem_region *regptr;
-       unsigned char buf[256];
-
-       struct vfe_stats_ack sack;
-       struct axidata *axid;
-       uint32_t i;
-
-       struct vfe_stats_we_cfg *scfg = NULL;
-       struct vfe_stats_af_cfg *sfcfg = NULL;
-
-       struct axiout *axio = NULL;
-       void   *cmd_data = NULL;
-       void   *cmd_data_alloc = NULL;
-       long rc = 0;
-       struct msm_vfe_command_7k *vfecmd;
-
-       vfecmd =
-                       kmalloc(sizeof(struct msm_vfe_command_7k),
-                               GFP_ATOMIC);
-       if (!vfecmd) {
-               pr_err("vfecmd alloc failed!\n");
-               return -ENOMEM;
-       }
-
-       if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
-           cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
-           cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
-               if (copy_from_user(vfecmd,
-                               (void __user *)(cmd->value),
-                               sizeof(struct msm_vfe_command_7k))) {
-                       rc = -EFAULT;
-                       goto config_failure;
-               }
-       }
-
-       switch (cmd->cmd_type) {
-       case CMD_STATS_ENABLE:
-       case CMD_STATS_AXI_CFG: {
-               axid = data;
-               if (!axid) {
-                       rc = -EFAULT;
-                       goto config_failure;
-               }
-
-               scfg =
-                       kmalloc(sizeof(struct vfe_stats_we_cfg),
-                               GFP_ATOMIC);
-               if (!scfg) {
-                       rc = -ENOMEM;
-                       goto config_failure;
-               }
-
-               if (copy_from_user(scfg,
-                                       (void __user *)(vfecmd->value),
-                                       vfecmd->length)) {
-
-                       rc = -EFAULT;
-                       goto config_done;
-               }
-
-               CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
-                       axid->bufnum1, scfg->wb_expstatsenable);
-
-               if (axid->bufnum1 > 0) {
-                       regptr = axid->region;
-
-                       for (i = 0; i < axid->bufnum1; i++) {
-
-                               CDBG("STATS_ENABLE, phy = 0x%lx\n",
-                                       regptr->paddr);
-
-                               scfg->wb_expstatoutputbuffer[i] =
-                                       (void *)regptr->paddr;
-                               regptr++;
-                       }
-
-                       cmd_data = scfg;
-
-               } else {
-                       rc = -EINVAL;
-                       goto config_done;
-               }
-       }
-               break;
-
-       case CMD_STATS_AF_ENABLE:
-       case CMD_STATS_AF_AXI_CFG: {
-               axid = data;
-               if (!axid) {
-                       rc = -EFAULT;
-                       goto config_failure;
-               }
-
-               sfcfg =
-                       kmalloc(sizeof(struct vfe_stats_af_cfg),
-                               GFP_ATOMIC);
-
-               if (!sfcfg) {
-                       rc = -ENOMEM;
-                       goto config_failure;
-               }
-
-               if (copy_from_user(sfcfg,
-                                       (void __user *)(vfecmd->value),
-                                       vfecmd->length)) {
-
-                       rc = -EFAULT;
-                       goto config_done;
-               }
-
-               CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
-                       axid->bufnum1, sfcfg->af_enable);
-
-               if (axid->bufnum1 > 0) {
-                       regptr = axid->region;
-
-                       for (i = 0; i < axid->bufnum1; i++) {
-
-                               CDBG("STATS_ENABLE, phy = 0x%lx\n",
-                                       regptr->paddr);
-
-                               sfcfg->af_outbuf[i] =
-                                       (void *)regptr->paddr;
-
-                               regptr++;
-                       }
-
-                       cmd_data = sfcfg;
-
-               } else {
-                       rc = -EINVAL;
-                       goto config_done;
-               }
-       }
-               break;
-
-       case CMD_FRAME_BUF_RELEASE: {
-               struct msm_frame *b;
-               unsigned long p;
-               struct vfe_outputack fack;
-               if (!data)  {
-                       rc = -EFAULT;
-                       goto config_failure;
-               }
-
-               b = (struct msm_frame *)(cmd->value);
-               p = *(unsigned long *)data;
-
-               fack.header = VFE_FRAME_ACK;
-
-               fack.output2newybufferaddress =
-                       (void *)(p + b->y_off);
-
-               fack.output2newcbcrbufferaddress =
-                       (void *)(p + b->cbcr_off);
-
-               vfecmd->queue = QDSP_CMDQUEUE;
-               vfecmd->length = sizeof(struct vfe_outputack);
-               cmd_data = &fack;
-       }
-               break;
-
-       case CMD_SNAP_BUF_RELEASE:
-               break;
-
-       case CMD_STATS_BUF_RELEASE: {
-               CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
-               if (!data) {
-                       rc = -EFAULT;
-                       goto config_failure;
-               }
-
-               sack.header = STATS_WE_ACK;
-               sack.bufaddr = (void *)*(uint32_t *)data;
-
-               vfecmd->queue  = QDSP_CMDQUEUE;
-               vfecmd->length = sizeof(struct vfe_stats_ack);
-               cmd_data = &sack;
-       }
-               break;
-
-       case CMD_STATS_AF_BUF_RELEASE: {
-               CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
-               if (!data) {
-                       rc = -EFAULT;
-                       goto config_failure;
-               }
-
-               sack.header = STATS_AF_ACK;
-               sack.bufaddr = (void *)*(uint32_t *)data;
-
-               vfecmd->queue  = QDSP_CMDQUEUE;
-               vfecmd->length = sizeof(struct vfe_stats_ack);
-               cmd_data = &sack;
-       }
-               break;
-
-       case CMD_GENERAL:
-       case CMD_STATS_DISABLE: {
-               if (vfecmd->length > 256) {
-                       cmd_data_alloc =
-                       cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
-                       if (!cmd_data) {
-                               rc = -ENOMEM;
-                               goto config_failure;
-                       }
-               } else
-                       cmd_data = buf;
-
-               if (copy_from_user(cmd_data,
-                                       (void __user *)(vfecmd->value),
-                                       vfecmd->length)) {
-
-                       rc = -EFAULT;
-                       goto config_done;
-               }
-
-               if (vfecmd->queue == QDSP_CMDQUEUE) {
-                       switch (*(uint32_t *)cmd_data) {
-                       case VFE_RESET_CMD:
-                               msm_camio_vfe_blk_reset();
-                               msm_camio_camif_pad_reg_reset_2();
-                               vfestopped = 0;
-                               break;
-
-                       case VFE_START_CMD:
-                               msm_camio_camif_pad_reg_reset_2();
-                               vfestopped = 0;
-                               break;
-
-                       case VFE_STOP_CMD:
-                               vfestopped = 1;
-                               goto config_send;
-
-                       default:
-                               break;
-                       }
-               } /* QDSP_CMDQUEUE */
-       }
-               break;
-
-       case CMD_AXI_CFG_OUT1: {
-               axid = data;
-               if (!axid) {
-                       rc = -EFAULT;
-                       goto config_failure;
-               }
-
-               axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-               if (!axio) {
-                       rc = -ENOMEM;
-                       goto config_failure;
-               }
-
-               if (copy_from_user(axio, (void *)(vfecmd->value),
-                                       sizeof(struct axiout))) {
-                       rc = -EFAULT;
-                       goto config_done;
-               }
-
-               vfe_7x_config_axi(OUTPUT_1, axid, axio);
-
-               cmd_data = axio;
-       }
-               break;
-
-       case CMD_AXI_CFG_OUT2:
-       case CMD_RAW_PICT_AXI_CFG: {
-               axid = data;
-               if (!axid) {
-                       rc = -EFAULT;
-                       goto config_failure;
-               }
-
-               axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-               if (!axio) {
-                       rc = -ENOMEM;
-                       goto config_failure;
-               }
-
-               if (copy_from_user(axio, (void __user *)(vfecmd->value),
-                                       sizeof(struct axiout))) {
-                       rc = -EFAULT;
-                       goto config_done;
-               }
-
-               vfe_7x_config_axi(OUTPUT_2, axid, axio);
-               cmd_data = axio;
-       }
-               break;
-
-       case CMD_AXI_CFG_SNAP_O1_AND_O2: {
-               axid = data;
-               if (!axid) {
-                       rc = -EFAULT;
-                       goto config_failure;
-               }
-
-               axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-               if (!axio) {
-                       rc = -ENOMEM;
-                       goto config_failure;
-               }
-
-               if (copy_from_user(axio, (void __user *)(vfecmd->value),
-                                       sizeof(struct axiout))) {
-                       rc = -EFAULT;
-                       goto config_done;
-               }
-
-               vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
-
-               cmd_data = axio;
-       }
-               break;
-
-       default:
-               break;
-       } /* switch */
-
-       if (vfestopped)
-               goto config_done;
-
-config_send:
-       CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
-       rc = msm_adsp_write(vfe_mod, vfecmd->queue,
-                               cmd_data, vfecmd->length);
-
-config_done:
-       if (cmd_data_alloc != NULL)
-               kfree(cmd_data_alloc);
-
-config_failure:
-       kfree(scfg);
-       kfree(axio);
-       kfree(vfecmd);
-       return rc;
-}
-
-void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
-{
-       mutex_init(&vfe_lock);
-       fptr->vfe_init    = vfe_7x_init;
-       fptr->vfe_enable  = vfe_7x_enable;
-       fptr->vfe_config  = vfe_7x_config;
-       fptr->vfe_disable = vfe_7x_disable;
-       fptr->vfe_release = vfe_7x_release;
-       vfe_syncdata = data;
-}
diff --git a/drivers/staging/dream/camera/msm_vfe7x.h b/drivers/staging/dream/camera/msm_vfe7x.h
deleted file mode 100644 (file)
index be3e9ad..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-#ifndef __MSM_VFE7X_H__
-#define __MSM_VFE7X_H__
-#include <media/msm_camera.h>
-#include <mach/camera.h>
-
-struct vfe_frame_extra {
-       uint32_t  bl_evencol;
-       uint32_t  bl_oddcol;
-       uint16_t  g_def_p_cnt;
-       uint16_t  r_b_def_p_cnt;
-};
-
-struct vfe_endframe {
-       uint32_t      y_address;
-       uint32_t      cbcr_address;
-
-       unsigned int  blacklevelevencolumn:23;
-       uint16_t      reserved1:9;
-       unsigned int  blackleveloddcolumn:23;
-       uint16_t      reserved2:9;
-
-       uint16_t      greendefectpixelcount:8;
-       uint16_t      reserved3:8;
-       uint16_t      redbluedefectpixelcount:8;
-       uint16_t      reserved4:8;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_outputack {
-       uint32_t  header;
-       void      *output2newybufferaddress;
-       void      *output2newcbcrbufferaddress;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_stats_ack {
-       uint32_t header;
-       /* MUST BE 64 bit ALIGNED */
-       void     *bufaddr;
-} __attribute__((packed, aligned(4)));
-
-/* AXI Output Config Command sent to DSP */
-struct axiout {
-       uint32_t            cmdheader:32;
-       int                 outputmode:3;
-       uint8_t             format:2;
-       uint32_t            /* reserved */ : 27;
-
-       /* AXI Output 1 Y Configuration, Part 1 */
-       uint32_t            out1yimageheight:12;
-       uint32_t            /* reserved */ : 4;
-       uint32_t            out1yimagewidthin64bitwords:10;
-       uint32_t            /* reserved */ : 6;
-
-       /* AXI Output 1 Y Configuration, Part 2 */
-       uint8_t             out1yburstlen:2;
-       uint32_t            out1ynumrows:12;
-       uint32_t            out1yrowincin64bitincs:12;
-       uint32_t            /* reserved */ : 6;
-
-       /* AXI Output 1 CbCr Configuration, Part 1 */
-       uint32_t            out1cbcrimageheight:12;
-       uint32_t            /* reserved */ : 4;
-       uint32_t            out1cbcrimagewidthin64bitwords:10;
-       uint32_t            /* reserved */ : 6;
-
-       /* AXI Output 1 CbCr Configuration, Part 2 */
-       uint8_t             out1cbcrburstlen:2;
-       uint32_t            out1cbcrnumrows:12;
-       uint32_t            out1cbcrrowincin64bitincs:12;
-       uint32_t            /* reserved */ : 6;
-
-       /* AXI Output 2 Y Configuration, Part 1 */
-       uint32_t            out2yimageheight:12;
-       uint32_t            /* reserved */ : 4;
-       uint32_t            out2yimagewidthin64bitwords:10;
-       uint32_t            /* reserved */ : 6;
-
-       /* AXI Output 2 Y Configuration, Part 2 */
-       uint8_t             out2yburstlen:2;
-       uint32_t            out2ynumrows:12;
-       uint32_t            out2yrowincin64bitincs:12;
-       uint32_t            /* reserved */ : 6;
-
-       /* AXI Output 2 CbCr Configuration, Part 1 */
-       uint32_t            out2cbcrimageheight:12;
-       uint32_t            /* reserved */ : 4;
-       uint32_t            out2cbcrimagewidtein64bitwords:10;
-       uint32_t            /* reserved */ : 6;
-
-       /* AXI Output 2 CbCr Configuration, Part 2 */
-       uint8_t             out2cbcrburstlen:2;
-       uint32_t            out2cbcrnumrows:12;
-       uint32_t            out2cbcrrowincin64bitincs:12;
-       uint32_t            /* reserved */ : 6;
-
-       /* Address configuration:
-        * output1 phisycal address */
-       unsigned long   output1buffer1_y_phy;
-       unsigned long   output1buffer1_cbcr_phy;
-       unsigned long   output1buffer2_y_phy;
-       unsigned long   output1buffer2_cbcr_phy;
-       unsigned long   output1buffer3_y_phy;
-       unsigned long   output1buffer3_cbcr_phy;
-       unsigned long   output1buffer4_y_phy;
-       unsigned long   output1buffer4_cbcr_phy;
-       unsigned long   output1buffer5_y_phy;
-       unsigned long   output1buffer5_cbcr_phy;
-       unsigned long   output1buffer6_y_phy;
-       unsigned long   output1buffer6_cbcr_phy;
-       unsigned long   output1buffer7_y_phy;
-       unsigned long   output1buffer7_cbcr_phy;
-       unsigned long   output1buffer8_y_phy;
-       unsigned long   output1buffer8_cbcr_phy;
-
-       /* output2 phisycal address */
-       unsigned long   output2buffer1_y_phy;
-       unsigned long   output2buffer1_cbcr_phy;
-       unsigned long   output2buffer2_y_phy;
-       unsigned long   output2buffer2_cbcr_phy;
-       unsigned long   output2buffer3_y_phy;
-       unsigned long   output2buffer3_cbcr_phy;
-       unsigned long   output2buffer4_y_phy;
-       unsigned long   output2buffer4_cbcr_phy;
-       unsigned long   output2buffer5_y_phy;
-       unsigned long   output2buffer5_cbcr_phy;
-       unsigned long   output2buffer6_y_phy;
-       unsigned long   output2buffer6_cbcr_phy;
-       unsigned long   output2buffer7_y_phy;
-       unsigned long   output2buffer7_cbcr_phy;
-       unsigned long   output2buffer8_y_phy;
-       unsigned long   output2buffer8_cbcr_phy;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_stats_we_cfg {
-       uint32_t       header;
-
-       /* White Balance/Exposure Statistic Selection */
-       uint8_t        wb_expstatsenable:1;
-       uint8_t        wb_expstatbuspriorityselection:1;
-       unsigned int   wb_expstatbuspriorityvalue:4;
-       unsigned int   /* reserved */ : 26;
-
-       /* White Balance/Exposure Statistic Configuration, Part 1 */
-       uint8_t        exposurestatregions:1;
-       uint8_t        exposurestatsubregions:1;
-       unsigned int   /* reserved */ : 14;
-
-       unsigned int   whitebalanceminimumy:8;
-       unsigned int   whitebalancemaximumy:8;
-
-       /* White Balance/Exposure Statistic Configuration, Part 2 */
-       uint8_t wb_expstatslopeofneutralregionline[
-               NUM_WB_EXP_NEUTRAL_REGION_LINES];
-
-       /* White Balance/Exposure Statistic Configuration, Part 3 */
-       unsigned int   wb_expstatcrinterceptofneutralregionline2:12;
-       unsigned int   /* reserved */ : 4;
-       unsigned int   wb_expstatcbinterceptofneutralreginnline1:12;
-       unsigned int    /* reserved */ : 4;
-
-       /* White Balance/Exposure Statistic Configuration, Part 4 */
-       unsigned int   wb_expstatcrinterceptofneutralregionline4:12;
-       unsigned int   /* reserved */ : 4;
-       unsigned int   wb_expstatcbinterceptofneutralregionline3:12;
-       unsigned int   /* reserved */ : 4;
-
-       /* White Balance/Exposure Statistic Output Buffer Header */
-       unsigned int   wb_expmetricheaderpattern:8;
-       unsigned int   /* reserved */ : 24;
-
-       /* White Balance/Exposure Statistic Output Buffers-MUST
-       * BE 64 bit ALIGNED */
-       void  *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
-} __attribute__((packed, aligned(4)));
-
-struct vfe_stats_af_cfg {
-       uint32_t header;
-
-       /* Autofocus Statistic Selection */
-       uint8_t       af_enable:1;
-       uint8_t       af_busprioritysel:1;
-       unsigned int  af_buspriorityval:4;
-       unsigned int  /* reserved */ : 26;
-
-       /* Autofocus Statistic Configuration, Part 1 */
-       unsigned int  af_singlewinvoffset:12;
-       unsigned int  /* reserved */ : 4;
-       unsigned int  af_singlewinhoffset:12;
-       unsigned int  /* reserved */ : 3;
-       uint8_t       af_winmode:1;
-
-       /* Autofocus Statistic Configuration, Part 2 */
-       unsigned int  af_singglewinvh:11;
-       unsigned int  /* reserved */ : 5;
-       unsigned int  af_singlewinhw:11;
-       unsigned int  /* reserved */ : 5;
-
-       /* Autofocus Statistic Configuration, Parts 3-6 */
-       uint8_t       af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
-
-       /* Autofocus Statistic Configuration, Part 7 */
-       signed int    af_metrichpfcoefa00:5;
-       signed int    af_metrichpfcoefa04:5;
-       unsigned int  af_metricmaxval:11;
-       uint8_t       af_metricsel:1;
-       unsigned int  /* reserved */ : 10;
-
-       /* Autofocus Statistic Configuration, Part 8 */
-       signed int    af_metrichpfcoefa20:5;
-       signed int    af_metrichpfcoefa21:5;
-       signed int    af_metrichpfcoefa22:5;
-       signed int    af_metrichpfcoefa23:5;
-       signed int    af_metrichpfcoefa24:5;
-       unsigned int  /* reserved */ : 7;
-
-       /* Autofocus Statistic Output Buffer Header */
-       unsigned int  af_metrichp:8;
-       unsigned int  /* reserved */ : 24;
-
-       /* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
-       void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
-} __attribute__((packed, aligned(4))); /* VFE_StatsAutofocusConfigCmdType */
-
-struct msm_camera_frame_msg {
-       unsigned long   output_y_address;
-       unsigned long   output_cbcr_address;
-
-       unsigned int    blacklevelevenColumn:23;
-       uint16_t        reserved1:9;
-       unsigned int    blackleveloddColumn:23;
-       uint16_t        reserved2:9;
-
-       uint16_t        greendefectpixelcount:8;
-       uint16_t        reserved3:8;
-       uint16_t        redbluedefectpixelcount:8;
-       uint16_t        reserved4:8;
-} __attribute__((packed, aligned(4)));
-
-/* New one for 7k */
-struct msm_vfe_command_7k {
-       uint16_t queue;
-       uint16_t length;
-       void     *value;
-};
-
-struct stop_event {
-  wait_queue_head_t wait;
-       int state;
-  int timeout;
-};
-
-
-#endif /* __MSM_VFE7X_H__ */
diff --git a/drivers/staging/dream/camera/msm_vfe8x.c b/drivers/staging/dream/camera/msm_vfe8x.c
deleted file mode 100644 (file)
index d87d56f..0000000
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/interrupt.h>
-#include <mach/irqs.h>
-#include "msm_vfe8x_proc.h"
-
-#define ON  1
-#define OFF 0
-
-struct mutex vfe_lock;
-static void     *vfe_syncdata;
-
-static int vfe_enable(struct camera_enable_cmd *enable)
-{
-       int rc = 0;
-       return rc;
-}
-
-static int vfe_disable(struct camera_enable_cmd *enable,
-       struct platform_device *dev)
-{
-       int rc = 0;
-
-       vfe_stop();
-
-       msm_camio_disable(dev);
-       return rc;
-}
-
-static void vfe_release(struct platform_device *dev)
-{
-       msm_camio_disable(dev);
-       vfe_cmd_release(dev);
-
-       mutex_lock(&vfe_lock);
-       vfe_syncdata = NULL;
-       mutex_unlock(&vfe_lock);
-}
-
-static void vfe_config_axi(int mode,
-       struct axidata *ad, struct vfe_cmd_axi_output_config *ao)
-{
-       struct msm_pmem_region *regptr;
-       int i, j;
-       uint32_t *p1, *p2;
-
-       if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
-               regptr = ad->region;
-               for (i = 0;
-                       i < ad->bufnum1; i++) {
-
-                       p1 = &(ao->output1.outputY.outFragments[i][0]);
-                       p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
-
-                       for (j = 0;
-                               j < ao->output1.fragmentCount; j++) {
-
-                               *p1 = regptr->paddr + regptr->y_off;
-                               p1++;
-
-                               *p2 = regptr->paddr + regptr->cbcr_off;
-                               p2++;
-                       }
-                       regptr++;
-               }
-       } /* if OUTPUT1 or Both */
-
-       if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
-
-               regptr = &(ad->region[ad->bufnum1]);
-               CDBG("bufnum2 = %d\n", ad->bufnum2);
-
-               for (i = 0;
-                       i < ad->bufnum2; i++) {
-
-                       p1 = &(ao->output2.outputY.outFragments[i][0]);
-                       p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
-
-               CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, cbcr_off = %d\n",
-                       regptr->paddr, regptr->y_off, regptr->cbcr_off);
-
-                       for (j = 0;
-                               j < ao->output2.fragmentCount; j++) {
-
-                               *p1 = regptr->paddr + regptr->y_off;
-                               CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
-                               p1++;
-
-                               *p2 = regptr->paddr + regptr->cbcr_off;
-                               CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
-                               p2++;
-                       }
-                       regptr++;
-               }
-       }
-}
-
-static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
-{
-       int rc = 0;
-
-       CDBG("vfe_proc_general: cmdID = %d\n", cmd->id);
-
-       switch (cmd->id) {
-       case VFE_CMD_ID_RESET:
-               msm_camio_vfe_blk_reset();
-               msm_camio_camif_pad_reg_reset_2();
-               vfe_reset();
-               break;
-
-       case VFE_CMD_ID_START: {
-               struct vfe_cmd_start start;
-               if (copy_from_user(&start,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               /* msm_camio_camif_pad_reg_reset_2(); */
-               msm_camio_camif_pad_reg_reset();
-               vfe_start(&start);
-       }
-               break;
-
-       case VFE_CMD_ID_CAMIF_CONFIG: {
-               struct vfe_cmd_camif_config camif;
-               if (copy_from_user(&camif,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_camif_config(&camif);
-       }
-               break;
-
-       case VFE_CMD_ID_BLACK_LEVEL_CONFIG: {
-               struct vfe_cmd_black_level_config bl;
-               if (copy_from_user(&bl,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_black_level_config(&bl);
-       }
-               break;
-
-       case VFE_CMD_ID_ROLL_OFF_CONFIG: {
-               struct vfe_cmd_roll_off_config rolloff;
-               if (copy_from_user(&rolloff,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_roll_off_config(&rolloff);
-       }
-               break;
-
-       case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: {
-               struct vfe_cmd_demux_channel_gain_config demuxc;
-               if (copy_from_user(&demuxc,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               /* demux is always enabled.  */
-               vfe_demux_channel_gain_config(&demuxc);
-       }
-               break;
-
-       case VFE_CMD_ID_DEMOSAIC_CONFIG: {
-               struct vfe_cmd_demosaic_config demosaic;
-               if (copy_from_user(&demosaic,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_demosaic_config(&demosaic);
-       }
-               break;
-
-       case VFE_CMD_ID_FOV_CROP_CONFIG:
-       case VFE_CMD_ID_FOV_CROP_UPDATE: {
-               struct vfe_cmd_fov_crop_config fov;
-               if (copy_from_user(&fov,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_fov_crop_config(&fov);
-       }
-               break;
-
-       case VFE_CMD_ID_MAIN_SCALER_CONFIG:
-       case VFE_CMD_ID_MAIN_SCALER_UPDATE: {
-               struct vfe_cmd_main_scaler_config mainds;
-               if (copy_from_user(&mainds,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_main_scaler_config(&mainds);
-       }
-               break;
-
-       case VFE_CMD_ID_WHITE_BALANCE_CONFIG:
-       case VFE_CMD_ID_WHITE_BALANCE_UPDATE: {
-               struct vfe_cmd_white_balance_config wb;
-               if (copy_from_user(&wb,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_white_balance_config(&wb);
-       }
-               break;
-
-       case VFE_CMD_ID_COLOR_CORRECTION_CONFIG:
-       case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: {
-               struct vfe_cmd_color_correction_config cc;
-               if (copy_from_user(&cc,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_color_correction_config(&cc);
-       }
-               break;
-
-       case VFE_CMD_ID_LA_CONFIG: {
-               struct vfe_cmd_la_config la;
-               if (copy_from_user(&la,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_la_config(&la);
-       }
-               break;
-
-       case VFE_CMD_ID_RGB_GAMMA_CONFIG: {
-               struct vfe_cmd_rgb_gamma_config rgb;
-               if (copy_from_user(&rgb,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               rc = vfe_rgb_gamma_config(&rgb);
-       }
-               break;
-
-       case VFE_CMD_ID_CHROMA_ENHAN_CONFIG:
-       case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: {
-               struct vfe_cmd_chroma_enhan_config chrom;
-               if (copy_from_user(&chrom,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_chroma_enhan_config(&chrom);
-       }
-               break;
-
-       case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG:
-       case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: {
-               struct vfe_cmd_chroma_suppression_config chromsup;
-               if (copy_from_user(&chromsup,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_chroma_sup_config(&chromsup);
-       }
-               break;
-
-       case VFE_CMD_ID_ASF_CONFIG: {
-               struct vfe_cmd_asf_config asf;
-               if (copy_from_user(&asf,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_asf_config(&asf);
-       }
-               break;
-
-       case VFE_CMD_ID_SCALER2Y_CONFIG:
-       case VFE_CMD_ID_SCALER2Y_UPDATE: {
-               struct vfe_cmd_scaler2_config ds2y;
-               if (copy_from_user(&ds2y,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_scaler2y_config(&ds2y);
-       }
-               break;
-
-       case VFE_CMD_ID_SCALER2CbCr_CONFIG:
-       case VFE_CMD_ID_SCALER2CbCr_UPDATE: {
-               struct vfe_cmd_scaler2_config ds2cbcr;
-               if (copy_from_user(&ds2cbcr,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_scaler2cbcr_config(&ds2cbcr);
-       }
-               break;
-
-       case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: {
-               struct vfe_cmd_chroma_subsample_config sub;
-               if (copy_from_user(&sub,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_chroma_subsample_config(&sub);
-       }
-               break;
-
-       case VFE_CMD_ID_FRAME_SKIP_CONFIG: {
-               struct vfe_cmd_frame_skip_config fskip;
-               if (copy_from_user(&fskip,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_frame_skip_config(&fskip);
-       }
-               break;
-
-       case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: {
-               struct vfe_cmd_output_clamp_config clamp;
-               if (copy_from_user(&clamp,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_output_clamp_config(&clamp);
-       }
-               break;
-
-       /* module update commands */
-       case VFE_CMD_ID_BLACK_LEVEL_UPDATE: {
-               struct vfe_cmd_black_level_config blk;
-               if (copy_from_user(&blk,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_black_level_update(&blk);
-       }
-               break;
-
-       case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: {
-               struct vfe_cmd_demux_channel_gain_config dmu;
-               if (copy_from_user(&dmu,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_demux_channel_gain_update(&dmu);
-       }
-               break;
-
-       case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: {
-               struct vfe_cmd_demosaic_bpc_update demo_bpc;
-               if (copy_from_user(&demo_bpc,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_demosaic_bpc_update(&demo_bpc);
-       }
-               break;
-
-       case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: {
-               struct vfe_cmd_demosaic_abf_update demo_abf;
-               if (copy_from_user(&demo_abf,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_demosaic_abf_update(&demo_abf);
-       }
-               break;
-
-       case VFE_CMD_ID_LA_UPDATE: {
-               struct vfe_cmd_la_config la;
-               if (copy_from_user(&la,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_la_update(&la);
-       }
-               break;
-
-       case VFE_CMD_ID_RGB_GAMMA_UPDATE: {
-               struct vfe_cmd_rgb_gamma_config rgb;
-               if (copy_from_user(&rgb,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               rc = vfe_rgb_gamma_update(&rgb);
-       }
-               break;
-
-       case VFE_CMD_ID_ASF_UPDATE: {
-               struct vfe_cmd_asf_update asf;
-               if (copy_from_user(&asf,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_asf_update(&asf);
-       }
-               break;
-
-       case VFE_CMD_ID_FRAME_SKIP_UPDATE: {
-               struct vfe_cmd_frame_skip_update fskip;
-               if (copy_from_user(&fskip,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_frame_skip_update(&fskip);
-       }
-               break;
-
-       case VFE_CMD_ID_CAMIF_FRAME_UPDATE: {
-               struct vfe_cmds_camif_frame fup;
-               if (copy_from_user(&fup,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_camif_frame_update(&fup);
-       }
-               break;
-
-       /* stats update commands */
-       case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: {
-               struct vfe_cmd_stats_af_update afup;
-               if (copy_from_user(&afup,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_stats_update_af(&afup);
-       }
-               break;
-
-       case VFE_CMD_ID_STATS_WB_EXP_UPDATE: {
-               struct vfe_cmd_stats_wb_exp_update wbexp;
-               if (copy_from_user(&wbexp,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_stats_update_wb_exp(&wbexp);
-       }
-               break;
-
-       /* control of start, stop, update, etc... */
-       case VFE_CMD_ID_STOP:
-               vfe_stop();
-               break;
-
-       case VFE_CMD_ID_GET_HW_VERSION:
-               break;
-
-       /* stats */
-       case VFE_CMD_ID_STATS_SETTING: {
-               struct vfe_cmd_stats_setting stats;
-               if (copy_from_user(&stats,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_stats_setting(&stats);
-       }
-               break;
-
-       case VFE_CMD_ID_STATS_AUTOFOCUS_START: {
-               struct vfe_cmd_stats_af_start af;
-               if (copy_from_user(&af,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_stats_start_af(&af);
-       }
-               break;
-
-       case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
-               vfe_stats_af_stop();
-               break;
-
-       case VFE_CMD_ID_STATS_WB_EXP_START: {
-               struct vfe_cmd_stats_wb_exp_start awexp;
-               if (copy_from_user(&awexp,
-                       (void __user *) cmd->value, cmd->length))
-                       rc = -EFAULT;
-
-               vfe_stats_start_wb_exp(&awexp);
-       }
-               break;
-
-       case VFE_CMD_ID_STATS_WB_EXP_STOP:
-               vfe_stats_wb_exp_stop();
-               break;
-
-       case VFE_CMD_ID_ASYNC_TIMER_SETTING:
-               break;
-
-       case VFE_CMD_ID_UPDATE:
-               vfe_update();
-               break;
-
-       /* test gen */
-       case VFE_CMD_ID_TEST_GEN_START:
-               break;
-
-/*
-  acknowledge from upper layer
-       these are not in general command.
-
-       case VFE_CMD_ID_OUTPUT1_ACK:
-               break;
-       case VFE_CMD_ID_OUTPUT2_ACK:
-               break;
-       case VFE_CMD_ID_EPOCH1_ACK:
-               break;
-       case VFE_CMD_ID_EPOCH2_ACK:
-               break;
-       case VFE_CMD_ID_STATS_AUTOFOCUS_ACK:
-               break;
-       case VFE_CMD_ID_STATS_WB_EXP_ACK:
-               break;
-*/
-
-       default:
-               break;
-       } /* switch */
-
-       return rc;
-}
-
-static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
-{
-       struct msm_pmem_region *regptr;
-       struct msm_vfe_command_8k vfecmd;
-
-       uint32_t i;
-
-       void *cmd_data = NULL;
-       long rc = 0;
-
-       struct vfe_cmd_axi_output_config *axio = NULL;
-       struct vfe_cmd_stats_setting *scfg = NULL;
-
-       if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
-           cmd->cmd_type != CMD_STATS_BUF_RELEASE) {
-
-               if (copy_from_user(&vfecmd,
-                               (void __user *)(cmd->value),
-                               sizeof(struct msm_vfe_command_8k)))
-                       return -EFAULT;
-       }
-
-       CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type);
-
-       switch (cmd->cmd_type) {
-       case CMD_GENERAL:
-               rc = vfe_proc_general(&vfecmd);
-               break;
-
-       case CMD_STATS_ENABLE:
-       case CMD_STATS_AXI_CFG: {
-               struct axidata *axid;
-
-               axid = data;
-               if (!axid)
-                       return -EFAULT;
-
-               scfg =
-                       kmalloc(sizeof(struct vfe_cmd_stats_setting),
-                               GFP_ATOMIC);
-               if (!scfg)
-                       return -ENOMEM;
-
-               if (copy_from_user(scfg,
-                                       (void __user *)(vfecmd.value),
-                                       vfecmd.length)) {
-
-                       kfree(scfg);
-                       return -EFAULT;
-               }
-
-               regptr = axid->region;
-               if (axid->bufnum1 > 0) {
-                       for (i = 0; i < axid->bufnum1; i++) {
-                               scfg->awbBuffer[i] =
-                                       (uint32_t)(regptr->paddr);
-                               regptr++;
-                       }
-               }
-
-               if (axid->bufnum2 > 0) {
-                       for (i = 0; i < axid->bufnum2; i++) {
-                               scfg->afBuffer[i] =
-                                       (uint32_t)(regptr->paddr);
-                               regptr++;
-                       }
-               }
-
-               vfe_stats_config(scfg);
-       }
-               break;
-
-       case CMD_STATS_AF_AXI_CFG: {
-       }
-               break;
-
-       case CMD_FRAME_BUF_RELEASE: {
-               /* preview buffer release */
-               struct msm_frame *b;
-               unsigned long p;
-               struct vfe_cmd_output_ack fack;
-
-               if (!data)
-                       return -EFAULT;
-
-               b = (struct msm_frame *)(cmd->value);
-               p = *(unsigned long *)data;
-
-               b->path = MSM_FRAME_ENC;
-
-               fack.ybufaddr[0] =
-                       (uint32_t)(p + b->y_off);
-
-               fack.chromabufaddr[0] =
-                       (uint32_t)(p + b->cbcr_off);
-
-               if (b->path == MSM_FRAME_PREV_1)
-                       vfe_output1_ack(&fack);
-
-               if (b->path == MSM_FRAME_ENC ||
-                   b->path == MSM_FRAME_PREV_2)
-                       vfe_output2_ack(&fack);
-       }
-               break;
-
-       case CMD_SNAP_BUF_RELEASE: {
-       }
-               break;
-
-       case CMD_STATS_BUF_RELEASE: {
-               struct vfe_cmd_stats_wb_exp_ack sack;
-
-               if (!data)
-                       return -EFAULT;
-
-               sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
-               vfe_stats_wb_exp_ack(&sack);
-       }
-               break;
-
-       case CMD_AXI_CFG_OUT1: {
-               struct axidata *axid;
-
-               axid = data;
-               if (!axid)
-                       return -EFAULT;
-
-               axio = memdup_user((void __user *)(vfecmd.value),
-                                  sizeof(struct vfe_cmd_axi_output_config));
-               if (IS_ERR(axio))
-                       return PTR_ERR(axio);
-
-               vfe_config_axi(OUTPUT_1, axid, axio);
-               vfe_axi_output_config(axio);
-       }
-               break;
-
-       case CMD_AXI_CFG_OUT2:
-       case CMD_RAW_PICT_AXI_CFG: {
-               struct axidata *axid;
-
-               axid = data;
-               if (!axid)
-                       return -EFAULT;
-
-               axio = memdup_user((void __user *)(vfecmd.value),
-                                  sizeof(struct vfe_cmd_axi_output_config));
-               if (IS_ERR(axio))
-                       return PTR_ERR(axio);
-
-               vfe_config_axi(OUTPUT_2, axid, axio);
-
-               axio->outputDataSize = 0;
-               vfe_axi_output_config(axio);
-       }
-               break;
-
-       case CMD_AXI_CFG_SNAP_O1_AND_O2: {
-               struct axidata *axid;
-               axid = data;
-               if (!axid)
-                       return -EFAULT;
-
-               axio = memdup_user((void __user *)(vfecmd.value),
-                                  sizeof(struct vfe_cmd_axi_output_config));
-               if (IS_ERR(axio))
-                       return PTR_ERR(axio);
-
-               vfe_config_axi(OUTPUT_1_AND_2,
-                       axid, axio);
-               vfe_axi_output_config(axio);
-               cmd_data = axio;
-       }
-               break;
-
-       default:
-               break;
-       } /* switch */
-
-       kfree(scfg);
-
-       kfree(axio);
-
-/*
-       if (cmd->length > 256 &&
-                       cmd_data &&
-                       (cmd->cmd_type == CMD_GENERAL ||
-                        cmd->cmd_type == CMD_STATS_DISABLE)) {
-               kfree(cmd_data);
-       }
-*/
-       return rc;
-}
-
-static int vfe_init(struct msm_vfe_callback *presp,
-       struct platform_device *dev)
-{
-       int rc = 0;
-
-       rc = vfe_cmd_init(presp, dev, vfe_syncdata);
-       if (rc < 0)
-               return rc;
-
-       /* Bring up all the required GPIOs and Clocks */
-       return msm_camio_enable(dev);
-}
-
-void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
-{
-       mutex_init(&vfe_lock);
-       fptr->vfe_init    = vfe_init;
-       fptr->vfe_enable  = vfe_enable;
-       fptr->vfe_config  = vfe_config;
-       fptr->vfe_disable = vfe_disable;
-       fptr->vfe_release = vfe_release;
-       vfe_syncdata = data;
-}
diff --git a/drivers/staging/dream/camera/msm_vfe8x.h b/drivers/staging/dream/camera/msm_vfe8x.h
deleted file mode 100644 (file)
index 28a70a9..0000000
+++ /dev/null
@@ -1,895 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-#ifndef __MSM_VFE8X_H__
-#define __MSM_VFE8X_H__
-
-#define TRUE  1
-#define FALSE 0
-#define boolean uint8_t
-
-enum  VFE_STATE {
-       VFE_STATE_IDLE,
-       VFE_STATE_ACTIVE
-};
-
-enum vfe_cmd_id {
-       /*
-       *Important! Command_ID are arranged in order.
-       *Don't change!*/
-       VFE_CMD_ID_START,
-       VFE_CMD_ID_RESET,
-
-       /* bus and camif config */
-       VFE_CMD_ID_AXI_INPUT_CONFIG,
-       VFE_CMD_ID_CAMIF_CONFIG,
-       VFE_CMD_ID_AXI_OUTPUT_CONFIG,
-
-       /* module config  */
-       VFE_CMD_ID_BLACK_LEVEL_CONFIG,
-       VFE_CMD_ID_ROLL_OFF_CONFIG,
-       VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG,
-       VFE_CMD_ID_DEMOSAIC_CONFIG,
-       VFE_CMD_ID_FOV_CROP_CONFIG,
-       VFE_CMD_ID_MAIN_SCALER_CONFIG,
-       VFE_CMD_ID_WHITE_BALANCE_CONFIG,
-       VFE_CMD_ID_COLOR_CORRECTION_CONFIG,
-       VFE_CMD_ID_LA_CONFIG,
-       VFE_CMD_ID_RGB_GAMMA_CONFIG,
-       VFE_CMD_ID_CHROMA_ENHAN_CONFIG,
-       VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG,
-       VFE_CMD_ID_ASF_CONFIG,
-       VFE_CMD_ID_SCALER2Y_CONFIG,
-       VFE_CMD_ID_SCALER2CbCr_CONFIG,
-       VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG,
-       VFE_CMD_ID_FRAME_SKIP_CONFIG,
-       VFE_CMD_ID_OUTPUT_CLAMP_CONFIG,
-
-       /* test gen */
-       VFE_CMD_ID_TEST_GEN_START,
-
-       VFE_CMD_ID_UPDATE,
-
-       /* ackownledge from upper layer */
-       VFE_CMD_ID_OUTPUT1_ACK,
-       VFE_CMD_ID_OUTPUT2_ACK,
-       VFE_CMD_ID_EPOCH1_ACK,
-       VFE_CMD_ID_EPOCH2_ACK,
-       VFE_CMD_ID_STATS_AUTOFOCUS_ACK,
-       VFE_CMD_ID_STATS_WB_EXP_ACK,
-
-       /* module update commands */
-       VFE_CMD_ID_BLACK_LEVEL_UPDATE,
-       VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE,
-       VFE_CMD_ID_DEMOSAIC_BPC_UPDATE,
-       VFE_CMD_ID_DEMOSAIC_ABF_UPDATE,
-       VFE_CMD_ID_FOV_CROP_UPDATE,
-       VFE_CMD_ID_WHITE_BALANCE_UPDATE,
-       VFE_CMD_ID_COLOR_CORRECTION_UPDATE,
-       VFE_CMD_ID_LA_UPDATE,
-       VFE_CMD_ID_RGB_GAMMA_UPDATE,
-       VFE_CMD_ID_CHROMA_ENHAN_UPDATE,
-       VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE,
-       VFE_CMD_ID_MAIN_SCALER_UPDATE,
-       VFE_CMD_ID_SCALER2CbCr_UPDATE,
-       VFE_CMD_ID_SCALER2Y_UPDATE,
-       VFE_CMD_ID_ASF_UPDATE,
-       VFE_CMD_ID_FRAME_SKIP_UPDATE,
-       VFE_CMD_ID_CAMIF_FRAME_UPDATE,
-
-       /* stats update commands */
-       VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE,
-       VFE_CMD_ID_STATS_WB_EXP_UPDATE,
-
-       /* control of start, stop, update, etc... */
-  VFE_CMD_ID_STOP,
-       VFE_CMD_ID_GET_HW_VERSION,
-
-       /* stats */
-       VFE_CMD_ID_STATS_SETTING,
-       VFE_CMD_ID_STATS_AUTOFOCUS_START,
-       VFE_CMD_ID_STATS_AUTOFOCUS_STOP,
-       VFE_CMD_ID_STATS_WB_EXP_START,
-       VFE_CMD_ID_STATS_WB_EXP_STOP,
-
-       VFE_CMD_ID_ASYNC_TIMER_SETTING,
-
-       /* max id  */
-       VFE_CMD_ID_MAX
-};
-
-struct vfe_cmd_hw_version {
-       uint32_t minorVersion;
-       uint32_t majorVersion;
-       uint32_t coreVersion;
-};
-
-enum VFE_CAMIF_SYNC_EDGE {
-       VFE_CAMIF_SYNC_EDGE_ActiveHigh,
-       VFE_CAMIF_SYNC_EDGE_ActiveLow
-};
-
-enum VFE_CAMIF_SYNC_MODE {
-       VFE_CAMIF_SYNC_MODE_APS,
-       VFE_CAMIF_SYNC_MODE_EFS,
-       VFE_CAMIF_SYNC_MODE_ELS,
-       VFE_CAMIF_SYNC_MODE_ILLEGAL
-};
-
-struct vfe_cmds_camif_efs {
-       uint8_t efsendofline;
-       uint8_t efsstartofline;
-       uint8_t efsendofframe;
-       uint8_t efsstartofframe;
-};
-
-struct vfe_cmds_camif_frame {
-       uint16_t pixelsPerLine;
-       uint16_t linesPerFrame;
-};
-
-struct vfe_cmds_camif_window {
-       uint16_t firstpixel;
-       uint16_t lastpixel;
-       uint16_t firstline;
-       uint16_t lastline;
-};
-
-enum CAMIF_SUBSAMPLE_FRAME_SKIP {
-       CAMIF_SUBSAMPLE_FRAME_SKIP_0,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_AllFrames,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_2Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_3Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_4Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_5Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_6Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_7Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_8Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_9Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_10Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_11Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_12Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_13Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_14Frame,
-       CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_15Frame
-};
-
-struct vfe_cmds_camif_subsample {
-       uint16_t pixelskipmask;
-       uint16_t lineskipmask;
-       enum CAMIF_SUBSAMPLE_FRAME_SKIP frameskip;
-       uint8_t frameskipmode;
-       uint8_t pixelskipwrap;
-};
-
-struct vfe_cmds_camif_epoch {
-       uint8_t  enable;
-       uint16_t lineindex;
-};
-
-struct vfe_cmds_camif_cfg {
-       enum VFE_CAMIF_SYNC_EDGE  vSyncEdge;
-       enum VFE_CAMIF_SYNC_EDGE  hSyncEdge;
-       enum VFE_CAMIF_SYNC_MODE  syncMode;
-       uint8_t vfeSubSampleEnable;
-       uint8_t busSubSampleEnable;
-       uint8_t irqSubSampleEnable;
-       uint8_t binningEnable;
-       uint8_t misrEnable;
-};
-
-struct vfe_cmd_camif_config {
-       struct vfe_cmds_camif_cfg camifConfig;
-       struct vfe_cmds_camif_efs EFS;
-       struct vfe_cmds_camif_frame     frame;
-       struct vfe_cmds_camif_window    window;
-       struct vfe_cmds_camif_subsample subsample;
-       struct vfe_cmds_camif_epoch     epoch1;
-       struct vfe_cmds_camif_epoch     epoch2;
-};
-
-enum VFE_AXI_OUTPUT_MODE {
-       VFE_AXI_OUTPUT_MODE_Output1,
-       VFE_AXI_OUTPUT_MODE_Output2,
-       VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
-       VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
-       VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
-       VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
-       VFE_AXI_LAST_OUTPUT_MODE_ENUM
-};
-
-enum VFE_RAW_WR_PATH_SEL {
-       VFE_RAW_OUTPUT_DISABLED,
-       VFE_RAW_OUTPUT_ENC_CBCR_PATH,
-       VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
-       VFE_RAW_OUTPUT_PATH_INVALID
-};
-
-enum VFE_RAW_PIXEL_DATA_SIZE {
-       VFE_RAW_PIXEL_DATA_SIZE_8BIT,
-       VFE_RAW_PIXEL_DATA_SIZE_10BIT,
-       VFE_RAW_PIXEL_DATA_SIZE_12BIT,
-};
-
-#define VFE_AXI_OUTPUT_BURST_LENGTH     4
-#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
-#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
-
-struct vfe_cmds_axi_out_per_component {
-       uint16_t imageWidth;
-       uint16_t imageHeight;
-       uint16_t outRowCount;
-       uint16_t outRowIncrement;
-       uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
-               [VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-};
-
-struct vfe_cmds_axi_per_output_path {
-       uint8_t fragmentCount;
-       struct vfe_cmds_axi_out_per_component outputY;
-       struct vfe_cmds_axi_out_per_component outputCbcr;
-};
-
-enum VFE_AXI_BURST_LENGTH {
-       VFE_AXI_BURST_LENGTH_IS_2  = 2,
-       VFE_AXI_BURST_LENGTH_IS_4  = 4,
-       VFE_AXI_BURST_LENGTH_IS_8  = 8,
-       VFE_AXI_BURST_LENGTH_IS_16 = 16
-};
-
-struct vfe_cmd_axi_output_config {
-       enum VFE_AXI_BURST_LENGTH burstLength;
-       enum VFE_AXI_OUTPUT_MODE outputMode;
-       enum VFE_RAW_PIXEL_DATA_SIZE outputDataSize;
-       struct vfe_cmds_axi_per_output_path output1;
-       struct vfe_cmds_axi_per_output_path output2;
-};
-
-struct vfe_cmd_fov_crop_config {
-       uint8_t enable;
-       uint16_t firstPixel;
-       uint16_t lastPixel;
-       uint16_t firstLine;
-       uint16_t lastLine;
-};
-
-struct vfe_cmds_main_scaler_stripe_init {
-       uint16_t MNCounterInit;
-       uint16_t phaseInit;
-};
-
-struct vfe_cmds_scaler_one_dimension {
-       uint8_t  enable;
-       uint16_t inputSize;
-       uint16_t outputSize;
-       uint32_t phaseMultiplicationFactor;
-       uint8_t  interpolationResolution;
-};
-
-struct vfe_cmd_main_scaler_config {
-       uint8_t enable;
-       struct vfe_cmds_scaler_one_dimension    hconfig;
-       struct vfe_cmds_scaler_one_dimension    vconfig;
-       struct vfe_cmds_main_scaler_stripe_init MNInitH;
-       struct vfe_cmds_main_scaler_stripe_init MNInitV;
-};
-
-struct vfe_cmd_scaler2_config {
-       uint8_t enable;
-       struct vfe_cmds_scaler_one_dimension hconfig;
-       struct vfe_cmds_scaler_one_dimension vconfig;
-};
-
-struct vfe_cmd_frame_skip_config {
-       uint8_t output1Period;
-       uint32_t output1Pattern;
-       uint8_t output2Period;
-       uint32_t output2Pattern;
-};
-
-struct vfe_cmd_frame_skip_update {
-       uint32_t output1Pattern;
-       uint32_t output2Pattern;
-};
-
-struct vfe_cmd_output_clamp_config {
-       uint8_t minCh0;
-       uint8_t minCh1;
-       uint8_t minCh2;
-       uint8_t maxCh0;
-       uint8_t maxCh1;
-       uint8_t maxCh2;
-};
-
-struct vfe_cmd_chroma_subsample_config {
-       uint8_t enable;
-       uint8_t cropEnable;
-       uint8_t vsubSampleEnable;
-       uint8_t hsubSampleEnable;
-       uint8_t vCosited;
-       uint8_t hCosited;
-       uint8_t vCositedPhase;
-       uint8_t hCositedPhase;
-       uint16_t cropWidthFirstPixel;
-       uint16_t cropWidthLastPixel;
-       uint16_t cropHeightFirstLine;
-       uint16_t cropHeightLastLine;
-};
-
-enum VFE_START_INPUT_SOURCE {
-       VFE_START_INPUT_SOURCE_CAMIF,
-       VFE_START_INPUT_SOURCE_TESTGEN,
-       VFE_START_INPUT_SOURCE_AXI,
-       VFE_START_INPUT_SOURCE_INVALID
-};
-
-enum VFE_START_OPERATION_MODE {
-       VFE_START_OPERATION_MODE_CONTINUOUS,
-       VFE_START_OPERATION_MODE_SNAPSHOT
-};
-
-enum VFE_START_PIXEL_PATTERN {
-       VFE_BAYER_RGRGRG,
-       VFE_BAYER_GRGRGR,
-       VFE_BAYER_BGBGBG,
-       VFE_BAYER_GBGBGB,
-       VFE_YUV_YCbYCr,
-       VFE_YUV_YCrYCb,
-       VFE_YUV_CbYCrY,
-       VFE_YUV_CrYCbY
-};
-
-enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
-       VFE_BAYER_RAW,
-       VFE_YUV_INTERLEAVED,
-       VFE_YUV_PSEUDO_PLANAR_Y,
-       VFE_YUV_PSEUDO_PLANAR_CBCR
-};
-
-enum VFE_YUV_INPUT_COSITING_MODE {
-       VFE_YUV_COSITED,
-       VFE_YUV_INTERPOLATED
-};
-
-struct vfe_cmd_start {
-       enum VFE_START_INPUT_SOURCE inputSource;
-       enum VFE_START_OPERATION_MODE operationMode;
-       uint8_t     snapshotCount;
-       enum VFE_START_PIXEL_PATTERN pixel;
-       enum VFE_YUV_INPUT_COSITING_MODE yuvInputCositingMode;
-};
-
-struct vfe_cmd_output_ack {
-       uint32_t ybufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-       uint32_t chromabufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
-};
-
-#define VFE_STATS_BUFFER_COUNT 3
-
-struct vfe_cmd_stats_setting {
-       uint16_t frameHDimension;
-       uint16_t frameVDimension;
-       uint8_t  afBusPrioritySelection;
-       uint8_t  afBusPriority;
-       uint8_t  awbBusPrioritySelection;
-       uint8_t  awbBusPriority;
-       uint8_t  histBusPrioritySelection;
-       uint8_t  histBusPriority;
-       uint32_t afBuffer[VFE_STATS_BUFFER_COUNT];
-       uint32_t awbBuffer[VFE_STATS_BUFFER_COUNT];
-       uint32_t histBuffer[VFE_STATS_BUFFER_COUNT];
-};
-
-struct vfe_cmd_stats_af_start {
-       uint8_t  enable;
-       uint8_t  windowMode;
-       uint16_t windowHOffset;
-       uint16_t windowVOffset;
-       uint16_t windowWidth;
-       uint16_t windowHeight;
-       uint8_t  gridForMultiWindows[16];
-       uint8_t     metricSelection;
-       int16_t  metricMax;
-       int8_t   highPassCoef[7];
-       int8_t   bufferHeader;
-};
-
-struct vfe_cmd_stats_af_update {
-       uint8_t  windowMode;
-       uint16_t windowHOffset;
-       uint16_t windowVOffset;
-       uint16_t windowWidth;
-       uint16_t windowHeight;
-};
-
-struct vfe_cmd_stats_wb_exp_start {
-       uint8_t   enable;
-       uint8_t   wbExpRegions;
-       uint8_t   wbExpSubRegion;
-       uint8_t   awbYMin;
-       uint8_t   awbYMax;
-       int8_t    awbMCFG[4];
-       int16_t   awbCCFG[4];
-       int8_t    axwHeader;
-};
-
-struct vfe_cmd_stats_wb_exp_update {
-       uint8_t wbExpRegions;
-       uint8_t wbExpSubRegion;
-       int8_t  awbYMin;
-       int8_t  awbYMax;
-       int8_t  awbMCFG[4];
-       int16_t awbCCFG[4];
-};
-
-struct vfe_cmd_stats_af_ack {
-       uint32_t nextAFOutputBufferAddr;
-};
-
-struct vfe_cmd_stats_wb_exp_ack {
-       uint32_t  nextWbExpOutputBufferAddr;
-};
-
-struct vfe_cmd_black_level_config {
-       uint8_t  enable;
-       uint16_t evenEvenAdjustment;
-       uint16_t evenOddAdjustment;
-       uint16_t oddEvenAdjustment;
-       uint16_t oddOddAdjustment;
-};
-
-/* 13*1  */
-#define  VFE_ROLL_OFF_INIT_TABLE_SIZE  13
-/* 13*16 */
-#define  VFE_ROLL_OFF_DELTA_TABLE_SIZE 208
-
-struct vfe_cmd_roll_off_config {
-       uint8_t  enable;
-       uint16_t gridWidth;
-       uint16_t gridHeight;
-       uint16_t  yDelta;
-       uint8_t  gridXIndex;
-       uint8_t  gridYIndex;
-       uint16_t gridPixelXIndex;
-       uint16_t gridPixelYIndex;
-       uint16_t yDeltaAccum;
-       uint16_t initTableR[VFE_ROLL_OFF_INIT_TABLE_SIZE];
-       uint16_t initTableGr[VFE_ROLL_OFF_INIT_TABLE_SIZE];
-       uint16_t initTableB[VFE_ROLL_OFF_INIT_TABLE_SIZE];
-       uint16_t initTableGb[VFE_ROLL_OFF_INIT_TABLE_SIZE];
-       int16_t  deltaTableR[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
-       int16_t  deltaTableGr[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
-       int16_t  deltaTableB[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
-       int16_t  deltaTableGb[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
-};
-
-struct vfe_cmd_demux_channel_gain_config {
-       uint16_t ch0EvenGain;
-       uint16_t ch0OddGain;
-       uint16_t ch1Gain;
-       uint16_t ch2Gain;
-};
-
-struct vfe_cmds_demosaic_abf {
-       uint8_t   enable;
-       uint8_t   forceOn;
-       uint8_t   shift;
-       uint16_t  lpThreshold;
-       uint16_t  max;
-       uint16_t  min;
-       uint8_t   ratio;
-};
-
-struct vfe_cmds_demosaic_bpc {
-       uint8_t   enable;
-       uint16_t  fmaxThreshold;
-       uint16_t  fminThreshold;
-       uint16_t  redDiffThreshold;
-       uint16_t  blueDiffThreshold;
-       uint16_t  greenDiffThreshold;
-};
-
-struct vfe_cmd_demosaic_config {
-       uint8_t   enable;
-       uint8_t   slopeShift;
-       struct vfe_cmds_demosaic_abf abfConfig;
-       struct vfe_cmds_demosaic_bpc bpcConfig;
-};
-
-struct vfe_cmd_demosaic_bpc_update {
-       struct vfe_cmds_demosaic_bpc bpcUpdate;
-};
-
-struct vfe_cmd_demosaic_abf_update {
-       struct vfe_cmds_demosaic_abf abfUpdate;
-};
-
-struct vfe_cmd_white_balance_config {
-       uint8_t  enable;
-       uint16_t ch2Gain;
-       uint16_t ch1Gain;
-       uint16_t ch0Gain;
-};
-
-enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
-       COEF_IS_Q7_SIGNED,
-       COEF_IS_Q8_SIGNED,
-       COEF_IS_Q9_SIGNED,
-       COEF_IS_Q10_SIGNED
-};
-
-struct vfe_cmd_color_correction_config {
-       uint8_t     enable;
-       enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
-       int16_t  C0;
-       int16_t  C1;
-       int16_t  C2;
-       int16_t  C3;
-       int16_t  C4;
-       int16_t  C5;
-       int16_t  C6;
-       int16_t  C7;
-       int16_t  C8;
-       int16_t  K0;
-       int16_t  K1;
-       int16_t  K2;
-};
-
-#define VFE_LA_TABLE_LENGTH 256
-struct vfe_cmd_la_config {
-       uint8_t enable;
-       int16_t table[VFE_LA_TABLE_LENGTH];
-};
-
-#define VFE_GAMMA_TABLE_LENGTH 256
-enum VFE_RGB_GAMMA_TABLE_SELECT {
-       RGB_GAMMA_CH0_SELECTED,
-       RGB_GAMMA_CH1_SELECTED,
-       RGB_GAMMA_CH2_SELECTED,
-       RGB_GAMMA_CH0_CH1_SELECTED,
-       RGB_GAMMA_CH0_CH2_SELECTED,
-       RGB_GAMMA_CH1_CH2_SELECTED,
-       RGB_GAMMA_CH0_CH1_CH2_SELECTED
-};
-
-struct vfe_cmd_rgb_gamma_config {
-       uint8_t enable;
-       enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
-       int16_t table[VFE_GAMMA_TABLE_LENGTH];
-};
-
-struct vfe_cmd_chroma_enhan_config {
-       uint8_t  enable;
-       int16_t am;
-       int16_t ap;
-       int16_t bm;
-       int16_t bp;
-       int16_t cm;
-       int16_t cp;
-       int16_t dm;
-       int16_t dp;
-       int16_t kcr;
-       int16_t kcb;
-       int16_t RGBtoYConversionV0;
-       int16_t RGBtoYConversionV1;
-       int16_t RGBtoYConversionV2;
-       uint8_t RGBtoYConversionOffset;
-};
-
-struct vfe_cmd_chroma_suppression_config {
-       uint8_t enable;
-       uint8_t m1;
-       uint8_t m3;
-       uint8_t n1;
-       uint8_t n3;
-       uint8_t nn1;
-       uint8_t mm1;
-};
-
-struct vfe_cmd_asf_config {
-       uint8_t enable;
-       uint8_t smoothFilterEnabled;
-       uint8_t sharpMode;
-       uint8_t smoothCoefCenter;
-       uint8_t smoothCoefSurr;
-       uint8_t normalizeFactor;
-       uint8_t sharpK1;
-       uint8_t sharpK2;
-       uint8_t sharpThreshE1;
-       int8_t sharpThreshE2;
-       int8_t sharpThreshE3;
-       int8_t sharpThreshE4;
-       int8_t sharpThreshE5;
-       int8_t filter1Coefficients[9];
-       int8_t filter2Coefficients[9];
-       uint8_t  cropEnable;
-       uint16_t cropFirstPixel;
-       uint16_t cropLastPixel;
-       uint16_t cropFirstLine;
-       uint16_t cropLastLine;
-};
-
-struct vfe_cmd_asf_update {
-       uint8_t enable;
-       uint8_t smoothFilterEnabled;
-       uint8_t sharpMode;
-       uint8_t smoothCoefCenter;
-       uint8_t smoothCoefSurr;
-       uint8_t normalizeFactor;
-       uint8_t sharpK1;
-       uint8_t sharpK2;
-       uint8_t sharpThreshE1;
-       int8_t  sharpThreshE2;
-       int8_t  sharpThreshE3;
-       int8_t  sharpThreshE4;
-       int8_t  sharpThreshE5;
-       int8_t  filter1Coefficients[9];
-       int8_t  filter2Coefficients[9];
-       uint8_t cropEnable;
-};
-
-enum VFE_TEST_GEN_SYNC_EDGE {
-       VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
-       VFE_TEST_GEN_SYNC_EDGE_ActiveLow
-};
-
-struct vfe_cmd_test_gen_start {
-       uint8_t pixelDataSelect;
-       uint8_t systematicDataSelect;
-       enum VFE_TEST_GEN_SYNC_EDGE  hsyncEdge;
-       enum VFE_TEST_GEN_SYNC_EDGE  vsyncEdge;
-       uint16_t numFrame;
-       enum VFE_RAW_PIXEL_DATA_SIZE pixelDataSize;
-       uint16_t imageWidth;
-       uint16_t imageHeight;
-       uint32_t startOfFrameOffset;
-       uint32_t endOfFrameNOffset;
-       uint16_t startOfLineOffset;
-       uint16_t endOfLineNOffset;
-       uint16_t hbi;
-       uint8_t  vblEnable;
-       uint16_t vbl;
-       uint8_t  startOfFrameDummyLine;
-       uint8_t  endOfFrameDummyLine;
-       uint8_t  unicolorBarEnable;
-       uint8_t  colorBarsSplitEnable;
-       uint8_t  unicolorBarSelect;
-       enum VFE_START_PIXEL_PATTERN  colorBarsPixelPattern;
-       uint8_t  colorBarsRotatePeriod;
-       uint16_t testGenRandomSeed;
-};
-
-struct vfe_cmd_bus_pm_start {
-       uint8_t output2YWrPmEnable;
-       uint8_t output2CbcrWrPmEnable;
-       uint8_t output1YWrPmEnable;
-       uint8_t output1CbcrWrPmEnable;
-};
-
-struct vfe_cmd_camif_frame_update {
-       struct vfe_cmds_camif_frame camifFrame;
-};
-
-struct vfe_cmd_sync_timer_setting {
-       uint8_t  whichSyncTimer;
-       uint8_t  operation;
-       uint8_t  polarity;
-       uint16_t repeatCount;
-       uint16_t hsyncCount;
-       uint32_t pclkCount;
-       uint32_t outputDuration;
-};
-
-struct vfe_cmd_async_timer_setting {
-       uint8_t  whichAsyncTimer;
-       uint8_t  operation;
-       uint8_t  polarity;
-       uint16_t repeatCount;
-       uint16_t inactiveCount;
-       uint32_t activeCount;
-};
-
-struct  vfe_frame_skip_counts {
-       uint32_t  totalFrameCount;
-       uint32_t  output1Count;
-       uint32_t  output2Count;
-};
-
-enum VFE_AXI_RD_UNPACK_HBI_SEL {
-       VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
-       VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
-       VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
-       VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
-       VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
-       VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
-       VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
-       VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
-};
-
-struct vfe_cmd_axi_input_config {
-       uint32_t  fragAddr[4];
-       uint8_t   totalFragmentCount;
-       uint16_t  ySize;
-       uint16_t  xOffset;
-       uint16_t  xSize;
-       uint16_t  rowIncrement;
-       uint16_t  numOfRows;
-       enum VFE_AXI_BURST_LENGTH burstLength;
-       uint8_t   unpackPhase;
-       enum VFE_AXI_RD_UNPACK_HBI_SEL unpackHbi;
-       enum VFE_RAW_PIXEL_DATA_SIZE   pixelSize;
-       uint8_t   padRepeatCountLeft;
-       uint8_t   padRepeatCountRight;
-       uint8_t   padRepeatCountTop;
-       uint8_t   padRepeatCountBottom;
-       uint8_t   padLeftComponentSelectCycle0;
-       uint8_t   padLeftComponentSelectCycle1;
-       uint8_t   padLeftComponentSelectCycle2;
-       uint8_t   padLeftComponentSelectCycle3;
-       uint8_t   padLeftStopCycle0;
-       uint8_t   padLeftStopCycle1;
-       uint8_t   padLeftStopCycle2;
-       uint8_t   padLeftStopCycle3;
-       uint8_t   padRightComponentSelectCycle0;
-       uint8_t   padRightComponentSelectCycle1;
-       uint8_t   padRightComponentSelectCycle2;
-       uint8_t   padRightComponentSelectCycle3;
-       uint8_t   padRightStopCycle0;
-       uint8_t   padRightStopCycle1;
-       uint8_t   padRightStopCycle2;
-       uint8_t   padRightStopCycle3;
-       uint8_t   padTopLineCount;
-       uint8_t   padBottomLineCount;
-};
-
-struct vfe_interrupt_status {
-       uint8_t camifErrorIrq;
-       uint8_t camifSofIrq;
-       uint8_t camifEolIrq;
-       uint8_t camifEofIrq;
-       uint8_t camifEpoch1Irq;
-       uint8_t camifEpoch2Irq;
-       uint8_t camifOverflowIrq;
-       uint8_t ceIrq;
-       uint8_t regUpdateIrq;
-       uint8_t resetAckIrq;
-       uint8_t encYPingpongIrq;
-       uint8_t encCbcrPingpongIrq;
-       uint8_t viewYPingpongIrq;
-       uint8_t viewCbcrPingpongIrq;
-       uint8_t rdPingpongIrq;
-       uint8_t afPingpongIrq;
-       uint8_t awbPingpongIrq;
-       uint8_t histPingpongIrq;
-       uint8_t encIrq;
-       uint8_t viewIrq;
-       uint8_t busOverflowIrq;
-       uint8_t afOverflowIrq;
-       uint8_t awbOverflowIrq;
-       uint8_t syncTimer0Irq;
-       uint8_t syncTimer1Irq;
-       uint8_t syncTimer2Irq;
-       uint8_t asyncTimer0Irq;
-       uint8_t asyncTimer1Irq;
-       uint8_t asyncTimer2Irq;
-       uint8_t asyncTimer3Irq;
-       uint8_t axiErrorIrq;
-       uint8_t violationIrq;
-       uint8_t anyErrorIrqs;
-       uint8_t anyOutput1PathIrqs;
-       uint8_t anyOutput2PathIrqs;
-       uint8_t anyOutputPathIrqs;
-       uint8_t anyAsyncTimerIrqs;
-       uint8_t anySyncTimerIrqs;
-       uint8_t anyIrqForActiveStatesOnly;
-};
-
-enum VFE_MESSAGE_ID {
-       VFE_MSG_ID_RESET_ACK,
-       VFE_MSG_ID_START_ACK,
-       VFE_MSG_ID_STOP_ACK,
-       VFE_MSG_ID_UPDATE_ACK,
-       VFE_MSG_ID_OUTPUT1,
-       VFE_MSG_ID_OUTPUT2,
-       VFE_MSG_ID_SNAPSHOT_DONE,
-       VFE_MSG_ID_STATS_AUTOFOCUS,
-       VFE_MSG_ID_STATS_WB_EXP,
-       VFE_MSG_ID_EPOCH1,
-       VFE_MSG_ID_EPOCH2,
-       VFE_MSG_ID_SYNC_TIMER0_DONE,
-       VFE_MSG_ID_SYNC_TIMER1_DONE,
-       VFE_MSG_ID_SYNC_TIMER2_DONE,
-       VFE_MSG_ID_ASYNC_TIMER0_DONE,
-       VFE_MSG_ID_ASYNC_TIMER1_DONE,
-       VFE_MSG_ID_ASYNC_TIMER2_DONE,
-       VFE_MSG_ID_ASYNC_TIMER3_DONE,
-       VFE_MSG_ID_AF_OVERFLOW,
-       VFE_MSG_ID_AWB_OVERFLOW,
-       VFE_MSG_ID_AXI_ERROR,
-       VFE_MSG_ID_CAMIF_OVERFLOW,
-       VFE_MSG_ID_VIOLATION,
-       VFE_MSG_ID_CAMIF_ERROR,
-       VFE_MSG_ID_BUS_OVERFLOW,
-};
-
-struct vfe_msg_stats_autofocus {
-       uint32_t    afBuffer;
-       uint32_t    frameCounter;
-};
-
-struct vfe_msg_stats_wb_exp {
-       uint32_t awbBuffer;
-       uint32_t frameCounter;
-};
-
-struct vfe_frame_bpc_info {
-       uint32_t greenDefectPixelCount;
-       uint32_t redBlueDefectPixelCount;
-};
-
-struct vfe_frame_asf_info {
-       uint32_t  asfMaxEdge;
-       uint32_t  asfHbiCount;
-};
-
-struct vfe_msg_camif_status {
-       uint8_t  camifState;
-       uint32_t pixelCount;
-       uint32_t lineCount;
-};
-
-struct vfe_bus_pm_per_path {
-       uint32_t yWrPmStats0;
-       uint32_t yWrPmStats1;
-       uint32_t cbcrWrPmStats0;
-       uint32_t cbcrWrPmStats1;
-};
-
-struct vfe_bus_performance_monitor {
-       struct vfe_bus_pm_per_path encPathPmInfo;
-       struct vfe_bus_pm_per_path viewPathPmInfo;
-};
-
-struct vfe_irq_thread_msg {
-       uint32_t  vfeIrqStatus;
-       uint32_t  camifStatus;
-       uint32_t  demosaicStatus;
-       uint32_t  asfMaxEdge;
-       struct vfe_bus_performance_monitor pmInfo;
-};
-
-struct vfe_msg_output {
-       uint32_t  yBuffer;
-       uint32_t  cbcrBuffer;
-       struct vfe_frame_bpc_info bpcInfo;
-       struct vfe_frame_asf_info asfInfo;
-       uint32_t  frameCounter;
-       struct vfe_bus_pm_per_path pmData;
-};
-
-struct vfe_message {
-       enum VFE_MESSAGE_ID _d;
-       union {
-               struct vfe_msg_output              msgOutput1;
-               struct vfe_msg_output              msgOutput2;
-               struct vfe_msg_stats_autofocus     msgStatsAf;
-               struct vfe_msg_stats_wb_exp        msgStatsWbExp;
-               struct vfe_msg_camif_status        msgCamifError;
-               struct vfe_bus_performance_monitor msgBusOverflow;
-   } _u;
-};
-
-/* New one for 8k */
-struct msm_vfe_command_8k {
-       int32_t  id;
-       uint16_t length;
-       void     *value;
-};
-
-struct vfe_frame_extra {
-       struct vfe_frame_bpc_info bpcInfo;
-       struct vfe_frame_asf_info asfInfo;
-       uint32_t  frameCounter;
-       struct vfe_bus_pm_per_path pmData;
-};
-#endif /* __MSM_VFE8X_H__ */
diff --git a/drivers/staging/dream/camera/msm_vfe8x_proc.c b/drivers/staging/dream/camera/msm_vfe8x_proc.c
deleted file mode 100644 (file)
index f80ef96..0000000
+++ /dev/null
@@ -1,4003 +0,0 @@
-/*
-* Copyright (C) 2008-2009 QUALCOMM Incorporated.
-*/
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include "msm_vfe8x_proc.h"
-#include <media/msm_camera.h>
-
-struct msm_vfe8x_ctrl {
-       /* bit 1:0 ENC_IRQ_MASK = 0x11:
-        * generate IRQ when both y and cbcr frame is ready. */
-
-       /* bit 1:0 VIEW_IRQ_MASK= 0x11:
-        * generate IRQ when both y and cbcr frame is ready. */
-       struct vfe_irq_composite_mask_config vfeIrqCompositeMaskLocal;
-       struct vfe_module_enable vfeModuleEnableLocal;
-       struct vfe_camif_cfg_data   vfeCamifConfigLocal;
-       struct vfe_interrupt_mask   vfeImaskLocal;
-       struct vfe_stats_cmd_data   vfeStatsCmdLocal;
-       struct vfe_bus_cfg_data     vfeBusConfigLocal;
-       struct vfe_cmd_bus_pm_start vfeBusPmConfigLocal;
-       struct vfe_bus_cmd_data     vfeBusCmdLocal;
-       enum vfe_interrupt_name     vfeInterruptNameLocal;
-       uint32_t vfeLaBankSel;
-       struct vfe_gamma_lut_sel  vfeGammaLutSel;
-
-       boolean vfeStartAckPendingFlag;
-       boolean vfeStopAckPending;
-       boolean vfeResetAckPending;
-       boolean vfeUpdateAckPending;
-
-       enum VFE_AXI_OUTPUT_MODE        axiOutputMode;
-       enum VFE_START_OPERATION_MODE   vfeOperationMode;
-
-       uint32_t            vfeSnapShotCount;
-       uint32_t            vfeRequestedSnapShotCount;
-       boolean             vfeStatsPingPongReloadFlag;
-       uint32_t            vfeFrameId;
-
-       struct vfe_cmd_frame_skip_config vfeFrameSkip;
-       uint32_t vfeFrameSkipPattern;
-       uint8_t  vfeFrameSkipCount;
-       uint8_t  vfeFrameSkipPeriod;
-
-       boolean  vfeTestGenStartFlag;
-       uint32_t vfeImaskPacked;
-       uint32_t vfeImaskCompositePacked;
-       enum VFE_RAW_PIXEL_DATA_SIZE       axiInputDataSize;
-       struct vfe_irq_thread_msg          vfeIrqThreadMsgLocal;
-
-       struct vfe_output_path_combo  viewPath;
-       struct vfe_output_path_combo  encPath;
-       struct vfe_frame_skip_counts vfeDroppedFrameCounts;
-       struct vfe_stats_control afStatsControl;
-       struct vfe_stats_control awbStatsControl;
-
-       enum VFE_STATE  vstate;
-
-       spinlock_t  ack_lock;
-       spinlock_t  state_lock;
-       spinlock_t  io_lock;
-
-       struct msm_vfe_callback *resp;
-       uint32_t extlen;
-       void *extdata;
-
-       spinlock_t  tasklet_lock;
-       struct list_head tasklet_q;
-
-       int vfeirq;
-       void __iomem *vfebase;
-
-       void *syncdata;
-};
-static struct msm_vfe8x_ctrl *ctrl;
-static irqreturn_t vfe_parse_irq(int irq_num, void *data);
-
-struct isr_queue_cmd {
-       struct list_head list;
-       struct vfe_interrupt_status        vfeInterruptStatus;
-       struct vfe_frame_asf_info          vfeAsfFrameInfo;
-       struct vfe_frame_bpc_info          vfeBpcFrameInfo;
-       struct vfe_msg_camif_status        vfeCamifStatusLocal;
-       struct vfe_bus_performance_monitor vfePmData;
-};
-
-static void vfe_prog_hw(uint8_t *hwreg,
-       uint32_t *inptr, uint32_t regcnt)
-{
-       /* unsigned long flags; */
-       uint32_t i;
-       uint32_t *p;
-
-       /* @todo This is causing issues, need further investigate */
-       /* spin_lock_irqsave(&ctrl->io_lock, flags); */
-
-       p = (uint32_t *)(hwreg);
-       for (i = 0; i < (regcnt >> 2); i++)
-               writel(*inptr++, p++);
-               /* *p++ = *inptr++; */
-
-       /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
-}
-
-static void vfe_read_reg_values(uint8_t *hwreg,
-       uint32_t *dest, uint32_t count)
-{
-       /* unsigned long flags; */
-       uint32_t *temp;
-       uint32_t i;
-
-       /* @todo This is causing issues, need further investigate */
-       /* spin_lock_irqsave(&ctrl->io_lock, flags); */
-
-       temp = (uint32_t *)(hwreg);
-       for (i = 0; i < count; i++)
-               *dest++ = *temp++;
-
-       /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
-}
-
-static struct vfe_irqenable vfe_read_irq_mask(void)
-{
-       /* unsigned long flags; */
-       uint32_t *temp;
-       struct vfe_irqenable rc;
-
-       memset(&rc, 0, sizeof(rc));
-
-       /* @todo This is causing issues, need further investigate */
-       /* spin_lock_irqsave(&ctrl->io_lock, flags); */
-       temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_MASK);
-
-       rc = *((struct vfe_irqenable *)temp);
-       /* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
-
-       return rc;
-}
-
-static void
-vfe_set_bus_pipo_addr(struct vfe_output_path_combo *vpath,
-       struct vfe_output_path_combo *epath)
-{
-       vpath->yPath.hwRegPingAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PING_ADDR);
-       vpath->yPath.hwRegPongAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PONG_ADDR);
-       vpath->cbcrPath.hwRegPingAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PING_ADDR);
-       vpath->cbcrPath.hwRegPongAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PONG_ADDR);
-
-       epath->yPath.hwRegPingAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR);
-       epath->yPath.hwRegPongAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_ENC_Y_WR_PONG_ADDR);
-       epath->cbcrPath.hwRegPingAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PING_ADDR);
-       epath->cbcrPath.hwRegPongAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PONG_ADDR);
-}
-
-static void vfe_axi_output(struct vfe_cmd_axi_output_config *in,
-       struct vfe_output_path_combo *out1,
-       struct vfe_output_path_combo *out2, uint16_t out)
-{
-       struct vfe_axi_out_cfg cmd;
-
-       uint16_t temp;
-       uint32_t burstLength;
-
-       /* force it to burst length 4, hardware does not support it. */
-       burstLength = 1;
-
-       /* AXI Output 2 Y Configuration*/
-       /* VFE_BUS_ENC_Y_WR_PING_ADDR  */
-       cmd.out2YPingAddr = out2->yPath.addressBuffer[0];
-
-       /* VFE_BUS_ENC_Y_WR_PONG_ADDR  */
-       cmd.out2YPongAddr = out2->yPath.addressBuffer[1];
-
-       /* VFE_BUS_ENC_Y_WR_IMAGE_SIZE */
-       cmd.out2YImageHeight = in->output2.outputY.imageHeight;
-       /* convert the image width and row increment to be in
-        * unit of 64bit (8 bytes) */
-       temp = (in->output2.outputY.imageWidth + (out - 1)) /
-               out;
-       cmd.out2YImageWidthin64bit = temp;
-
-       /* VFE_BUS_ENC_Y_WR_BUFFER_CFG */
-       cmd.out2YBurstLength = burstLength;
-       cmd.out2YNumRows = in->output2.outputY.outRowCount;
-       temp = (in->output2.outputY.outRowIncrement + (out - 1)) /
-               out;
-       cmd.out2YRowIncrementIn64bit = temp;
-
-       /* AXI Output 2 Cbcr Configuration*/
-       /* VFE_BUS_ENC_Cbcr_WR_PING_ADDR  */
-       cmd.out2CbcrPingAddr = out2->cbcrPath.addressBuffer[0];
-
-       /* VFE_BUS_ENC_Cbcr_WR_PONG_ADDR  */
-       cmd.out2CbcrPongAddr = out2->cbcrPath.addressBuffer[1];
-
-       /* VFE_BUS_ENC_Cbcr_WR_IMAGE_SIZE */
-       cmd.out2CbcrImageHeight = in->output2.outputCbcr.imageHeight;
-       temp = (in->output2.outputCbcr.imageWidth + (out - 1)) /
-               out;
-       cmd.out2CbcrImageWidthIn64bit = temp;
-
-       /* VFE_BUS_ENC_Cbcr_WR_BUFFER_CFG */
-       cmd.out2CbcrBurstLength = burstLength;
-       cmd.out2CbcrNumRows = in->output2.outputCbcr.outRowCount;
-       temp = (in->output2.outputCbcr.outRowIncrement + (out - 1)) /
-               out;
-       cmd.out2CbcrRowIncrementIn64bit = temp;
-
-       /* AXI Output 1 Y Configuration */
-       /* VFE_BUS_VIEW_Y_WR_PING_ADDR  */
-       cmd.out1YPingAddr = out1->yPath.addressBuffer[0];
-
-       /* VFE_BUS_VIEW_Y_WR_PONG_ADDR */
-       cmd.out1YPongAddr = out1->yPath.addressBuffer[1];
-
-       /* VFE_BUS_VIEW_Y_WR_IMAGE_SIZE */
-       cmd.out1YImageHeight = in->output1.outputY.imageHeight;
-       temp = (in->output1.outputY.imageWidth + (out - 1)) /
-               out;
-       cmd.out1YImageWidthin64bit = temp;
-
-       /* VFE_BUS_VIEW_Y_WR_BUFFER_CFG     */
-       cmd.out1YBurstLength = burstLength;
-       cmd.out1YNumRows = in->output1.outputY.outRowCount;
-
-       temp =
-               (in->output1.outputY.outRowIncrement +
-                (out - 1)) / out;
-       cmd.out1YRowIncrementIn64bit = temp;
-
-       /* AXI Output 1 Cbcr Configuration*/
-       cmd.out1CbcrPingAddr = out1->cbcrPath.addressBuffer[0];
-
-       /* VFE_BUS_VIEW_Cbcr_WR_PONG_ADDR  */
-       cmd.out1CbcrPongAddr =
-               out1->cbcrPath.addressBuffer[1];
-
-       /* VFE_BUS_VIEW_Cbcr_WR_IMAGE_SIZE */
-       cmd.out1CbcrImageHeight = in->output1.outputCbcr.imageHeight;
-       temp = (in->output1.outputCbcr.imageWidth +
-               (out - 1)) / out;
-       cmd.out1CbcrImageWidthIn64bit = temp;
-
-       cmd.out1CbcrBurstLength = burstLength;
-       cmd.out1CbcrNumRows = in->output1.outputCbcr.outRowCount;
-       temp =
-               (in->output1.outputCbcr.outRowIncrement +
-                (out - 1)) / out;
-
-       cmd.out1CbcrRowIncrementIn64bit = temp;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-static void vfe_reg_bus_cfg(struct vfe_bus_cfg_data *in)
-{
-       struct vfe_axi_bus_cfg cmd;
-
-       cmd.stripeRdPathEn      = in->stripeRdPathEn;
-       cmd.encYWrPathEn        = in->encYWrPathEn;
-       cmd.encCbcrWrPathEn     = in->encCbcrWrPathEn;
-       cmd.viewYWrPathEn       = in->viewYWrPathEn;
-       cmd.viewCbcrWrPathEn    = in->viewCbcrWrPathEn;
-       cmd.rawPixelDataSize    = (uint32_t)in->rawPixelDataSize;
-       cmd.rawWritePathSelect  = (uint32_t)in->rawWritePathSelect;
-
-       /*  program vfe_bus_cfg */
-       writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CFG);
-}
-
-static void vfe_reg_camif_config(struct vfe_camif_cfg_data *in)
-{
-       struct VFE_CAMIFConfigType cfg;
-
-       memset(&cfg, 0, sizeof(cfg));
-
-       cfg.VSyncEdge          =
-               in->camifCfgFromCmd.vSyncEdge;
-
-       cfg.HSyncEdge          =
-               in->camifCfgFromCmd.hSyncEdge;
-
-       cfg.syncMode           =
-               in->camifCfgFromCmd.syncMode;
-
-       cfg.vfeSubsampleEnable =
-               in->camifCfgFromCmd.vfeSubSampleEnable;
-
-       cfg.busSubsampleEnable =
-               in->camifCfgFromCmd.busSubSampleEnable;
-
-       cfg.camif2vfeEnable    =
-               in->camif2OutputEnable;
-
-       cfg.camif2busEnable    =
-               in->camif2BusEnable;
-
-       cfg.irqSubsampleEnable =
-               in->camifCfgFromCmd.irqSubSampleEnable;
-
-       cfg.binningEnable      =
-               in->camifCfgFromCmd.binningEnable;
-
-       cfg.misrEnable         =
-               in->camifCfgFromCmd.misrEnable;
-
-       /*  program camif_config */
-       writel(*((uint32_t *)&cfg), ctrl->vfebase + CAMIF_CONFIG);
-}
-
-static void vfe_reg_bus_cmd(struct vfe_bus_cmd_data *in)
-{
-       struct vfe_buscmd cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       cmd.stripeReload        = in->stripeReload;
-       cmd.busPingpongReload   = in->busPingpongReload;
-       cmd.statsPingpongReload = in->statsPingpongReload;
-
-       writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CMD);
-
-       CDBG("bus command = 0x%x\n", (*((uint32_t *)&cmd)));
-
-       /* this is needed, as the control bits are pulse based.
-        * Don't want to reload bus pingpong again. */
-       in->busPingpongReload = 0;
-       in->statsPingpongReload = 0;
-       in->stripeReload = 0;
-}
-
-static void vfe_reg_module_cfg(struct vfe_module_enable *in)
-{
-       struct vfe_mod_enable ena;
-
-       memset(&ena, 0, sizeof(ena));
-
-       ena.blackLevelCorrectionEnable = in->blackLevelCorrectionEnable;
-       ena.lensRollOffEnable          = in->lensRollOffEnable;
-       ena.demuxEnable                = in->demuxEnable;
-       ena.chromaUpsampleEnable       = in->chromaUpsampleEnable;
-       ena.demosaicEnable             = in->demosaicEnable;
-       ena.statsEnable                = in->statsEnable;
-       ena.cropEnable                 = in->cropEnable;
-       ena.mainScalerEnable           = in->mainScalerEnable;
-       ena.whiteBalanceEnable         = in->whiteBalanceEnable;
-       ena.colorCorrectionEnable      = in->colorCorrectionEnable;
-       ena.yHistEnable                = in->yHistEnable;
-       ena.skinToneEnable             = in->skinToneEnable;
-       ena.lumaAdaptationEnable       = in->lumaAdaptationEnable;
-       ena.rgbLUTEnable               = in->rgbLUTEnable;
-       ena.chromaEnhanEnable          = in->chromaEnhanEnable;
-       ena.asfEnable                  = in->asfEnable;
-       ena.chromaSuppressionEnable    = in->chromaSuppressionEnable;
-       ena.chromaSubsampleEnable      = in->chromaSubsampleEnable;
-       ena.scaler2YEnable             = in->scaler2YEnable;
-       ena.scaler2CbcrEnable          = in->scaler2CbcrEnable;
-
-       writel(*((uint32_t *)&ena), ctrl->vfebase + VFE_MODULE_CFG);
-}
-
-static void vfe_program_dmi_cfg(enum VFE_DMI_RAM_SEL bankSel)
-{
-       /* set bit 8 for auto increment. */
-       uint32_t value = (uint32_t) ctrl->vfebase + VFE_DMI_CFG_DEFAULT;
-
-       value += (uint32_t)bankSel;
-       /* CDBG("dmi cfg input bank is  0x%x\n", bankSel); */
-
-       writel(value, ctrl->vfebase + VFE_DMI_CFG);
-       writel(0, ctrl->vfebase + VFE_DMI_ADDR);
-}
-
-static void vfe_write_lens_roll_off_table(
-       struct vfe_cmd_roll_off_config *in)
-{
-       uint16_t i;
-       uint32_t data;
-
-       uint16_t *initGr = in->initTableGr;
-       uint16_t *initGb = in->initTableGb;
-       uint16_t *initB =  in->initTableB;
-       uint16_t *initR =  in->initTableR;
-
-       int16_t *pDeltaGr = in->deltaTableGr;
-       int16_t *pDeltaGb = in->deltaTableGb;
-       int16_t *pDeltaB =  in->deltaTableB;
-       int16_t *pDeltaR =  in->deltaTableR;
-
-       vfe_program_dmi_cfg(ROLLOFF_RAM);
-
-       /* first pack and write init table */
-       for (i = 0; i < VFE_ROLL_OFF_INIT_TABLE_SIZE; i++) {
-               data = (((uint32_t)(*initR)) & 0x0000FFFF) |
-                       (((uint32_t)(*initGr)) << 16);
-               initR++;
-               initGr++;
-
-               writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
-
-               data = (((uint32_t)(*initB)) & 0x0000FFFF) |
-                       (((uint32_t)(*initGr))<<16);
-               initB++;
-               initGb++;
-
-               writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
-       }
-
-       /* there are gaps between the init table and delta table,
-        * set the offset for delta table. */
-       writel(LENS_ROLL_OFF_DELTA_TABLE_OFFSET,
-               ctrl->vfebase + VFE_DMI_ADDR);
-
-       /* pack and write delta table */
-       for (i = 0; i < VFE_ROLL_OFF_DELTA_TABLE_SIZE; i++) {
-               data = (((int32_t)(*pDeltaR)) & 0x0000FFFF) |
-                       (((int32_t)(*pDeltaGr))<<16);
-               pDeltaR++;
-               pDeltaGr++;
-
-               writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
-
-               data = (((int32_t)(*pDeltaB)) & 0x0000FFFF) |
-                       (((int32_t)(*pDeltaGb))<<16);
-               pDeltaB++;
-               pDeltaGb++;
-
-               writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
-       }
-
-       /* After DMI transfer, to make it safe, need to set the
-        * DMI_CFG to unselect any SRAM
-        */
-       /* unselect the SRAM Bank. */
-       writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
-}
-
-static void vfe_set_default_reg_values(void)
-{
-       writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_0);
-       writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_1);
-       writel(0xFFFFF, ctrl->vfebase + VFE_CGC_OVERRIDE);
-
-       /* default frame drop period and pattern */
-       writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
-       writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
-       writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
-       writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
-       writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_CFG);
-       writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_CFG);
-       writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
-       writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
-       writel(0, ctrl->vfebase + VFE_CLAMP_MIN_CFG);
-       writel(0xFFFFFF, ctrl->vfebase + VFE_CLAMP_MAX_CFG);
-}
-
-static void vfe_config_demux(uint32_t period, uint32_t even, uint32_t odd)
-{
-       writel(period, ctrl->vfebase + VFE_DEMUX_CFG);
-       writel(even, ctrl->vfebase + VFE_DEMUX_EVEN_CFG);
-       writel(odd, ctrl->vfebase + VFE_DEMUX_ODD_CFG);
-}
-
-static void vfe_pm_stop(void)
-{
-       writel(VFE_PERFORMANCE_MONITOR_STOP, ctrl->vfebase + VFE_BUS_PM_CMD);
-}
-
-static void vfe_program_bus_rd_irq_en(uint32_t value)
-{
-       writel(value, ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN);
-}
-
-static void vfe_camif_go(void)
-{
-       writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND);
-}
-
-static void vfe_camif_stop_immediately(void)
-{
-       writel(CAMIF_COMMAND_STOP_IMMEDIATELY, ctrl->vfebase + CAMIF_COMMAND);
-       writel(0, ctrl->vfebase + VFE_CGC_OVERRIDE);
-}
-
-static void vfe_program_reg_update_cmd(uint32_t value)
-{
-       writel(value, ctrl->vfebase + VFE_REG_UPDATE_CMD);
-}
-
-static void vfe_program_bus_cmd(uint32_t value)
-{
-       writel(value, ctrl->vfebase + VFE_BUS_CMD);
-}
-
-static void vfe_program_global_reset_cmd(uint32_t value)
-{
-       writel(value, ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
-}
-
-static void vfe_program_axi_cmd(uint32_t value)
-{
-       writel(value, ctrl->vfebase + VFE_AXI_CMD);
-}
-
-static void vfe_program_irq_composite_mask(uint32_t value)
-{
-       writel(value, ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
-}
-
-static inline void vfe_program_irq_mask(uint32_t value)
-{
-       writel(value, ctrl->vfebase + VFE_IRQ_MASK);
-}
-
-static void vfe_program_chroma_upsample_cfg(uint32_t value)
-{
-       writel(value, ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG);
-}
-
-static uint32_t vfe_read_axi_status(void)
-{
-       return readl(ctrl->vfebase + VFE_AXI_STATUS);
-}
-
-static uint32_t vfe_read_pm_status_in_raw_capture(void)
-{
-       return readl(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PM_STATS_1);
-}
-
-static void
-vfe_set_stats_pingpong_address(struct vfe_stats_control *afControl,
-       struct vfe_stats_control *awbControl)
-{
-       afControl->hwRegPingAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-       afControl->hwRegPongAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-
-       awbControl->hwRegPingAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-       awbControl->hwRegPongAddress = (uint8_t *)
-               (ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-}
-
-static uint32_t vfe_read_camif_status(void)
-{
-       return readl(ctrl->vfebase + CAMIF_STATUS);
-}
-
-static void vfe_program_lut_bank_sel(struct vfe_gamma_lut_sel *in)
-{
-       struct VFE_GammaLutSelect_ConfigCmdType cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       cmd.ch0BankSelect = in->ch0BankSelect;
-       cmd.ch1BankSelect = in->ch1BankSelect;
-       cmd.ch2BankSelect = in->ch2BankSelect;
-       CDBG("VFE gamma lut bank selection is 0x%x\n", *((uint32_t *)&cmd));
-       vfe_prog_hw(ctrl->vfebase + VFE_LUT_BANK_SEL,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-static void vfe_program_stats_cmd(struct vfe_stats_cmd_data *in)
-{
-       struct VFE_StatsCmdType stats;
-       memset(&stats, 0, sizeof(stats));
-
-       stats.autoFocusEnable        = in->autoFocusEnable;
-       stats.axwEnable              = in->axwEnable;
-       stats.histEnable             = in->histEnable;
-       stats.clearHistEnable        = in->clearHistEnable;
-       stats.histAutoClearEnable    = in->histAutoClearEnable;
-       stats.colorConversionEnable  = in->colorConversionEnable;
-
-       writel(*((uint32_t *)&stats), ctrl->vfebase + VFE_STATS_CMD);
-}
-
-static void vfe_pm_start(struct vfe_cmd_bus_pm_start *in)
-{
-       struct VFE_Bus_Pm_ConfigCmdType cmd;
-       memset(&cmd, 0, sizeof(struct VFE_Bus_Pm_ConfigCmdType));
-
-       cmd.output2YWrPmEnable     = in->output2YWrPmEnable;
-       cmd.output2CbcrWrPmEnable  = in->output2CbcrWrPmEnable;
-       cmd.output1YWrPmEnable     = in->output1YWrPmEnable;
-       cmd.output1CbcrWrPmEnable  = in->output1CbcrWrPmEnable;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_BUS_PM_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-static void vfe_8k_pm_start(struct vfe_cmd_bus_pm_start *in)
-{
-       in->output1CbcrWrPmEnable = ctrl->vfeBusConfigLocal.viewCbcrWrPathEn;
-       in->output1YWrPmEnable    = ctrl->vfeBusConfigLocal.viewYWrPathEn;
-       in->output2CbcrWrPmEnable = ctrl->vfeBusConfigLocal.encCbcrWrPathEn;
-       in->output2YWrPmEnable    = ctrl->vfeBusConfigLocal.encYWrPathEn;
-
-       if (in->output1CbcrWrPmEnable || in->output1YWrPmEnable)
-               ctrl->viewPath.pmEnabled = TRUE;
-
-       if (in->output2CbcrWrPmEnable || in->output2YWrPmEnable)
-               ctrl->encPath.pmEnabled = TRUE;
-
-       vfe_pm_start(in);
-
-       writel(VFE_PERFORMANCE_MONITOR_GO, ctrl->vfebase + VFE_BUS_PM_CMD);
-}
-
-static uint32_t vfe_irq_pack(struct vfe_interrupt_mask data)
-{
-       struct vfe_irqenable packedData;
-
-       memset(&packedData, 0, sizeof(packedData));
-
-       packedData.camifErrorIrq          = data.camifErrorIrq;
-       packedData.camifSofIrq            = data.camifSofIrq;
-       packedData.camifEolIrq            = data.camifEolIrq;
-       packedData.camifEofIrq            = data.camifEofIrq;
-       packedData.camifEpoch1Irq         = data.camifEpoch1Irq;
-       packedData.camifEpoch2Irq         = data.camifEpoch2Irq;
-       packedData.camifOverflowIrq       = data.camifOverflowIrq;
-       packedData.ceIrq                  = data.ceIrq;
-       packedData.regUpdateIrq           = data.regUpdateIrq;
-       packedData.resetAckIrq            = data.resetAckIrq;
-       packedData.encYPingpongIrq        = data.encYPingpongIrq;
-       packedData.encCbcrPingpongIrq     = data.encCbcrPingpongIrq;
-       packedData.viewYPingpongIrq       = data.viewYPingpongIrq;
-       packedData.viewCbcrPingpongIrq    = data.viewCbcrPingpongIrq;
-       packedData.rdPingpongIrq          = data.rdPingpongIrq;
-       packedData.afPingpongIrq          = data.afPingpongIrq;
-       packedData.awbPingpongIrq         = data.awbPingpongIrq;
-       packedData.histPingpongIrq        = data.histPingpongIrq;
-       packedData.encIrq                 = data.encIrq;
-       packedData.viewIrq                = data.viewIrq;
-       packedData.busOverflowIrq         = data.busOverflowIrq;
-       packedData.afOverflowIrq          = data.afOverflowIrq;
-       packedData.awbOverflowIrq         = data.awbOverflowIrq;
-       packedData.syncTimer0Irq          = data.syncTimer0Irq;
-       packedData.syncTimer1Irq          = data.syncTimer1Irq;
-       packedData.syncTimer2Irq          = data.syncTimer2Irq;
-       packedData.asyncTimer0Irq         = data.asyncTimer0Irq;
-       packedData.asyncTimer1Irq         = data.asyncTimer1Irq;
-       packedData.asyncTimer2Irq         = data.asyncTimer2Irq;
-       packedData.asyncTimer3Irq         = data.asyncTimer3Irq;
-       packedData.axiErrorIrq            = data.axiErrorIrq;
-       packedData.violationIrq           = data.violationIrq;
-
-       return *((uint32_t *)&packedData);
-}
-
-static uint32_t
-vfe_irq_composite_pack(struct vfe_irq_composite_mask_config data)
-{
-       struct VFE_Irq_Composite_MaskType packedData;
-
-       memset(&packedData, 0, sizeof(packedData));
-
-       packedData.encIrqComMaskBits   = data.encIrqComMask;
-       packedData.viewIrqComMaskBits  = data.viewIrqComMask;
-       packedData.ceDoneSelBits       = data.ceDoneSel;
-
-       return *((uint32_t *)&packedData);
-}
-
-static void vfe_addr_convert(struct msm_vfe_phy_info *pinfo,
-       enum vfe_resp_msg type, void *data, void **ext, int32_t *elen)
-{
-       switch (type) {
-       case VFE_MSG_OUTPUT1: {
-               pinfo->y_phy =
-                       ((struct vfe_message *)data)->_u.msgOutput1.yBuffer;
-               pinfo->cbcr_phy =
-                       ((struct vfe_message *)data)->_u.msgOutput1.cbcrBuffer;
-
-               ((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo =
-               ((struct vfe_message *)data)->_u.msgOutput1.bpcInfo;
-
-               ((struct vfe_frame_extra *)ctrl->extdata)->asfInfo =
-               ((struct vfe_message *)data)->_u.msgOutput1.asfInfo;
-
-               ((struct vfe_frame_extra *)ctrl->extdata)->frameCounter =
-               ((struct vfe_message *)data)->_u.msgOutput1.frameCounter;
-
-               ((struct vfe_frame_extra *)ctrl->extdata)->pmData =
-               ((struct vfe_message *)data)->_u.msgOutput1.pmData;
-
-               *ext  = ctrl->extdata;
-               *elen = ctrl->extlen;
-       }
-               break;
-
-       case VFE_MSG_OUTPUT2: {
-               pinfo->y_phy =
-                       ((struct vfe_message *)data)->_u.msgOutput2.yBuffer;
-               pinfo->cbcr_phy =
-                       ((struct vfe_message *)data)->_u.msgOutput2.cbcrBuffer;
-
-               CDBG("vfe_addr_convert, pinfo->y_phy = 0x%x\n", pinfo->y_phy);
-               CDBG("vfe_addr_convert, pinfo->cbcr_phy = 0x%x\n",
-                       pinfo->cbcr_phy);
-
-               ((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo =
-               ((struct vfe_message *)data)->_u.msgOutput2.bpcInfo;
-
-               ((struct vfe_frame_extra *)ctrl->extdata)->asfInfo =
-               ((struct vfe_message *)data)->_u.msgOutput2.asfInfo;
-
-               ((struct vfe_frame_extra *)ctrl->extdata)->frameCounter =
-               ((struct vfe_message *)data)->_u.msgOutput2.frameCounter;
-
-               ((struct vfe_frame_extra *)ctrl->extdata)->pmData =
-               ((struct vfe_message *)data)->_u.msgOutput2.pmData;
-
-               *ext  = ctrl->extdata;
-               *elen = ctrl->extlen;
-       }
-               break;
-
-       case VFE_MSG_STATS_AF:
-               pinfo->sbuf_phy =
-               ((struct vfe_message *)data)->_u.msgStatsAf.afBuffer;
-               break;
-
-       case VFE_MSG_STATS_WE:
-               pinfo->sbuf_phy =
-               ((struct vfe_message *)data)->_u.msgStatsWbExp.awbBuffer;
-               break;
-
-       default:
-               break;
-       } /* switch */
-}
-
-static void
-vfe_proc_ops(enum VFE_MESSAGE_ID id, void *msg, size_t len)
-{
-       struct msm_vfe_resp *rp;
-
-       /* In 8k, OUTPUT1 & OUTPUT2 messages arrive before
-        * SNAPSHOT_DONE. We don't send such messages to user */
-
-       CDBG("ctrl->vfeOperationMode = %d, msgId = %d\n",
-               ctrl->vfeOperationMode, id);
-
-       if ((ctrl->vfeOperationMode == VFE_START_OPERATION_MODE_SNAPSHOT) &&
-               (id == VFE_MSG_ID_OUTPUT1 || id == VFE_MSG_ID_OUTPUT2)) {
-               return;
-       }
-
-       rp = ctrl->resp->vfe_alloc(sizeof(struct msm_vfe_resp), ctrl->syncdata);
-       if (!rp) {
-               CDBG("rp: cannot allocate buffer\n");
-               return;
-       }
-
-       CDBG("vfe_proc_ops, msgId = %d\n", id);
-
-       rp->evt_msg.type   = MSM_CAMERA_MSG;
-       rp->evt_msg.msg_id = id;
-       rp->evt_msg.len    = len;
-       rp->evt_msg.data   = msg;
-
-       switch (rp->evt_msg.msg_id) {
-       case VFE_MSG_ID_SNAPSHOT_DONE:
-               rp->type = VFE_MSG_SNAPSHOT;
-               break;
-
-       case VFE_MSG_ID_OUTPUT1:
-               rp->type = VFE_MSG_OUTPUT1;
-               vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT1,
-                       rp->evt_msg.data, &(rp->extdata),
-                       &(rp->extlen));
-               break;
-
-       case VFE_MSG_ID_OUTPUT2:
-               rp->type = VFE_MSG_OUTPUT2;
-               vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT2,
-                               rp->evt_msg.data, &(rp->extdata),
-                               &(rp->extlen));
-               break;
-
-       case VFE_MSG_ID_STATS_AUTOFOCUS:
-               rp->type = VFE_MSG_STATS_AF;
-               vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_AF,
-                               rp->evt_msg.data, NULL, NULL);
-               break;
-
-       case VFE_MSG_ID_STATS_WB_EXP:
-               rp->type = VFE_MSG_STATS_WE;
-               vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_WE,
-                               rp->evt_msg.data, NULL, NULL);
-               break;
-
-       default:
-               rp->type = VFE_MSG_GENERAL;
-               break;
-       }
-
-       ctrl->resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, ctrl->syncdata);
-}
-
-static void vfe_send_msg_no_payload(enum VFE_MESSAGE_ID id)
-{
-       struct vfe_message *msg;
-
-       msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
-       if (!msg)
-               return;
-
-       msg->_d = id;
-       vfe_proc_ops(id, msg, 0);
-}
-
-static void vfe_send_bus_overflow_msg(void)
-{
-       struct vfe_message *msg;
-       msg =
-               kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
-       if (!msg)
-               return;
-
-       msg->_d = VFE_MSG_ID_BUS_OVERFLOW;
-#if 0
-       memcpy(&(msg->_u.msgBusOverflow),
-               &ctrl->vfePmData, sizeof(ctrl->vfePmData));
-#endif
-
-       vfe_proc_ops(VFE_MSG_ID_BUS_OVERFLOW,
-               msg, sizeof(struct vfe_message));
-}
-
-static void vfe_send_camif_error_msg(void)
-{
-#if 0
-       struct vfe_message *msg;
-       msg =
-               kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
-       if (!msg)
-               return;
-
-       msg->_d = VFE_MSG_ID_CAMIF_ERROR;
-       memcpy(&(msg->_u.msgCamifError),
-               &ctrl->vfeCamifStatusLocal, sizeof(ctrl->vfeCamifStatusLocal));
-
-       vfe_proc_ops(VFE_MSG_ID_CAMIF_ERROR,
-               msg, sizeof(struct vfe_message));
-#endif
-}
-
-static void vfe_process_error_irq(
-       struct vfe_interrupt_status *irqstatus)
-{
-       /* all possible error irq.  Note error irqs are not enabled, it is
-        * checked only when other interrupts are present. */
-       if (irqstatus->afOverflowIrq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_AF_OVERFLOW);
-
-       if (irqstatus->awbOverflowIrq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_AWB_OVERFLOW);
-
-       if (irqstatus->axiErrorIrq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_AXI_ERROR);
-
-       if (irqstatus->busOverflowIrq)
-               vfe_send_bus_overflow_msg();
-
-       if (irqstatus->camifErrorIrq)
-               vfe_send_camif_error_msg();
-
-       if (irqstatus->camifOverflowIrq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_CAMIF_OVERFLOW);
-
-       if (irqstatus->violationIrq)
-               ;
-}
-
-static void vfe_process_camif_sof_irq(void)
-{
-       /* increment the frame id number. */
-       ctrl->vfeFrameId++;
-
-       CDBG("camif_sof_irq, frameId = %d\n",
-               ctrl->vfeFrameId);
-
-       /* In snapshot mode, if frame skip is programmed,
-       * need to check it accordingly to stop camif at
-       * correct frame boundary. For the dropped frames,
-       * there won't be any output path irqs, but there is
-       * still SOF irq, which can help us determine when
-       * to stop the camif.
-       */
-       if (ctrl->vfeOperationMode) {
-               if ((1 << ctrl->vfeFrameSkipCount) &
-                               ctrl->vfeFrameSkipPattern) {
-
-                       ctrl->vfeSnapShotCount--;
-                       if (ctrl->vfeSnapShotCount == 0)
-                               /* terminate vfe pipeline at frame boundary. */
-                               writel(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
-                                       ctrl->vfebase + CAMIF_COMMAND);
-               }
-
-               /* update frame skip counter for bit checking. */
-               ctrl->vfeFrameSkipCount++;
-               if (ctrl->vfeFrameSkipCount ==
-                               (ctrl->vfeFrameSkipPeriod + 1))
-                       ctrl->vfeFrameSkipCount = 0;
-       }
-}
-
-static int vfe_get_af_pingpong_status(void)
-{
-       uint32_t busPingPongStatus;
-       int rc = 0;
-
-       busPingPongStatus =
-               readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
-
-       if ((busPingPongStatus & VFE_AF_PINGPONG_STATUS_BIT) == 0)
-               return -EFAULT;
-
-       return rc;
-}
-
-static uint32_t vfe_read_af_buf_addr(boolean pipo)
-{
-       if (pipo == FALSE)
-               return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-       else
-               return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-}
-
-static void
-vfe_update_af_buf_addr(boolean pipo, uint32_t addr)
-{
-       if (pipo == FALSE)
-               writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-       else
-               writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-}
-
-static void
-vfe_send_af_stats_msg(uint32_t afBufAddress)
-{
-       /* unsigned long flags; */
-       struct vfe_message *msg;
-       msg =
-               kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
-       if (!msg)
-               return;
-
-       /* fill message with right content. */
-       /* @todo This is causing issues, need further investigate */
-       /* spin_lock_irqsave(&ctrl->state_lock, flags); */
-       if (ctrl->vstate != VFE_STATE_ACTIVE) {
-               kfree(msg);
-               goto af_stats_done;
-       }
-
-       msg->_d = VFE_MSG_ID_STATS_AUTOFOCUS;
-       msg->_u.msgStatsAf.afBuffer = afBufAddress;
-       msg->_u.msgStatsAf.frameCounter = ctrl->vfeFrameId;
-
-       vfe_proc_ops(VFE_MSG_ID_STATS_AUTOFOCUS,
-               msg, sizeof(struct vfe_message));
-
-       ctrl->afStatsControl.ackPending = TRUE;
-
-af_stats_done:
-       /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-       return;
-}
-
-static void vfe_process_stats_af_irq(void)
-{
-       boolean bufferAvailable;
-
-       if (!(ctrl->afStatsControl.ackPending)) {
-
-               /* read hardware status. */
-               ctrl->afStatsControl.pingPongStatus =
-                       vfe_get_af_pingpong_status();
-
-               bufferAvailable =
-                       (ctrl->afStatsControl.pingPongStatus) ^ 1;
-
-               ctrl->afStatsControl.bufToRender =
-                       vfe_read_af_buf_addr(bufferAvailable);
-
-               /* update the same buffer address (ping or pong) */
-               vfe_update_af_buf_addr(bufferAvailable,
-                       ctrl->afStatsControl.nextFrameAddrBuf);
-
-               vfe_send_af_stats_msg(ctrl->afStatsControl.bufToRender);
-       } else
-               ctrl->afStatsControl.droppedStatsFrameCount++;
-}
-
-static boolean vfe_get_awb_pingpong_status(void)
-{
-       uint32_t busPingPongStatus;
-
-       busPingPongStatus =
-               readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
-
-       if ((busPingPongStatus & VFE_AWB_PINGPONG_STATUS_BIT) == 0)
-               return FALSE;
-
-       return TRUE;
-}
-
-static uint32_t
-vfe_read_awb_buf_addr(boolean pingpong)
-{
-       if (pingpong == FALSE)
-               return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-       else
-               return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-}
-
-static void vfe_update_awb_buf_addr(
-       boolean pingpong, uint32_t addr)
-{
-       if (pingpong == FALSE)
-               writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-       else
-               writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-}
-
-static void vfe_send_awb_stats_msg(uint32_t awbBufAddress)
-{
-       /* unsigned long flags; */
-       struct vfe_message   *msg;
-
-       msg =
-               kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
-       if (!msg)
-               return;
-
-       /* fill message with right content. */
-       /* @todo This is causing issues, need further investigate */
-       /* spin_lock_irqsave(&ctrl->state_lock, flags); */
-       if (ctrl->vstate != VFE_STATE_ACTIVE) {
-               kfree(msg);
-               goto awb_stats_done;
-       }
-
-       msg->_d = VFE_MSG_ID_STATS_WB_EXP;
-       msg->_u.msgStatsWbExp.awbBuffer = awbBufAddress;
-       msg->_u.msgStatsWbExp.frameCounter = ctrl->vfeFrameId;
-
-       vfe_proc_ops(VFE_MSG_ID_STATS_WB_EXP,
-               msg, sizeof(struct vfe_message));
-
-       ctrl->awbStatsControl.ackPending = TRUE;
-
-awb_stats_done:
-       /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-       return;
-}
-
-static void vfe_process_stats_awb_irq(void)
-{
-       boolean bufferAvailable;
-
-       if (!(ctrl->awbStatsControl.ackPending)) {
-
-               ctrl->awbStatsControl.pingPongStatus =
-                       vfe_get_awb_pingpong_status();
-
-               bufferAvailable = (ctrl->awbStatsControl.pingPongStatus) ^ 1;
-
-               ctrl->awbStatsControl.bufToRender =
-                       vfe_read_awb_buf_addr(bufferAvailable);
-
-               vfe_update_awb_buf_addr(bufferAvailable,
-                       ctrl->awbStatsControl.nextFrameAddrBuf);
-
-               vfe_send_awb_stats_msg(ctrl->awbStatsControl.bufToRender);
-
-       } else
-               ctrl->awbStatsControl.droppedStatsFrameCount++;
-}
-
-static void vfe_process_sync_timer_irq(
-       struct vfe_interrupt_status *irqstatus)
-{
-       if (irqstatus->syncTimer0Irq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER0_DONE);
-
-       if (irqstatus->syncTimer1Irq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER1_DONE);
-
-       if (irqstatus->syncTimer2Irq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER2_DONE);
-}
-
-static void vfe_process_async_timer_irq(
-       struct vfe_interrupt_status *irqstatus)
-{
-
-       if (irqstatus->asyncTimer0Irq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE);
-
-       if (irqstatus->asyncTimer1Irq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER1_DONE);
-
-       if (irqstatus->asyncTimer2Irq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER2_DONE);
-
-       if (irqstatus->asyncTimer3Irq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER3_DONE);
-}
-
-static void vfe_send_violation_msg(void)
-{
-       vfe_send_msg_no_payload(VFE_MSG_ID_VIOLATION);
-}
-
-static void vfe_send_async_timer_msg(void)
-{
-       vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE);
-}
-
-static void vfe_write_gamma_table(uint8_t channel,
-       boolean bank, int16_t *pTable)
-{
-       uint16_t i;
-
-       enum VFE_DMI_RAM_SEL dmiRamSel = NO_MEM_SELECTED;
-
-       switch (channel) {
-       case 0:
-               if (bank == 0)
-                       dmiRamSel = RGBLUT_RAM_CH0_BANK0;
-               else
-                       dmiRamSel = RGBLUT_RAM_CH0_BANK1;
-               break;
-
-       case 1:
-               if (bank == 0)
-                       dmiRamSel = RGBLUT_RAM_CH1_BANK0;
-               else
-                       dmiRamSel = RGBLUT_RAM_CH1_BANK1;
-               break;
-
-       case 2:
-               if (bank == 0)
-                       dmiRamSel = RGBLUT_RAM_CH2_BANK0;
-               else
-                       dmiRamSel = RGBLUT_RAM_CH2_BANK1;
-               break;
-
-       default:
-               break;
-       }
-
-       vfe_program_dmi_cfg(dmiRamSel);
-
-       for (i = 0; i < VFE_GAMMA_TABLE_LENGTH; i++) {
-               writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
-               pTable++;
-       }
-
-       /* After DMI transfer, need to set the DMI_CFG to unselect any SRAM
-       unselect the SRAM Bank. */
-       writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
-}
-
-static void vfe_prog_hw_testgen_cmd(uint32_t value)
-{
-       writel(value, ctrl->vfebase + VFE_HW_TESTGEN_CMD);
-}
-
-static inline void vfe_read_irq_status(struct vfe_irq_thread_msg *out)
-{
-       uint32_t *temp;
-
-       memset(out, 0, sizeof(struct vfe_irq_thread_msg));
-
-       temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_STATUS);
-       out->vfeIrqStatus = readl(temp);
-
-       temp = (uint32_t *)(ctrl->vfebase + CAMIF_STATUS);
-       out->camifStatus = readl(temp);
-       writel(0x7, ctrl->vfebase + CAMIF_COMMAND);
-       writel(0x3, ctrl->vfebase + CAMIF_COMMAND);
-       CDBG("camifStatus  = 0x%x\n", out->camifStatus);
-
-/*
-       temp = (uint32_t *)(ctrl->vfebase + VFE_DEMOSAIC_STATUS);
-       out->demosaicStatus = readl(temp);
-
-       temp = (uint32_t *)(ctrl->vfebase + VFE_ASF_MAX_EDGE);
-       out->asfMaxEdge = readl(temp);
-
-       temp = (uint32_t *)(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PM_STATS_0);
-*/
-
-#if 0
-       out->pmInfo.encPathPmInfo.yWrPmStats0      = readl(temp++);
-       out->pmInfo.encPathPmInfo.yWrPmStats1      = readl(temp++);
-       out->pmInfo.encPathPmInfo.cbcrWrPmStats0   = readl(temp++);
-       out->pmInfo.encPathPmInfo.cbcrWrPmStats1   = readl(temp++);
-       out->pmInfo.viewPathPmInfo.yWrPmStats0     = readl(temp++);
-       out->pmInfo.viewPathPmInfo.yWrPmStats1     = readl(temp++);
-       out->pmInfo.viewPathPmInfo.cbcrWrPmStats0  = readl(temp++);
-       out->pmInfo.viewPathPmInfo.cbcrWrPmStats1  = readl(temp);
-#endif /* if 0 Jeff */
-}
-
-static struct vfe_interrupt_status
-vfe_parse_interrupt_status(uint32_t irqStatusIn)
-{
-       struct vfe_irqenable hwstat;
-       struct vfe_interrupt_status ret;
-       boolean temp;
-
-       memset(&hwstat, 0, sizeof(hwstat));
-       memset(&ret, 0, sizeof(ret));
-
-       hwstat = *((struct vfe_irqenable *)(&irqStatusIn));
-
-       ret.camifErrorIrq       = hwstat.camifErrorIrq;
-       ret.camifSofIrq         = hwstat.camifSofIrq;
-       ret.camifEolIrq         = hwstat.camifEolIrq;
-       ret.camifEofIrq         = hwstat.camifEofIrq;
-       ret.camifEpoch1Irq      = hwstat.camifEpoch1Irq;
-       ret.camifEpoch2Irq      = hwstat.camifEpoch2Irq;
-       ret.camifOverflowIrq    = hwstat.camifOverflowIrq;
-       ret.ceIrq               = hwstat.ceIrq;
-       ret.regUpdateIrq        = hwstat.regUpdateIrq;
-       ret.resetAckIrq         = hwstat.resetAckIrq;
-       ret.encYPingpongIrq     = hwstat.encYPingpongIrq;
-       ret.encCbcrPingpongIrq  = hwstat.encCbcrPingpongIrq;
-       ret.viewYPingpongIrq    = hwstat.viewYPingpongIrq;
-       ret.viewCbcrPingpongIrq = hwstat.viewCbcrPingpongIrq;
-       ret.rdPingpongIrq       = hwstat.rdPingpongIrq;
-       ret.afPingpongIrq       = hwstat.afPingpongIrq;
-       ret.awbPingpongIrq      = hwstat.awbPingpongIrq;
-       ret.histPingpongIrq     = hwstat.histPingpongIrq;
-       ret.encIrq              = hwstat.encIrq;
-       ret.viewIrq             = hwstat.viewIrq;
-       ret.busOverflowIrq      = hwstat.busOverflowIrq;
-       ret.afOverflowIrq       = hwstat.afOverflowIrq;
-       ret.awbOverflowIrq      = hwstat.awbOverflowIrq;
-       ret.syncTimer0Irq       = hwstat.syncTimer0Irq;
-       ret.syncTimer1Irq       = hwstat.syncTimer1Irq;
-       ret.syncTimer2Irq       = hwstat.syncTimer2Irq;
-       ret.asyncTimer0Irq      = hwstat.asyncTimer0Irq;
-       ret.asyncTimer1Irq      = hwstat.asyncTimer1Irq;
-       ret.asyncTimer2Irq      = hwstat.asyncTimer2Irq;
-       ret.asyncTimer3Irq      = hwstat.asyncTimer3Irq;
-       ret.axiErrorIrq         = hwstat.axiErrorIrq;
-       ret.violationIrq        = hwstat.violationIrq;
-
-       /* logic OR of any error bits
-        * although each irq corresponds to a bit, the data type here is a
-        * boolean already. hence use logic operation.
-        */
-       temp =
-               ret.camifErrorIrq    ||
-               ret.camifOverflowIrq ||
-               ret.afOverflowIrq    ||
-               ret.awbPingpongIrq   ||
-               ret.busOverflowIrq   ||
-               ret.axiErrorIrq      ||
-               ret.violationIrq;
-
-       ret.anyErrorIrqs = temp;
-
-       /* logic OR of any output path bits*/
-       temp =
-               ret.encYPingpongIrq    ||
-               ret.encCbcrPingpongIrq ||
-               ret.encIrq;
-
-       ret.anyOutput2PathIrqs = temp;
-
-       temp =
-               ret.viewYPingpongIrq    ||
-               ret.viewCbcrPingpongIrq ||
-               ret.viewIrq;
-
-       ret.anyOutput1PathIrqs = temp;
-
-       ret.anyOutputPathIrqs =
-               ret.anyOutput1PathIrqs ||
-               ret.anyOutput2PathIrqs;
-
-       /* logic OR of any sync timer bits*/
-       temp =
-               ret.syncTimer0Irq ||
-               ret.syncTimer1Irq ||
-               ret.syncTimer2Irq;
-
-       ret.anySyncTimerIrqs = temp;
-
-       /* logic OR of any async timer bits*/
-       temp =
-               ret.asyncTimer0Irq ||
-               ret.asyncTimer1Irq ||
-               ret.asyncTimer2Irq ||
-               ret.asyncTimer3Irq;
-
-       ret.anyAsyncTimerIrqs = temp;
-
-       /* bool for all interrupts that are not allowed in idle state */
-       temp =
-               ret.anyErrorIrqs      ||
-               ret.anyOutputPathIrqs ||
-               ret.anySyncTimerIrqs  ||
-               ret.regUpdateIrq      ||
-               ret.awbPingpongIrq    ||
-               ret.afPingpongIrq     ||
-               ret.camifSofIrq       ||
-               ret.camifEpoch2Irq    ||
-               ret.camifEpoch1Irq;
-
-       ret.anyIrqForActiveStatesOnly =
-               temp;
-
-       return ret;
-}
-
-static struct vfe_frame_asf_info
-vfe_get_asf_frame_info(struct vfe_irq_thread_msg *in)
-{
-       struct vfe_asf_info     asfInfoTemp;
-       struct vfe_frame_asf_info rc;
-
-       memset(&rc, 0, sizeof(rc));
-       memset(&asfInfoTemp, 0, sizeof(asfInfoTemp));
-
-       asfInfoTemp =
-               *((struct vfe_asf_info *)(&(in->asfMaxEdge)));
-
-       rc.asfHbiCount = asfInfoTemp.HBICount;
-       rc.asfMaxEdge  = asfInfoTemp.maxEdge;
-
-       return rc;
-}
-
-static struct vfe_frame_bpc_info
-vfe_get_demosaic_frame_info(struct vfe_irq_thread_msg *in)
-{
-       struct vfe_bps_info     bpcInfoTemp;
-       struct vfe_frame_bpc_info rc;
-
-       memset(&rc, 0, sizeof(rc));
-       memset(&bpcInfoTemp, 0, sizeof(bpcInfoTemp));
-
-       bpcInfoTemp =
-               *((struct vfe_bps_info *)(&(in->demosaicStatus)));
-
-       rc.greenDefectPixelCount    =
-               bpcInfoTemp.greenBadPixelCount;
-
-       rc.redBlueDefectPixelCount  =
-               bpcInfoTemp.RedBlueBadPixelCount;
-
-       return rc;
-}
-
-static struct vfe_msg_camif_status
-vfe_get_camif_status(struct vfe_irq_thread_msg *in)
-{
-       struct vfe_camif_stats camifStatusTemp;
-       struct vfe_msg_camif_status rc;
-
-       memset(&rc, 0, sizeof(rc));
-       memset(&camifStatusTemp, 0, sizeof(camifStatusTemp));
-
-       camifStatusTemp =
-               *((struct vfe_camif_stats *)(&(in->camifStatus)));
-
-       rc.camifState = (boolean)camifStatusTemp.camifHalt;
-       rc.lineCount  = camifStatusTemp.lineCount;
-       rc.pixelCount = camifStatusTemp.pixelCount;
-
-       return rc;
-}
-
-static struct vfe_bus_performance_monitor
-vfe_get_performance_monitor_data(struct vfe_irq_thread_msg *in)
-{
-       struct vfe_bus_performance_monitor rc;
-       memset(&rc, 0, sizeof(rc));
-
-       rc.encPathPmInfo.yWrPmStats0     =
-               in->pmInfo.encPathPmInfo.yWrPmStats0;
-       rc.encPathPmInfo.yWrPmStats1     =
-               in->pmInfo.encPathPmInfo.yWrPmStats1;
-       rc.encPathPmInfo.cbcrWrPmStats0  =
-               in->pmInfo.encPathPmInfo.cbcrWrPmStats0;
-       rc.encPathPmInfo.cbcrWrPmStats1  =
-               in->pmInfo.encPathPmInfo.cbcrWrPmStats1;
-       rc.viewPathPmInfo.yWrPmStats0    =
-               in->pmInfo.viewPathPmInfo.yWrPmStats0;
-       rc.viewPathPmInfo.yWrPmStats1    =
-               in->pmInfo.viewPathPmInfo.yWrPmStats1;
-       rc.viewPathPmInfo.cbcrWrPmStats0 =
-               in->pmInfo.viewPathPmInfo.cbcrWrPmStats0;
-       rc.viewPathPmInfo.cbcrWrPmStats1 =
-               in->pmInfo.viewPathPmInfo.cbcrWrPmStats1;
-
-       return rc;
-}
-
-static void vfe_process_reg_update_irq(void)
-{
-       CDBG("vfe_process_reg_update_irq: ackPendingFlag is %d\n",
-       ctrl->vfeStartAckPendingFlag);
-       if (ctrl->vfeStartAckPendingFlag == TRUE) {
-               vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK);
-               ctrl->vfeStartAckPendingFlag = FALSE;
-       } else
-               vfe_send_msg_no_payload(VFE_MSG_ID_UPDATE_ACK);
-}
-
-static void vfe_process_reset_irq(void)
-{
-       /* unsigned long flags; */
-
-       /* @todo This is causing issues, need further investigate */
-       /* spin_lock_irqsave(&ctrl->state_lock, flags); */
-       ctrl->vstate = VFE_STATE_IDLE;
-       /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-
-       if (ctrl->vfeStopAckPending == TRUE) {
-               ctrl->vfeStopAckPending = FALSE;
-               vfe_send_msg_no_payload(VFE_MSG_ID_STOP_ACK);
-       } else {
-               vfe_set_default_reg_values();
-               vfe_send_msg_no_payload(VFE_MSG_ID_RESET_ACK);
-       }
-}
-
-static void vfe_process_pingpong_irq(struct vfe_output_path *in,
-       uint8_t fragmentCount)
-{
-       uint16_t circularIndex;
-       uint32_t nextFragmentAddr;
-
-       /* get next fragment address from circular buffer */
-       circularIndex    = (in->fragIndex) % (2 * fragmentCount);
-       nextFragmentAddr = in->addressBuffer[circularIndex];
-
-       in->fragIndex = circularIndex + 1;
-
-       /* use next fragment to program hardware ping/pong address. */
-       if (in->hwCurrentFlag == ping) {
-               writel(nextFragmentAddr, in->hwRegPingAddress);
-               in->hwCurrentFlag = pong;
-
-       } else {
-               writel(nextFragmentAddr, in->hwRegPongAddress);
-               in->hwCurrentFlag = ping;
-       }
-}
-
-static void vfe_send_output2_msg(
-       struct vfe_msg_output *pPayload)
-{
-       /* unsigned long flags; */
-       struct vfe_message *msg;
-
-       msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
-       if (!msg)
-               return;
-
-       /* fill message with right content. */
-       /* @todo This is causing issues, need further investigate */
-       /* spin_lock_irqsave(&ctrl->state_lock, flags); */
-       if (ctrl->vstate != VFE_STATE_ACTIVE) {
-               kfree(msg);
-               goto output2_msg_done;
-       }
-
-       msg->_d = VFE_MSG_ID_OUTPUT2;
-
-       memcpy(&(msg->_u.msgOutput2),
-               (void *)pPayload, sizeof(struct vfe_msg_output));
-
-       vfe_proc_ops(VFE_MSG_ID_OUTPUT2,
-               msg, sizeof(struct vfe_message));
-
-       ctrl->encPath.ackPending = TRUE;
-
-       if (!(ctrl->vfeRequestedSnapShotCount <= 3) &&
-                       (ctrl->vfeOperationMode ==
-                        VFE_START_OPERATION_MODE_SNAPSHOT))
-               ctrl->encPath.ackPending = TRUE;
-
-output2_msg_done:
-       /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-       return;
-}
-
-static void vfe_send_output1_msg(
-       struct vfe_msg_output *pPayload)
-{
-       /* unsigned long flags; */
-       struct vfe_message *msg;
-
-       msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
-       if (!msg)
-               return;
-
-       /* @todo This is causing issues, need further investigate */
-       /* spin_lock_irqsave(&ctrl->state_lock, flags); */
-       if (ctrl->vstate != VFE_STATE_ACTIVE) {
-               kfree(msg);
-               goto output1_msg_done;
-       }
-
-       msg->_d = VFE_MSG_ID_OUTPUT1;
-       memmove(&(msg->_u),
-               (void *)pPayload, sizeof(struct vfe_msg_output));
-
-       vfe_proc_ops(VFE_MSG_ID_OUTPUT1,
-               msg, sizeof(struct vfe_message));
-
-       ctrl->viewPath.ackPending = TRUE;
-
-       if (!(ctrl->vfeRequestedSnapShotCount <= 3) &&
-                       (ctrl->vfeOperationMode ==
-                        VFE_START_OPERATION_MODE_SNAPSHOT))
-               ctrl->viewPath.ackPending = TRUE;
-
-output1_msg_done:
-       /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-       return;
-}
-
-static void vfe_send_output_msg(boolean whichOutputPath,
-       uint32_t yPathAddr, uint32_t cbcrPathAddr)
-{
-       struct vfe_msg_output msgPayload;
-
-       msgPayload.yBuffer = yPathAddr;
-       msgPayload.cbcrBuffer = cbcrPathAddr;
-
-       /* asf info is common for both output1 and output2 */
-#if 0
-       msgPayload.asfInfo.asfHbiCount = ctrl->vfeAsfFrameInfo.asfHbiCount;
-       msgPayload.asfInfo.asfMaxEdge = ctrl->vfeAsfFrameInfo.asfMaxEdge;
-
-       /* demosaic info is common for both output1 and output2 */
-       msgPayload.bpcInfo.greenDefectPixelCount =
-               ctrl->vfeBpcFrameInfo.greenDefectPixelCount;
-       msgPayload.bpcInfo.redBlueDefectPixelCount =
-               ctrl->vfeBpcFrameInfo.redBlueDefectPixelCount;
-#endif /* if 0 */
-
-       /* frame ID is common for both paths. */
-       msgPayload.frameCounter = ctrl->vfeFrameId;
-
-       if (whichOutputPath) {
-               /* msgPayload.pmData = ctrl->vfePmData.encPathPmInfo; */
-               vfe_send_output2_msg(&msgPayload);
-       } else {
-               /* msgPayload.pmData = ctrl->vfePmData.viewPathPmInfo; */
-               vfe_send_output1_msg(&msgPayload);
-       }
-}
-
-static void vfe_process_frame_done_irq_multi_frag(
-       struct vfe_output_path_combo *in)
-{
-       uint32_t yAddress, cbcrAddress;
-       uint16_t idx;
-       uint32_t *ptrY;
-       uint32_t *ptrCbcr;
-       const uint32_t *ptrSrc;
-       uint8_t i;
-
-       if (!in->ackPending) {
-
-               idx = (in->currentFrame) * (in->fragCount);
-
-               /* Send output message. */
-               yAddress = in->yPath.addressBuffer[idx];
-               cbcrAddress = in->cbcrPath.addressBuffer[idx];
-
-               /* copy next frame to current frame. */
-               ptrSrc  = in->nextFrameAddrBuf;
-               ptrY    = (uint32_t *)&(in->yPath.addressBuffer[idx]);
-               ptrCbcr = (uint32_t *)&(in->cbcrPath.addressBuffer[idx]);
-
-               /* Copy Y address */
-               for (i = 0; i < in->fragCount; i++)
-                       *ptrY++ = *ptrSrc++;
-
-               /* Copy Cbcr address */
-               for (i = 0; i < in->fragCount; i++)
-                       *ptrCbcr++ = *ptrSrc++;
-
-               vfe_send_output_msg(in->whichOutputPath, yAddress, cbcrAddress);
-
-       } else {
-               if (in->whichOutputPath == 0)
-                       ctrl->vfeDroppedFrameCounts.output1Count++;
-
-               if (in->whichOutputPath == 1)
-                       ctrl->vfeDroppedFrameCounts.output2Count++;
-       }
-
-       /* toggle current frame. */
-       in->currentFrame = in->currentFrame^1;
-
-       if (ctrl->vfeOperationMode)
-               in->snapshotPendingCount--;
-}
-
-static void vfe_process_frame_done_irq_no_frag_io(
-       struct vfe_output_path_combo *in, uint32_t *pNextAddr,
-       uint32_t *pdestRenderAddr)
-{
-       uint32_t busPingPongStatus;
-       uint32_t tempAddress;
-
-       /* 1. read hw status register. */
-       busPingPongStatus =
-               readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
-
-       CDBG("hardware status is 0x%x\n", busPingPongStatus);
-
-       /* 2. determine ping or pong */
-       /* use cbcr status */
-       busPingPongStatus = busPingPongStatus & (1<<(in->cbcrStatusBit));
-
-       /* 3. read out address and update address */
-       if (busPingPongStatus == 0) {
-               /* hw is working on ping, render pong buffer */
-               /* a. read out pong address */
-               /* read out y address. */
-               tempAddress = readl(in->yPath.hwRegPongAddress);
-
-               CDBG("pong 1 addr = 0x%x\n", tempAddress);
-               *pdestRenderAddr++ = tempAddress;
-               /* read out cbcr address. */
-               tempAddress = readl(in->cbcrPath.hwRegPongAddress);
-
-               CDBG("pong 2 addr = 0x%x\n", tempAddress);
-               *pdestRenderAddr = tempAddress;
-
-               /* b. update pong address */
-               writel(*pNextAddr++, in->yPath.hwRegPongAddress);
-               writel(*pNextAddr, in->cbcrPath.hwRegPongAddress);
-       } else {
-               /* hw is working on pong, render ping buffer */
-
-               /* a. read out ping address */
-               tempAddress = readl(in->yPath.hwRegPingAddress);
-               CDBG("ping 1 addr = 0x%x\n", tempAddress);
-               *pdestRenderAddr++ = tempAddress;
-               tempAddress = readl(in->cbcrPath.hwRegPingAddress);
-
-               CDBG("ping 2 addr = 0x%x\n", tempAddress);
-               *pdestRenderAddr = tempAddress;
-
-               /* b. update ping address */
-               writel(*pNextAddr++, in->yPath.hwRegPingAddress);
-               CDBG("NextAddress = 0x%x\n", *pNextAddr);
-               writel(*pNextAddr, in->cbcrPath.hwRegPingAddress);
-       }
-}
-
-static void vfe_process_frame_done_irq_no_frag(
-       struct vfe_output_path_combo *in)
-{
-       uint32_t addressToRender[2];
-       static uint32_t fcnt;
-
-       if (fcnt++ < 3)
-               return;
-
-       if (!in->ackPending) {
-               vfe_process_frame_done_irq_no_frag_io(in,
-                       in->nextFrameAddrBuf, addressToRender);
-
-               /* use addressToRender to send out message. */
-               vfe_send_output_msg(in->whichOutputPath,
-                               addressToRender[0], addressToRender[1]);
-
-       } else {
-               /* ackPending is still there, accumulate dropped frame count.
-                * These count can be read through ioctrl command. */
-               CDBG("waiting frame ACK\n");
-
-               if (in->whichOutputPath == 0)
-                       ctrl->vfeDroppedFrameCounts.output1Count++;
-
-               if (in->whichOutputPath == 1)
-                       ctrl->vfeDroppedFrameCounts.output2Count++;
-       }
-
-       /* in case of multishot when upper layer did not ack, there will still
-        * be a snapshot done msg sent out, even though the number of frames
-        * sent out may be less than the desired number of frames.  snapshot
-        * done msg would be helpful to indicate that vfe pipeline has stop,
-        * and in good known state.
-        */
-       if (ctrl->vfeOperationMode)
-               in->snapshotPendingCount--;
-}
-
-static void vfe_process_output_path_irq(
-       struct vfe_interrupt_status *irqstatus)
-{
-       /* unsigned long flags; */
-
-       /* process the view path interrupts */
-       if (irqstatus->anyOutput1PathIrqs) {
-               if (ctrl->viewPath.multiFrag) {
-
-                       if (irqstatus->viewCbcrPingpongIrq)
-                               vfe_process_pingpong_irq(
-                                       &(ctrl->viewPath.cbcrPath),
-                                       ctrl->viewPath.fragCount);
-
-                       if (irqstatus->viewYPingpongIrq)
-                               vfe_process_pingpong_irq(
-                                       &(ctrl->viewPath.yPath),
-                                       ctrl->viewPath.fragCount);
-
-                       if (irqstatus->viewIrq)
-                               vfe_process_frame_done_irq_multi_frag(
-                                       &ctrl->viewPath);
-
-               } else {
-                       /* typical case for no fragment,
-                        only frame done irq is enabled. */
-                       if (irqstatus->viewIrq)
-                               vfe_process_frame_done_irq_no_frag(
-                                       &ctrl->viewPath);
-               }
-       }
-
-       /* process the encoder path interrupts */
-       if (irqstatus->anyOutput2PathIrqs) {
-               if (ctrl->encPath.multiFrag) {
-                       if (irqstatus->encCbcrPingpongIrq)
-                               vfe_process_pingpong_irq(
-                                       &(ctrl->encPath.cbcrPath),
-                                       ctrl->encPath.fragCount);
-
-                       if (irqstatus->encYPingpongIrq)
-                               vfe_process_pingpong_irq(&(ctrl->encPath.yPath),
-                               ctrl->encPath.fragCount);
-
-                       if (irqstatus->encIrq)
-                               vfe_process_frame_done_irq_multi_frag(
-                                       &ctrl->encPath);
-
-               } else {
-                       if (irqstatus->encIrq)
-                               vfe_process_frame_done_irq_no_frag(
-                                       &ctrl->encPath);
-               }
-       }
-
-       if (ctrl->vfeOperationMode) {
-               if ((ctrl->encPath.snapshotPendingCount == 0) &&
-                               (ctrl->viewPath.snapshotPendingCount == 0)) {
-
-                       /* @todo This is causing issues, further investigate */
-                       /* spin_lock_irqsave(&ctrl->state_lock, flags); */
-                       ctrl->vstate = VFE_STATE_IDLE;
-                       /* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
-
-                       vfe_send_msg_no_payload(VFE_MSG_ID_SNAPSHOT_DONE);
-                       vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
-                       vfe_pm_stop();
-               }
-       }
-}
-
-static void vfe_do_tasklet(unsigned long data)
-{
-       unsigned long flags;
-
-       struct isr_queue_cmd *qcmd = NULL;
-
-       CDBG("=== vfe_do_tasklet start === \n");
-
-       spin_lock_irqsave(&ctrl->tasklet_lock, flags);
-       qcmd = list_first_entry(&ctrl->tasklet_q,
-                       struct isr_queue_cmd, list);
-
-       if (!qcmd) {
-               spin_unlock_irqrestore(&ctrl->tasklet_lock, flags);
-               return;
-       }
-
-       list_del(&qcmd->list);
-       spin_unlock_irqrestore(&ctrl->tasklet_lock, flags);
-
-       if (qcmd->vfeInterruptStatus.regUpdateIrq) {
-               CDBG("irq       regUpdateIrq\n");
-               vfe_process_reg_update_irq();
-       }
-
-       if (qcmd->vfeInterruptStatus.resetAckIrq) {
-               CDBG("irq       resetAckIrq\n");
-               vfe_process_reset_irq();
-       }
-
-       spin_lock_irqsave(&ctrl->state_lock, flags);
-       if (ctrl->vstate != VFE_STATE_ACTIVE) {
-               spin_unlock_irqrestore(&ctrl->state_lock, flags);
-               return;
-       }
-       spin_unlock_irqrestore(&ctrl->state_lock, flags);
-
-#if 0
-       if (qcmd->vfeInterruptStatus.camifEpoch1Irq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH1);
-
-       if (qcmd->vfeInterruptStatus.camifEpoch2Irq)
-               vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH2);
-#endif /* Jeff */
-
-       /* next, check output path related interrupts. */
-       if (qcmd->vfeInterruptStatus.anyOutputPathIrqs) {
-               CDBG("irq       anyOutputPathIrqs\n");
-               vfe_process_output_path_irq(&qcmd->vfeInterruptStatus);
-       }
-
-       if (qcmd->vfeInterruptStatus.afPingpongIrq)
-               vfe_process_stats_af_irq();
-
-       if (qcmd->vfeInterruptStatus.awbPingpongIrq)
-               vfe_process_stats_awb_irq();
-
-       /* any error irqs*/
-       if (qcmd->vfeInterruptStatus.anyErrorIrqs)
-               vfe_process_error_irq(&qcmd->vfeInterruptStatus);
-
-#if 0
-       if (qcmd->vfeInterruptStatus.anySyncTimerIrqs)
-               vfe_process_sync_timer_irq();
-
-       if (qcmd->vfeInterruptStatus.anyAsyncTimerIrqs)
-               vfe_process_async_timer_irq();
-#endif /* Jeff */
-
-       if (qcmd->vfeInterruptStatus.camifSofIrq) {
-               CDBG("irq       camifSofIrq\n");
-               vfe_process_camif_sof_irq();
-       }
-
-       kfree(qcmd);
-       CDBG("=== vfe_do_tasklet end === \n");
-}
-
-DECLARE_TASKLET(vfe_tasklet, vfe_do_tasklet, 0);
-
-static irqreturn_t vfe_parse_irq(int irq_num, void *data)
-{
-       unsigned long flags;
-       uint32_t irqStatusLocal;
-       struct vfe_irq_thread_msg irq;
-       struct isr_queue_cmd *qcmd;
-
-       CDBG("vfe_parse_irq\n");
-
-       vfe_read_irq_status(&irq);
-
-       if (irq.vfeIrqStatus == 0) {
-               CDBG("vfe_parse_irq: irq.vfeIrqStatus is 0\n");
-               return IRQ_HANDLED;
-       }
-
-       qcmd = kzalloc(sizeof(struct isr_queue_cmd),
-               GFP_ATOMIC);
-       if (!qcmd) {
-               CDBG("vfe_parse_irq: qcmd malloc failed!\n");
-               return IRQ_HANDLED;
-       }
-
-       spin_lock_irqsave(&ctrl->ack_lock, flags);
-
-       if (ctrl->vfeStopAckPending)
-               irqStatusLocal =
-                       (VFE_IMASK_WHILE_STOPPING & irq.vfeIrqStatus);
-       else
-               irqStatusLocal =
-                       ((ctrl->vfeImaskPacked | VFE_IMASK_ERROR_ONLY) &
-                               irq.vfeIrqStatus);
-
-       spin_unlock_irqrestore(&ctrl->ack_lock, flags);
-
-       /* first parse the interrupt status to local data structures. */
-       qcmd->vfeInterruptStatus = vfe_parse_interrupt_status(irqStatusLocal);
-       qcmd->vfeAsfFrameInfo = vfe_get_asf_frame_info(&irq);
-       qcmd->vfeBpcFrameInfo = vfe_get_demosaic_frame_info(&irq);
-       qcmd->vfeCamifStatusLocal = vfe_get_camif_status(&irq);
-       qcmd->vfePmData = vfe_get_performance_monitor_data(&irq);
-
-       spin_lock_irqsave(&ctrl->tasklet_lock, flags);
-       list_add_tail(&qcmd->list, &ctrl->tasklet_q);
-       spin_unlock_irqrestore(&ctrl->tasklet_lock, flags);
-       tasklet_schedule(&vfe_tasklet);
-
-       /* clear the pending interrupt of the same kind.*/
-       writel(irq.vfeIrqStatus, ctrl->vfebase + VFE_IRQ_CLEAR);
-
-       return IRQ_HANDLED;
-}
-
-int vfe_cmd_init(struct msm_vfe_callback *presp,
-       struct platform_device *pdev, void *sdata)
-{
-       struct resource *vfemem, *vfeirq, *vfeio;
-       int rc;
-
-       vfemem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!vfemem) {
-               CDBG("no mem resource?\n");
-               return -ENODEV;
-       }
-
-       vfeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!vfeirq) {
-               CDBG("no irq resource?\n");
-               return -ENODEV;
-       }
-
-       vfeio = request_mem_region(vfemem->start,
-               resource_size(vfemem), pdev->name);
-       if (!vfeio) {
-               CDBG("VFE region already claimed\n");
-               return -EBUSY;
-       }
-
-       ctrl =
-       kzalloc(sizeof(struct msm_vfe8x_ctrl), GFP_KERNEL);
-       if (!ctrl) {
-               rc = -ENOMEM;
-               goto cmd_init_failed1;
-       }
-
-       ctrl->vfeirq  = vfeirq->start;
-
-       ctrl->vfebase =
-               ioremap(vfemem->start, (vfemem->end - vfemem->start) + 1);
-       if (!ctrl->vfebase) {
-               rc = -ENOMEM;
-               goto cmd_init_failed2;
-       }
-
-       rc = request_irq(ctrl->vfeirq, vfe_parse_irq,
-               IRQF_TRIGGER_RISING, "vfe", 0);
-       if (rc < 0)
-               goto cmd_init_failed2;
-
-       if (presp && presp->vfe_resp)
-               ctrl->resp = presp;
-       else {
-               rc = -EINVAL;
-               goto cmd_init_failed3;
-       }
-
-       ctrl->extdata =
-               kmalloc(sizeof(struct vfe_frame_extra), GFP_KERNEL);
-       if (!ctrl->extdata) {
-               rc = -ENOMEM;
-               goto cmd_init_failed3;
-       }
-
-       spin_lock_init(&ctrl->ack_lock);
-       spin_lock_init(&ctrl->state_lock);
-       spin_lock_init(&ctrl->io_lock);
-
-       ctrl->extlen = sizeof(struct vfe_frame_extra);
-
-       spin_lock_init(&ctrl->tasklet_lock);
-       INIT_LIST_HEAD(&ctrl->tasklet_q);
-
-       ctrl->syncdata = sdata;
-       return 0;
-
-cmd_init_failed3:
-       disable_irq(ctrl->vfeirq);
-       free_irq(ctrl->vfeirq, 0);
-       iounmap(ctrl->vfebase);
-cmd_init_failed2:
-       kfree(ctrl);
-cmd_init_failed1:
-       release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1);
-       return rc;
-}
-
-void vfe_cmd_release(struct platform_device *dev)
-{
-       struct resource *mem;
-
-       disable_irq(ctrl->vfeirq);
-       free_irq(ctrl->vfeirq, 0);
-
-       iounmap(ctrl->vfebase);
-       mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
-       release_mem_region(mem->start, (mem->end - mem->start) + 1);
-
-       ctrl->extlen = 0;
-
-       kfree(ctrl->extdata);
-       kfree(ctrl);
-}
-
-void vfe_stats_af_stop(void)
-{
-       ctrl->vfeStatsCmdLocal.autoFocusEnable = FALSE;
-       ctrl->vfeImaskLocal.afPingpongIrq = FALSE;
-}
-
-void vfe_stop(void)
-{
-       boolean vfeAxiBusy;
-       uint32_t vfeAxiStauts;
-
-       /* for reset hw modules, and send msg when reset_irq comes.*/
-       ctrl->vfeStopAckPending = TRUE;
-
-       ctrl->vfeStatsPingPongReloadFlag = FALSE;
-       vfe_pm_stop();
-
-       /* disable all interrupts.  */
-       vfe_program_irq_mask(VFE_DISABLE_ALL_IRQS);
-
-       /* in either continuous or snapshot mode, stop command can be issued
-        * at any time.
-        */
-       vfe_camif_stop_immediately();
-       vfe_program_axi_cmd(AXI_HALT);
-       vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
-
-       vfeAxiBusy = TRUE;
-
-       while (vfeAxiBusy) {
-               vfeAxiStauts = vfe_read_axi_status();
-               if ((vfeAxiStauts & AXI_STATUS_BUSY_MASK) != 0)
-                       vfeAxiBusy = FALSE;
-       }
-
-       vfe_program_axi_cmd(AXI_HALT_CLEAR);
-
-       /* clear all pending interrupts */
-       writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
-
-       /* enable reset_ack and async timer interrupt only while stopping
-        * the pipeline.
-        */
-       vfe_program_irq_mask(VFE_IMASK_WHILE_STOPPING);
-
-       vfe_program_global_reset_cmd(VFE_RESET_UPON_STOP_CMD);
-}
-
-void vfe_update(void)
-{
-       ctrl->vfeModuleEnableLocal.statsEnable =
-               ctrl->vfeStatsCmdLocal.autoFocusEnable |
-               ctrl->vfeStatsCmdLocal.axwEnable;
-
-       vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
-
-       vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
-
-       ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
-       vfe_program_irq_mask(ctrl->vfeImaskPacked);
-
-       if ((ctrl->vfeModuleEnableLocal.statsEnable == TRUE) &&
-                       (ctrl->vfeStatsPingPongReloadFlag == FALSE)) {
-               ctrl->vfeStatsPingPongReloadFlag = TRUE;
-
-               ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
-               vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
-       }
-
-       vfe_program_reg_update_cmd(VFE_REG_UPDATE_TRIGGER);
-}
-
-int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *in)
-{
-       int rc = 0;
-
-       ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
-
-       switch (in->channelSelect) {
-       case RGB_GAMMA_CH0_SELECTED:
-               ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
-               vfe_write_gamma_table(0,
-                       ctrl->vfeGammaLutSel.ch0BankSelect, in->table);
-               break;
-
-       case RGB_GAMMA_CH1_SELECTED:
-               ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
-               vfe_write_gamma_table(1,
-                       ctrl->vfeGammaLutSel.ch1BankSelect, in->table);
-               break;
-
-       case RGB_GAMMA_CH2_SELECTED:
-               ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
-               vfe_write_gamma_table(2,
-                       ctrl->vfeGammaLutSel.ch2BankSelect, in->table);
-               break;
-
-       case RGB_GAMMA_CH0_CH1_SELECTED:
-               ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
-               ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
-               vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
-                       in->table);
-               vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
-                       in->table);
-               break;
-
-       case RGB_GAMMA_CH0_CH2_SELECTED:
-               ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
-               ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
-               vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
-                       in->table);
-               vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
-                       in->table);
-               break;
-
-       case RGB_GAMMA_CH1_CH2_SELECTED:
-               ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
-               ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
-               vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
-                       in->table);
-               vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
-                       in->table);
-               break;
-
-       case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
-               ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
-               ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
-               ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
-               vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
-                       in->table);
-               vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
-                       in->table);
-               vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
-                       in->table);
-               break;
-
-       default:
-               return -EINVAL;
-       } /* switch */
-
-       /* update the gammaLutSel register. */
-       vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
-
-       return rc;
-}
-
-int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *in)
-{
-       int rc = 0;
-
-       ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
-
-       switch (in->channelSelect) {
-       case RGB_GAMMA_CH0_SELECTED:
-vfe_write_gamma_table(0, 0, in->table);
-break;
-
-       case RGB_GAMMA_CH1_SELECTED:
-               vfe_write_gamma_table(1, 0, in->table);
-               break;
-
-       case RGB_GAMMA_CH2_SELECTED:
-               vfe_write_gamma_table(2, 0, in->table);
-               break;
-
-       case RGB_GAMMA_CH0_CH1_SELECTED:
-               vfe_write_gamma_table(0, 0, in->table);
-               vfe_write_gamma_table(1, 0, in->table);
-               break;
-
-       case RGB_GAMMA_CH0_CH2_SELECTED:
-               vfe_write_gamma_table(0, 0, in->table);
-               vfe_write_gamma_table(2, 0, in->table);
-               break;
-
-       case RGB_GAMMA_CH1_CH2_SELECTED:
-               vfe_write_gamma_table(1, 0, in->table);
-               vfe_write_gamma_table(2, 0, in->table);
-               break;
-
-       case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
-               vfe_write_gamma_table(0, 0, in->table);
-               vfe_write_gamma_table(1, 0, in->table);
-               vfe_write_gamma_table(2, 0, in->table);
-               break;
-
-       default:
-               rc = -EINVAL;
-               break;
-       } /* switch */
-
-       return rc;
-}
-
-void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *in)
-{
-       ctrl->afStatsControl.nextFrameAddrBuf = in->nextAFOutputBufferAddr;
-       ctrl->afStatsControl.ackPending = FALSE;
-}
-
-void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *in)
-{
-       ctrl->awbStatsControl.nextFrameAddrBuf = in->nextWbExpOutputBufferAddr;
-       ctrl->awbStatsControl.ackPending = FALSE;
-}
-
-void vfe_output2_ack(struct vfe_cmd_output_ack *in)
-{
-       const uint32_t *psrc;
-       uint32_t *pdest;
-       uint8_t i;
-
-       pdest = ctrl->encPath.nextFrameAddrBuf;
-
-       CDBG("output2_ack: ack addr = 0x%x\n", in->ybufaddr[0]);
-
-       psrc = in->ybufaddr;
-       for (i = 0; i < ctrl->encPath.fragCount; i++)
-               *pdest++ = *psrc++;
-
-       psrc = in->chromabufaddr;
-       for (i = 0; i < ctrl->encPath.fragCount; i++)
-               *pdest++ = *psrc++;
-
-       ctrl->encPath.ackPending = FALSE;
-}
-
-void vfe_output1_ack(struct vfe_cmd_output_ack *in)
-{
-       const uint32_t *psrc;
-       uint32_t *pdest;
-       uint8_t i;
-
-       pdest = ctrl->viewPath.nextFrameAddrBuf;
-
-       psrc = in->ybufaddr;
-       for (i = 0; i < ctrl->viewPath.fragCount; i++)
-               *pdest++ = *psrc++;
-
-       psrc = in->chromabufaddr;
-       for (i = 0; i < ctrl->viewPath.fragCount; i++)
-               *pdest++ = *psrc++;
-
-       ctrl->viewPath.ackPending = FALSE;
-}
-
-void vfe_start(struct vfe_cmd_start *in)
-{
-       unsigned long flags;
-       uint32_t  pmstatus = 0;
-       boolean rawmode;
-       uint32_t  demperiod = 0;
-       uint32_t  demeven = 0;
-       uint32_t  demodd = 0;
-
-       /* derived from other commands.  (camif config, axi output config,
-        * etc)
-       */
-       struct vfe_cfg hwcfg;
-       struct vfe_upsample_cfg chromupcfg;
-
-       CDBG("vfe_start operationMode = %d\n", in->operationMode);
-
-       memset(&hwcfg, 0, sizeof(hwcfg));
-       memset(&chromupcfg, 0, sizeof(chromupcfg));
-
-       switch (in->pixel) {
-       case VFE_BAYER_RGRGRG:
-               demperiod = 1;
-               demeven = 0xC9;
-               demodd = 0xAC;
-               break;
-
-       case VFE_BAYER_GRGRGR:
-               demperiod = 1;
-               demeven = 0x9C;
-               demodd = 0xCA;
-               break;
-
-       case VFE_BAYER_BGBGBG:
-               demperiod = 1;
-               demeven = 0xCA;
-               demodd = 0x9C;
-               break;
-
-       case VFE_BAYER_GBGBGB:
-               demperiod = 1;
-               demeven = 0xAC;
-               demodd = 0xC9;
-               break;
-
-       case VFE_YUV_YCbYCr:
-               demperiod = 3;
-               demeven = 0x9CAC;
-               demodd = 0x9CAC;
-               break;
-
-       case VFE_YUV_YCrYCb:
-               demperiod = 3;
-               demeven = 0xAC9C;
-               demodd = 0xAC9C;
-               break;
-
-       case VFE_YUV_CbYCrY:
-               demperiod = 3;
-               demeven = 0xC9CA;
-               demodd = 0xC9CA;
-               break;
-
-       case VFE_YUV_CrYCbY:
-               demperiod = 3;
-               demeven = 0xCAC9;
-               demodd = 0xCAC9;
-               break;
-
-       default:
-               return;
-       }
-
-       vfe_config_demux(demperiod, demeven, demodd);
-
-       vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
-
-       /* save variables to local. */
-       ctrl->vfeOperationMode = in->operationMode;
-       if (ctrl->vfeOperationMode ==
-                       VFE_START_OPERATION_MODE_SNAPSHOT) {
-               /* in snapshot mode, initialize snapshot count*/
-               ctrl->vfeSnapShotCount = in->snapshotCount;
-
-               /* save the requested count, this is temporarily done, to
-               help with HJR / multishot. */
-               ctrl->vfeRequestedSnapShotCount = ctrl->vfeSnapShotCount;
-
-               CDBG("requested snapshot count = %d\n", ctrl->vfeSnapShotCount);
-
-               /* Assumption is to have the same pattern and period for both
-               paths, if both paths are used. */
-               if (ctrl->viewPath.pathEnabled) {
-                       ctrl->viewPath.snapshotPendingCount =
-                               in->snapshotCount;
-
-                       ctrl->vfeFrameSkipPattern =
-                               ctrl->vfeFrameSkip.output1Pattern;
-                       ctrl->vfeFrameSkipPeriod =
-                               ctrl->vfeFrameSkip.output1Period;
-               }
-
-               if (ctrl->encPath.pathEnabled) {
-                       ctrl->encPath.snapshotPendingCount =
-                               in->snapshotCount;
-
-                       ctrl->vfeFrameSkipPattern =
-                               ctrl->vfeFrameSkip.output2Pattern;
-                       ctrl->vfeFrameSkipPeriod =
-                               ctrl->vfeFrameSkip.output2Period;
-               }
-       }
-
-       /* enable color conversion for bayer sensor
-       if stats enabled, need to do color conversion. */
-       if (in->pixel <= VFE_BAYER_GBGBGB)
-               ctrl->vfeStatsCmdLocal.colorConversionEnable = TRUE;
-
-       vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
-
-       if (in->pixel >= VFE_YUV_YCbYCr)
-               ctrl->vfeModuleEnableLocal.chromaUpsampleEnable = TRUE;
-
-       ctrl->vfeModuleEnableLocal.demuxEnable = TRUE;
-
-       /* if any stats module is enabled, the main bit is enabled. */
-       ctrl->vfeModuleEnableLocal.statsEnable =
-               ctrl->vfeStatsCmdLocal.autoFocusEnable |
-               ctrl->vfeStatsCmdLocal.axwEnable;
-
-       vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
-
-       /* in case of offline processing, do not need to config camif. Having
-        * bus output enabled in camif_config register might confuse the
-        * hardware?
-        */
-       if (in->inputSource != VFE_START_INPUT_SOURCE_AXI) {
-               vfe_reg_camif_config(&ctrl->vfeCamifConfigLocal);
-       } else {
-               /* offline processing, enable axi read */
-               ctrl->vfeBusConfigLocal.stripeRdPathEn = TRUE;
-               ctrl->vfeBusCmdLocal.stripeReload = TRUE;
-               ctrl->vfeBusConfigLocal.rawPixelDataSize =
-                       ctrl->axiInputDataSize;
-       }
-
-       vfe_reg_bus_cfg(&ctrl->vfeBusConfigLocal);
-
-       /* directly from start command */
-       hwcfg.pixelPattern = in->pixel;
-       hwcfg.inputSource = in->inputSource;
-       writel(*(uint32_t *)&hwcfg, ctrl->vfebase + VFE_CFG);
-
-       /* regardless module enabled or not, it does not hurt
-        * to program the cositing mode. */
-       chromupcfg.chromaCositingForYCbCrInputs =
-               in->yuvInputCositingMode;
-
-       writel(*(uint32_t *)&(chromupcfg),
-               ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG);
-
-       /* MISR to monitor the axi read. */
-       writel(0xd8, ctrl->vfebase + VFE_BUS_MISR_MAST_CFG_0);
-
-       /* clear all pending interrupts. */
-       writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
-
-       /*  define how composite interrupt work.  */
-       ctrl->vfeImaskCompositePacked =
-               vfe_irq_composite_pack(ctrl->vfeIrqCompositeMaskLocal);
-
-       vfe_program_irq_composite_mask(ctrl->vfeImaskCompositePacked);
-
-       /*  enable all necessary interrupts.      */
-       ctrl->vfeImaskLocal.camifSofIrq  = TRUE;
-       ctrl->vfeImaskLocal.regUpdateIrq = TRUE;
-       ctrl->vfeImaskLocal.resetAckIrq  = TRUE;
-
-       ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
-       vfe_program_irq_mask(ctrl->vfeImaskPacked);
-
-       /* enable bus performance monitor */
-       vfe_8k_pm_start(&ctrl->vfeBusPmConfigLocal);
-
-       /* trigger vfe reg update */
-       ctrl->vfeStartAckPendingFlag = TRUE;
-
-       /* write bus command to trigger reload of ping pong buffer. */
-       ctrl->vfeBusCmdLocal.busPingpongReload = TRUE;
-
-       if (ctrl->vfeModuleEnableLocal.statsEnable == TRUE) {
-               ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
-               ctrl->vfeStatsPingPongReloadFlag = TRUE;
-       }
-
-       writel(VFE_REG_UPDATE_TRIGGER,
-               ctrl->vfebase + VFE_REG_UPDATE_CMD);
-
-       /* program later than the reg update. */
-       vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
-
-       if ((in->inputSource ==
-                        VFE_START_INPUT_SOURCE_CAMIF) ||
-                       (in->inputSource ==
-                        VFE_START_INPUT_SOURCE_TESTGEN))
-               writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND);
-
-       /* start test gen if it is enabled */
-       if (ctrl->vfeTestGenStartFlag == TRUE) {
-               ctrl->vfeTestGenStartFlag = FALSE;
-               vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_GO);
-       }
-
-       CDBG("ctrl->axiOutputMode = %d\n", ctrl->axiOutputMode);
-       if (ctrl->axiOutputMode == VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2) {
-               /* raw dump mode */
-               rawmode = TRUE;
-
-               while (rawmode) {
-                       pmstatus =
-                               readl(ctrl->vfebase +
-                                       VFE_BUS_ENC_CBCR_WR_PM_STATS_1);
-
-                       if ((pmstatus & VFE_PM_BUF_MAX_CNT_MASK) != 0)
-                               rawmode = FALSE;
-               }
-
-               vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK);
-               ctrl->vfeStartAckPendingFlag = FALSE;
-       }
-
-       spin_lock_irqsave(&ctrl->state_lock, flags);
-       ctrl->vstate = VFE_STATE_ACTIVE;
-       spin_unlock_irqrestore(&ctrl->state_lock, flags);
-}
-
-void vfe_la_update(struct vfe_cmd_la_config *in)
-{
-       int16_t *pTable;
-       enum VFE_DMI_RAM_SEL dmiRamSel;
-       int i;
-
-       pTable = in->table;
-       ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
-
-       /* toggle the bank to be used. */
-       ctrl->vfeLaBankSel ^= 1;
-
-       if (ctrl->vfeLaBankSel == 0)
-               dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
-       else
-               dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
-
-       /* configure the DMI_CFG to select right sram */
-       vfe_program_dmi_cfg(dmiRamSel);
-
-       for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
-               writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
-               pTable++;
-       }
-
-       /* After DMI transfer, to make it safe, need to set
-        * the DMI_CFG to unselect any SRAM */
-       writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
-       writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
-}
-
-void vfe_la_config(struct vfe_cmd_la_config *in)
-{
-       uint16_t i;
-       int16_t  *pTable;
-       enum VFE_DMI_RAM_SEL dmiRamSel;
-
-       pTable = in->table;
-       ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
-
-       if (ctrl->vfeLaBankSel == 0)
-               dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
-       else
-               dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
-
-       /* configure the DMI_CFG to select right sram */
-       vfe_program_dmi_cfg(dmiRamSel);
-
-       for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
-               writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
-               pTable++;
-       }
-
-       /* After DMI transfer, to make it safe, need to set the
-        * DMI_CFG to unselect any SRAM */
-       writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
-
-       /* can only be bank 0 or bank 1 for now. */
-       writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
-       CDBG("VFE Luma adaptation bank selection is 0x%x\n",
-                        *(uint32_t *)&ctrl->vfeLaBankSel);
-}
-
-void vfe_test_gen_start(struct vfe_cmd_test_gen_start *in)
-{
-       struct VFE_TestGen_ConfigCmdType cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       cmd.numFrame              = in->numFrame;
-       cmd.pixelDataSelect       = in->pixelDataSelect;
-       cmd.systematicDataSelect  = in->systematicDataSelect;
-       cmd.pixelDataSize         = (uint32_t)in->pixelDataSize;
-       cmd.hsyncEdge             = (uint32_t)in->hsyncEdge;
-       cmd.vsyncEdge             = (uint32_t)in->vsyncEdge;
-       cmd.imageWidth            = in->imageWidth;
-       cmd.imageHeight           = in->imageHeight;
-       cmd.sofOffset             = in->startOfFrameOffset;
-       cmd.eofNOffset            = in->endOfFrameNOffset;
-       cmd.solOffset             = in->startOfLineOffset;
-       cmd.eolNOffset            = in->endOfLineNOffset;
-       cmd.hBlankInterval        = in->hbi;
-       cmd.vBlankInterval        = in->vbl;
-       cmd.vBlankIntervalEnable  = in->vblEnable;
-       cmd.sofDummy              = in->startOfFrameDummyLine;
-       cmd.eofDummy              = in->endOfFrameDummyLine;
-       cmd.unicolorBarSelect     = in->unicolorBarSelect;
-       cmd.unicolorBarEnable     = in->unicolorBarEnable;
-       cmd.splitEnable           = in->colorBarsSplitEnable;
-       cmd.pixelPattern          = (uint32_t)in->colorBarsPixelPattern;
-       cmd.rotatePeriod          = in->colorBarsRotatePeriod;
-       cmd.randomSeed            = in->testGenRandomSeed;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_HW_TESTGEN_CFG,
-               (uint32_t *) &cmd, sizeof(cmd));
-}
-
-void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *in)
-{
-       struct VFE_FRAME_SKIP_UpdateCmdType cmd;
-
-       cmd.yPattern    = in->output1Pattern;
-       cmd.cbcrPattern = in->output1Pattern;
-       vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       cmd.yPattern    = in->output2Pattern;
-       cmd.cbcrPattern = in->output2Pattern;
-       vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *in)
-{
-       struct vfe_frame_skip_cfg cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeFrameSkip = *in;
-
-       cmd.output2YPeriod     = in->output2Period;
-       cmd.output2CbCrPeriod  = in->output2Period;
-       cmd.output2YPattern    = in->output2Pattern;
-       cmd.output2CbCrPattern = in->output2Pattern;
-       cmd.output1YPeriod     = in->output1Period;
-       cmd.output1CbCrPeriod  = in->output1Period;
-       cmd.output1YPattern    = in->output1Pattern;
-       cmd.output1CbCrPattern = in->output1Pattern;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *in)
-{
-       struct vfe_output_clamp_cfg cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       cmd.yChanMax  = in->maxCh0;
-       cmd.cbChanMax = in->maxCh1;
-       cmd.crChanMax = in->maxCh2;
-
-       cmd.yChanMin  = in->minCh0;
-       cmd.cbChanMin = in->minCh1;
-       cmd.crChanMin = in->minCh2;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_CLAMP_MAX_CFG, (uint32_t *)&cmd,
-               sizeof(cmd));
-}
-
-void vfe_camif_frame_update(struct vfe_cmds_camif_frame *in)
-{
-       struct vfe_camifframe_update cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       cmd.pixelsPerLine = in->pixelsPerLine;
-       cmd.linesPerFrame = in->linesPerFrame;
-
-       vfe_prog_hw(ctrl->vfebase + CAMIF_FRAME_CONFIG, (uint32_t *)&cmd,
-               sizeof(cmd));
-}
-
-void vfe_color_correction_config(
-       struct vfe_cmd_color_correction_config *in)
-{
-       struct vfe_color_correction_cfg cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       ctrl->vfeModuleEnableLocal.colorCorrectionEnable = in->enable;
-
-       cmd.c0 = in->C0;
-       cmd.c1 = in->C1;
-       cmd.c2 = in->C2;
-       cmd.c3 = in->C3;
-       cmd.c4 = in->C4;
-       cmd.c5 = in->C5;
-       cmd.c6 = in->C6;
-       cmd.c7 = in->C7;
-       cmd.c8 = in->C8;
-
-       cmd.k0 = in->K0;
-       cmd.k1 = in->K1;
-       cmd.k2 = in->K2;
-
-       cmd.coefQFactor = in->coefQFactor;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CORRECT_COEFF_0,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *in)
-{
-struct vfe_demosaic_cfg cmd;
-       struct vfe_demosaic_abf_cfg cmdabf;
-       uint32_t temp;
-
-       memset(&cmd, 0, sizeof(cmd));
-       temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
-
-       cmd = *((struct vfe_demosaic_cfg *)(&temp));
-       cmd.abfEnable       = in->abfUpdate.enable;
-       cmd.forceAbfOn      = in->abfUpdate.forceOn;
-       cmd.abfShift        = in->abfUpdate.shift;
-       vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       cmdabf.lpThreshold  = in->abfUpdate.lpThreshold;
-       cmdabf.ratio        = in->abfUpdate.ratio;
-       cmdabf.minValue     = in->abfUpdate.min;
-       cmdabf.maxValue     = in->abfUpdate.max;
-       vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
-               (uint32_t *)&cmdabf, sizeof(cmdabf));
-}
-
-void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *in)
-{
-       struct vfe_demosaic_cfg cmd;
-       struct vfe_demosaic_bpc_cfg cmdbpc;
-       uint32_t temp;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
-
-       cmd = *((struct vfe_demosaic_cfg *)(&temp));
-       cmd.badPixelCorrEnable = in->bpcUpdate.enable;
-       cmd.fminThreshold      = in->bpcUpdate.fminThreshold;
-       cmd.fmaxThreshold      = in->bpcUpdate.fmaxThreshold;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       cmdbpc.blueDiffThreshold  = in->bpcUpdate.blueDiffThreshold;
-       cmdbpc.redDiffThreshold   = in->bpcUpdate.redDiffThreshold;
-       cmdbpc.greenDiffThreshold = in->bpcUpdate.greenDiffThreshold;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
-               (uint32_t *)&cmdbpc, sizeof(cmdbpc));
-}
-
-void vfe_demosaic_config(struct vfe_cmd_demosaic_config *in)
-{
-       struct vfe_demosaic_cfg cmd;
-       struct vfe_demosaic_bpc_cfg cmd_bpc;
-       struct vfe_demosaic_abf_cfg cmd_abf;
-
-       memset(&cmd, 0, sizeof(cmd));
-       memset(&cmd_bpc, 0, sizeof(cmd_bpc));
-       memset(&cmd_abf, 0, sizeof(cmd_abf));
-
-       ctrl->vfeModuleEnableLocal.demosaicEnable = in->enable;
-
-       cmd.abfEnable          = in->abfConfig.enable;
-       cmd.badPixelCorrEnable = in->bpcConfig.enable;
-       cmd.forceAbfOn         = in->abfConfig.forceOn;
-       cmd.abfShift           = in->abfConfig.shift;
-       cmd.fminThreshold      = in->bpcConfig.fminThreshold;
-       cmd.fmaxThreshold      = in->bpcConfig.fmaxThreshold;
-       cmd.slopeShift         = in->slopeShift;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       cmd_abf.lpThreshold = in->abfConfig.lpThreshold;
-       cmd_abf.ratio       = in->abfConfig.ratio;
-       cmd_abf.minValue    = in->abfConfig.min;
-       cmd_abf.maxValue    = in->abfConfig.max;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
-               (uint32_t *)&cmd_abf, sizeof(cmd_abf));
-
-       cmd_bpc.blueDiffThreshold   = in->bpcConfig.blueDiffThreshold;
-       cmd_bpc.redDiffThreshold    = in->bpcConfig.redDiffThreshold;
-       cmd_bpc.greenDiffThreshold  = in->bpcConfig.greenDiffThreshold;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
-               (uint32_t *)&cmd_bpc, sizeof(cmd_bpc));
-}
-
-void vfe_demux_channel_gain_update(
-       struct vfe_cmd_demux_channel_gain_config *in)
-{
-       struct vfe_demux_cfg cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       cmd.ch0EvenGain  = in->ch0EvenGain;
-       cmd.ch0OddGain   = in->ch0OddGain;
-       cmd.ch1Gain      = in->ch1Gain;
-       cmd.ch2Gain      = in->ch2Gain;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_demux_channel_gain_config(
-       struct vfe_cmd_demux_channel_gain_config *in)
-{
-       struct vfe_demux_cfg cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       cmd.ch0EvenGain = in->ch0EvenGain;
-       cmd.ch0OddGain  = in->ch0OddGain;
-       cmd.ch1Gain     = in->ch1Gain;
-       cmd.ch2Gain     = in->ch2Gain;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_black_level_update(struct vfe_cmd_black_level_config *in)
-{
-       struct vfe_blacklevel_cfg cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
-
-       cmd.evenEvenAdjustment = in->evenEvenAdjustment;
-       cmd.evenOddAdjustment  = in->evenOddAdjustment;
-       cmd.oddEvenAdjustment  = in->oddEvenAdjustment;
-       cmd.oddOddAdjustment   = in->oddOddAdjustment;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_black_level_config(struct vfe_cmd_black_level_config *in)
-{
-       struct vfe_blacklevel_cfg cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
-
-       cmd.evenEvenAdjustment = in->evenEvenAdjustment;
-       cmd.evenOddAdjustment  = in->evenOddAdjustment;
-       cmd.oddEvenAdjustment  = in->oddEvenAdjustment;
-       cmd.oddOddAdjustment   = in->oddOddAdjustment;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_asf_update(struct vfe_cmd_asf_update *in)
-{
-       struct vfe_asf_update cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
-
-       cmd.smoothEnable     = in->smoothFilterEnabled;
-       cmd.sharpMode        = in->sharpMode;
-       cmd.smoothCoeff1     = in->smoothCoefCenter;
-       cmd.smoothCoeff0     = in->smoothCoefSurr;
-       cmd.cropEnable       = in->cropEnable;
-       cmd.sharpThresholdE1 = in->sharpThreshE1;
-       cmd.sharpDegreeK1    = in->sharpK1;
-       cmd.sharpDegreeK2    = in->sharpK2;
-       cmd.normalizeFactor  = in->normalizeFactor;
-       cmd.sharpThresholdE2 = in->sharpThreshE2;
-       cmd.sharpThresholdE3 = in->sharpThreshE3;
-       cmd.sharpThresholdE4 = in->sharpThreshE4;
-       cmd.sharpThresholdE5 = in->sharpThreshE5;
-       cmd.F1Coeff0         = in->filter1Coefficients[0];
-       cmd.F1Coeff1         = in->filter1Coefficients[1];
-       cmd.F1Coeff2         = in->filter1Coefficients[2];
-       cmd.F1Coeff3         = in->filter1Coefficients[3];
-       cmd.F1Coeff4         = in->filter1Coefficients[4];
-       cmd.F1Coeff5         = in->filter1Coefficients[5];
-       cmd.F1Coeff6         = in->filter1Coefficients[6];
-       cmd.F1Coeff7         = in->filter1Coefficients[7];
-       cmd.F1Coeff8         = in->filter1Coefficients[8];
-       cmd.F2Coeff0         = in->filter2Coefficients[0];
-       cmd.F2Coeff1         = in->filter2Coefficients[1];
-       cmd.F2Coeff2         = in->filter2Coefficients[2];
-       cmd.F2Coeff3         = in->filter2Coefficients[3];
-       cmd.F2Coeff4         = in->filter2Coefficients[4];
-       cmd.F2Coeff5         = in->filter2Coefficients[5];
-       cmd.F2Coeff6         = in->filter2Coefficients[6];
-       cmd.F2Coeff7         = in->filter2Coefficients[7];
-       cmd.F2Coeff8         = in->filter2Coefficients[8];
-
-       vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_asf_config(struct vfe_cmd_asf_config *in)
-{
-       struct vfe_asf_update     cmd;
-       struct vfe_asfcrop_cfg cmd2;
-
-       memset(&cmd, 0, sizeof(cmd));
-       memset(&cmd2, 0, sizeof(cmd2));
-
-       ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
-
-       cmd.smoothEnable       = in->smoothFilterEnabled;
-       cmd.sharpMode          = in->sharpMode;
-       cmd.smoothCoeff0       = in->smoothCoefCenter;
-       cmd.smoothCoeff1       = in->smoothCoefSurr;
-       cmd.cropEnable         = in->cropEnable;
-       cmd.sharpThresholdE1   = in->sharpThreshE1;
-       cmd.sharpDegreeK1      = in->sharpK1;
-       cmd.sharpDegreeK2      = in->sharpK2;
-       cmd.normalizeFactor    = in->normalizeFactor;
-       cmd.sharpThresholdE2   = in->sharpThreshE2;
-       cmd.sharpThresholdE3   = in->sharpThreshE3;
-       cmd.sharpThresholdE4   = in->sharpThreshE4;
-       cmd.sharpThresholdE5   = in->sharpThreshE5;
-       cmd.F1Coeff0           = in->filter1Coefficients[0];
-       cmd.F1Coeff1           = in->filter1Coefficients[1];
-       cmd.F1Coeff2           = in->filter1Coefficients[2];
-       cmd.F1Coeff3           = in->filter1Coefficients[3];
-       cmd.F1Coeff4           = in->filter1Coefficients[4];
-       cmd.F1Coeff5           = in->filter1Coefficients[5];
-       cmd.F1Coeff6           = in->filter1Coefficients[6];
-       cmd.F1Coeff7           = in->filter1Coefficients[7];
-       cmd.F1Coeff8           = in->filter1Coefficients[8];
-       cmd.F2Coeff0           = in->filter2Coefficients[0];
-       cmd.F2Coeff1           = in->filter2Coefficients[1];
-       cmd.F2Coeff2           = in->filter2Coefficients[2];
-       cmd.F2Coeff3           = in->filter2Coefficients[3];
-       cmd.F2Coeff4           = in->filter2Coefficients[4];
-       cmd.F2Coeff5           = in->filter2Coefficients[5];
-       cmd.F2Coeff6           = in->filter2Coefficients[6];
-       cmd.F2Coeff7           = in->filter2Coefficients[7];
-       cmd.F2Coeff8           = in->filter2Coefficients[8];
-
-       vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       cmd2.firstLine  = in->cropFirstLine;
-       cmd2.lastLine   = in->cropLastLine;
-       cmd2.firstPixel = in->cropFirstPixel;
-       cmd2.lastPixel  = in->cropLastPixel;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_ASF_CROP_WIDTH_CFG,
-               (uint32_t *)&cmd2, sizeof(cmd2));
-}
-
-void vfe_white_balance_config(struct vfe_cmd_white_balance_config *in)
-{
-       struct vfe_wb_cfg cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.whiteBalanceEnable =
-               in->enable;
-
-       cmd.ch0Gain = in->ch0Gain;
-       cmd.ch1Gain = in->ch1Gain;
-       cmd.ch2Gain = in->ch2Gain;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_WB_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *in)
-{
-       struct vfe_chroma_suppress_cfg cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.chromaSuppressionEnable = in->enable;
-
-       cmd.m1  = in->m1;
-       cmd.m3  = in->m3;
-       cmd.n1  = in->n1;
-       cmd.n3  = in->n3;
-       cmd.mm1 = in->mm1;
-       cmd.nn1 = in->nn1;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUPPRESS_CFG_0,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_roll_off_config(struct vfe_cmd_roll_off_config *in)
-{
-       struct vfe_rolloff_cfg cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.lensRollOffEnable = in->enable;
-
-       cmd.gridWidth   = in->gridWidth;
-       cmd.gridHeight  = in->gridHeight;
-       cmd.yDelta      = in->yDelta;
-       cmd.gridX       = in->gridXIndex;
-       cmd.gridY       = in->gridYIndex;
-       cmd.pixelX      = in->gridPixelXIndex;
-       cmd.pixelY      = in->gridPixelYIndex;
-       cmd.yDeltaAccum = in->yDeltaAccum;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_ROLLOFF_CFG_0,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       vfe_write_lens_roll_off_table(in);
-}
-
-void vfe_chroma_subsample_config(
-       struct vfe_cmd_chroma_subsample_config *in)
-{
-       struct vfe_chromasubsample_cfg cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.chromaSubsampleEnable = in->enable;
-
-       cmd.hCositedPhase       = in->hCositedPhase;
-       cmd.vCositedPhase       = in->vCositedPhase;
-       cmd.hCosited            = in->hCosited;
-       cmd.vCosited            = in->vCosited;
-       cmd.hsubSampleEnable    = in->hsubSampleEnable;
-       cmd.vsubSampleEnable    = in->vsubSampleEnable;
-       cmd.cropEnable          = in->cropEnable;
-       cmd.cropWidthLastPixel  = in->cropWidthLastPixel;
-       cmd.cropWidthFirstPixel = in->cropWidthFirstPixel;
-       cmd.cropHeightLastLine  = in->cropHeightLastLine;
-       cmd.cropHeightFirstLine = in->cropHeightFirstLine;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUBSAMPLE_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *in)
-{
-       struct vfe_chroma_enhance_cfg cmd;
-       struct vfe_color_convert_cfg cmd2;
-
-       memset(&cmd, 0, sizeof(cmd));
-       memset(&cmd2, 0, sizeof(cmd2));
-
-       ctrl->vfeModuleEnableLocal.chromaEnhanEnable = in->enable;
-
-       cmd.ap             = in->ap;
-       cmd.am             = in->am;
-       cmd.bp             = in->bp;
-       cmd.bm             = in->bm;
-       cmd.cp             = in->cp;
-       cmd.cm             = in->cm;
-       cmd.dp             = in->dp;
-       cmd.dm             = in->dm;
-       cmd.kcb            = in->kcb;
-       cmd.kcr            = in->kcr;
-
-       cmd2.v0            = in->RGBtoYConversionV0;
-       cmd2.v1            = in->RGBtoYConversionV1;
-       cmd2.v2            = in->RGBtoYConversionV2;
-       cmd2.ConvertOffset = in->RGBtoYConversionOffset;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_ENHAN_A,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CONVERT_COEFF_0,
-               (uint32_t *)&cmd2, sizeof(cmd2));
-}
-
-void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *in)
-{
-       struct vfe_scaler2_cfg cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.scaler2CbcrEnable = in->enable;
-
-       cmd.hEnable              = in->hconfig.enable;
-       cmd.vEnable              = in->vconfig.enable;
-       cmd.inWidth              = in->hconfig.inputSize;
-       cmd.outWidth             = in->hconfig.outputSize;
-       cmd.horizPhaseMult       = in->hconfig.phaseMultiplicationFactor;
-       cmd.horizInterResolution = in->hconfig.interpolationResolution;
-       cmd.inHeight             = in->vconfig.inputSize;
-       cmd.outHeight            = in->vconfig.outputSize;
-       cmd.vertPhaseMult        = in->vconfig.phaseMultiplicationFactor;
-       cmd.vertInterResolution  = in->vconfig.interpolationResolution;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CBCR_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *in)
-{
-       struct vfe_scaler2_cfg cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.scaler2YEnable = in->enable;
-
-       cmd.hEnable               = in->hconfig.enable;
-       cmd.vEnable               = in->vconfig.enable;
-       cmd.inWidth               = in->hconfig.inputSize;
-       cmd.outWidth              = in->hconfig.outputSize;
-       cmd.horizPhaseMult        = in->hconfig.phaseMultiplicationFactor;
-       cmd.horizInterResolution  = in->hconfig.interpolationResolution;
-       cmd.inHeight              = in->vconfig.inputSize;
-       cmd.outHeight             = in->vconfig.outputSize;
-       cmd.vertPhaseMult         = in->vconfig.phaseMultiplicationFactor;
-       cmd.vertInterResolution   = in->vconfig.interpolationResolution;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_SCALE_Y_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *in)
-{
-       struct vfe_main_scaler_cfg cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.mainScalerEnable = in->enable;
-
-       cmd.hEnable              = in->hconfig.enable;
-       cmd.vEnable              = in->vconfig.enable;
-       cmd.inWidth              = in->hconfig.inputSize;
-       cmd.outWidth             = in->hconfig.outputSize;
-       cmd.horizPhaseMult       = in->hconfig.phaseMultiplicationFactor;
-       cmd.horizInterResolution = in->hconfig.interpolationResolution;
-       cmd.horizMNInit          = in->MNInitH.MNCounterInit;
-       cmd.horizPhaseInit       = in->MNInitH.phaseInit;
-       cmd.inHeight             = in->vconfig.inputSize;
-       cmd.outHeight            = in->vconfig.outputSize;
-       cmd.vertPhaseMult        = in->vconfig.phaseMultiplicationFactor;
-       cmd.vertInterResolution  = in->vconfig.interpolationResolution;
-       cmd.vertMNInit           = in->MNInitV.MNCounterInit;
-       cmd.vertPhaseInit        = in->MNInitV.phaseInit;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_stats_wb_exp_stop(void)
-{
-       ctrl->vfeStatsCmdLocal.axwEnable = FALSE;
-       ctrl->vfeImaskLocal.awbPingpongIrq = FALSE;
-}
-
-void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *in)
-{
-       struct vfe_statsawb_update   cmd;
-       struct vfe_statsawbae_update cmd2;
-
-       memset(&cmd, 0, sizeof(cmd));
-       memset(&cmd2, 0, sizeof(cmd2));
-
-       cmd.m1  = in->awbMCFG[0];
-       cmd.m2  = in->awbMCFG[1];
-       cmd.m3  = in->awbMCFG[2];
-       cmd.m4  = in->awbMCFG[3];
-       cmd.c1  = in->awbCCFG[0];
-       cmd.c2  = in->awbCCFG[1];
-       cmd.c3  = in->awbCCFG[2];
-       cmd.c4  = in->awbCCFG[3];
-       vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       cmd2.aeRegionCfg    = in->wbExpRegions;
-       cmd2.aeSubregionCfg = in->wbExpSubRegion;
-       cmd2.awbYMin        = in->awbYMin;
-       cmd2.awbYMax        = in->awbYMax;
-       vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
-               (uint32_t *)&cmd2, sizeof(cmd2));
-}
-
-void vfe_stats_update_af(struct vfe_cmd_stats_af_update *in)
-{
-       struct vfe_statsaf_update cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       cmd.windowVOffset = in->windowVOffset;
-       cmd.windowHOffset = in->windowHOffset;
-       cmd.windowMode    = in->windowMode;
-       cmd.windowHeight  = in->windowHeight;
-       cmd.windowWidth   = in->windowWidth;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *in)
-{
-       struct vfe_statsawb_update   cmd;
-       struct vfe_statsawbae_update cmd2;
-       struct vfe_statsaxw_hdr_cfg  cmd3;
-
-       ctrl->vfeStatsCmdLocal.axwEnable   =  in->enable;
-       ctrl->vfeImaskLocal.awbPingpongIrq = TRUE;
-
-       memset(&cmd, 0, sizeof(cmd));
-       memset(&cmd2, 0, sizeof(cmd2));
-       memset(&cmd3, 0, sizeof(cmd3));
-
-       cmd.m1  = in->awbMCFG[0];
-       cmd.m2  = in->awbMCFG[1];
-       cmd.m3  = in->awbMCFG[2];
-       cmd.m4  = in->awbMCFG[3];
-       cmd.c1  = in->awbCCFG[0];
-       cmd.c2  = in->awbCCFG[1];
-       cmd.c3  = in->awbCCFG[2];
-       cmd.c4  = in->awbCCFG[3];
-       vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       cmd2.aeRegionCfg     = in->wbExpRegions;
-       cmd2.aeSubregionCfg  = in->wbExpSubRegion;
-       cmd2.awbYMin         = in->awbYMin;
-       cmd2.awbYMax         = in->awbYMax;
-       vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
-               (uint32_t *)&cmd2, sizeof(cmd2));
-
-       cmd3.axwHeader       = in->axwHeader;
-       vfe_prog_hw(ctrl->vfebase + VFE_STATS_AXW_HEADER,
-               (uint32_t *)&cmd3, sizeof(cmd3));
-}
-
-void vfe_stats_start_af(struct vfe_cmd_stats_af_start *in)
-{
-       struct vfe_statsaf_update cmd;
-       struct vfe_statsaf_cfg    cmd2;
-
-       memset(&cmd, 0, sizeof(cmd));
-       memset(&cmd2, 0, sizeof(cmd2));
-
-ctrl->vfeStatsCmdLocal.autoFocusEnable = in->enable;
-ctrl->vfeImaskLocal.afPingpongIrq = TRUE;
-
-       cmd.windowVOffset = in->windowVOffset;
-       cmd.windowHOffset = in->windowHOffset;
-       cmd.windowMode    = in->windowMode;
-       cmd.windowHeight  = in->windowHeight;
-       cmd.windowWidth   = in->windowWidth;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       cmd2.a00       = in->highPassCoef[0];
-       cmd2.a04       = in->highPassCoef[1];
-       cmd2.a20       = in->highPassCoef[2];
-       cmd2.a21       = in->highPassCoef[3];
-       cmd2.a22       = in->highPassCoef[4];
-       cmd2.a23       = in->highPassCoef[5];
-       cmd2.a24       = in->highPassCoef[6];
-       cmd2.fvMax     = in->metricMax;
-       cmd2.fvMetric  = in->metricSelection;
-       cmd2.afHeader  = in->bufferHeader;
-       cmd2.entry00   = in->gridForMultiWindows[0];
-       cmd2.entry01   = in->gridForMultiWindows[1];
-       cmd2.entry02   = in->gridForMultiWindows[2];
-       cmd2.entry03   = in->gridForMultiWindows[3];
-       cmd2.entry10   = in->gridForMultiWindows[4];
-       cmd2.entry11   = in->gridForMultiWindows[5];
-       cmd2.entry12   = in->gridForMultiWindows[6];
-       cmd2.entry13   = in->gridForMultiWindows[7];
-       cmd2.entry20   = in->gridForMultiWindows[8];
-       cmd2.entry21   = in->gridForMultiWindows[9];
-       cmd2.entry22   = in->gridForMultiWindows[10];
-       cmd2.entry23   = in->gridForMultiWindows[11];
-       cmd2.entry30   = in->gridForMultiWindows[12];
-       cmd2.entry31   = in->gridForMultiWindows[13];
-       cmd2.entry32   = in->gridForMultiWindows[14];
-       cmd2.entry33   = in->gridForMultiWindows[15];
-
-       vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_GRID_0,
-               (uint32_t *)&cmd2, sizeof(cmd2));
-}
-
-void vfe_stats_setting(struct vfe_cmd_stats_setting *in)
-{
-       struct vfe_statsframe cmd1;
-       struct vfe_busstats_wrprio cmd2;
-
-       memset(&cmd1, 0, sizeof(cmd1));
-       memset(&cmd2, 0, sizeof(cmd2));
-
-       ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0];
-       ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1];
-       ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2];
-
-       ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0];
-       ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1];
-       ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2];
-
-       cmd1.lastPixel = in->frameHDimension;
-       cmd1.lastLine  = in->frameVDimension;
-       vfe_prog_hw(ctrl->vfebase + VFE_STATS_FRAME_SIZE,
-               (uint32_t *)&cmd1, sizeof(cmd1));
-
-       cmd2.afBusPriority    = in->afBusPriority;
-       cmd2.awbBusPriority   = in->awbBusPriority;
-       cmd2.histBusPriority  = in->histBusPriority;
-       cmd2.afBusPriorityEn  = in->afBusPrioritySelection;
-       cmd2.awbBusPriorityEn = in->awbBusPrioritySelection;
-       cmd2.histBusPriorityEn = in->histBusPrioritySelection;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_BUS_STATS_WR_PRIORITY,
-               (uint32_t *)&cmd2, sizeof(cmd2));
-
-       /* Program the bus ping pong address for statistics modules. */
-       writel(in->afBuffer[0], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
-       writel(in->afBuffer[1], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
-       writel(in->awbBuffer[0],
-               ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
-       writel(in->awbBuffer[1],
-               ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
-       writel(in->histBuffer[0],
-               ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
-       writel(in->histBuffer[1],
-               ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
-}
-
-void vfe_axi_input_config(struct vfe_cmd_axi_input_config *in)
-{
-       struct VFE_AxiInputCmdType cmd;
-       uint32_t xSizeWord, axiRdUnpackPattern;
-       uint8_t  axiInputPpw;
-       uint32_t busPingpongRdIrqEnable;
-
-       ctrl->vfeImaskLocal.rdPingpongIrq = TRUE;
-
-       switch (in->pixelSize) {
-       case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
-               ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_10BIT;
-               break;
-
-       case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
-               ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_12BIT;
-               break;
-
-       case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
-       default:
-               ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_8BIT;
-               break;
-       }
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       switch (in->pixelSize) {
-       case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
-               axiInputPpw = 6;
-               axiRdUnpackPattern = 0xD43210;
-               break;
-
-       case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
-               axiInputPpw = 5;
-               axiRdUnpackPattern = 0xC3210;
-               break;
-
-       case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
-       default:
-               axiInputPpw = 8;
-               axiRdUnpackPattern = 0xF6543210;
-               break;
-       }
-
-       xSizeWord =
-               ((((in->xOffset % axiInputPpw) + in->xSize) +
-                       (axiInputPpw-1)) / axiInputPpw) - 1;
-
-       cmd.stripeStartAddr0  = in->fragAddr[0];
-       cmd.stripeStartAddr1  = in->fragAddr[1];
-       cmd.stripeStartAddr2  = in->fragAddr[2];
-       cmd.stripeStartAddr3  = in->fragAddr[3];
-       cmd.ySize             = in->ySize;
-       cmd.yOffsetDelta      = 0;
-       cmd.xSizeWord         = xSizeWord;
-       cmd.burstLength       = 1;
-       cmd.NumOfRows         = in->numOfRows;
-       cmd.RowIncrement      =
-               (in->rowIncrement + (axiInputPpw-1))/axiInputPpw;
-       cmd.mainUnpackHeight  = in->ySize;
-       cmd.mainUnpackWidth   = in->xSize - 1;
-       cmd.mainUnpackHbiSel  = (uint32_t)in->unpackHbi;
-       cmd.mainUnpackPhase   = in->unpackPhase;
-       cmd.unpackPattern     = axiRdUnpackPattern;
-       cmd.padLeft           = in->padRepeatCountLeft;
-       cmd.padRight          = in->padRepeatCountRight;
-       cmd.padTop            = in->padRepeatCountTop;
-       cmd.padBottom         = in->padRepeatCountBottom;
-       cmd.leftUnpackPattern0   = in->padLeftComponentSelectCycle0;
-       cmd.leftUnpackPattern1   = in->padLeftComponentSelectCycle1;
-       cmd.leftUnpackPattern2   = in->padLeftComponentSelectCycle2;
-       cmd.leftUnpackPattern3   = in->padLeftComponentSelectCycle3;
-       cmd.leftUnpackStop0      = in->padLeftStopCycle0;
-       cmd.leftUnpackStop1      = in->padLeftStopCycle1;
-       cmd.leftUnpackStop2      = in->padLeftStopCycle2;
-       cmd.leftUnpackStop3      = in->padLeftStopCycle3;
-       cmd.rightUnpackPattern0  = in->padRightComponentSelectCycle0;
-       cmd.rightUnpackPattern1  = in->padRightComponentSelectCycle1;
-       cmd.rightUnpackPattern2  = in->padRightComponentSelectCycle2;
-       cmd.rightUnpackPattern3  = in->padRightComponentSelectCycle3;
-       cmd.rightUnpackStop0     = in->padRightStopCycle0;
-       cmd.rightUnpackStop1     = in->padRightStopCycle1;
-       cmd.rightUnpackStop2     = in->padRightStopCycle2;
-       cmd.rightUnpackStop3     = in->padRightStopCycle3;
-       cmd.topUnapckPattern     = in->padTopLineCount;
-       cmd.bottomUnapckPattern  = in->padBottomLineCount;
-
-       /*  program vfe_bus_cfg */
-       vfe_prog_hw(ctrl->vfebase + VFE_BUS_STRIPE_RD_ADDR_0,
-               (uint32_t *)&cmd, sizeof(cmd));
-
-       /* hacking code, put it to default value */
-       busPingpongRdIrqEnable = 0xf;
-
-       writel(busPingpongRdIrqEnable,
-               ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN);
-}
-
-void vfe_stats_config(struct vfe_cmd_stats_setting *in)
-{
-       ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0];
-       ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1];
-       ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2];
-
-       ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0];
-       ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1];
-       ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2];
-
-       vfe_stats_setting(in);
-}
-
-void vfe_axi_output_config(
-       struct vfe_cmd_axi_output_config *in)
-{
-       /* local variable  */
-       uint32_t *pcircle;
-       uint32_t *pdest;
-       uint32_t *psrc;
-       uint8_t  i;
-       uint8_t  fcnt;
-       uint16_t axioutpw = 8;
-
-       /* parameters check, condition and usage mode check */
-       ctrl->encPath.fragCount = in->output2.fragmentCount;
-       if (ctrl->encPath.fragCount > 1)
-               ctrl->encPath.multiFrag = TRUE;
-
-       ctrl->viewPath.fragCount = in->output1.fragmentCount;
-       if (ctrl->viewPath.fragCount > 1)
-               ctrl->viewPath.multiFrag = TRUE;
-
-       /* VFE_BUS_CFG.  raw data size */
-       ctrl->vfeBusConfigLocal.rawPixelDataSize = in->outputDataSize;
-
-       switch (in->outputDataSize) {
-       case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
-               axioutpw = 8;
-               break;
-
-       case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
-               axioutpw = 6;
-               break;
-
-       case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
-               axioutpw = 5;
-               break;
-       }
-
-       ctrl->axiOutputMode = in->outputMode;
-
-       CDBG("axiOutputMode = %d\n", ctrl->axiOutputMode);
-
-       switch (ctrl->axiOutputMode) {
-       case VFE_AXI_OUTPUT_MODE_Output1: {
-               ctrl->vfeCamifConfigLocal.camif2BusEnable   = FALSE;
-               ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-               ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-                       VFE_RAW_OUTPUT_DISABLED;
-
-               ctrl->encPath.pathEnabled                   = FALSE;
-               ctrl->vfeImaskLocal.encIrq                  = FALSE;
-               ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-                       VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-               ctrl->vfeBusConfigLocal.encYWrPathEn          = FALSE;
-               ctrl->vfeBusConfigLocal.encCbcrWrPathEn       = FALSE;
-               ctrl->viewPath.pathEnabled                    = TRUE;
-               ctrl->vfeImaskLocal.viewIrq                   = TRUE;
-               ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-                       VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-               ctrl->vfeBusConfigLocal.viewYWrPathEn    = TRUE;
-               ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-       } /* VFE_AXI_OUTPUT_MODE_Output1 */
-               break;
-
-       case VFE_AXI_OUTPUT_MODE_Output2: {
-               ctrl->vfeCamifConfigLocal.camif2BusEnable   = FALSE;
-               ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-               ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-                       VFE_RAW_OUTPUT_DISABLED;
-
-               ctrl->encPath.pathEnabled                   = TRUE;
-               ctrl->vfeImaskLocal.encIrq                  = TRUE;
-               ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-                       VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-               ctrl->vfeBusConfigLocal.encYWrPathEn        = TRUE;
-               ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
-
-               ctrl->viewPath.pathEnabled                   = FALSE;
-               ctrl->vfeImaskLocal.viewIrq                  = FALSE;
-               ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-                       VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-               ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
-               ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = FALSE;
-
-               if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-       } /* VFE_AXI_OUTPUT_MODE_Output2 */
-                       break;
-
-       case VFE_AXI_OUTPUT_MODE_Output1AndOutput2: {
-               ctrl->vfeCamifConfigLocal.camif2BusEnable    = FALSE;
-               ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-               ctrl->vfeBusConfigLocal.rawWritePathSelect   =
-                       VFE_RAW_OUTPUT_DISABLED;
-
-               ctrl->encPath.pathEnabled                    = TRUE;
-               ctrl->vfeImaskLocal.encIrq                   = TRUE;
-               ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-                       VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-               ctrl->vfeBusConfigLocal.encYWrPathEn         = TRUE;
-               ctrl->vfeBusConfigLocal.encCbcrWrPathEn      = TRUE;
-               ctrl->viewPath.pathEnabled                   = TRUE;
-               ctrl->vfeImaskLocal.viewIrq                  = TRUE;
-               ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-                       VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-               ctrl->vfeBusConfigLocal.viewYWrPathEn        = TRUE;
-               ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-       } /* VFE_AXI_OUTPUT_MODE_Output1AndOutput2 */
-               break;
-
-       case VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2: {
-               /* For raw snapshot, we need both ping and pong buffer
-                * initialized to the same address. Otherwise, if we
-                * leave the pong buffer to NULL, there will be axi_error.
-                * Note that ideally we should deal with this at upper layer,
-                * which is in msm_vfe8x.c */
-               if (!in->output2.outputCbcr.outFragments[1][0]) {
-                       in->output2.outputCbcr.outFragments[1][0] =
-                               in->output2.outputCbcr.outFragments[0][0];
-               }
-
-               ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
-               ctrl->vfeCamifConfigLocal.camif2OutputEnable = FALSE;
-               ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-                       VFE_RAW_OUTPUT_ENC_CBCR_PATH;
-
-               ctrl->encPath.pathEnabled                   = TRUE;
-               ctrl->vfeImaskLocal.encIrq                  = TRUE;
-               ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-                       VFE_COMP_IRQ_CBCR_ONLY;
-
-               ctrl->vfeBusConfigLocal.encYWrPathEn        = FALSE;
-               ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
-
-               ctrl->viewPath.pathEnabled                   = FALSE;
-               ctrl->vfeImaskLocal.viewIrq                  = FALSE;
-               ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-                       VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-               ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
-               ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = FALSE;
-
-               if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-       } /* VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2 */
-               break;
-
-       case VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1: {
-               ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
-               ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-               ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-                       VFE_RAW_OUTPUT_VIEW_CBCR_PATH;
-
-               ctrl->encPath.pathEnabled                   = TRUE;
-               ctrl->vfeImaskLocal.encIrq                  = TRUE;
-               ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-                       VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-               ctrl->vfeBusConfigLocal.encYWrPathEn        = TRUE;
-               ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
-
-               ctrl->viewPath.pathEnabled                   = TRUE;
-               ctrl->vfeImaskLocal.viewIrq                  = TRUE;
-               ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-                       VFE_COMP_IRQ_CBCR_ONLY;
-
-               ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
-               ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
-       } /* VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1 */
-               break;
-
-       case VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2: {
-               ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
-               ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
-               ctrl->vfeBusConfigLocal.rawWritePathSelect  =
-                       VFE_RAW_OUTPUT_ENC_CBCR_PATH;
-
-               ctrl->encPath.pathEnabled                     = TRUE;
-               ctrl->vfeImaskLocal.encIrq                    = TRUE;
-               ctrl->vfeIrqCompositeMaskLocal.encIrqComMask  =
-                       VFE_COMP_IRQ_CBCR_ONLY;
-
-               ctrl->vfeBusConfigLocal.encYWrPathEn          = FALSE;
-               ctrl->vfeBusConfigLocal.encCbcrWrPathEn       = TRUE;
-
-               ctrl->viewPath.pathEnabled                    = TRUE;
-               ctrl->vfeImaskLocal.viewIrq                   = TRUE;
-
-               ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-                       VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-               ctrl->vfeBusConfigLocal.viewYWrPathEn         = TRUE;
-               ctrl->vfeBusConfigLocal.viewCbcrWrPathEn      = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encYPingpongIrq       = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
-                               ctrl->encPath.multiFrag)
-                       ctrl->vfeImaskLocal.encCbcrPingpongIrq    = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewYPingpongIrq      = TRUE;
-
-               if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
-                               ctrl->viewPath.multiFrag)
-                       ctrl->vfeImaskLocal.viewCbcrPingpongIrq   = TRUE;
-       } /* VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2 */
-               break;
-
-       case VFE_AXI_LAST_OUTPUT_MODE_ENUM:
-               break;
-       } /* switch */
-
-       /* Save the addresses for each path. */
-       /* output2 path */
-       fcnt = ctrl->encPath.fragCount;
-
-       pcircle = ctrl->encPath.yPath.addressBuffer;
-       pdest = ctrl->encPath.nextFrameAddrBuf;
-
-       psrc = &(in->output2.outputY.outFragments[0][0]);
-       for (i = 0; i < fcnt; i++)
-               *pcircle++ = *psrc++;
-
-       psrc = &(in->output2.outputY.outFragments[1][0]);
-       for (i = 0; i < fcnt; i++)
-               *pcircle++ = *psrc++;
-
-       psrc = &(in->output2.outputY.outFragments[2][0]);
-       for (i = 0; i < fcnt; i++)
-               *pdest++ = *psrc++;
-
-       pcircle = ctrl->encPath.cbcrPath.addressBuffer;
-
-       psrc = &(in->output2.outputCbcr.outFragments[0][0]);
-       for (i = 0; i < fcnt; i++)
-               *pcircle++ = *psrc++;
-
-       psrc = &(in->output2.outputCbcr.outFragments[1][0]);
-       for (i = 0; i < fcnt; i++)
-               *pcircle++ = *psrc++;
-
-       psrc = &(in->output2.outputCbcr.outFragments[2][0]);
-       for (i = 0; i < fcnt; i++)
-               *pdest++ = *psrc++;
-
-       vfe_set_bus_pipo_addr(&ctrl->viewPath, &ctrl->encPath);
-
-       ctrl->encPath.ackPending = FALSE;
-       ctrl->encPath.currentFrame = ping;
-       ctrl->encPath.whichOutputPath = 1;
-       ctrl->encPath.yPath.fragIndex = 2;
-       ctrl->encPath.cbcrPath.fragIndex = 2;
-       ctrl->encPath.yPath.hwCurrentFlag = ping;
-       ctrl->encPath.cbcrPath.hwCurrentFlag = ping;
-
-       /* output1 path */
-       pcircle = ctrl->viewPath.yPath.addressBuffer;
-       pdest = ctrl->viewPath.nextFrameAddrBuf;
-       fcnt = ctrl->viewPath.fragCount;
-
-       psrc = &(in->output1.outputY.outFragments[0][0]);
-       for (i = 0; i < fcnt; i++)
-               *pcircle++ = *psrc++;
-
-       psrc = &(in->output1.outputY.outFragments[1][0]);
-       for (i = 0; i < fcnt; i++)
-               *pcircle++ = *psrc++;
-
-       psrc = &(in->output1.outputY.outFragments[2][0]);
-       for (i = 0; i < fcnt; i++)
-               *pdest++ = *psrc++;
-
-       pcircle = ctrl->viewPath.cbcrPath.addressBuffer;
-
-       psrc = &(in->output1.outputCbcr.outFragments[0][0]);
-       for (i = 0; i < fcnt; i++)
-               *pcircle++ = *psrc++;
-
-       psrc = &(in->output1.outputCbcr.outFragments[1][0]);
-       for (i = 0; i < fcnt; i++)
-               *pcircle++ = *psrc++;
-
-       psrc = &(in->output1.outputCbcr.outFragments[2][0]);
-       for (i = 0; i < fcnt; i++)
-               *pdest++ = *psrc++;
-
-       ctrl->viewPath.ackPending = FALSE;
-       ctrl->viewPath.currentFrame = ping;
-       ctrl->viewPath.whichOutputPath = 0;
-       ctrl->viewPath.yPath.fragIndex = 2;
-       ctrl->viewPath.cbcrPath.fragIndex = 2;
-       ctrl->viewPath.yPath.hwCurrentFlag = ping;
-       ctrl->viewPath.cbcrPath.hwCurrentFlag = ping;
-
-       /* call to program the registers. */
-       vfe_axi_output(in, &ctrl->viewPath, &ctrl->encPath, axioutpw);
-}
-
-void vfe_camif_config(struct vfe_cmd_camif_config *in)
-{
-       struct vfe_camifcfg cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       CDBG("camif.frame pixelsPerLine = %d\n", in->frame.pixelsPerLine);
-       CDBG("camif.frame linesPerFrame = %d\n", in->frame.linesPerFrame);
-       CDBG("camif.window firstpixel = %d\n", in->window.firstpixel);
-       CDBG("camif.window lastpixel = %d\n",  in->window.lastpixel);
-       CDBG("camif.window firstline = %d\n",  in->window.firstline);
-       CDBG("camif.window lastline = %d\n",   in->window.lastline);
-
-       /* determine if epoch interrupt needs to be enabled.  */
-       if ((in->epoch1.enable == TRUE) &&
-                       (in->epoch1.lineindex <=
-                        in->frame.linesPerFrame))
-               ctrl->vfeImaskLocal.camifEpoch1Irq = 1;
-
-       if ((in->epoch2.enable == TRUE) &&
-                       (in->epoch2.lineindex <=
-                        in->frame.linesPerFrame)) {
-               ctrl->vfeImaskLocal.camifEpoch2Irq = 1;
-       }
-
-       /*  save the content to program CAMIF_CONFIG separately. */
-       ctrl->vfeCamifConfigLocal.camifCfgFromCmd = in->camifConfig;
-
-       /* EFS_Config */
-       cmd.efsEndOfLine     = in->EFS.efsendofline;
-       cmd.efsStartOfLine   = in->EFS.efsstartofline;
-       cmd.efsEndOfFrame    = in->EFS.efsendofframe;
-       cmd.efsStartOfFrame  = in->EFS.efsstartofframe;
-
-       /* Frame Config */
-       cmd.frameConfigPixelsPerLine = in->frame.pixelsPerLine;
-       cmd.frameConfigLinesPerFrame = in->frame.linesPerFrame;
-
-       /* Window Width Config */
-       cmd.windowWidthCfgLastPixel  = in->window.lastpixel;
-       cmd.windowWidthCfgFirstPixel = in->window.firstpixel;
-
-       /* Window Height Config */
-       cmd.windowHeightCfglastLine   = in->window.lastline;
-       cmd.windowHeightCfgfirstLine  = in->window.firstline;
-
-       /* Subsample 1 Config */
-       cmd.subsample1CfgPixelSkip = in->subsample.pixelskipmask;
-       cmd.subsample1CfgLineSkip  = in->subsample.lineskipmask;
-
-       /* Subsample 2 Config */
-       cmd.subsample2CfgFrameSkip      = in->subsample.frameskip;
-       cmd.subsample2CfgFrameSkipMode  = in->subsample.frameskipmode;
-       cmd.subsample2CfgPixelSkipWrap  = in->subsample.pixelskipwrap;
-
-       /* Epoch Interrupt */
-       cmd.epoch1Line = in->epoch1.lineindex;
-       cmd.epoch2Line = in->epoch2.lineindex;
-
-       vfe_prog_hw(ctrl->vfebase + CAMIF_EFS_CONFIG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *in)
-{
-       struct vfe_fov_crop_cfg cmd;
-       memset(&cmd, 0, sizeof(cmd));
-
-       ctrl->vfeModuleEnableLocal.cropEnable = in->enable;
-
-       /* FOV Corp, Part 1 */
-       cmd.lastPixel  = in->lastPixel;
-       cmd.firstPixel = in->firstPixel;
-
-       /* FOV Corp, Part 2 */
-       cmd.lastLine   = in->lastLine;
-       cmd.firstLine  = in->firstLine;
-
-       vfe_prog_hw(ctrl->vfebase + VFE_CROP_WIDTH_CFG,
-               (uint32_t *)&cmd, sizeof(cmd));
-}
-
-void vfe_get_hw_version(struct vfe_cmd_hw_version *out)
-{
-       uint32_t vfeHwVersionPacked;
-       struct vfe_hw_ver ver;
-
-       vfeHwVersionPacked = readl(ctrl->vfebase + VFE_HW_VERSION);
-
-       ver = *((struct vfe_hw_ver *)&vfeHwVersionPacked);
-
-       out->coreVersion  = ver.coreVersion;
-       out->minorVersion = ver.minorVersion;
-       out->majorVersion = ver.majorVersion;
-}
-
-static void vfe_reset_internal_variables(void)
-{
-       unsigned long flags;
-
-       /* local variables to program the hardware. */
-       ctrl->vfeImaskPacked = 0;
-       ctrl->vfeImaskCompositePacked = 0;
-
-       /* FALSE = disable,  1 = enable. */
-       memset(&ctrl->vfeModuleEnableLocal, 0,
-               sizeof(ctrl->vfeModuleEnableLocal));
-
-       /* 0 = disable, 1 = enable */
-       memset(&ctrl->vfeCamifConfigLocal, 0,
-               sizeof(ctrl->vfeCamifConfigLocal));
-       /* 0 = disable, 1 = enable */
-       memset(&ctrl->vfeImaskLocal, 0, sizeof(ctrl->vfeImaskLocal));
-       memset(&ctrl->vfeStatsCmdLocal, 0, sizeof(ctrl->vfeStatsCmdLocal));
-       memset(&ctrl->vfeBusConfigLocal, 0, sizeof(ctrl->vfeBusConfigLocal));
-       memset(&ctrl->vfeBusPmConfigLocal, 0,
-               sizeof(ctrl->vfeBusPmConfigLocal));
-       memset(&ctrl->vfeBusCmdLocal, 0, sizeof(ctrl->vfeBusCmdLocal));
-       memset(&ctrl->vfeInterruptNameLocal, 0,
-               sizeof(ctrl->vfeInterruptNameLocal));
-       memset(&ctrl->vfeDroppedFrameCounts, 0,
-               sizeof(ctrl->vfeDroppedFrameCounts));
-       memset(&ctrl->vfeIrqThreadMsgLocal, 0,
-               sizeof(ctrl->vfeIrqThreadMsgLocal));
-
-       /* state control variables */
-       ctrl->vfeStartAckPendingFlag = FALSE;
-       ctrl->vfeStopAckPending = FALSE;
-       ctrl->vfeIrqCompositeMaskLocal.ceDoneSel = 0;
-       ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
-               VFE_COMP_IRQ_BOTH_Y_CBCR;
-       ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
-               VFE_COMP_IRQ_BOTH_Y_CBCR;
-
-       spin_lock_irqsave(&ctrl->state_lock, flags);
-       ctrl->vstate = VFE_STATE_IDLE;
-       spin_unlock_irqrestore(&ctrl->state_lock, flags);
-
-       ctrl->axiOutputMode = VFE_AXI_LAST_OUTPUT_MODE_ENUM;
-       /* 0 for continuous mode, 1 for snapshot mode */
-       ctrl->vfeOperationMode = VFE_START_OPERATION_MODE_CONTINUOUS;
-       ctrl->vfeSnapShotCount = 0;
-       ctrl->vfeStatsPingPongReloadFlag = FALSE;
-       /* this is unsigned 32 bit integer. */
-       ctrl->vfeFrameId = 0;
-       ctrl->vfeFrameSkip.output1Pattern = 0xffffffff;
-       ctrl->vfeFrameSkip.output1Period  = 31;
-       ctrl->vfeFrameSkip.output2Pattern = 0xffffffff;
-       ctrl->vfeFrameSkip.output2Period  = 31;
-       ctrl->vfeFrameSkipPattern = 0xffffffff;
-       ctrl->vfeFrameSkipCount   = 0;
-       ctrl->vfeFrameSkipPeriod  = 31;
-
-       memset((void *)&ctrl->encPath, 0, sizeof(ctrl->encPath));
-       memset((void *)&ctrl->viewPath, 0, sizeof(ctrl->viewPath));
-
-       ctrl->encPath.whichOutputPath  = 1;
-       ctrl->encPath.cbcrStatusBit    = 5;
-       ctrl->viewPath.whichOutputPath = 0;
-       ctrl->viewPath.cbcrStatusBit   = 7;
-
-       ctrl->vfeTestGenStartFlag = FALSE;
-
-       /* default to bank 0. */
-       ctrl->vfeLaBankSel = 0;
-
-       /* default to bank 0 for all channels. */
-       memset(&ctrl->vfeGammaLutSel, 0, sizeof(ctrl->vfeGammaLutSel));
-
-       /* Stats control variables. */
-       memset(&ctrl->afStatsControl, 0, sizeof(ctrl->afStatsControl));
-       memset(&ctrl->awbStatsControl, 0, sizeof(ctrl->awbStatsControl));
-       vfe_set_stats_pingpong_address(&ctrl->afStatsControl,
-               &ctrl->awbStatsControl);
-}
-
-void vfe_reset(void)
-{
-       vfe_reset_internal_variables();
-
-       ctrl->vfeImaskLocal.resetAckIrq = TRUE;
-       ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
-
-       /* disable all interrupts. */
-       writel(VFE_DISABLE_ALL_IRQS,
-               ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
-
-       /* clear all pending interrupts*/
-       writel(VFE_CLEAR_ALL_IRQS,
-               ctrl->vfebase + VFE_IRQ_CLEAR);
-
-       /* enable reset_ack interrupt.  */
-       writel(ctrl->vfeImaskPacked,
-               ctrl->vfebase + VFE_IRQ_MASK);
-
-       writel(VFE_RESET_UPON_RESET_CMD,
-               ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
-}
diff --git a/drivers/staging/dream/camera/msm_vfe8x_proc.h b/drivers/staging/dream/camera/msm_vfe8x_proc.h
deleted file mode 100644 (file)
index 9182856..0000000
+++ /dev/null
@@ -1,1549 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#ifndef __MSM_VFE8X_REG_H__
-#define __MSM_VFE8X_REG_H__
-
-#include <mach/msm_iomap.h>
-#include <mach/camera.h>
-#include "msm_vfe8x.h"
-
-/* at start of camif,  bit 1:0 = 0x01:enable
- * image data capture at frame boundary. */
-#define CAMIF_COMMAND_START  0x00000005
-
-/* bit 2= 0x1:clear the CAMIF_STATUS register
- * value. */
-#define CAMIF_COMMAND_CLEAR  0x00000004
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x10:
- * disable image data capture immediately. */
-#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
-
-/* at stop of vfe pipeline, for now it is assumed
- * that camif will stop at any time. Bit 1:0 = 0x00:
- * disable image data capture at frame boundary */
-#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
-
-/* to halt axi bridge */
-#define AXI_HALT  0x00000001
-
-/* clear the halt bit. */
-#define AXI_HALT_CLEAR  0x00000000
-
-/* reset the pipeline when stop command is issued.
- * (without reset the register.) bit 26-31 = 0,
- * domain reset, bit 0-9 = 1 for module reset, except
- * register module. */
-#define VFE_RESET_UPON_STOP_CMD  0x000003ef
-
-/* reset the pipeline when reset command.
- * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
-#define VFE_RESET_UPON_RESET_CMD  0x000003ff
-
-/* bit 5 is for axi status idle or busy.
- * 1 =  halted,  0 = busy */
-#define AXI_STATUS_BUSY_MASK 0x00000020
-
-/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
- * for frame done interrupt */
-#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
-
-/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_CBCR_ONLY 2
-
-/* bit 0 = 1, only y irq triggers frame done interrupt */
-#define VFE_COMP_IRQ_Y_ONLY 1
-
-/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
-#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
-#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
-
-/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
-#define VFE_TEST_GEN_GO   0x00000001
-#define VFE_TEST_GEN_STOP 0x00000002
-
-/* the chroma is assumed to be interpolated between
- * the luma samples.  JPEG 4:2:2 */
-#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
-
-/* constants for irq registers */
-#define VFE_DISABLE_ALL_IRQS 0
-/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
-#define VFE_CLEAR_ALL_IRQS   0xffffffff
-/* imask for while waiting for stop ack,  driver has already
- * requested stop, waiting for reset irq,
- * bit 29,28,27,26 for async timer, bit 9 for reset */
-#define VFE_IMASK_WHILE_STOPPING  0x3c000200
-
-/* when normal case, don't want to block error status.
- * bit 0,6,20,21,22,30,31 */
-#define VFE_IMASK_ERROR_ONLY             0xC0700041
-#define VFE_REG_UPDATE_TRIGGER           1
-#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
-#define VFE_DMI_CFG_DEFAULT              0x00000100
-#define LENS_ROLL_OFF_DELTA_TABLE_OFFSET 32
-#define VFE_AF_PINGPONG_STATUS_BIT       0x100
-#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
-
-/* VFE I/O registers */
-enum {
-       VFE_HW_VERSION                    = 0x00000000,
-       VFE_GLOBAL_RESET_CMD              = 0x00000004,
-       VFE_MODULE_RESET                  = 0x00000008,
-       VFE_CGC_OVERRIDE                  = 0x0000000C,
-       VFE_MODULE_CFG                    = 0x00000010,
-       VFE_CFG                           = 0x00000014,
-       VFE_IRQ_MASK                      = 0x00000018,
-       VFE_IRQ_CLEAR                     = 0x0000001C,
-VFE_IRQ_STATUS                    = 0x00000020,
-VFE_IRQ_COMPOSITE_MASK            = 0x00000024,
-VFE_BUS_CMD                       = 0x00000028,
-VFE_BUS_CFG                       = 0x0000002C,
-VFE_BUS_ENC_Y_WR_PING_ADDR        = 0x00000030,
-VFE_BUS_ENC_Y_WR_PONG_ADDR        = 0x00000034,
-VFE_BUS_ENC_Y_WR_IMAGE_SIZE       = 0x00000038,
-VFE_BUS_ENC_Y_WR_BUFFER_CFG       = 0x0000003C,
-VFE_BUS_ENC_CBCR_WR_PING_ADDR     = 0x00000040,
-VFE_BUS_ENC_CBCR_WR_PONG_ADDR     = 0x00000044,
-VFE_BUS_ENC_CBCR_WR_IMAGE_SIZE    = 0x00000048,
-VFE_BUS_ENC_CBCR_WR_BUFFER_CFG    = 0x0000004C,
-VFE_BUS_VIEW_Y_WR_PING_ADDR       = 0x00000050,
-VFE_BUS_VIEW_Y_WR_PONG_ADDR       = 0x00000054,
-VFE_BUS_VIEW_Y_WR_IMAGE_SIZE      = 0x00000058,
-VFE_BUS_VIEW_Y_WR_BUFFER_CFG      = 0x0000005C,
-VFE_BUS_VIEW_CBCR_WR_PING_ADDR    = 0x00000060,
-VFE_BUS_VIEW_CBCR_WR_PONG_ADDR    = 0x00000064,
-VFE_BUS_VIEW_CBCR_WR_IMAGE_SIZE   = 0x00000068,
-VFE_BUS_VIEW_CBCR_WR_BUFFER_CFG   = 0x0000006C,
-VFE_BUS_STATS_AF_WR_PING_ADDR     = 0x00000070,
-VFE_BUS_STATS_AF_WR_PONG_ADDR     = 0x00000074,
-VFE_BUS_STATS_AWB_WR_PING_ADDR    = 0x00000078,
-VFE_BUS_STATS_AWB_WR_PONG_ADDR    = 0x0000007C,
-VFE_BUS_STATS_HIST_WR_PING_ADDR   = 0x00000080,
-VFE_BUS_STATS_HIST_WR_PONG_ADDR   = 0x00000084,
-VFE_BUS_STATS_WR_PRIORITY         = 0x00000088,
-VFE_BUS_STRIPE_RD_ADDR_0          = 0x0000008C,
-VFE_BUS_STRIPE_RD_ADDR_1          = 0x00000090,
-VFE_BUS_STRIPE_RD_ADDR_2          = 0x00000094,
-VFE_BUS_STRIPE_RD_ADDR_3          = 0x00000098,
-VFE_BUS_STRIPE_RD_VSIZE           = 0x0000009C,
-VFE_BUS_STRIPE_RD_HSIZE           = 0x000000A0,
-VFE_BUS_STRIPE_RD_BUFFER_CFG      = 0x000000A4,
-VFE_BUS_STRIPE_RD_UNPACK_CFG      = 0x000000A8,
-VFE_BUS_STRIPE_RD_UNPACK          = 0x000000AC,
-VFE_BUS_STRIPE_RD_PAD_SIZE        = 0x000000B0,
-VFE_BUS_STRIPE_RD_PAD_L_UNPACK    = 0x000000B4,
-VFE_BUS_STRIPE_RD_PAD_R_UNPACK    = 0x000000B8,
-VFE_BUS_STRIPE_RD_PAD_TB_UNPACK   = 0x000000BC,
-VFE_BUS_PINGPONG_IRQ_EN           = 0x000000C0,
-VFE_BUS_PINGPONG_STATUS           = 0x000000C4,
-VFE_BUS_PM_CMD                    = 0x000000C8,
-VFE_BUS_PM_CFG                    = 0x000000CC,
-VFE_BUS_ENC_Y_WR_PM_STATS_0       = 0x000000D0,
-VFE_BUS_ENC_Y_WR_PM_STATS_1       = 0x000000D4,
-VFE_BUS_ENC_CBCR_WR_PM_STATS_0    = 0x000000D8,
-VFE_BUS_ENC_CBCR_WR_PM_STATS_1    = 0x000000DC,
-VFE_BUS_VIEW_Y_WR_PM_STATS_0      = 0x000000E0,
-VFE_BUS_VIEW_Y_WR_PM_STATS_1      = 0x000000E4,
-VFE_BUS_VIEW_CBCR_WR_PM_STATS_0   = 0x000000E8,
-VFE_BUS_VIEW_CBCR_WR_PM_STATS_1   = 0x000000EC,
-VFE_BUS_MISR_CFG                  = 0x000000F4,
-VFE_BUS_MISR_MAST_CFG_0           = 0x000000F8,
-VFE_BUS_MISR_MAST_CFG_1           = 0x000000FC,
-VFE_BUS_MISR_RD_VAL               = 0x00000100,
-VFE_AXI_CMD                       = 0x00000104,
-VFE_AXI_CFG                       = 0x00000108,
-VFE_AXI_STATUS                    = 0x0000010C,
-CAMIF_COMMAND                     = 0x00000110,
-CAMIF_CONFIG                      = 0x00000114,
-CAMIF_EFS_CONFIG                  = 0x00000118,
-CAMIF_FRAME_CONFIG                = 0x0000011C,
-CAMIF_WINDOW_WIDTH_CONFIG         = 0x00000120,
-CAMIF_WINDOW_HEIGHT_CONFIG        = 0x00000124,
-CAMIF_SUBSAMPLE1_CONFIG           = 0x00000128,
-CAMIF_SUBSAMPLE2_CONFIG           = 0x0000012C,
-CAMIF_EPOCH_IRQ                   = 0x00000130,
-CAMIF_STATUS                      = 0x00000134,
-CAMIF_MISR                        = 0x00000138,
-VFE_SYNC_TIMER_CMD                = 0x0000013C,
-VFE_SYNC_TIMER0_LINE_START        = 0x00000140,
-VFE_SYNC_TIMER0_PIXEL_START       = 0x00000144,
-VFE_SYNC_TIMER0_PIXEL_DURATION    = 0x00000148,
-VFE_SYNC_TIMER1_LINE_START        = 0x0000014C,
-VFE_SYNC_TIMER1_PIXEL_START       = 0x00000150,
-VFE_SYNC_TIMER1_PIXEL_DURATION    = 0x00000154,
-VFE_SYNC_TIMER2_LINE_START        = 0x00000158,
-VFE_SYNC_TIMER2_PIXEL_START       = 0x0000015C,
-VFE_SYNC_TIMER2_PIXEL_DURATION    = 0x00000160,
-VFE_SYNC_TIMER_POLARITY           = 0x00000164,
-VFE_ASYNC_TIMER_CMD               = 0x00000168,
-VFE_ASYNC_TIMER0_CFG_0            = 0x0000016C,
-VFE_ASYNC_TIMER0_CFG_1            = 0x00000170,
-VFE_ASYNC_TIMER1_CFG_0            = 0x00000174,
-VFE_ASYNC_TIMER1_CFG_1            = 0x00000178,
-VFE_ASYNC_TIMER2_CFG_0            = 0x0000017C,
-VFE_ASYNC_TIMER2_CFG_1            = 0x00000180,
-VFE_ASYNC_TIMER3_CFG_0            = 0x00000184,
-VFE_ASYNC_TIMER3_CFG_1            = 0x00000188,
-VFE_TIMER_SEL                     = 0x0000018C,
-VFE_REG_UPDATE_CMD                = 0x00000190,
-VFE_BLACK_EVEN_EVEN_VALUE         = 0x00000194,
-VFE_BLACK_EVEN_ODD_VALUE          = 0x00000198,
-VFE_BLACK_ODD_EVEN_VALUE          = 0x0000019C,
-VFE_BLACK_ODD_ODD_VALUE           = 0x000001A0,
-VFE_ROLLOFF_CFG_0                 = 0x000001A4,
-VFE_ROLLOFF_CFG_1                 = 0x000001A8,
-VFE_ROLLOFF_CFG_2                 = 0x000001AC,
-VFE_DEMUX_CFG                     = 0x000001B0,
-VFE_DEMUX_GAIN_0                  = 0x000001B4,
-VFE_DEMUX_GAIN_1                  = 0x000001B8,
-VFE_DEMUX_EVEN_CFG                = 0x000001BC,
-VFE_DEMUX_ODD_CFG                 = 0x000001C0,
-VFE_DEMOSAIC_CFG                  = 0x000001C4,
-VFE_DEMOSAIC_ABF_CFG_0            = 0x000001C8,
-VFE_DEMOSAIC_ABF_CFG_1            = 0x000001CC,
-VFE_DEMOSAIC_BPC_CFG_0            = 0x000001D0,
-VFE_DEMOSAIC_BPC_CFG_1            = 0x000001D4,
-VFE_DEMOSAIC_STATUS               = 0x000001D8,
-VFE_CHROMA_UPSAMPLE_CFG           = 0x000001DC,
-VFE_CROP_WIDTH_CFG                = 0x000001E0,
-VFE_CROP_HEIGHT_CFG               = 0x000001E4,
-VFE_COLOR_CORRECT_COEFF_0         = 0x000001E8,
-VFE_COLOR_CORRECT_COEFF_1         = 0x000001EC,
-VFE_COLOR_CORRECT_COEFF_2         = 0x000001F0,
-VFE_COLOR_CORRECT_COEFF_3         = 0x000001F4,
-VFE_COLOR_CORRECT_COEFF_4         = 0x000001F8,
-VFE_COLOR_CORRECT_COEFF_5         = 0x000001FC,
-VFE_COLOR_CORRECT_COEFF_6         = 0x00000200,
-VFE_COLOR_CORRECT_COEFF_7         = 0x00000204,
-VFE_COLOR_CORRECT_COEFF_8         = 0x00000208,
-VFE_COLOR_CORRECT_OFFSET_0        = 0x0000020C,
-VFE_COLOR_CORRECT_OFFSET_1        = 0x00000210,
-VFE_COLOR_CORRECT_OFFSET_2        = 0x00000214,
-VFE_COLOR_CORRECT_COEFF_Q         = 0x00000218,
-VFE_LA_CFG                        = 0x0000021C,
-VFE_LUT_BANK_SEL                  = 0x00000220,
-VFE_CHROMA_ENHAN_A                = 0x00000224,
-VFE_CHROMA_ENHAN_B                = 0x00000228,
-VFE_CHROMA_ENHAN_C                = 0x0000022C,
-VFE_CHROMA_ENHAN_D                = 0x00000230,
-VFE_CHROMA_ENHAN_K                = 0x00000234,
-VFE_COLOR_CONVERT_COEFF_0         = 0x00000238,
-VFE_COLOR_CONVERT_COEFF_1         = 0x0000023C,
-VFE_COLOR_CONVERT_COEFF_2         = 0x00000240,
-VFE_COLOR_CONVERT_OFFSET          = 0x00000244,
-VFE_ASF_CFG                       = 0x00000248,
-VFE_ASF_SHARP_CFG_0               = 0x0000024C,
-VFE_ASF_SHARP_CFG_1               = 0x00000250,
-VFE_ASF_SHARP_COEFF_0             = 0x00000254,
-VFE_ASF_SHARP_COEFF_1             = 0x00000258,
-VFE_ASF_SHARP_COEFF_2             = 0x0000025C,
-VFE_ASF_SHARP_COEFF_3             = 0x00000260,
-VFE_ASF_MAX_EDGE                  = 0x00000264,
-VFE_ASF_CROP_WIDTH_CFG            = 0x00000268,
-VFE_ASF_CROP_HEIGHT_CFG           = 0x0000026C,
-VFE_SCALE_CFG                     = 0x00000270,
-VFE_SCALE_H_IMAGE_SIZE_CFG        = 0x00000274,
-VFE_SCALE_H_PHASE_CFG             = 0x00000278,
-VFE_SCALE_H_STRIPE_CFG            = 0x0000027C,
-VFE_SCALE_V_IMAGE_SIZE_CFG        = 0x00000280,
-VFE_SCALE_V_PHASE_CFG             = 0x00000284,
-VFE_SCALE_V_STRIPE_CFG            = 0x00000288,
-VFE_SCALE_Y_CFG                   = 0x0000028C,
-VFE_SCALE_Y_H_IMAGE_SIZE_CFG      = 0x00000290,
-VFE_SCALE_Y_H_PHASE_CFG           = 0x00000294,
-VFE_SCALE_Y_V_IMAGE_SIZE_CFG      = 0x00000298,
-VFE_SCALE_Y_V_PHASE_CFG           = 0x0000029C,
-VFE_SCALE_CBCR_CFG                = 0x000002A0,
-VFE_SCALE_CBCR_H_IMAGE_SIZE_CFG   = 0x000002A4,
-VFE_SCALE_CBCR_H_PHASE_CFG        = 0x000002A8,
-VFE_SCALE_CBCR_V_IMAGE_SIZE_CFG   = 0x000002AC,
-VFE_SCALE_CBCR_V_PHASE_CFG        = 0x000002B0,
-VFE_WB_CFG                        = 0x000002B4,
-VFE_CHROMA_SUPPRESS_CFG_0         = 0x000002B8,
-VFE_CHROMA_SUPPRESS_CFG_1         = 0x000002BC,
-VFE_CHROMA_SUBSAMPLE_CFG          = 0x000002C0,
-VFE_CHROMA_SUB_CROP_WIDTH_CFG     = 0x000002C4,
-VFE_CHROMA_SUB_CROP_HEIGHT_CFG    = 0x000002C8,
-VFE_FRAMEDROP_ENC_Y_CFG           = 0x000002CC,
-VFE_FRAMEDROP_ENC_CBCR_CFG        = 0x000002D0,
-VFE_FRAMEDROP_ENC_Y_PATTERN       = 0x000002D4,
-VFE_FRAMEDROP_ENC_CBCR_PATTERN    = 0x000002D8,
-VFE_FRAMEDROP_VIEW_Y_CFG          = 0x000002DC,
-VFE_FRAMEDROP_VIEW_CBCR_CFG       = 0x000002E0,
-VFE_FRAMEDROP_VIEW_Y_PATTERN      = 0x000002E4,
-VFE_FRAMEDROP_VIEW_CBCR_PATTERN   = 0x000002E8,
-VFE_CLAMP_MAX_CFG                 = 0x000002EC,
-VFE_CLAMP_MIN_CFG                 = 0x000002F0,
-VFE_STATS_CMD                     = 0x000002F4,
-VFE_STATS_AF_CFG                  = 0x000002F8,
-VFE_STATS_AF_DIM                  = 0x000002FC,
-VFE_STATS_AF_GRID_0               = 0x00000300,
-VFE_STATS_AF_GRID_1               = 0x00000304,
-VFE_STATS_AF_GRID_2               = 0x00000308,
-VFE_STATS_AF_GRID_3               = 0x0000030C,
-VFE_STATS_AF_HEADER               = 0x00000310,
-VFE_STATS_AF_COEF0                = 0x00000314,
-VFE_STATS_AF_COEF1                = 0x00000318,
-VFE_STATS_AWBAE_CFG               = 0x0000031C,
-VFE_STATS_AXW_HEADER              = 0x00000320,
-VFE_STATS_AWB_MCFG                = 0x00000324,
-VFE_STATS_AWB_CCFG1               = 0x00000328,
-VFE_STATS_AWB_CCFG2               = 0x0000032C,
-VFE_STATS_HIST_HEADER             = 0x00000330,
-VFE_STATS_HIST_INNER_OFFSET       = 0x00000334,
-VFE_STATS_HIST_INNER_DIM          = 0x00000338,
-VFE_STATS_FRAME_SIZE              = 0x0000033C,
-VFE_DMI_CFG                       = 0x00000340,
-VFE_DMI_ADDR                      = 0x00000344,
-VFE_DMI_DATA_HI                   = 0x00000348,
-VFE_DMI_DATA_LO                   = 0x0000034C,
-VFE_DMI_RAM_AUTO_LOAD_CMD         = 0x00000350,
-VFE_DMI_RAM_AUTO_LOAD_STATUS      = 0x00000354,
-VFE_DMI_RAM_AUTO_LOAD_CFG         = 0x00000358,
-VFE_DMI_RAM_AUTO_LOAD_SEED        = 0x0000035C,
-VFE_TESTBUS_SEL                   = 0x00000360,
-VFE_TESTGEN_CFG                   = 0x00000364,
-VFE_SW_TESTGEN_CMD                = 0x00000368,
-VFE_HW_TESTGEN_CMD                = 0x0000036C,
-VFE_HW_TESTGEN_CFG                = 0x00000370,
-VFE_HW_TESTGEN_IMAGE_CFG          = 0x00000374,
-VFE_HW_TESTGEN_SOF_OFFSET_CFG     = 0x00000378,
-VFE_HW_TESTGEN_EOF_NOFFSET_CFG    = 0x0000037C,
-VFE_HW_TESTGEN_SOL_OFFSET_CFG     = 0x00000380,
-VFE_HW_TESTGEN_EOL_NOFFSET_CFG    = 0x00000384,
-VFE_HW_TESTGEN_HBI_CFG            = 0x00000388,
-VFE_HW_TESTGEN_VBL_CFG            = 0x0000038C,
-VFE_HW_TESTGEN_SOF_DUMMY_LINE_CFG2 = 0x00000390,
-VFE_HW_TESTGEN_EOF_DUMMY_LINE_CFG2 = 0x00000394,
-VFE_HW_TESTGEN_COLOR_BARS_CFG     = 0x00000398,
-VFE_HW_TESTGEN_RANDOM_CFG         = 0x0000039C,
-VFE_SPARE                         = 0x000003A0,
-};
-
-#define ping 0x0
-#define pong 0x1
-
-struct vfe_bus_cfg_data {
-       boolean                  stripeRdPathEn;
-       boolean                  encYWrPathEn;
-       boolean                  encCbcrWrPathEn;
-       boolean                  viewYWrPathEn;
-       boolean                  viewCbcrWrPathEn;
-       enum VFE_RAW_PIXEL_DATA_SIZE rawPixelDataSize;
-       enum VFE_RAW_WR_PATH_SEL     rawWritePathSelect;
-};
-
-struct vfe_camif_cfg_data {
-       boolean camif2OutputEnable;
-       boolean camif2BusEnable;
-       struct vfe_cmds_camif_cfg camifCfgFromCmd;
-};
-
-struct vfe_irq_composite_mask_config {
-       uint8_t encIrqComMask;
-       uint8_t viewIrqComMask;
-       uint8_t ceDoneSel;
-};
-
-/* define a structure for each output path.*/
-struct vfe_output_path {
-       uint32_t addressBuffer[8];
-       uint16_t fragIndex;
-       boolean  hwCurrentFlag;
-       uint8_t  *hwRegPingAddress;
-       uint8_t  *hwRegPongAddress;
-};
-
-struct vfe_output_path_combo {
-       boolean           whichOutputPath;
-       boolean           pathEnabled;
-       boolean           multiFrag;
-       uint8_t           fragCount;
-       boolean           ackPending;
-       uint8_t           currentFrame;
-       uint32_t          nextFrameAddrBuf[8];
-       struct vfe_output_path   yPath;
-       struct vfe_output_path   cbcrPath;
-       uint8_t           snapshotPendingCount;
-       boolean           pmEnabled;
-       uint8_t           cbcrStatusBit;
-};
-
-struct vfe_stats_control {
-       boolean  ackPending;
-       uint32_t addressBuffer[2];
-       uint32_t nextFrameAddrBuf;
-       boolean  pingPongStatus;
-       uint8_t  *hwRegPingAddress;
-       uint8_t  *hwRegPongAddress;
-       uint32_t droppedStatsFrameCount;
-       uint32_t bufToRender;
-};
-
-struct vfe_gamma_lut_sel {
-       boolean  ch0BankSelect;
-       boolean  ch1BankSelect;
-       boolean  ch2BankSelect;
-};
-
-struct vfe_interrupt_mask {
-       boolean  camifErrorIrq;
-       boolean  camifSofIrq;
-       boolean  camifEolIrq;
-       boolean  camifEofIrq;
-       boolean  camifEpoch1Irq;
-       boolean  camifEpoch2Irq;
-       boolean  camifOverflowIrq;
-       boolean  ceIrq;
-       boolean  regUpdateIrq;
-       boolean  resetAckIrq;
-       boolean  encYPingpongIrq;
-       boolean  encCbcrPingpongIrq;
-       boolean  viewYPingpongIrq;
-       boolean  viewCbcrPingpongIrq;
-       boolean  rdPingpongIrq;
-       boolean  afPingpongIrq;
-       boolean  awbPingpongIrq;
-       boolean  histPingpongIrq;
-       boolean  encIrq;
-       boolean  viewIrq;
-       boolean  busOverflowIrq;
-       boolean  afOverflowIrq;
-       boolean  awbOverflowIrq;
-       boolean  syncTimer0Irq;
-       boolean  syncTimer1Irq;
-       boolean  syncTimer2Irq;
-       boolean  asyncTimer0Irq;
-       boolean  asyncTimer1Irq;
-       boolean  asyncTimer2Irq;
-       boolean  asyncTimer3Irq;
-       boolean  axiErrorIrq;
-       boolean  violationIrq;
-};
-
-enum vfe_interrupt_name {
-       CAMIF_ERROR_IRQ,
-       CAMIF_SOF_IRQ,
-       CAMIF_EOL_IRQ,
-       CAMIF_EOF_IRQ,
-       CAMIF_EPOCH1_IRQ,
-       CAMIF_EPOCH2_IRQ,
-       CAMIF_OVERFLOW_IRQ,
-       CE_IRQ,
-       REG_UPDATE_IRQ,
-       RESET_ACK_IRQ,
-       ENC_Y_PINGPONG_IRQ,
-       ENC_CBCR_PINGPONG_IRQ,
-       VIEW_Y_PINGPONG_IRQ,
-       VIEW_CBCR_PINGPONG_IRQ,
-       RD_PINGPONG_IRQ,
-       AF_PINGPONG_IRQ,
-       AWB_PINGPONG_IRQ,
-       HIST_PINGPONG_IRQ,
-       ENC_IRQ,
-       VIEW_IRQ,
-       BUS_OVERFLOW_IRQ,
-       AF_OVERFLOW_IRQ,
-       AWB_OVERFLOW_IRQ,
-       SYNC_TIMER0_IRQ,
-       SYNC_TIMER1_IRQ,
-       SYNC_TIMER2_IRQ,
-       ASYNC_TIMER0_IRQ,
-       ASYNC_TIMER1_IRQ,
-       ASYNC_TIMER2_IRQ,
-       ASYNC_TIMER3_IRQ,
-       AXI_ERROR_IRQ,
-       VIOLATION_IRQ
-};
-
-enum VFE_DMI_RAM_SEL {
-       NO_MEM_SELECTED          = 0,
-       ROLLOFF_RAM              = 0x1,
-       RGBLUT_RAM_CH0_BANK0     = 0x2,
-       RGBLUT_RAM_CH0_BANK1     = 0x3,
-       RGBLUT_RAM_CH1_BANK0     = 0x4,
-       RGBLUT_RAM_CH1_BANK1     = 0x5,
-       RGBLUT_RAM_CH2_BANK0     = 0x6,
-       RGBLUT_RAM_CH2_BANK1     = 0x7,
-       STATS_HIST_CB_EVEN_RAM   = 0x8,
-       STATS_HIST_CB_ODD_RAM    = 0x9,
-       STATS_HIST_CR_EVEN_RAM   = 0xa,
-       STATS_HIST_CR_ODD_RAM    = 0xb,
-       RGBLUT_CHX_BANK0         = 0xc,
-       RGBLUT_CHX_BANK1         = 0xd,
-       LUMA_ADAPT_LUT_RAM_BANK0 = 0xe,
-       LUMA_ADAPT_LUT_RAM_BANK1 = 0xf
-};
-
-struct vfe_module_enable {
-       boolean  blackLevelCorrectionEnable;
-       boolean  lensRollOffEnable;
-       boolean  demuxEnable;
-       boolean  chromaUpsampleEnable;
-       boolean  demosaicEnable;
-       boolean  statsEnable;
-       boolean  cropEnable;
-       boolean  mainScalerEnable;
-       boolean  whiteBalanceEnable;
-       boolean  colorCorrectionEnable;
-       boolean  yHistEnable;
-       boolean  skinToneEnable;
-       boolean  lumaAdaptationEnable;
-       boolean  rgbLUTEnable;
-       boolean  chromaEnhanEnable;
-       boolean  asfEnable;
-       boolean  chromaSuppressionEnable;
-       boolean  chromaSubsampleEnable;
-       boolean  scaler2YEnable;
-       boolean  scaler2CbcrEnable;
-};
-
-struct vfe_bus_cmd_data {
-       boolean  stripeReload;
-       boolean  busPingpongReload;
-       boolean  statsPingpongReload;
-};
-
-struct vfe_stats_cmd_data {
-       boolean  autoFocusEnable;
-       boolean  axwEnable;
-       boolean  histEnable;
-       boolean  clearHistEnable;
-       boolean  histAutoClearEnable;
-       boolean  colorConversionEnable;
-};
-
-struct vfe_hw_ver {
-       uint32_t minorVersion:8;
-       uint32_t majorVersion:8;
-       uint32_t coreVersion:4;
-       uint32_t /* reserved */ : 12;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_cfg {
-       uint32_t pixelPattern:3;
-       uint32_t /* reserved */ : 13;
-       uint32_t inputSource:2;
-       uint32_t /* reserved */ : 14;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_buscmd {
-       uint32_t  stripeReload:1;
-       uint32_t  /* reserved */ : 3;
-       uint32_t  busPingpongReload:1;
-       uint32_t  statsPingpongReload:1;
-       uint32_t  /* reserved */ : 26;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_Irq_Composite_MaskType {
-       uint32_t  encIrqComMaskBits:2;
-       uint32_t  viewIrqComMaskBits:2;
-       uint32_t  ceDoneSelBits:5;
-       uint32_t  /* reserved */ : 23;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_mod_enable {
-       uint32_t blackLevelCorrectionEnable:1;
-       uint32_t lensRollOffEnable:1;
-       uint32_t demuxEnable:1;
-       uint32_t chromaUpsampleEnable:1;
-       uint32_t demosaicEnable:1;
-       uint32_t statsEnable:1;
-       uint32_t cropEnable:1;
-       uint32_t mainScalerEnable:1;
-       uint32_t whiteBalanceEnable:1;
-       uint32_t colorCorrectionEnable:1;
-       uint32_t yHistEnable:1;
-       uint32_t skinToneEnable:1;
-       uint32_t lumaAdaptationEnable:1;
-       uint32_t rgbLUTEnable:1;
-       uint32_t chromaEnhanEnable:1;
-       uint32_t asfEnable:1;
-       uint32_t chromaSuppressionEnable:1;
-       uint32_t chromaSubsampleEnable:1;
-       uint32_t scaler2YEnable:1;
-       uint32_t scaler2CbcrEnable:1;
-       uint32_t /* reserved */ : 14;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_irqenable {
-       uint32_t camifErrorIrq:1;
-       uint32_t camifSofIrq:1;
-       uint32_t camifEolIrq:1;
-       uint32_t camifEofIrq:1;
-       uint32_t camifEpoch1Irq:1;
-       uint32_t camifEpoch2Irq:1;
-       uint32_t camifOverflowIrq:1;
-       uint32_t ceIrq:1;
-       uint32_t regUpdateIrq:1;
-       uint32_t resetAckIrq:1;
-       uint32_t encYPingpongIrq:1;
-       uint32_t encCbcrPingpongIrq:1;
-       uint32_t viewYPingpongIrq:1;
-       uint32_t viewCbcrPingpongIrq:1;
-       uint32_t rdPingpongIrq:1;
-       uint32_t afPingpongIrq:1;
-       uint32_t awbPingpongIrq:1;
-       uint32_t histPingpongIrq:1;
-       uint32_t encIrq:1;
-       uint32_t viewIrq:1;
-       uint32_t busOverflowIrq:1;
-       uint32_t afOverflowIrq:1;
-       uint32_t awbOverflowIrq:1;
-       uint32_t syncTimer0Irq:1;
-       uint32_t syncTimer1Irq:1;
-       uint32_t syncTimer2Irq:1;
-       uint32_t asyncTimer0Irq:1;
-       uint32_t asyncTimer1Irq:1;
-       uint32_t asyncTimer2Irq:1;
-       uint32_t asyncTimer3Irq:1;
-       uint32_t axiErrorIrq:1;
-       uint32_t violationIrq:1;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_upsample_cfg {
-       uint32_t chromaCositingForYCbCrInputs:1;
-       uint32_t /* reserved */ : 31;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_CAMIFConfigType {
-       /* CAMIF Config */
-       uint32_t  /* reserved */ : 1;
-       uint32_t  VSyncEdge:1;
-       uint32_t  HSyncEdge:1;
-       uint32_t  syncMode:2;
-       uint32_t  vfeSubsampleEnable:1;
-       uint32_t  /* reserved */ : 1;
-       uint32_t  busSubsampleEnable:1;
-       uint32_t  camif2vfeEnable:1;
-       uint32_t  /* reserved */ : 1;
-       uint32_t  camif2busEnable:1;
-       uint32_t  irqSubsampleEnable:1;
-       uint32_t  binningEnable:1;
-       uint32_t  /* reserved */ : 18;
-       uint32_t  misrEnable:1;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_camifcfg {
-       /* EFS_Config */
-       uint32_t efsEndOfLine:8;
-       uint32_t efsStartOfLine:8;
-       uint32_t efsEndOfFrame:8;
-       uint32_t efsStartOfFrame:8;
-       /* Frame Config */
-       uint32_t frameConfigPixelsPerLine:14;
-       uint32_t /* reserved */ : 2;
-       uint32_t frameConfigLinesPerFrame:14;
-       uint32_t /* reserved */ : 2;
-       /* Window Width Config */
-       uint32_t windowWidthCfgLastPixel:14;
-       uint32_t /* reserved */ : 2;
-       uint32_t windowWidthCfgFirstPixel:14;
-       uint32_t /* reserved */ : 2;
-       /* Window Height Config */
-       uint32_t windowHeightCfglastLine:14;
-       uint32_t /* reserved */ : 2;
-       uint32_t windowHeightCfgfirstLine:14;
-       uint32_t /* reserved */ : 2;
-       /* Subsample 1 Config */
-       uint32_t subsample1CfgPixelSkip:16;
-       uint32_t subsample1CfgLineSkip:16;
-       /* Subsample 2 Config */
-       uint32_t subsample2CfgFrameSkip:4;
-       uint32_t subsample2CfgFrameSkipMode:1;
-       uint32_t subsample2CfgPixelSkipWrap:1;
-       uint32_t /* reserved */ : 26;
-       /* Epoch Interrupt */
-       uint32_t epoch1Line:14;
-       uint32_t /* reserved */ : 2;
-       uint32_t epoch2Line:14;
-       uint32_t /* reserved */ : 2;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_camifframe_update {
-       uint32_t pixelsPerLine:14;
-       uint32_t /* reserved */ : 2;
-       uint32_t linesPerFrame:14;
-       uint32_t /* reserved */ : 2;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_axi_bus_cfg {
-       uint32_t  stripeRdPathEn:1;
-       uint32_t  /* reserved */ : 3;
-       uint32_t  encYWrPathEn:1;
-       uint32_t  encCbcrWrPathEn:1;
-       uint32_t  viewYWrPathEn:1;
-       uint32_t  viewCbcrWrPathEn:1;
-       uint32_t  rawPixelDataSize:2;
-       uint32_t  rawWritePathSelect:2;
-       uint32_t  /* reserved */ : 20;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_axi_out_cfg {
-       uint32_t  out2YPingAddr:32;
-       uint32_t  out2YPongAddr:32;
-       uint32_t  out2YImageHeight:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  out2YImageWidthin64bit:10;
-       uint32_t  /* reserved */ : 6;
-       uint32_t  out2YBurstLength:2;
-       uint32_t  /* reserved */ : 2;
-       uint32_t  out2YNumRows:12;
-       uint32_t  out2YRowIncrementIn64bit:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  out2CbcrPingAddr:32;
-       uint32_t  out2CbcrPongAddr:32;
-       uint32_t  out2CbcrImageHeight:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  out2CbcrImageWidthIn64bit:10;
-       uint32_t  /* reserved */ : 6;
-       uint32_t  out2CbcrBurstLength:2;
-       uint32_t  /* reserved */ : 2;
-       uint32_t  out2CbcrNumRows:12;
-       uint32_t  out2CbcrRowIncrementIn64bit:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  out1YPingAddr:32;
-       uint32_t  out1YPongAddr:32;
-       uint32_t  out1YImageHeight:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  out1YImageWidthin64bit:10;
-       uint32_t  /* reserved */ : 6;
-       uint32_t  out1YBurstLength:2;
-       uint32_t  /* reserved */ : 2;
-       uint32_t  out1YNumRows:12;
-       uint32_t  out1YRowIncrementIn64bit:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  out1CbcrPingAddr:32;
-       uint32_t  out1CbcrPongAddr:32;
-       uint32_t  out1CbcrImageHeight:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  out1CbcrImageWidthIn64bit:10;
-       uint32_t  /* reserved */ : 6;
-       uint32_t  out1CbcrBurstLength:2;
-       uint32_t  /* reserved */ : 2;
-       uint32_t  out1CbcrNumRows:12;
-       uint32_t  out1CbcrRowIncrementIn64bit:12;
-       uint32_t  /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_output_clamp_cfg {
-       /* Output Clamp Maximums */
-       uint32_t yChanMax:8;
-       uint32_t cbChanMax:8;
-       uint32_t crChanMax:8;
-       uint32_t /* reserved */ : 8;
-       /* Output Clamp Minimums */
-       uint32_t yChanMin:8;
-       uint32_t cbChanMin:8;
-       uint32_t crChanMin:8;
-       uint32_t /* reserved */ : 8;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_fov_crop_cfg {
-       uint32_t lastPixel:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t firstPixel:12;
-       uint32_t /* reserved */ : 4;
-
-       /* FOV Corp, Part 2 */
-       uint32_t lastLine:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t firstLine:12;
-       uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_FRAME_SKIP_UpdateCmdType {
-       uint32_t  yPattern:32;
-       uint32_t  cbcrPattern:32;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_frame_skip_cfg {
-       /* Frame Drop Enc (output2) */
-       uint32_t output2YPeriod:5;
-       uint32_t /* reserved */ : 27;
-       uint32_t output2CbCrPeriod:5;
-       uint32_t /* reserved */ : 27;
-       uint32_t output2YPattern:32;
-       uint32_t output2CbCrPattern:32;
-       /* Frame Drop View (output1) */
-       uint32_t output1YPeriod:5;
-       uint32_t /* reserved */ : 27;
-       uint32_t output1CbCrPeriod:5;
-       uint32_t /* reserved */ : 27;
-       uint32_t output1YPattern:32;
-       uint32_t output1CbCrPattern:32;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_main_scaler_cfg {
-       /* Scaler Enable Config */
-       uint32_t hEnable:1;
-       uint32_t vEnable:1;
-       uint32_t /* reserved */ : 30;
-       /* Scale H Image Size Config */
-       uint32_t inWidth:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t outWidth:12;
-       uint32_t /* reserved */ : 4;
-       /* Scale H Phase Config */
-       uint32_t horizPhaseMult:18;
-       uint32_t /* reserved */ : 2;
-       uint32_t horizInterResolution:2;
-       uint32_t /* reserved */ : 10;
-       /* Scale H Stripe Config */
-       uint32_t horizMNInit:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t horizPhaseInit:15;
-       uint32_t /* reserved */ : 1;
-       /* Scale V Image Size Config */
-       uint32_t inHeight:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t outHeight:12;
-       uint32_t /* reserved */ : 4;
-       /* Scale V Phase Config */
-       uint32_t vertPhaseMult:18;
-       uint32_t /* reserved */ : 2;
-       uint32_t vertInterResolution:2;
-       uint32_t /* reserved */ : 10;
-       /* Scale V Stripe Config */
-       uint32_t vertMNInit:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t vertPhaseInit:15;
-       uint32_t /* reserved */ : 1;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_scaler2_cfg {
-       /* Scaler   Enable Config */
-       uint32_t  hEnable:1;
-       uint32_t  vEnable:1;
-       uint32_t  /* reserved */ : 30;
-       /* Scaler   H Image Size Config */
-       uint32_t  inWidth:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  outWidth:12;
-       uint32_t  /* reserved */ : 4;
-       /* Scaler   H Phase Config */
-       uint32_t  horizPhaseMult:18;
-       uint32_t  /* reserved */ : 2;
-       uint32_t  horizInterResolution:2;
-       uint32_t  /* reserved */ : 10;
-       /* Scaler   V Image Size Config */
-       uint32_t  inHeight:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  outHeight:12;
-       uint32_t  /* reserved */ : 4;
-       /* Scaler   V Phase Config */
-       uint32_t  vertPhaseMult:18;
-       uint32_t  /* reserved */ : 2;
-       uint32_t  vertInterResolution:2;
-       uint32_t  /* reserved */ : 10;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_rolloff_cfg {
-       /* Rolloff 0 Config */
-       uint32_t  gridWidth:9;
-       uint32_t  gridHeight:9;
-       uint32_t  yDelta:9;
-       uint32_t  /* reserved */ : 5;
-       /* Rolloff 1 Config*/
-       uint32_t  gridX:4;
-       uint32_t  gridY:4;
-       uint32_t  pixelX:9;
-       uint32_t  /* reserved */ : 3;
-       uint32_t  pixelY:9;
-       uint32_t  /* reserved */ : 3;
-       /* Rolloff 2 Config */
-       uint32_t  yDeltaAccum:12;
-       uint32_t  /* reserved */ : 20;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_asf_update {
-       /* ASF Config Command */
-       uint32_t smoothEnable:1;
-       uint32_t sharpMode:2;
-       uint32_t /* reserved */ : 1;
-       uint32_t smoothCoeff1:4;
-       uint32_t smoothCoeff0:8;
-       uint32_t pipeFlushCount:12;
-       uint32_t pipeFlushOvd:1;
-       uint32_t flushHaltOvd:1;
-       uint32_t cropEnable:1;
-       uint32_t /* reserved */ : 1;
-       /* Sharpening Config 0 */
-       uint32_t sharpThresholdE1:7;
-       uint32_t /* reserved */ : 1;
-       uint32_t sharpDegreeK1:5;
-       uint32_t /* reserved */ : 3;
-       uint32_t sharpDegreeK2:5;
-       uint32_t /* reserved */ : 3;
-       uint32_t normalizeFactor:7;
-       uint32_t /* reserved */ : 1;
-       /* Sharpening Config 1 */
-       uint32_t sharpThresholdE2:8;
-       uint32_t sharpThresholdE3:8;
-       uint32_t sharpThresholdE4:8;
-       uint32_t sharpThresholdE5:8;
-       /* Sharpening Coefficients 0 */
-       uint32_t F1Coeff0:6;
-       uint32_t F1Coeff1:6;
-       uint32_t F1Coeff2:6;
-       uint32_t F1Coeff3:6;
-       uint32_t F1Coeff4:6;
-       uint32_t /* reserved */ : 2;
-       /* Sharpening Coefficients 1 */
-       uint32_t F1Coeff5:6;
-       uint32_t F1Coeff6:6;
-       uint32_t F1Coeff7:6;
-       uint32_t F1Coeff8:7;
-       uint32_t /* reserved */ : 7;
-       /* Sharpening Coefficients 2 */
-       uint32_t F2Coeff0:6;
-       uint32_t F2Coeff1:6;
-       uint32_t F2Coeff2:6;
-       uint32_t F2Coeff3:6;
-       uint32_t F2Coeff4:6;
-       uint32_t /* reserved */ : 2;
-       /* Sharpening Coefficients 3 */
-       uint32_t F2Coeff5:6;
-       uint32_t F2Coeff6:6;
-       uint32_t F2Coeff7:6;
-       uint32_t F2Coeff8:7;
-       uint32_t /* reserved */ : 7;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_asfcrop_cfg {
-       /* ASF Crop Width Config */
-       uint32_t lastPixel:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t firstPixel:12;
-       uint32_t /* reserved */ : 4;
-       /* ASP Crop Height Config */
-       uint32_t lastLine:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t firstLine:12;
-       uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_chroma_suppress_cfg {
-       /* Chroma Suppress 0 Config */
-       uint32_t m1:8;
-       uint32_t m3:8;
-       uint32_t n1:3;
-       uint32_t /* reserved */ : 1;
-       uint32_t n3:3;
-       uint32_t /* reserved */ : 9;
-       /* Chroma Suppress 1 Config */
-       uint32_t mm1:8;
-       uint32_t nn1:3;
-       uint32_t /* reserved */ : 21;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_chromasubsample_cfg {
-       /* Chroma Subsample Selection */
-       uint32_t  hCositedPhase:1;
-       uint32_t  vCositedPhase:1;
-       uint32_t  hCosited:1;
-       uint32_t  vCosited:1;
-       uint32_t  hsubSampleEnable:1;
-       uint32_t  vsubSampleEnable:1;
-       uint32_t  cropEnable:1;
-       uint32_t  /* reserved */ : 25;
-       uint32_t  cropWidthLastPixel:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  cropWidthFirstPixel:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  cropHeightLastLine:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  cropHeightFirstLine:12;
-       uint32_t  /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_blacklevel_cfg {
-       /* Black Even-Even Value Config */
-       uint32_t    evenEvenAdjustment:9;
-       uint32_t   /* reserved */ : 23;
-       /* Black Even-Odd Value Config */
-       uint32_t    evenOddAdjustment:9;
-       uint32_t   /* reserved */ : 23;
-       /* Black Odd-Even Value Config */
-       uint32_t    oddEvenAdjustment:9;
-       uint32_t   /* reserved */ : 23;
-       /* Black Odd-Odd Value Config */
-       uint32_t    oddOddAdjustment:9;
-       uint32_t   /* reserved */ : 23;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_demux_cfg {
-       /* Demux Gain 0 Config */
-       uint32_t  ch0EvenGain:10;
-       uint32_t  /* reserved */ : 6;
-       uint32_t  ch0OddGain:10;
-       uint32_t  /* reserved */ : 6;
-       /* Demux Gain 1 Config */
-       uint32_t  ch1Gain:10;
-       uint32_t  /* reserved */ : 6;
-       uint32_t  ch2Gain:10;
-       uint32_t  /* reserved */ : 6;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_bps_info {
-  uint32_t greenBadPixelCount:8;
-  uint32_t /* reserved */ : 8;
-  uint32_t RedBlueBadPixelCount:8;
-  uint32_t /* reserved */ : 8;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_demosaic_cfg {
-       /* Demosaic Config */
-       uint32_t abfEnable:1;
-       uint32_t badPixelCorrEnable:1;
-       uint32_t forceAbfOn:1;
-       uint32_t /* reserved */ : 1;
-       uint32_t abfShift:4;
-       uint32_t fminThreshold:7;
-       uint32_t /* reserved */ : 1;
-       uint32_t fmaxThreshold:7;
-       uint32_t /* reserved */ : 5;
-       uint32_t slopeShift:3;
-       uint32_t /* reserved */ : 1;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_demosaic_bpc_cfg {
-       /* Demosaic BPC Config 0 */
-       uint32_t blueDiffThreshold:12;
-       uint32_t redDiffThreshold:12;
-       uint32_t /* reserved */ : 8;
-       /* Demosaic BPC Config 1 */
-       uint32_t greenDiffThreshold:12;
-       uint32_t /* reserved */ : 20;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_demosaic_abf_cfg {
-       /* Demosaic ABF Config 0 */
-       uint32_t lpThreshold:10;
-       uint32_t /* reserved */ : 22;
-       /* Demosaic ABF Config 1 */
-       uint32_t ratio:4;
-       uint32_t minValue:10;
-       uint32_t /* reserved */ : 2;
-       uint32_t maxValue:10;
-       uint32_t /* reserved */ : 6;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_color_correction_cfg {
-       /* Color Corr. Coefficient 0 Config */
-       uint32_t   c0:12;
-       uint32_t   /* reserved */ : 20;
-       /* Color Corr. Coefficient 1 Config */
-       uint32_t   c1:12;
-       uint32_t   /* reserved */ : 20;
-       /* Color Corr. Coefficient 2 Config */
-       uint32_t   c2:12;
-       uint32_t   /* reserved */ : 20;
-       /* Color Corr. Coefficient 3 Config */
-       uint32_t   c3:12;
-       uint32_t   /* reserved */ : 20;
-       /* Color Corr. Coefficient 4 Config */
-       uint32_t   c4:12;
-       uint32_t   /* reserved */ : 20;
-       /* Color Corr. Coefficient 5 Config */
-       uint32_t   c5:12;
-       uint32_t   /* reserved */ : 20;
-       /* Color Corr. Coefficient 6 Config */
-       uint32_t   c6:12;
-       uint32_t   /* reserved */ : 20;
-       /* Color Corr. Coefficient 7 Config */
-       uint32_t   c7:12;
-       uint32_t   /* reserved */ : 20;
-       /* Color Corr. Coefficient 8 Config */
-       uint32_t   c8:12;
-       uint32_t   /* reserved */ : 20;
-       /* Color Corr. Offset 0 Config */
-       uint32_t   k0:11;
-       uint32_t   /* reserved */ : 21;
-       /* Color Corr. Offset 1 Config */
-       uint32_t   k1:11;
-       uint32_t   /* reserved */ : 21;
-       /* Color Corr. Offset 2 Config */
-       uint32_t   k2:11;
-       uint32_t   /* reserved */ : 21;
-       /* Color Corr. Coefficient Q Config */
-       uint32_t   coefQFactor:2;
-       uint32_t   /* reserved */ : 30;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_LumaAdaptation_ConfigCmdType {
-       /* LA Config */
-       uint32_t   lutBankSelect:1;
-       uint32_t   /* reserved */ : 31;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_wb_cfg {
-       /* WB Config */
-       uint32_t ch0Gain:9;
-       uint32_t ch1Gain:9;
-       uint32_t ch2Gain:9;
-       uint32_t /* reserved */ : 5;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_GammaLutSelect_ConfigCmdType {
-       /* LUT Bank Select Config */
-       uint32_t   ch0BankSelect:1;
-       uint32_t   ch1BankSelect:1;
-       uint32_t   ch2BankSelect:1;
-       uint32_t   /* reserved */ : 29;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_chroma_enhance_cfg {
-       /* Chroma Enhance A Config */
-       uint32_t ap:11;
-       uint32_t /* reserved */ : 5;
-       uint32_t am:11;
-       uint32_t /* reserved */ : 5;
-       /* Chroma Enhance B Config */
-       uint32_t bp:11;
-       uint32_t /* reserved */ : 5;
-       uint32_t bm:11;
-       uint32_t /* reserved */ : 5;
-       /* Chroma Enhance C Config */
-       uint32_t cp:11;
-       uint32_t /* reserved */ : 5;
-       uint32_t cm:11;
-       uint32_t /* reserved */ : 5;
-       /* Chroma Enhance D Config */
-       uint32_t dp:11;
-       uint32_t /* reserved */ : 5;
-       uint32_t dm:11;
-       uint32_t /* reserved */ : 5;
-       /* Chroma Enhance K Config */
-       uint32_t kcb:11;
-       uint32_t /* reserved */ : 5;
-       uint32_t kcr:11;
-       uint32_t /* reserved */ : 5;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_color_convert_cfg {
-       /* Conversion Coefficient 0 */
-       uint32_t v0:12;
-       uint32_t /* reserved */ : 20;
-       /* Conversion Coefficient 1 */
-       uint32_t v1:12;
-       uint32_t /* reserved */ : 20;
-       /* Conversion Coefficient 2 */
-       uint32_t v2:12;
-       uint32_t /* reserved */ : 20;
-       /* Conversion Offset */
-       uint32_t ConvertOffset:8;
-       uint32_t /* reserved */ : 24;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_SyncTimer_ConfigCmdType {
-       /* Timer Line Start Config */
-       uint32_t       timerLineStart:12;
-       uint32_t       /* reserved */ : 20;
-       /* Timer Pixel Start Config */
-       uint32_t       timerPixelStart:18;
-       uint32_t       /* reserved */ : 14;
-       /* Timer Pixel Duration Config */
-       uint32_t       timerPixelDuration:28;
-       uint32_t       /* reserved */ : 4;
-       /* Sync Timer Polarity Config */
-       uint32_t       timer0Polarity:1;
-       uint32_t       timer1Polarity:1;
-       uint32_t       timer2Polarity:1;
-       uint32_t       /* reserved */ : 29;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AsyncTimer_ConfigCmdType {
-       /* Async Timer Config 0 */
-       uint32_t     inactiveLength:20;
-       uint32_t     numRepetition:10;
-       uint32_t     /* reserved */ : 1;
-       uint32_t     polarity:1;
-       /* Async Timer Config 1 */
-       uint32_t     activeLength:20;
-       uint32_t     /* reserved */ : 12;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AWBAEStatistics_ConfigCmdType {
-       /* AWB autoexposure Config */
-       uint32_t    aeRegionConfig:1;
-       uint32_t    aeSubregionConfig:1;
-       uint32_t    /* reserved */ : 14;
-       uint32_t    awbYMin:8;
-       uint32_t    awbYMax:8;
-       /* AXW Header */
-       uint32_t    axwHeader:8;
-       uint32_t    /* reserved */ : 24;
-       /* AWB Mconfig */
-       uint32_t    m4:8;
-       uint32_t    m3:8;
-       uint32_t    m2:8;
-       uint32_t    m1:8;
-       /* AWB Cconfig */
-       uint32_t    c2:12;
-       uint32_t    /* reserved */ : 4;
-       uint32_t    c1:12;
-       uint32_t    /* reserved */ : 4;
-       /* AWB Cconfig 2 */
-       uint32_t    c4:12;
-       uint32_t    /* reserved */ : 4;
-       uint32_t    c3:12;
-       uint32_t    /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_TestGen_ConfigCmdType {
-       /* HW Test Gen Config */
-       uint32_t   numFrame:10;
-       uint32_t   /* reserved */ : 2;
-       uint32_t   pixelDataSelect:1;
-       uint32_t   systematicDataSelect:1;
-       uint32_t   /* reserved */ : 2;
-       uint32_t   pixelDataSize:2;
-       uint32_t   hsyncEdge:1;
-       uint32_t   vsyncEdge:1;
-       uint32_t   /* reserved */ : 12;
-       /* HW Test Gen Image Config */
-       uint32_t   imageWidth:14;
-       uint32_t   /* reserved */ : 2;
-       uint32_t   imageHeight:14;
-       uint32_t   /* reserved */ : 2;
-       /* SOF Offset Config */
-       uint32_t   sofOffset:24;
-       uint32_t   /* reserved */ : 8;
-       /* EOF NOffset Config */
-       uint32_t   eofNOffset:24;
-       uint32_t   /* reserved */ : 8;
-       /* SOL Offset Config */
-       uint32_t   solOffset:9;
-       uint32_t   /* reserved */ : 23;
-       /* EOL NOffset Config */
-       uint32_t   eolNOffset:9;
-       uint32_t   /* reserved */ : 23;
-       /* HBI Config */
-       uint32_t   hBlankInterval:14;
-       uint32_t   /* reserved */ : 18;
-       /* VBL Config */
-       uint32_t   vBlankInterval:14;
-       uint32_t   /* reserved */ : 2;
-       uint32_t   vBlankIntervalEnable:1;
-       uint32_t   /* reserved */ : 15;
-       /* SOF Dummy Line Config */
-       uint32_t   sofDummy:8;
-       uint32_t   /* reserved */ : 24;
-       /* EOF Dummy Line Config */
-       uint32_t   eofDummy:8;
-       uint32_t   /* reserved */ : 24;
-       /* Color Bars Config */
-       uint32_t   unicolorBarSelect:3;
-       uint32_t   /* reserved */ : 1;
-       uint32_t   unicolorBarEnable:1;
-       uint32_t   splitEnable:1;
-       uint32_t   pixelPattern:2;
-       uint32_t   rotatePeriod:6;
-       uint32_t   /* reserved */ : 18;
-       /* Random Config */
-       uint32_t   randomSeed:16;
-       uint32_t   /* reserved */ : 16;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_Bus_Pm_ConfigCmdType {
-       /* VFE Bus Performance Monitor Config */
-       uint32_t  output2YWrPmEnable:1;
-       uint32_t  output2CbcrWrPmEnable:1;
-       uint32_t  output1YWrPmEnable:1;
-       uint32_t  output1CbcrWrPmEnable:1;
-       uint32_t  /* reserved */ : 28;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_asf_info {
-       /* asf max edge  */
-       uint32_t maxEdge:13;
-       uint32_t /* reserved */ : 3;
-       /* HBi count  */
-       uint32_t HBICount:12;
-       uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_camif_stats {
-  uint32_t  pixelCount:14;
-  uint32_t  /* reserved */ : 2;
-  uint32_t  lineCount:14;
-  uint32_t  /* reserved */ : 1;
-  uint32_t  camifHalt:1;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_StatsCmdType {
-       uint32_t  autoFocusEnable:1;
-       uint32_t  axwEnable:1;
-       uint32_t  histEnable:1;
-       uint32_t  clearHistEnable:1;
-       uint32_t  histAutoClearEnable:1;
-       uint32_t  colorConversionEnable:1;
-       uint32_t  /* reserved */ : 26;
-} __attribute__((packed, aligned(4)));
-
-
-struct vfe_statsframe {
-       uint32_t lastPixel:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t lastLine:12;
-       uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_busstats_wrprio {
-       uint32_t afBusPriority:4;
-       uint32_t awbBusPriority:4;
-       uint32_t histBusPriority:4;
-       uint32_t afBusPriorityEn:1;
-       uint32_t awbBusPriorityEn:1;
-       uint32_t histBusPriorityEn:1;
-       uint32_t /* reserved */ : 17;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsaf_update {
-       /* VFE_STATS_AF_CFG */
-       uint32_t windowVOffset:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t windowHOffset:12;
-       uint32_t /* reserved */ : 3;
-       uint32_t windowMode:1;
-
-       /* VFE_STATS_AF_DIM */
-       uint32_t windowHeight:12;
-       uint32_t /* reserved */ : 4;
-       uint32_t windowWidth:12;
-       uint32_t /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsaf_cfg {
-       /* VFE_STATS_AF_GRID_0 */
-       uint32_t  entry00:8;
-       uint32_t  entry01:8;
-       uint32_t  entry02:8;
-       uint32_t  entry03:8;
-
-       /* VFE_STATS_AF_GRID_1 */
-       uint32_t  entry10:8;
-       uint32_t  entry11:8;
-       uint32_t  entry12:8;
-       uint32_t  entry13:8;
-
-       /* VFE_STATS_AF_GRID_2 */
-       uint32_t  entry20:8;
-       uint32_t  entry21:8;
-       uint32_t  entry22:8;
-       uint32_t  entry23:8;
-
-       /* VFE_STATS_AF_GRID_3 */
-       uint32_t  entry30:8;
-       uint32_t  entry31:8;
-       uint32_t  entry32:8;
-       uint32_t  entry33:8;
-
-       /* VFE_STATS_AF_HEADER */
-       uint32_t  afHeader:8;
-       uint32_t  /* reserved */ : 24;
-       /*  VFE_STATS_AF_COEF0 */
-       uint32_t  a00:5;
-       uint32_t  a04:5;
-       uint32_t  fvMax:11;
-       uint32_t  fvMetric:1;
-       uint32_t  /* reserved */ : 10;
-
-       /* VFE_STATS_AF_COEF1 */
-       uint32_t  a20:5;
-       uint32_t  a21:5;
-       uint32_t  a22:5;
-       uint32_t  a23:5;
-       uint32_t  a24:5;
-       uint32_t  /* reserved */ : 7;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsawbae_update {
-       uint32_t  aeRegionCfg:1;
-       uint32_t  aeSubregionCfg:1;
-       uint32_t  /* reserved */ : 14;
-       uint32_t  awbYMin:8;
-       uint32_t  awbYMax:8;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsaxw_hdr_cfg {
-       /* Stats AXW Header Config */
-       uint32_t axwHeader:8;
-       uint32_t /* reserved */ : 24;
-} __attribute__((packed, aligned(4)));
-
-struct vfe_statsawb_update {
-       /* AWB MConfig */
-       uint32_t  m4:8;
-       uint32_t  m3:8;
-       uint32_t  m2:8;
-       uint32_t  m1:8;
-
-       /* AWB CConfig1 */
-       uint32_t  c2:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  c1:12;
-       uint32_t  /* reserved */ : 4;
-
-       /* AWB CConfig2 */
-       uint32_t  c4:12;
-       uint32_t  /* reserved */ : 4;
-       uint32_t  c3:12;
-       uint32_t  /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_SyncTimerCmdType {
-       uint32_t  hsyncCount:12;
-       uint32_t  /* reserved */ : 20;
-       uint32_t  pclkCount:18;
-       uint32_t  /* reserved */ : 14;
-       uint32_t  outputDuration:28;
-       uint32_t  /* reserved */ : 4;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AsyncTimerCmdType {
-       /*  config 0 */
-       uint32_t    inactiveCount:20;
-       uint32_t    repeatCount:10;
-       uint32_t    /* reserved */ : 1;
-       uint32_t    polarity:1;
-       /*  config 1 */
-       uint32_t    activeCount:20;
-       uint32_t    /* reserved */ : 12;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AxiInputCmdType {
-       uint32_t   stripeStartAddr0:32;
-       uint32_t   stripeStartAddr1:32;
-       uint32_t   stripeStartAddr2:32;
-       uint32_t   stripeStartAddr3:32;
-
-       uint32_t   ySize:12;
-       uint32_t   yOffsetDelta:12;
-       uint32_t   /* reserved */ : 8;
-
-       /* bus_stripe_rd_hSize */
-       uint32_t   /* reserved */ : 16;
-       uint32_t   xSizeWord:10;
-       uint32_t   /* reserved */ : 6;
-
-       /* bus_stripe_rd_buffer_cfg */
-       uint32_t   burstLength:2;
-       uint32_t   /* reserved */ : 2;
-       uint32_t   NumOfRows:12;
-       uint32_t   RowIncrement:12;
-       uint32_t   /* reserved */ : 4;
-
-       /* bus_stripe_rd_unpack_cfg */
-       uint32_t   mainUnpackHeight:12;
-       uint32_t   mainUnpackWidth:13;
-       uint32_t   mainUnpackHbiSel:3;
-       uint32_t   mainUnpackPhase:3;
-       uint32_t   /* reserved */ : 1;
-
-       /* bus_stripe_rd_unpack */
-       uint32_t   unpackPattern:32;
-
-       /* bus_stripe_rd_pad_size */
-       uint32_t   padLeft:7;
-       uint32_t   /* reserved */ : 1;
-       uint32_t   padRight:7;
-       uint32_t   /* reserved */ : 1;
-       uint32_t   padTop:7;
-       uint32_t   /* reserved */ : 1;
-       uint32_t   padBottom:7;
-       uint32_t   /* reserved */ : 1;
-
-       /* bus_stripe_rd_pad_L_unpack */
-       uint32_t   leftUnpackPattern0:4;
-       uint32_t   leftUnpackPattern1:4;
-       uint32_t   leftUnpackPattern2:4;
-       uint32_t   leftUnpackPattern3:4;
-       uint32_t   leftUnpackStop0:1;
-       uint32_t   leftUnpackStop1:1;
-       uint32_t   leftUnpackStop2:1;
-       uint32_t   leftUnpackStop3:1;
-       uint32_t   /* reserved */ : 12;
-
-       /* bus_stripe_rd_pad_R_unpack */
-       uint32_t   rightUnpackPattern0:4;
-       uint32_t   rightUnpackPattern1:4;
-       uint32_t   rightUnpackPattern2:4;
-       uint32_t   rightUnpackPattern3:4;
-       uint32_t   rightUnpackStop0:1;
-       uint32_t   rightUnpackStop1:1;
-       uint32_t   rightUnpackStop2:1;
-       uint32_t   rightUnpackStop3:1;
-       uint32_t   /* reserved */ : 12;
-
-       /* bus_stripe_rd_pad_tb_unpack */
-       uint32_t   topUnapckPattern:4;
-       uint32_t   /* reserved */ : 12;
-       uint32_t   bottomUnapckPattern:4;
-       uint32_t   /* reserved */ : 12;
-} __attribute__((packed, aligned(4)));
-
-struct VFE_AxiRdFragIrqEnable {
-       uint32_t stripeRdFragirq0Enable:1;
-       uint32_t stripeRdFragirq1Enable:1;
-       uint32_t stripeRdFragirq2Enable:1;
-       uint32_t stripeRdFragirq3Enable:1;
-       uint32_t   /* reserved */ : 28;
-} __attribute__((packed, aligned(4)));
-
-int vfe_cmd_init(struct msm_vfe_callback *, struct platform_device *, void *);
-void vfe_stats_af_stop(void);
-void vfe_stop(void);
-void vfe_update(void);
-int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *);
-int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *);
-void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *);
-void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *);
-void vfe_start(struct vfe_cmd_start *);
-void vfe_la_update(struct vfe_cmd_la_config *);
-void vfe_la_config(struct vfe_cmd_la_config *);
-void vfe_test_gen_start(struct vfe_cmd_test_gen_start *);
-void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *);
-void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *);
-void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *);
-void vfe_camif_frame_update(struct vfe_cmds_camif_frame *);
-void vfe_color_correction_config(struct vfe_cmd_color_correction_config *);
-void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *);
-void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *);
-void vfe_demosaic_config(struct vfe_cmd_demosaic_config *);
-void vfe_demux_channel_gain_update(struct vfe_cmd_demux_channel_gain_config *);
-void vfe_demux_channel_gain_config(struct vfe_cmd_demux_channel_gain_config *);
-void vfe_black_level_update(struct vfe_cmd_black_level_config *);
-void vfe_black_level_config(struct vfe_cmd_black_level_config *);
-void vfe_asf_update(struct vfe_cmd_asf_update *);
-void vfe_asf_config(struct vfe_cmd_asf_config *);
-void vfe_white_balance_config(struct vfe_cmd_white_balance_config *);
-void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *);
-void vfe_roll_off_config(struct vfe_cmd_roll_off_config *);
-void vfe_chroma_subsample_config(struct vfe_cmd_chroma_subsample_config *);
-void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *);
-void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *);
-void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *);
-void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *);
-void vfe_stats_wb_exp_stop(void);
-void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *);
-void vfe_stats_update_af(struct vfe_cmd_stats_af_update *);
-void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *);
-void vfe_stats_start_af(struct vfe_cmd_stats_af_start *);
-void vfe_stats_setting(struct vfe_cmd_stats_setting *);
-void vfe_axi_input_config(struct vfe_cmd_axi_input_config *);
-void vfe_stats_config(struct vfe_cmd_stats_setting *);
-void vfe_axi_output_config(struct vfe_cmd_axi_output_config *);
-void vfe_camif_config(struct vfe_cmd_camif_config *);
-void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *);
-void vfe_get_hw_version(struct vfe_cmd_hw_version *);
-void vfe_reset(void);
-void vfe_cmd_release(struct platform_device *);
-void vfe_output1_ack(struct vfe_cmd_output_ack *);
-void vfe_output2_ack(struct vfe_cmd_output_ack *);
-#endif /* __MSM_VFE8X_REG_H__ */
diff --git a/drivers/staging/dream/camera/mt9d112.c b/drivers/staging/dream/camera/mt9d112.c
deleted file mode 100644 (file)
index e6f2d51..0000000
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include "mt9d112.h"
-
-/* Micron MT9D112 Registers and their values */
-/* Sensor Core Registers */
-#define  REG_MT9D112_MODEL_ID 0x3000
-#define  MT9D112_MODEL_ID     0x1580
-
-/*  SOC Registers Page 1  */
-#define  REG_MT9D112_SENSOR_RESET     0x301A
-#define  REG_MT9D112_STANDBY_CONTROL  0x3202
-#define  REG_MT9D112_MCU_BOOT         0x3386
-
-struct mt9d112_work {
-       struct work_struct work;
-};
-
-static struct  mt9d112_work *mt9d112_sensorw;
-static struct  i2c_client *mt9d112_client;
-
-struct mt9d112_ctrl {
-       const struct msm_camera_sensor_info *sensordata;
-};
-
-
-static struct mt9d112_ctrl *mt9d112_ctrl;
-
-static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue);
-DECLARE_MUTEX(mt9d112_sem);
-
-
-/*=============================================================
-       EXTERNAL DECLARATIONS
-==============================================================*/
-extern struct mt9d112_reg mt9d112_regs;
-
-
-/*=============================================================*/
-
-static int mt9d112_reset(const struct msm_camera_sensor_info *dev)
-{
-       int rc = 0;
-
-       rc = gpio_request(dev->sensor_reset, "mt9d112");
-
-       if (!rc) {
-               rc = gpio_direction_output(dev->sensor_reset, 0);
-               mdelay(20);
-               rc = gpio_direction_output(dev->sensor_reset, 1);
-       }
-
-       gpio_free(dev->sensor_reset);
-       return rc;
-}
-
-static int32_t mt9d112_i2c_txdata(unsigned short saddr,
-       unsigned char *txdata, int length)
-{
-       struct i2c_msg msg[] = {
-               {
-                       .addr = saddr,
-                       .flags = 0,
-                       .len = length,
-                       .buf = txdata,
-               },
-       };
-
-       if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) {
-               CDBG("mt9d112_i2c_txdata failed\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int32_t mt9d112_i2c_write(unsigned short saddr,
-       unsigned short waddr, unsigned short wdata, enum mt9d112_width width)
-{
-       int32_t rc = -EIO;
-       unsigned char buf[4];
-
-       memset(buf, 0, sizeof(buf));
-       switch (width) {
-       case WORD_LEN: {
-               buf[0] = (waddr & 0xFF00)>>8;
-               buf[1] = (waddr & 0x00FF);
-               buf[2] = (wdata & 0xFF00)>>8;
-               buf[3] = (wdata & 0x00FF);
-
-               rc = mt9d112_i2c_txdata(saddr, buf, 4);
-       }
-               break;
-
-       case BYTE_LEN: {
-               buf[0] = waddr;
-               buf[1] = wdata;
-               rc = mt9d112_i2c_txdata(saddr, buf, 2);
-       }
-               break;
-
-       default:
-               break;
-       }
-
-       if (rc < 0)
-               CDBG(
-               "i2c_write failed, addr = 0x%x, val = 0x%x!\n",
-               waddr, wdata);
-
-       return rc;
-}
-
-static int32_t mt9d112_i2c_write_table(
-       struct mt9d112_i2c_reg_conf const *reg_conf_tbl,
-       int num_of_items_in_table)
-{
-       int i;
-       int32_t rc = -EIO;
-
-       for (i = 0; i < num_of_items_in_table; i++) {
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       reg_conf_tbl->waddr, reg_conf_tbl->wdata,
-                       reg_conf_tbl->width);
-               if (rc < 0)
-                       break;
-               if (reg_conf_tbl->mdelay_time != 0)
-                       mdelay(reg_conf_tbl->mdelay_time);
-               reg_conf_tbl++;
-       }
-
-       return rc;
-}
-
-static int mt9d112_i2c_rxdata(unsigned short saddr,
-       unsigned char *rxdata, int length)
-{
-       struct i2c_msg msgs[] = {
-       {
-               .addr   = saddr,
-               .flags = 0,
-               .len   = 2,
-               .buf   = rxdata,
-       },
-       {
-               .addr   = saddr,
-               .flags = I2C_M_RD,
-               .len   = length,
-               .buf   = rxdata,
-       },
-       };
-
-       if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) {
-               CDBG("mt9d112_i2c_rxdata failed!\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int32_t mt9d112_i2c_read(unsigned short   saddr,
-       unsigned short raddr, unsigned short *rdata, enum mt9d112_width width)
-{
-       int32_t rc = 0;
-       unsigned char buf[4];
-
-       if (!rdata)
-               return -EIO;
-
-       memset(buf, 0, sizeof(buf));
-
-       switch (width) {
-       case WORD_LEN: {
-               buf[0] = (raddr & 0xFF00)>>8;
-               buf[1] = (raddr & 0x00FF);
-
-               rc = mt9d112_i2c_rxdata(saddr, buf, 2);
-               if (rc < 0)
-                       return rc;
-
-               *rdata = buf[0] << 8 | buf[1];
-       }
-               break;
-
-       default:
-               break;
-       }
-
-       if (rc < 0)
-               CDBG("mt9d112_i2c_read failed!\n");
-
-       return rc;
-}
-
-static int32_t mt9d112_set_lens_roll_off(void)
-{
-       int32_t rc = 0;
-       rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0],
-                                                                mt9d112_regs.rftbl_size);
-       return rc;
-}
-
-static long mt9d112_reg_init(void)
-{
-       int32_t array_length;
-       int32_t i;
-       long rc;
-
-       /* PLL Setup Start */
-       rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0],
-                                       mt9d112_regs.plltbl_size);
-
-       if (rc < 0)
-               return rc;
-       /* PLL Setup End   */
-
-       array_length = mt9d112_regs.prev_snap_reg_settings_size;
-
-       /* Configure sensor for Preview mode and Snapshot mode */
-       for (i = 0; i < array_length; i++) {
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                 mt9d112_regs.prev_snap_reg_settings[i].register_address,
-                 mt9d112_regs.prev_snap_reg_settings[i].register_value,
-                 WORD_LEN);
-
-               if (rc < 0)
-                       return rc;
-       }
-
-       /* Configure for Noise Reduction, Saturation and Aperture Correction */
-       array_length = mt9d112_regs.noise_reduction_reg_settings_size;
-
-       for (i = 0; i < array_length; i++) {
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       mt9d112_regs.noise_reduction_reg_settings[i].register_address,
-                       mt9d112_regs.noise_reduction_reg_settings[i].register_value,
-                       WORD_LEN);
-
-               if (rc < 0)
-                       return rc;
-       }
-
-       /* Set Color Kill Saturation point to optimum value */
-       rc =
-       mt9d112_i2c_write(mt9d112_client->addr,
-       0x35A4,
-       0x0593,
-       WORD_LEN);
-       if (rc < 0)
-               return rc;
-
-       rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0],
-                                       mt9d112_regs.stbl_size);
-       if (rc < 0)
-               return rc;
-
-       rc = mt9d112_set_lens_roll_off();
-       if (rc < 0)
-               return rc;
-
-       return 0;
-}
-
-static long mt9d112_set_sensor_mode(int mode)
-{
-       uint16_t clock;
-       long rc = 0;
-
-       switch (mode) {
-       case SENSOR_PREVIEW_MODE:
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x338C, 0xA20C, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x3390, 0x0004, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x338C, 0xA215, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x3390, 0x0004, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x338C, 0xA20B, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x3390, 0x0000, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               clock = 0x0250;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x341C, clock, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x338C, 0xA103, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x3390, 0x0001, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               mdelay(5);
-               break;
-
-       case SENSOR_SNAPSHOT_MODE:
-               /* Switch to lower fps for Snapshot */
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x341C, 0x0120, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x338C, 0xA120, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x3390, 0x0002, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               mdelay(5);
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x338C, 0xA103, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9d112_i2c_write(mt9d112_client->addr,
-                               0x3390, 0x0002, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static long mt9d112_set_effect(int mode, int effect)
-{
-       uint16_t reg_addr;
-       uint16_t reg_val;
-       long rc = 0;
-
-       switch (mode) {
-       case SENSOR_PREVIEW_MODE:
-               /* Context A Special Effects */
-               reg_addr = 0x2799;
-               break;
-
-       case SENSOR_SNAPSHOT_MODE:
-               /* Context B Special Effects */
-               reg_addr = 0x279B;
-               break;
-
-       default:
-               reg_addr = 0x2799;
-               break;
-       }
-
-       switch (effect) {
-       case CAMERA_EFFECT_OFF: {
-               reg_val = 0x6440;
-
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x338C, reg_addr, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x3390, reg_val, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-       }
-                       break;
-
-       case CAMERA_EFFECT_MONO: {
-               reg_val = 0x6441;
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x338C, reg_addr, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x3390, reg_val, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-       }
-               break;
-
-       case CAMERA_EFFECT_NEGATIVE: {
-               reg_val = 0x6443;
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x338C, reg_addr, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x3390, reg_val, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-       }
-               break;
-
-       case CAMERA_EFFECT_SOLARIZE: {
-               reg_val = 0x6445;
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x338C, reg_addr, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x3390, reg_val, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-       }
-               break;
-
-       case CAMERA_EFFECT_SEPIA: {
-               reg_val = 0x6442;
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x338C, reg_addr, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x3390, reg_val, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-       }
-               break;
-
-       case CAMERA_EFFECT_PASTEL:
-       case CAMERA_EFFECT_MOSAIC:
-       case CAMERA_EFFECT_RESIZE:
-               return -EINVAL;
-
-       default: {
-               reg_val = 0x6440;
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x338C, reg_addr, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9d112_i2c_write(mt9d112_client->addr,
-                       0x3390, reg_val, WORD_LEN);
-               if (rc < 0)
-                       return rc;
-
-               return -EINVAL;
-       }
-       }
-
-       /* Refresh Sequencer */
-       rc = mt9d112_i2c_write(mt9d112_client->addr,
-               0x338C, 0xA103, WORD_LEN);
-       if (rc < 0)
-               return rc;
-
-       rc = mt9d112_i2c_write(mt9d112_client->addr,
-               0x3390, 0x0005, WORD_LEN);
-
-       return rc;
-}
-
-static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data)
-{
-       uint16_t model_id = 0;
-       int rc = 0;
-
-       CDBG("init entry \n");
-       rc = mt9d112_reset(data);
-       if (rc < 0) {
-               CDBG("reset failed!\n");
-               goto init_probe_fail;
-       }
-
-       mdelay(5);
-
-       /* Micron suggested Power up block Start:
-       * Put MCU into Reset - Stop MCU */
-       rc = mt9d112_i2c_write(mt9d112_client->addr,
-               REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       /* Pull MCU from Reset - Start MCU */
-       rc = mt9d112_i2c_write(mt9d112_client->addr,
-               REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       mdelay(5);
-
-       /* Micron Suggested - Power up block */
-       rc = mt9d112_i2c_write(mt9d112_client->addr,
-               REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       rc = mt9d112_i2c_write(mt9d112_client->addr,
-               REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       /* FUSED_DEFECT_CORRECTION */
-       rc = mt9d112_i2c_write(mt9d112_client->addr,
-               0x33F4, 0x031D, WORD_LEN);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       mdelay(5);
-
-       /* Micron suggested Power up block End */
-       /* Read the Model ID of the sensor */
-       rc = mt9d112_i2c_read(mt9d112_client->addr,
-               REG_MT9D112_MODEL_ID, &model_id, WORD_LEN);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       CDBG("mt9d112 model_id = 0x%x\n", model_id);
-
-       /* Check if it matches it with the value in Datasheet */
-       if (model_id != MT9D112_MODEL_ID) {
-               rc = -EINVAL;
-               goto init_probe_fail;
-       }
-
-       rc = mt9d112_reg_init();
-       if (rc < 0)
-               goto init_probe_fail;
-
-       return rc;
-
-init_probe_fail:
-       return rc;
-}
-
-int mt9d112_sensor_init(const struct msm_camera_sensor_info *data)
-{
-       int rc = 0;
-
-       mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL);
-       if (!mt9d112_ctrl) {
-               CDBG("mt9d112_init failed!\n");
-               rc = -ENOMEM;
-               goto init_done;
-       }
-
-       if (data)
-               mt9d112_ctrl->sensordata = data;
-
-       /* Input MCLK = 24MHz */
-       msm_camio_clk_rate_set(24000000);
-       mdelay(5);
-
-       msm_camio_camif_pad_reg_reset();
-
-       rc = mt9d112_sensor_init_probe(data);
-       if (rc < 0) {
-               CDBG("mt9d112_sensor_init failed!\n");
-               goto init_fail;
-       }
-
-init_done:
-       return rc;
-
-init_fail:
-       kfree(mt9d112_ctrl);
-       return rc;
-}
-
-static int mt9d112_init_client(struct i2c_client *client)
-{
-       /* Initialize the MSM_CAMI2C Chip */
-       init_waitqueue_head(&mt9d112_wait_queue);
-       return 0;
-}
-
-int mt9d112_sensor_config(void __user *argp)
-{
-       struct sensor_cfg_data cfg_data;
-       long   rc = 0;
-
-       if (copy_from_user(&cfg_data,
-                       (void *)argp,
-                       sizeof(struct sensor_cfg_data)))
-               return -EFAULT;
-
-       /* down(&mt9d112_sem); */
-
-       CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n",
-               cfg_data.cfgtype, cfg_data.mode);
-
-               switch (cfg_data.cfgtype) {
-               case CFG_SET_MODE:
-                       rc = mt9d112_set_sensor_mode(
-                                               cfg_data.mode);
-                       break;
-
-               case CFG_SET_EFFECT:
-                       rc = mt9d112_set_effect(cfg_data.mode,
-                                               cfg_data.cfg.effect);
-                       break;
-
-               case CFG_GET_AF_MAX_STEPS:
-               default:
-                       rc = -EINVAL;
-                       break;
-               }
-
-       /* up(&mt9d112_sem); */
-
-       return rc;
-}
-
-int mt9d112_sensor_release(void)
-{
-       int rc = 0;
-
-       /* down(&mt9d112_sem); */
-
-       kfree(mt9d112_ctrl);
-       /* up(&mt9d112_sem); */
-
-       return rc;
-}
-
-static int mt9d112_i2c_probe(struct i2c_client *client,
-       const struct i2c_device_id *id)
-{
-       int rc = 0;
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-               rc = -ENOTSUPP;
-               goto probe_failure;
-       }
-
-       mt9d112_sensorw =
-               kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL);
-
-       if (!mt9d112_sensorw) {
-               rc = -ENOMEM;
-               goto probe_failure;
-       }
-
-       i2c_set_clientdata(client, mt9d112_sensorw);
-       mt9d112_init_client(client);
-       mt9d112_client = client;
-
-       CDBG("mt9d112_probe succeeded!\n");
-
-       return 0;
-
-probe_failure:
-       kfree(mt9d112_sensorw);
-       mt9d112_sensorw = NULL;
-       CDBG("mt9d112_probe failed!\n");
-       return rc;
-}
-
-static const struct i2c_device_id mt9d112_i2c_id[] = {
-       { "mt9d112", 0},
-       { },
-};
-
-static struct i2c_driver mt9d112_i2c_driver = {
-       .id_table = mt9d112_i2c_id,
-       .probe  = mt9d112_i2c_probe,
-       .remove = __exit_p(mt9d112_i2c_remove),
-       .driver = {
-               .name = "mt9d112",
-       },
-};
-
-static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info,
-                               struct msm_sensor_ctrl *s)
-{
-       int rc = i2c_add_driver(&mt9d112_i2c_driver);
-       if (rc < 0 || mt9d112_client == NULL) {
-               rc = -ENOTSUPP;
-               goto probe_done;
-       }
-
-       /* Input MCLK = 24MHz */
-       msm_camio_clk_rate_set(24000000);
-       mdelay(5);
-
-       rc = mt9d112_sensor_init_probe(info);
-       if (rc < 0)
-               goto probe_done;
-
-       s->s_init = mt9d112_sensor_init;
-       s->s_release = mt9d112_sensor_release;
-       s->s_config  = mt9d112_sensor_config;
-
-probe_done:
-       CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
-       return rc;
-}
-
-static int __mt9d112_probe(struct platform_device *pdev)
-{
-       return msm_camera_drv_start(pdev, mt9d112_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-       .probe = __mt9d112_probe,
-       .driver = {
-               .name = "msm_camera_mt9d112",
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init mt9d112_init(void)
-{
-       return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9d112_init);
diff --git a/drivers/staging/dream/camera/mt9d112.h b/drivers/staging/dream/camera/mt9d112.h
deleted file mode 100644 (file)
index c678996..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#ifndef MT9D112_H
-#define MT9D112_H
-
-#include <linux/types.h>
-#include <mach/camera.h>
-
-enum mt9d112_width {
-       WORD_LEN,
-       BYTE_LEN
-};
-
-struct mt9d112_i2c_reg_conf {
-       unsigned short waddr;
-       unsigned short wdata;
-       enum mt9d112_width width;
-       unsigned short mdelay_time;
-};
-
-struct mt9d112_reg {
-       const struct register_address_value_pair *prev_snap_reg_settings;
-       uint16_t prev_snap_reg_settings_size;
-       const struct register_address_value_pair *noise_reduction_reg_settings;
-       uint16_t noise_reduction_reg_settings_size;
-       const struct mt9d112_i2c_reg_conf *plltbl;
-       uint16_t plltbl_size;
-       const struct mt9d112_i2c_reg_conf *stbl;
-       uint16_t stbl_size;
-       const struct mt9d112_i2c_reg_conf *rftbl;
-       uint16_t rftbl_size;
-};
-
-#endif /* MT9D112_H */
diff --git a/drivers/staging/dream/camera/mt9d112_reg.c b/drivers/staging/dream/camera/mt9d112_reg.c
deleted file mode 100644 (file)
index c52e96f..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#include "mt9d112.h"
-
-struct register_address_value_pair
-preview_snapshot_mode_reg_settings_array[] = {
-       {0x338C, 0x2703},
-       {0x3390, 800},    /* Output Width (P) = 640 */
-       {0x338C, 0x2705},
-       {0x3390, 600},    /* Output Height (P) = 480 */
-       {0x338C, 0x2707},
-       {0x3390, 0x0640}, /* Output Width (S) = 1600 */
-       {0x338C, 0x2709},
-       {0x3390, 0x04B0}, /* Output Height (S) = 1200 */
-       {0x338C, 0x270D},
-       {0x3390, 0x0000}, /* Row Start (P) = 0 */
-       {0x338C, 0x270F},
-       {0x3390, 0x0000}, /* Column Start (P) = 0 */
-       {0x338C, 0x2711},
-       {0x3390, 0x04BD}, /* Row End (P) = 1213 */
-       {0x338C, 0x2713},
-       {0x3390, 0x064D}, /* Column End (P) = 1613 */
-       {0x338C, 0x2715},
-       {0x3390, 0x0000}, /* Extra Delay (P) = 0 */
-       {0x338C, 0x2717},
-       {0x3390, 0x2111}, /* Row Speed (P) = 8465 */
-       {0x338C, 0x2719},
-       {0x3390, 0x046C}, /* Read Mode (P) = 1132 */
-       {0x338C, 0x271B},
-       {0x3390, 0x024F}, /* Sensor_Sample_Time_pck(P) = 591 */
-       {0x338C, 0x271D},
-       {0x3390, 0x0102}, /* Sensor_Fine_Correction(P) = 258 */
-       {0x338C, 0x271F},
-       {0x3390, 0x0279}, /* Sensor_Fine_IT_min(P) = 633 */
-       {0x338C, 0x2721},
-       {0x3390, 0x0155}, /* Sensor_Fine_IT_max_margin(P) = 341 */
-       {0x338C, 0x2723},
-       {0x3390, 659},    /* Frame Lines (P) = 679 */
-       {0x338C, 0x2725},
-       {0x3390, 0x0824}, /* Line Length (P) = 2084 */
-       {0x338C, 0x2727},
-       {0x3390, 0x2020},
-       {0x338C, 0x2729},
-       {0x3390, 0x2020},
-       {0x338C, 0x272B},
-       {0x3390, 0x1020},
-       {0x338C, 0x272D},
-       {0x3390, 0x2007},
-       {0x338C, 0x272F},
-       {0x3390, 0x0004}, /* Row Start(S) = 4 */
-       {0x338C, 0x2731},
-       {0x3390, 0x0004}, /* Column Start(S) = 4 */
-       {0x338C, 0x2733},
-       {0x3390, 0x04BB}, /* Row End(S) = 1211 */
-       {0x338C, 0x2735},
-       {0x3390, 0x064B}, /* Column End(S) = 1611 */
-       {0x338C, 0x2737},
-       {0x3390, 0x04CE}, /* Extra Delay(S) = 1230 */
-       {0x338C, 0x2739},
-       {0x3390, 0x2111}, /* Row Speed(S) = 8465 */
-       {0x338C, 0x273B},
-       {0x3390, 0x0024}, /* Read Mode(S) = 36 */
-       {0x338C, 0x273D},
-       {0x3390, 0x0120}, /* Sensor sample time pck(S) = 288 */
-       {0x338C, 0x2741},
-       {0x3390, 0x0169}, /* Sensor_Fine_IT_min(P) = 361 */
-       {0x338C, 0x2745},
-       {0x3390, 0x04FF}, /* Frame Lines(S) = 1279 */
-       {0x338C, 0x2747},
-       {0x3390, 0x0824}, /* Line Length(S) = 2084 */
-       {0x338C, 0x2751},
-       {0x3390, 0x0000}, /* Crop_X0(P) = 0 */
-       {0x338C, 0x2753},
-       {0x3390, 0x0320}, /* Crop_X1(P) = 800 */
-       {0x338C, 0x2755},
-       {0x3390, 0x0000}, /* Crop_Y0(P) = 0 */
-       {0x338C, 0x2757},
-       {0x3390, 0x0258}, /* Crop_Y1(P) = 600 */
-       {0x338C, 0x275F},
-       {0x3390, 0x0000}, /* Crop_X0(S) = 0 */
-       {0x338C, 0x2761},
-       {0x3390, 0x0640}, /* Crop_X1(S) = 1600 */
-       {0x338C, 0x2763},
-       {0x3390, 0x0000}, /* Crop_Y0(S) = 0 */
-       {0x338C, 0x2765},
-       {0x3390, 0x04B0}, /* Crop_Y1(S) = 1200 */
-       {0x338C, 0x222E},
-       {0x3390, 0x00A0}, /* R9 Step = 160 */
-       {0x338C, 0xA408},
-       {0x3390, 0x001F},
-       {0x338C, 0xA409},
-       {0x3390, 0x0021},
-       {0x338C, 0xA40A},
-       {0x3390, 0x0025},
-       {0x338C, 0xA40B},
-       {0x3390, 0x0027},
-       {0x338C, 0x2411},
-       {0x3390, 0x00A0},
-       {0x338C, 0x2413},
-       {0x3390, 0x00C0},
-       {0x338C, 0x2415},
-       {0x3390, 0x00A0},
-       {0x338C, 0x2417},
-       {0x3390, 0x00C0},
-       {0x338C, 0x2799},
-       {0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(P) */
-       {0x338C, 0x279B},
-       {0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(S) */
-};
-
-static struct register_address_value_pair
-noise_reduction_reg_settings_array[] = {
-       {0x338C, 0xA76D},
-       {0x3390, 0x0003},
-       {0x338C, 0xA76E},
-       {0x3390, 0x0003},
-       {0x338C, 0xA76F},
-       {0x3390, 0},
-       {0x338C, 0xA770},
-       {0x3390, 21},
-       {0x338C, 0xA771},
-       {0x3390, 37},
-       {0x338C, 0xA772},
-       {0x3390, 63},
-       {0x338C, 0xA773},
-       {0x3390, 100},
-       {0x338C, 0xA774},
-       {0x3390, 128},
-       {0x338C, 0xA775},
-       {0x3390, 151},
-       {0x338C, 0xA776},
-       {0x3390, 169},
-       {0x338C, 0xA777},
-       {0x3390, 186},
-       {0x338C, 0xA778},
-       {0x3390, 199},
-       {0x338C, 0xA779},
-       {0x3390, 210},
-       {0x338C, 0xA77A},
-       {0x3390, 220},
-       {0x338C, 0xA77B},
-       {0x3390, 228},
-       {0x338C, 0xA77C},
-       {0x3390, 234},
-       {0x338C, 0xA77D},
-       {0x3390, 240},
-       {0x338C, 0xA77E},
-       {0x3390, 244},
-       {0x338C, 0xA77F},
-       {0x3390, 248},
-       {0x338C, 0xA780},
-       {0x3390, 252},
-       {0x338C, 0xA781},
-       {0x3390, 255},
-       {0x338C, 0xA782},
-       {0x3390, 0},
-       {0x338C, 0xA783},
-       {0x3390, 21},
-       {0x338C, 0xA784},
-       {0x3390, 37},
-       {0x338C, 0xA785},
-       {0x3390, 63},
-       {0x338C, 0xA786},
-       {0x3390, 100},
-       {0x338C, 0xA787},
-       {0x3390, 128},
-       {0x338C, 0xA788},
-       {0x3390, 151},
-       {0x338C, 0xA789},
-       {0x3390, 169},
-       {0x338C, 0xA78A},
-       {0x3390, 186},
-       {0x338C, 0xA78B},
-       {0x3390, 199},
-       {0x338C, 0xA78C},
-       {0x3390, 210},
-       {0x338C, 0xA78D},
-       {0x3390, 220},
-       {0x338C, 0xA78E},
-       {0x3390, 228},
-       {0x338C, 0xA78F},
-       {0x3390, 234},
-       {0x338C, 0xA790},
-       {0x3390, 240},
-       {0x338C, 0xA791},
-       {0x3390, 244},
-       {0x338C, 0xA793},
-       {0x3390, 252},
-       {0x338C, 0xA794},
-       {0x3390, 255},
-       {0x338C, 0xA103},
-       {0x3390, 6},
-};
-
-static const struct mt9d112_i2c_reg_conf const lens_roll_off_tbl[] = {
-       { 0x34CE, 0x81A0, WORD_LEN, 0 },
-       { 0x34D0, 0x6331, WORD_LEN, 0 },
-       { 0x34D2, 0x3394, WORD_LEN, 0 },
-       { 0x34D4, 0x9966, WORD_LEN, 0 },
-       { 0x34D6, 0x4B25, WORD_LEN, 0 },
-       { 0x34D8, 0x2670, WORD_LEN, 0 },
-       { 0x34DA, 0x724C, WORD_LEN, 0 },
-       { 0x34DC, 0xFFFD, WORD_LEN, 0 },
-       { 0x34DE, 0x00CA, WORD_LEN, 0 },
-       { 0x34E6, 0x00AC, WORD_LEN, 0 },
-       { 0x34EE, 0x0EE1, WORD_LEN, 0 },
-       { 0x34F6, 0x0D87, WORD_LEN, 0 },
-       { 0x3500, 0xE1F7, WORD_LEN, 0 },
-       { 0x3508, 0x1CF4, WORD_LEN, 0 },
-       { 0x3510, 0x1D28, WORD_LEN, 0 },
-       { 0x3518, 0x1F26, WORD_LEN, 0 },
-       { 0x3520, 0x2220, WORD_LEN, 0 },
-       { 0x3528, 0x333D, WORD_LEN, 0 },
-       { 0x3530, 0x15D9, WORD_LEN, 0 },
-       { 0x3538, 0xCFB8, WORD_LEN, 0 },
-       { 0x354C, 0x05FE, WORD_LEN, 0 },
-       { 0x3544, 0x05F8, WORD_LEN, 0 },
-       { 0x355C, 0x0596, WORD_LEN, 0 },
-       { 0x3554, 0x0611, WORD_LEN, 0 },
-       { 0x34E0, 0x00F2, WORD_LEN, 0 },
-       { 0x34E8, 0x00A8, WORD_LEN, 0 },
-       { 0x34F0, 0x0F7B, WORD_LEN, 0 },
-       { 0x34F8, 0x0CD7, WORD_LEN, 0 },
-       { 0x3502, 0xFEDB, WORD_LEN, 0 },
-       { 0x350A, 0x13E4, WORD_LEN, 0 },
-       { 0x3512, 0x1F2C, WORD_LEN, 0 },
-       { 0x351A, 0x1D20, WORD_LEN, 0 },
-       { 0x3522, 0x2422, WORD_LEN, 0 },
-       { 0x352A, 0x2925, WORD_LEN, 0 },
-       { 0x3532, 0x1D04, WORD_LEN, 0 },
-       { 0x353A, 0xFBF2, WORD_LEN, 0 },
-       { 0x354E, 0x0616, WORD_LEN, 0 },
-       { 0x3546, 0x0597, WORD_LEN, 0 },
-       { 0x355E, 0x05CD, WORD_LEN, 0 },
-       { 0x3556, 0x0529, WORD_LEN, 0 },
-       { 0x34E4, 0x00B2, WORD_LEN, 0 },
-       { 0x34EC, 0x005E, WORD_LEN, 0 },
-       { 0x34F4, 0x0F43, WORD_LEN, 0 },
-       { 0x34FC, 0x0E2F, WORD_LEN, 0 },
-       { 0x3506, 0xF9FC, WORD_LEN, 0 },
-       { 0x350E, 0x0CE4, WORD_LEN, 0 },
-       { 0x3516, 0x1E1E, WORD_LEN, 0 },
-       { 0x351E, 0x1B19, WORD_LEN, 0 },
-       { 0x3526, 0x151B, WORD_LEN, 0 },
-       { 0x352E, 0x1416, WORD_LEN, 0 },
-       { 0x3536, 0x10FC, WORD_LEN, 0 },
-       { 0x353E, 0xC018, WORD_LEN, 0 },
-       { 0x3552, 0x06B4, WORD_LEN, 0 },
-       { 0x354A, 0x0506, WORD_LEN, 0 },
-       { 0x3562, 0x06AB, WORD_LEN, 0 },
-       { 0x355A, 0x063A, WORD_LEN, 0 },
-       { 0x34E2, 0x00E5, WORD_LEN, 0 },
-       { 0x34EA, 0x008B, WORD_LEN, 0 },
-       { 0x34F2, 0x0E4C, WORD_LEN, 0 },
-       { 0x34FA, 0x0CA3, WORD_LEN, 0 },
-       { 0x3504, 0x0907, WORD_LEN, 0 },
-       { 0x350C, 0x1DFD, WORD_LEN, 0 },
-       { 0x3514, 0x1E24, WORD_LEN, 0 },
-       { 0x351C, 0x2529, WORD_LEN, 0 },
-       { 0x3524, 0x1D20, WORD_LEN, 0 },
-       { 0x352C, 0x2332, WORD_LEN, 0 },
-       { 0x3534, 0x10E9, WORD_LEN, 0 },
-       { 0x353C, 0x0BCB, WORD_LEN, 0 },
-       { 0x3550, 0x04EF, WORD_LEN, 0 },
-       { 0x3548, 0x0609, WORD_LEN, 0 },
-       { 0x3560, 0x0580, WORD_LEN, 0 },
-       { 0x3558, 0x05DD, WORD_LEN, 0 },
-       { 0x3540, 0x0000, WORD_LEN, 0 },
-       { 0x3542, 0x0000, WORD_LEN, 0 }
-};
-
-static const struct mt9d112_i2c_reg_conf const pll_setup_tbl[] = {
-       { 0x341E, 0x8F09, WORD_LEN, 0 },
-       { 0x341C, 0x0250, WORD_LEN, 0 },
-       { 0x341E, 0x8F09, WORD_LEN, 5 },
-       { 0x341E, 0x8F08, WORD_LEN, 0 }
-};
-
-/* Refresh Sequencer */
-static const struct mt9d112_i2c_reg_conf const sequencer_tbl[] = {
-       { 0x338C, 0x2799, WORD_LEN, 0},
-       { 0x3390, 0x6440, WORD_LEN, 5},
-       { 0x338C, 0x279B, WORD_LEN, 0},
-       { 0x3390, 0x6440, WORD_LEN, 5},
-       { 0x338C, 0xA103, WORD_LEN, 0},
-       { 0x3390, 0x0005, WORD_LEN, 5},
-       { 0x338C, 0xA103, WORD_LEN, 0},
-       { 0x3390, 0x0006, WORD_LEN, 5}
-};
-
-struct mt9d112_reg mt9d112_regs = {
-       .prev_snap_reg_settings = &preview_snapshot_mode_reg_settings_array[0],
-       .prev_snap_reg_settings_size = ARRAY_SIZE(preview_snapshot_mode_reg_settings_array),
-       .noise_reduction_reg_settings = &noise_reduction_reg_settings_array[0],
-       .noise_reduction_reg_settings_size = ARRAY_SIZE(noise_reduction_reg_settings_array),
-       .plltbl = pll_setup_tbl,
-       .plltbl_size = ARRAY_SIZE(pll_setup_tbl),
-       .stbl = sequencer_tbl,
-       .stbl_size = ARRAY_SIZE(sequencer_tbl),
-       .rftbl = lens_roll_off_tbl,
-       .rftbl_size = ARRAY_SIZE(lens_roll_off_tbl)
-};
-
-
-
diff --git a/drivers/staging/dream/camera/mt9p012.h b/drivers/staging/dream/camera/mt9p012.h
deleted file mode 100644 (file)
index 678a002..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-
-#ifndef MT9T012_H
-#define MT9T012_H
-
-#include <linux/types.h>
-
-struct reg_struct {
-       uint16_t vt_pix_clk_div;     /* 0x0300 */
-       uint16_t vt_sys_clk_div;     /* 0x0302 */
-       uint16_t pre_pll_clk_div;    /* 0x0304 */
-       uint16_t pll_multiplier;     /* 0x0306 */
-       uint16_t op_pix_clk_div;     /* 0x0308 */
-       uint16_t op_sys_clk_div;     /* 0x030A */
-       uint16_t scale_m;            /* 0x0404 */
-       uint16_t row_speed;          /* 0x3016 */
-       uint16_t x_addr_start;       /* 0x3004 */
-       uint16_t x_addr_end;         /* 0x3008 */
-       uint16_t y_addr_start;       /* 0x3002 */
-       uint16_t y_addr_end;         /* 0x3006 */
-       uint16_t read_mode;          /* 0x3040 */
-       uint16_t x_output_size ;     /* 0x034C */
-       uint16_t y_output_size;      /* 0x034E */
-       uint16_t line_length_pck;    /* 0x300C */
-       uint16_t frame_length_lines; /* 0x300A */
-       uint16_t coarse_int_time;    /* 0x3012 */
-       uint16_t fine_int_time;      /* 0x3014 */
-};
-
-
-struct mt9p012_i2c_reg_conf {
-       unsigned short waddr;
-       unsigned short wdata;
-};
-
-
-struct mt9p012_reg {
-       struct reg_struct *reg_pat;
-       uint16_t reg_pat_size;
-       struct mt9p012_i2c_reg_conf *ttbl;
-       uint16_t ttbl_size;
-       struct mt9p012_i2c_reg_conf *lctbl;
-       uint16_t lctbl_size;
-       struct mt9p012_i2c_reg_conf *rftbl;
-       uint16_t rftbl_size;
-};
-
-#endif /* MT9T012_H */
diff --git a/drivers/staging/dream/camera/mt9p012_fox.c b/drivers/staging/dream/camera/mt9p012_fox.c
deleted file mode 100644 (file)
index 791bd6c..0000000
+++ /dev/null
@@ -1,1306 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/kernel.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "mt9p012.h"
-
-/*=============================================================
-    SENSOR REGISTER DEFINES
-==============================================================*/
-#define MT9P012_REG_MODEL_ID         0x0000
-#define MT9P012_MODEL_ID             0x2801
-#define REG_GROUPED_PARAMETER_HOLD   0x0104
-#define GROUPED_PARAMETER_HOLD       0x0100
-#define GROUPED_PARAMETER_UPDATE     0x0000
-#define REG_COARSE_INT_TIME          0x3012
-#define REG_VT_PIX_CLK_DIV           0x0300
-#define REG_VT_SYS_CLK_DIV           0x0302
-#define REG_PRE_PLL_CLK_DIV          0x0304
-#define REG_PLL_MULTIPLIER           0x0306
-#define REG_OP_PIX_CLK_DIV           0x0308
-#define REG_OP_SYS_CLK_DIV           0x030A
-#define REG_SCALE_M                  0x0404
-#define REG_FRAME_LENGTH_LINES       0x300A
-#define REG_LINE_LENGTH_PCK          0x300C
-#define REG_X_ADDR_START             0x3004
-#define REG_Y_ADDR_START             0x3002
-#define REG_X_ADDR_END               0x3008
-#define REG_Y_ADDR_END               0x3006
-#define REG_X_OUTPUT_SIZE            0x034C
-#define REG_Y_OUTPUT_SIZE            0x034E
-#define REG_FINE_INTEGRATION_TIME    0x3014
-#define REG_ROW_SPEED                0x3016
-#define MT9P012_REG_RESET_REGISTER   0x301A
-#define MT9P012_RESET_REGISTER_PWON  0x10CC
-#define MT9P012_RESET_REGISTER_PWOFF 0x10C8
-#define REG_READ_MODE                0x3040
-#define REG_GLOBAL_GAIN              0x305E
-#define REG_TEST_PATTERN_MODE        0x3070
-
-#define MT9P012_REV_7
-
-
-enum mt9p012_test_mode {
-       TEST_OFF,
-       TEST_1,
-       TEST_2,
-       TEST_3
-};
-
-enum mt9p012_resolution {
-       QTR_SIZE,
-       FULL_SIZE,
-       INVALID_SIZE
-};
-
-enum mt9p012_reg_update {
-       /* Sensor egisters that need to be updated during initialization */
-       REG_INIT,
-       /* Sensor egisters that needs periodic I2C writes */
-       UPDATE_PERIODIC,
-       /* All the sensor Registers will be updated */
-       UPDATE_ALL,
-       /* Not valid update */
-       UPDATE_INVALID
-};
-
-enum mt9p012_setting {
-       RES_PREVIEW,
-       RES_CAPTURE
-};
-
-/* actuator's Slave Address */
-#define MT9P012_AF_I2C_ADDR   0x18
-
-/* AF Total steps parameters */
-#define MT9P012_STEPS_NEAR_TO_CLOSEST_INF  32
-#define MT9P012_TOTAL_STEPS_NEAR_TO_FAR    32
-
-#define MT9P012_MU5M0_PREVIEW_DUMMY_PIXELS 0
-#define MT9P012_MU5M0_PREVIEW_DUMMY_LINES  0
-
-/* Time in milisecs for waiting for the sensor to reset.*/
-#define MT9P012_RESET_DELAY_MSECS   66
-
-/* for 20 fps preview */
-#define MT9P012_DEFAULT_CLOCK_RATE  24000000
-#define MT9P012_DEFAULT_MAX_FPS     26 /* ???? */
-
-struct mt9p012_work {
-       struct work_struct work;
-};
-static struct mt9p012_work *mt9p012_sensorw;
-static struct i2c_client *mt9p012_client;
-
-struct mt9p012_ctrl {
-       const struct msm_camera_sensor_info *sensordata;
-
-       int sensormode;
-       uint32_t fps_divider; /* init to 1 * 0x00000400 */
-       uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */
-
-       uint16_t curr_lens_pos;
-       uint16_t init_curr_lens_pos;
-       uint16_t my_reg_gain;
-       uint32_t my_reg_line_count;
-
-       enum mt9p012_resolution prev_res;
-       enum mt9p012_resolution pict_res;
-       enum mt9p012_resolution curr_res;
-       enum mt9p012_test_mode  set_test;
-};
-
-
-static struct mt9p012_ctrl *mt9p012_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(mt9p012_wait_queue);
-DECLARE_MUTEX(mt9p012_sem);
-
-/*=============================================================
-       EXTERNAL DECLARATIONS
-==============================================================*/
-extern struct mt9p012_reg mt9p012_regs;        /* from mt9p012_reg.c */
-
-
-
-/*=============================================================*/
-
-static int mt9p012_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
-       int length)
-{
-       struct i2c_msg msgs[] = {
-               {
-                       .addr   = saddr,
-                       .flags = 0,
-                       .len   = 2,
-                       .buf   = rxdata,
-               },
-               {
-                       .addr   = saddr,
-                       .flags = I2C_M_RD,
-                       .len   = length,
-                       .buf   = rxdata,
-               },
-       };
-
-       if (i2c_transfer(mt9p012_client->adapter, msgs, 2) < 0) {
-               CDBG("mt9p012_i2c_rxdata failed!\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int32_t mt9p012_i2c_read_w(unsigned short saddr, unsigned short raddr,
-       unsigned short *rdata)
-{
-       int32_t rc = 0;
-       unsigned char buf[4];
-
-       if (!rdata)
-               return -EIO;
-
-       memset(buf, 0, sizeof(buf));
-
-       buf[0] = (raddr & 0xFF00)>>8;
-       buf[1] = (raddr & 0x00FF);
-
-       rc = mt9p012_i2c_rxdata(saddr, buf, 2);
-       if (rc < 0)
-               return rc;
-
-       *rdata = buf[0] << 8 | buf[1];
-
-       if (rc < 0)
-               CDBG("mt9p012_i2c_read failed!\n");
-
-       return rc;
-}
-
-static int32_t mt9p012_i2c_txdata(unsigned short saddr, unsigned char *txdata,
-       int length)
-{
-       struct i2c_msg msg[] = {
-               {
-               .addr  = saddr,
-               .flags = 0,
-               .len = length,
-               .buf = txdata,
-               },
-       };
-
-       if (i2c_transfer(mt9p012_client->adapter, msg, 1) < 0) {
-               CDBG("mt9p012_i2c_txdata failed\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int32_t mt9p012_i2c_write_b(unsigned short saddr, unsigned short baddr,
-       unsigned short bdata)
-{
-       int32_t rc = -EIO;
-       unsigned char buf[2];
-
-       memset(buf, 0, sizeof(buf));
-       buf[0] = baddr;
-       buf[1] = bdata;
-       rc = mt9p012_i2c_txdata(saddr, buf, 2);
-
-       if (rc < 0)
-               CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
-               saddr, baddr, bdata);
-
-       return rc;
-}
-
-static int32_t mt9p012_i2c_write_w(unsigned short saddr, unsigned short waddr,
-       unsigned short wdata)
-{
-       int32_t rc = -EIO;
-       unsigned char buf[4];
-
-       memset(buf, 0, sizeof(buf));
-       buf[0] = (waddr & 0xFF00)>>8;
-       buf[1] = (waddr & 0x00FF);
-       buf[2] = (wdata & 0xFF00)>>8;
-       buf[3] = (wdata & 0x00FF);
-
-       rc = mt9p012_i2c_txdata(saddr, buf, 4);
-
-       if (rc < 0)
-               CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-                       waddr, wdata);
-
-       return rc;
-}
-
-static int32_t mt9p012_i2c_write_w_table(
-       struct mt9p012_i2c_reg_conf *reg_conf_tbl, int num)
-{
-       int i;
-       int32_t rc = -EIO;
-
-       for (i = 0; i < num; i++) {
-               rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-                       reg_conf_tbl->waddr, reg_conf_tbl->wdata);
-               if (rc < 0)
-                       break;
-               reg_conf_tbl++;
-       }
-
-       return rc;
-}
-
-static int32_t mt9p012_test(enum mt9p012_test_mode mo)
-{
-       int32_t rc = 0;
-
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-               REG_GROUPED_PARAMETER_HOLD,
-               GROUPED_PARAMETER_HOLD);
-       if (rc < 0)
-               return rc;
-
-       if (mo == TEST_OFF)
-               return 0;
-       else {
-               rc = mt9p012_i2c_write_w_table(mt9p012_regs.ttbl, mt9p012_regs.ttbl_size);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-                               REG_TEST_PATTERN_MODE, (uint16_t)mo);
-               if (rc < 0)
-                       return rc;
-       }
-
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-               REG_GROUPED_PARAMETER_HOLD,
-               GROUPED_PARAMETER_UPDATE);
-       if (rc < 0)
-               return rc;
-
-       return rc;
-}
-
-static int32_t mt9p012_lens_shading_enable(uint8_t is_enable)
-{
-       int32_t rc = 0;
-
-       CDBG("%s: entered. enable = %d\n", __func__, is_enable);
-
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-               REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD);
-       if (rc < 0)
-               return rc;
-
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3780,
-               ((uint16_t) is_enable) << 15);
-       if (rc < 0)
-               return rc;
-
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-               REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE);
-
-       CDBG("%s: exiting. rc = %d\n", __func__, rc);
-       return rc;
-}
-
-static int32_t mt9p012_set_lc(void)
-{
-       int32_t rc;
-
-       rc = mt9p012_i2c_write_w_table(mt9p012_regs.lctbl, mt9p012_regs.lctbl_size);
-       if (rc < 0)
-               return rc;
-
-       rc = mt9p012_i2c_write_w_table(mt9p012_regs.rftbl, mt9p012_regs.rftbl_size);
-
-       return rc;
-}
-
-static void mt9p012_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-       /* input fps is preview fps in Q8 format */
-       uint32_t divider;   /*Q10 */
-       uint32_t pclk_mult; /*Q10 */
-
-       if (mt9p012_ctrl->prev_res == QTR_SIZE) {
-               divider = (uint32_t)
-               (((mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines *
-               mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck) * 0x00000400) /
-               (mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines *
-               mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck));
-
-               pclk_mult =
-               (uint32_t) ((mt9p012_regs.reg_pat[RES_CAPTURE].pll_multiplier *
-               0x00000400) / (mt9p012_regs.reg_pat[RES_PREVIEW].pll_multiplier));
-       } else {
-               /* full size resolution used for preview. */
-               divider   = 0x00000400;  /*1.0 */
-               pclk_mult = 0x00000400;  /*1.0 */
-       }
-
-       /* Verify PCLK settings and frame sizes. */
-       *pfps = (uint16_t) (fps * divider * pclk_mult / 0x00000400 /
-               0x00000400);
-}
-
-static uint16_t mt9p012_get_prev_lines_pf(void)
-{
-       if (mt9p012_ctrl->prev_res == QTR_SIZE)
-               return mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines;
-       else
-               return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9p012_get_prev_pixels_pl(void)
-{
-       if (mt9p012_ctrl->prev_res == QTR_SIZE)
-               return mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck;
-       else
-               return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint16_t mt9p012_get_pict_lines_pf(void)
-{
-       return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9p012_get_pict_pixels_pl(void)
-{
-       return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint32_t mt9p012_get_pict_max_exp_lc(void)
-{
-       uint16_t snapshot_lines_per_frame;
-
-       if (mt9p012_ctrl->pict_res == QTR_SIZE)
-               snapshot_lines_per_frame =
-               mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
-       else
-               snapshot_lines_per_frame =
-               mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
-
-       return snapshot_lines_per_frame * 24;
-}
-
-static int32_t mt9p012_set_fps(struct fps_cfg *fps)
-{
-       /* input is new fps in Q10 format */
-       int32_t rc = 0;
-
-       mt9p012_ctrl->fps_divider = fps->fps_div;
-       mt9p012_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-       rc =
-               mt9p012_i2c_write_w(mt9p012_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_HOLD);
-       if (rc < 0)
-               return -EBUSY;
-
-       rc =
-               mt9p012_i2c_write_w(mt9p012_client->addr,
-                       REG_LINE_LENGTH_PCK,
-                       (mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck *
-                       fps->f_mult / 0x00000400));
-       if (rc < 0)
-               return rc;
-
-       rc =
-               mt9p012_i2c_write_w(mt9p012_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_UPDATE);
-
-       return rc;
-}
-
-static int32_t mt9p012_write_exp_gain(uint16_t gain, uint32_t line)
-{
-       uint16_t max_legal_gain = 0x01FF;
-       uint32_t line_length_ratio = 0x00000400;
-       enum mt9p012_setting setting;
-       int32_t rc = 0;
-
-       CDBG("Line:%d mt9p012_write_exp_gain \n", __LINE__);
-
-       if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-               mt9p012_ctrl->my_reg_gain = gain;
-               mt9p012_ctrl->my_reg_line_count = (uint16_t)line;
-       }
-
-       if (gain > max_legal_gain) {
-               CDBG("Max legal gain Line:%d \n", __LINE__);
-               gain = max_legal_gain;
-       }
-
-       /* Verify no overflow */
-       if (mt9p012_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
-               line = (uint32_t)(line * mt9p012_ctrl->fps_divider /
-                       0x00000400);
-               setting = RES_PREVIEW;
-       } else {
-               line = (uint32_t)(line * mt9p012_ctrl->pict_fps_divider /
-                       0x00000400);
-               setting = RES_CAPTURE;
-       }
-
-       /* Set digital gain to 1 */
-#ifdef MT9P012_REV_7
-       gain |= 0x1000;
-#else
-       gain |= 0x0200;
-#endif
-
-       if ((mt9p012_regs.reg_pat[setting].frame_length_lines - 1) < line) {
-               line_length_ratio = (uint32_t) (line * 0x00000400) /
-               (mt9p012_regs.reg_pat[setting].frame_length_lines - 1);
-       } else
-               line_length_ratio = 0x00000400;
-
-       rc =
-               mt9p012_i2c_write_w(mt9p012_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_HOLD);
-       if (rc < 0) {
-               CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-               return rc;
-       }
-
-       rc =
-               mt9p012_i2c_write_w(
-                       mt9p012_client->addr,
-                       REG_GLOBAL_GAIN, gain);
-       if (rc < 0) {
-               CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-               return rc;
-       }
-
-       rc =
-               mt9p012_i2c_write_w(mt9p012_client->addr,
-                       REG_COARSE_INT_TIME,
-                       line);
-       if (rc < 0) {
-               CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-               return rc;
-       }
-
-       CDBG("mt9p012_write_exp_gain: gain = %d, line = %d\n", gain, line);
-
-       rc =
-               mt9p012_i2c_write_w(mt9p012_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_UPDATE);
-       if (rc < 0)
-               CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-
-       return rc;
-}
-
-static int32_t mt9p012_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-       int32_t rc = 0;
-
-       CDBG("Line:%d mt9p012_set_pict_exp_gain \n", __LINE__);
-
-       rc =
-               mt9p012_write_exp_gain(gain, line);
-       if (rc < 0) {
-               CDBG("Line:%d mt9p012_set_pict_exp_gain failed... \n",
-                       __LINE__);
-               return rc;
-       }
-
-       rc =
-       mt9p012_i2c_write_w(mt9p012_client->addr,
-               MT9P012_REG_RESET_REGISTER,
-               0x10CC | 0x0002);
-       if (rc < 0) {
-               CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
-               return rc;
-       }
-
-       mdelay(5);
-
-       /* camera_timed_wait(snapshot_wait*exposure_ratio); */
-       return rc;
-}
-
-static int32_t mt9p012_setting(enum mt9p012_reg_update rupdate,
-       enum mt9p012_setting rt)
-{
-       int32_t rc = 0;
-
-       switch (rupdate) {
-       case UPDATE_PERIODIC:
-       if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-
-               struct mt9p012_i2c_reg_conf ppc_tbl[] = {
-               {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD},
-               {REG_ROW_SPEED, mt9p012_regs.reg_pat[rt].row_speed},
-               {REG_X_ADDR_START, mt9p012_regs.reg_pat[rt].x_addr_start},
-               {REG_X_ADDR_END, mt9p012_regs.reg_pat[rt].x_addr_end},
-               {REG_Y_ADDR_START, mt9p012_regs.reg_pat[rt].y_addr_start},
-               {REG_Y_ADDR_END, mt9p012_regs.reg_pat[rt].y_addr_end},
-               {REG_READ_MODE, mt9p012_regs.reg_pat[rt].read_mode},
-               {REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
-               {REG_X_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].x_output_size},
-               {REG_Y_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].y_output_size},
-
-               {REG_LINE_LENGTH_PCK, mt9p012_regs.reg_pat[rt].line_length_pck},
-               {REG_FRAME_LENGTH_LINES,
-                       (mt9p012_regs.reg_pat[rt].frame_length_lines *
-                       mt9p012_ctrl->fps_divider / 0x00000400)},
-               {REG_COARSE_INT_TIME, mt9p012_regs.reg_pat[rt].coarse_int_time},
-               {REG_FINE_INTEGRATION_TIME, mt9p012_regs.reg_pat[rt].fine_int_time},
-               {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE},
-               };
-
-               rc = mt9p012_i2c_write_w_table(&ppc_tbl[0],
-                       ARRAY_SIZE(ppc_tbl));
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9p012_test(mt9p012_ctrl->set_test);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9p012_i2c_write_w(mt9p012_client->addr,
-                       MT9P012_REG_RESET_REGISTER,
-                       MT9P012_RESET_REGISTER_PWON | 0x0002);
-               if (rc < 0)
-                       return rc;
-
-               mdelay(5); /* 15? wait for sensor to transition*/
-
-               return rc;
-       }
-       break; /* UPDATE_PERIODIC */
-
-       case REG_INIT:
-       if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-               struct mt9p012_i2c_reg_conf ipc_tbl1[] = {
-               {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWOFF},
-               {REG_VT_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
-               {REG_VT_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
-               {REG_PRE_PLL_CLK_DIV, mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
-               {REG_PLL_MULTIPLIER, mt9p012_regs.reg_pat[rt].pll_multiplier},
-               {REG_OP_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].op_pix_clk_div},
-               {REG_OP_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].op_sys_clk_div},
-#ifdef MT9P012_REV_7
-               {0x30B0, 0x0001},
-               {0x308E, 0xE060},
-               {0x3092, 0x0A52},
-               {0x3094, 0x4656},
-               {0x3096, 0x5652},
-               {0x30CA, 0x8006},
-               {0x312A, 0xDD02},
-               {0x312C, 0x00E4},
-               {0x3170, 0x299A},
-#endif
-               /* optimized settings for noise */
-               {0x3088, 0x6FF6},
-               {0x3154, 0x0282},
-               {0x3156, 0x0381},
-               {0x3162, 0x04CE},
-               {0x0204, 0x0010},
-               {0x0206, 0x0010},
-               {0x0208, 0x0010},
-               {0x020A, 0x0010},
-               {0x020C, 0x0010},
-               {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON},
-               };
-
-               struct mt9p012_i2c_reg_conf ipc_tbl2[] = {
-               {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWOFF},
-               {REG_VT_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
-               {REG_VT_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
-               {REG_PRE_PLL_CLK_DIV, mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
-               {REG_PLL_MULTIPLIER, mt9p012_regs.reg_pat[rt].pll_multiplier},
-               {REG_OP_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].op_pix_clk_div},
-               {REG_OP_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].op_sys_clk_div},
-#ifdef MT9P012_REV_7
-               {0x30B0, 0x0001},
-               {0x308E, 0xE060},
-               {0x3092, 0x0A52},
-               {0x3094, 0x4656},
-               {0x3096, 0x5652},
-               {0x30CA, 0x8006},
-               {0x312A, 0xDD02},
-               {0x312C, 0x00E4},
-               {0x3170, 0x299A},
-#endif
-               /* optimized settings for noise */
-               {0x3088, 0x6FF6},
-               {0x3154, 0x0282},
-               {0x3156, 0x0381},
-               {0x3162, 0x04CE},
-               {0x0204, 0x0010},
-               {0x0206, 0x0010},
-               {0x0208, 0x0010},
-               {0x020A, 0x0010},
-               {0x020C, 0x0010},
-               {MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON},
-               };
-
-               struct mt9p012_i2c_reg_conf ipc_tbl3[] = {
-               {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD},
-               /* Set preview or snapshot mode */
-               {REG_ROW_SPEED, mt9p012_regs.reg_pat[rt].row_speed},
-               {REG_X_ADDR_START, mt9p012_regs.reg_pat[rt].x_addr_start},
-               {REG_X_ADDR_END, mt9p012_regs.reg_pat[rt].x_addr_end},
-               {REG_Y_ADDR_START, mt9p012_regs.reg_pat[rt].y_addr_start},
-               {REG_Y_ADDR_END, mt9p012_regs.reg_pat[rt].y_addr_end},
-               {REG_READ_MODE, mt9p012_regs.reg_pat[rt].read_mode},
-               {REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
-               {REG_X_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].x_output_size},
-               {REG_Y_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].y_output_size},
-               {REG_LINE_LENGTH_PCK, mt9p012_regs.reg_pat[rt].line_length_pck},
-               {REG_FRAME_LENGTH_LINES,
-                       mt9p012_regs.reg_pat[rt].frame_length_lines},
-               {REG_COARSE_INT_TIME, mt9p012_regs.reg_pat[rt].coarse_int_time},
-               {REG_FINE_INTEGRATION_TIME, mt9p012_regs.reg_pat[rt].fine_int_time},
-               {REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE},
-               };
-
-               /* reset fps_divider */
-               mt9p012_ctrl->fps_divider = 1 * 0x0400;
-
-               rc = mt9p012_i2c_write_w_table(&ipc_tbl1[0],
-                       ARRAY_SIZE(ipc_tbl1));
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9p012_i2c_write_w_table(&ipc_tbl2[0],
-                       ARRAY_SIZE(ipc_tbl2));
-               if (rc < 0)
-                       return rc;
-
-               mdelay(5);
-
-               rc = mt9p012_i2c_write_w_table(&ipc_tbl3[0],
-                       ARRAY_SIZE(ipc_tbl3));
-               if (rc < 0)
-                       return rc;
-
-               /* load lens shading */
-               rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9p012_set_lc();
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE);
-
-               if (rc < 0)
-                       return rc;
-       }
-       break; /* case REG_INIT: */
-
-       default:
-               rc = -EINVAL;
-               break;
-       } /* switch (rupdate) */
-
-       return rc;
-}
-
-static int32_t mt9p012_video_config(int mode, int res)
-{
-       int32_t rc;
-
-       switch (res) {
-       case QTR_SIZE:
-               rc = mt9p012_setting(UPDATE_PERIODIC, RES_PREVIEW);
-               if (rc < 0)
-                       return rc;
-
-               CDBG("mt9p012 sensor configuration done!\n");
-               break;
-
-       case FULL_SIZE:
-               rc =
-               mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
-               if (rc < 0)
-                       return rc;
-
-               break;
-
-       default:
-               return 0;
-       } /* switch */
-
-       mt9p012_ctrl->prev_res = res;
-       mt9p012_ctrl->curr_res = res;
-       mt9p012_ctrl->sensormode = mode;
-
-       rc =
-               mt9p012_write_exp_gain(mt9p012_ctrl->my_reg_gain,
-                       mt9p012_ctrl->my_reg_line_count);
-
-       rc =
-               mt9p012_i2c_write_w(mt9p012_client->addr,
-                       MT9P012_REG_RESET_REGISTER,
-                       0x10cc|0x0002);
-
-       return rc;
-}
-
-static int32_t mt9p012_snapshot_config(int mode)
-{
-       int32_t rc = 0;
-
-       rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
-       if (rc < 0)
-               return rc;
-
-       mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
-
-       mt9p012_ctrl->sensormode = mode;
-
-       return rc;
-}
-
-static int32_t mt9p012_raw_snapshot_config(int mode)
-{
-       int32_t rc = 0;
-
-       rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
-       if (rc < 0)
-               return rc;
-
-       mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
-
-       mt9p012_ctrl->sensormode = mode;
-
-       return rc;
-}
-
-static int32_t mt9p012_power_down(void)
-{
-       int32_t rc = 0;
-
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-               MT9P012_REG_RESET_REGISTER,
-               MT9P012_RESET_REGISTER_PWOFF);
-
-       mdelay(5);
-       return rc;
-}
-
-static int32_t mt9p012_move_focus(int direction, int32_t num_steps)
-{
-       int16_t step_direction;
-       int16_t actual_step;
-       int16_t next_position;
-       uint8_t code_val_msb, code_val_lsb;
-
-       if (num_steps > MT9P012_TOTAL_STEPS_NEAR_TO_FAR)
-               num_steps = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
-       else if (num_steps == 0) {
-               CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
-               return -EINVAL;
-       }
-
-       if (direction == MOVE_NEAR)
-               step_direction = 16; /* 10bit */
-       else if (direction == MOVE_FAR)
-               step_direction = -16; /* 10 bit */
-       else {
-               CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
-               return -EINVAL;
-       }
-
-       if (mt9p012_ctrl->curr_lens_pos < mt9p012_ctrl->init_curr_lens_pos)
-               mt9p012_ctrl->curr_lens_pos =
-                       mt9p012_ctrl->init_curr_lens_pos;
-
-       actual_step = (int16_t)(step_direction * (int16_t)num_steps);
-       next_position = (int16_t)(mt9p012_ctrl->curr_lens_pos + actual_step);
-
-       if (next_position > 1023)
-               next_position = 1023;
-       else if (next_position < 0)
-               next_position = 0;
-
-       code_val_msb = next_position >> 4;
-       code_val_lsb = (next_position & 0x000F) << 4;
-       /* code_val_lsb |= mode_mask; */
-
-       /* Writing the digital code for current to the actuator */
-       if (mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
-               code_val_msb, code_val_lsb) < 0) {
-               CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
-               return -EBUSY;
-       }
-
-       /* Storing the current lens Position */
-       mt9p012_ctrl->curr_lens_pos = next_position;
-
-       return 0;
-}
-
-static int32_t mt9p012_set_default_focus(void)
-{
-       int32_t rc = 0;
-       uint8_t code_val_msb, code_val_lsb;
-
-       code_val_msb = 0x00;
-       code_val_lsb = 0x00;
-
-       /* Write the digital code for current to the actuator */
-       rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
-               code_val_msb, code_val_lsb);
-
-       mt9p012_ctrl->curr_lens_pos = 0;
-       mt9p012_ctrl->init_curr_lens_pos = 0;
-
-       return rc;
-}
-
-static int mt9p012_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-       gpio_direction_output(data->sensor_reset, 0);
-       gpio_free(data->sensor_reset);
-       return 0;
-}
-
-static int mt9p012_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-       int32_t  rc;
-       uint16_t chipid;
-
-       rc = gpio_request(data->sensor_reset, "mt9p012");
-       if (!rc)
-               gpio_direction_output(data->sensor_reset, 1);
-       else
-               goto init_probe_done;
-
-       mdelay(20);
-
-       /* RESET the sensor image part via I2C command */
-       CDBG("mt9p012_sensor_init(): reseting sensor.\n");
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-               MT9P012_REG_RESET_REGISTER, 0x10CC|0x0001);
-       if (rc < 0) {
-               CDBG("sensor reset failed. rc = %d\n", rc);
-               goto init_probe_fail;
-       }
-
-       mdelay(MT9P012_RESET_DELAY_MSECS);
-
-       /* 3. Read sensor Model ID: */
-       rc = mt9p012_i2c_read_w(mt9p012_client->addr,
-               MT9P012_REG_MODEL_ID, &chipid);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       /* 4. Compare sensor ID to MT9T012VC ID: */
-       if (chipid != MT9P012_MODEL_ID) {
-               CDBG("mt9p012 wrong model_id = 0x%x\n", chipid);
-               rc = -ENODEV;
-               goto init_probe_fail;
-       }
-
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x306E, 0x9000);
-       if (rc < 0) {
-               CDBG("REV_7 write failed. rc = %d\n", rc);
-               goto init_probe_fail;
-       }
-
-       /* RESET_REGISTER, enable parallel interface and disable serialiser */
-       CDBG("mt9p012_sensor_init(): enabling parallel interface.\n");
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x301A, 0x10CC);
-       if (rc < 0) {
-               CDBG("enable parallel interface failed. rc = %d\n", rc);
-               goto init_probe_fail;
-       }
-
-       /* To disable the 2 extra lines */
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-               0x3064, 0x0805);
-
-       if (rc < 0) {
-               CDBG("disable the 2 extra lines failed. rc = %d\n", rc);
-               goto init_probe_fail;
-       }
-
-       mdelay(MT9P012_RESET_DELAY_MSECS);
-       goto init_probe_done;
-
-init_probe_fail:
-       mt9p012_probe_init_done(data);
-init_probe_done:
-       return rc;
-}
-
-static int mt9p012_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-       int32_t  rc;
-
-       mt9p012_ctrl = kzalloc(sizeof(struct mt9p012_ctrl), GFP_KERNEL);
-       if (!mt9p012_ctrl) {
-               CDBG("mt9p012_init failed!\n");
-               rc = -ENOMEM;
-               goto init_done;
-       }
-
-       mt9p012_ctrl->fps_divider = 1 * 0x00000400;
-       mt9p012_ctrl->pict_fps_divider = 1 * 0x00000400;
-       mt9p012_ctrl->set_test = TEST_OFF;
-       mt9p012_ctrl->prev_res = QTR_SIZE;
-       mt9p012_ctrl->pict_res = FULL_SIZE;
-
-       if (data)
-               mt9p012_ctrl->sensordata = data;
-
-       /* enable mclk first */
-       msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
-       mdelay(20);
-
-       msm_camio_camif_pad_reg_reset();
-       mdelay(20);
-
-       rc = mt9p012_probe_init_sensor(data);
-       if (rc < 0)
-               goto init_fail1;
-
-       if (mt9p012_ctrl->prev_res == QTR_SIZE)
-               rc = mt9p012_setting(REG_INIT, RES_PREVIEW);
-       else
-               rc = mt9p012_setting(REG_INIT, RES_CAPTURE);
-
-       if (rc < 0) {
-               CDBG("mt9p012_setting failed. rc = %d\n", rc);
-               goto init_fail1;
-       }
-
-       /* sensor : output enable */
-       CDBG("mt9p012_sensor_open_init(): enabling output.\n");
-       rc = mt9p012_i2c_write_w(mt9p012_client->addr,
-               MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON);
-       if (rc < 0) {
-               CDBG("sensor output enable failed. rc = %d\n", rc);
-               goto init_fail1;
-       }
-
-       /* TODO: enable AF actuator */
-#if 0
-       CDBG("enable AF actuator, gpio = %d\n",
-               mt9p012_ctrl->sensordata->vcm_pwd);
-       rc = gpio_request(mt9p012_ctrl->sensordata->vcm_pwd, "mt9p012");
-       if (!rc)
-               gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 1);
-       else {
-               CDBG("mt9p012_ctrl gpio request failed!\n");
-               goto init_fail1;
-       }
-       mdelay(20);
-
-       rc = mt9p012_set_default_focus();
-#endif
-       if (rc >= 0)
-               goto init_done;
-
-       /* TODO:
-        * gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
-        * gpio_free(mt9p012_ctrl->sensordata->vcm_pwd); */
-init_fail1:
-       mt9p012_probe_init_done(data);
-       kfree(mt9p012_ctrl);
-init_done:
-       return rc;
-}
-
-static int mt9p012_init_client(struct i2c_client *client)
-{
-       /* Initialize the MSM_CAMI2C Chip */
-       init_waitqueue_head(&mt9p012_wait_queue);
-       return 0;
-}
-
-static int32_t mt9p012_set_sensor_mode(int mode, int res)
-{
-       int32_t rc = 0;
-
-       switch (mode) {
-       case SENSOR_PREVIEW_MODE:
-               rc = mt9p012_video_config(mode, res);
-               break;
-
-       case SENSOR_SNAPSHOT_MODE:
-               rc = mt9p012_snapshot_config(mode);
-               break;
-
-       case SENSOR_RAW_SNAPSHOT_MODE:
-               rc = mt9p012_raw_snapshot_config(mode);
-               break;
-
-       default:
-               rc = -EINVAL;
-               break;
-       }
-
-       return rc;
-}
-
-int mt9p012_sensor_config(void __user *argp)
-{
-       struct sensor_cfg_data cdata;
-       int rc = 0;
-
-       if (copy_from_user(&cdata,
-                       (void *)argp,
-                       sizeof(struct sensor_cfg_data)))
-               return -EFAULT;
-
-       down(&mt9p012_sem);
-
-               CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
-       switch (cdata.cfgtype) {
-       case CFG_GET_PICT_FPS:
-               mt9p012_get_pict_fps(cdata.cfg.gfps.prevfps,
-                               &(cdata.cfg.gfps.pictfps));
-
-               if (copy_to_user((void *)argp, &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PREV_L_PF:
-               cdata.cfg.prevl_pf = mt9p012_get_prev_lines_pf();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PREV_P_PL:
-               cdata.cfg.prevp_pl = mt9p012_get_prev_pixels_pl();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PICT_L_PF:
-               cdata.cfg.pictl_pf = mt9p012_get_pict_lines_pf();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PICT_P_PL:
-               cdata.cfg.pictp_pl = mt9p012_get_pict_pixels_pl();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PICT_MAX_EXP_LC:
-               cdata.cfg.pict_max_exp_lc =
-                       mt9p012_get_pict_max_exp_lc();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_SET_FPS:
-       case CFG_SET_PICT_FPS:
-               rc = mt9p012_set_fps(&(cdata.cfg.fps));
-               break;
-
-       case CFG_SET_EXP_GAIN:
-               rc = mt9p012_write_exp_gain(cdata.cfg.exp_gain.gain,
-                               cdata.cfg.exp_gain.line);
-               break;
-
-       case CFG_SET_PICT_EXP_GAIN:
-               CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
-               rc = mt9p012_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
-                               cdata.cfg.exp_gain.line);
-               break;
-
-       case CFG_SET_MODE:
-               rc = mt9p012_set_sensor_mode(cdata.mode, cdata.rs);
-               break;
-
-       case CFG_PWR_DOWN:
-               rc = mt9p012_power_down();
-               break;
-
-       case CFG_MOVE_FOCUS:
-               CDBG("mt9p012_ioctl: CFG_MOVE_FOCUS: cdata.cfg.focus.dir=%d cdata.cfg.focus.steps=%d\n",
-                               cdata.cfg.focus.dir, cdata.cfg.focus.steps);
-               rc = mt9p012_move_focus(cdata.cfg.focus.dir,
-                                       cdata.cfg.focus.steps);
-               break;
-
-       case CFG_SET_DEFAULT_FOCUS:
-               rc = mt9p012_set_default_focus();
-               break;
-
-       case CFG_SET_LENS_SHADING:
-               CDBG("%s: CFG_SET_LENS_SHADING\n", __func__);
-               rc = mt9p012_lens_shading_enable(cdata.cfg.lens_shading);
-               break;
-
-       case CFG_GET_AF_MAX_STEPS:
-               cdata.max_steps = MT9P012_STEPS_NEAR_TO_CLOSEST_INF;
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_SET_EFFECT:
-       default:
-               rc = -EINVAL;
-               break;
-       }
-
-       up(&mt9p012_sem);
-       return rc;
-}
-
-int mt9p012_sensor_release(void)
-{
-       int rc = -EBADF;
-
-       down(&mt9p012_sem);
-
-       mt9p012_power_down();
-
-       gpio_direction_output(mt9p012_ctrl->sensordata->sensor_reset,
-               0);
-       gpio_free(mt9p012_ctrl->sensordata->sensor_reset);
-
-       gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
-       gpio_free(mt9p012_ctrl->sensordata->vcm_pwd);
-
-       kfree(mt9p012_ctrl);
-       mt9p012_ctrl = NULL;
-
-       CDBG("mt9p012_release completed\n");
-
-       up(&mt9p012_sem);
-       return rc;
-}
-
-static int mt9p012_i2c_probe(struct i2c_client *client,
-       const struct i2c_device_id *id)
-{
-       int rc = 0;
-       CDBG("mt9p012_probe called!\n");
-
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-               CDBG("i2c_check_functionality failed\n");
-               goto probe_failure;
-       }
-
-       mt9p012_sensorw = kzalloc(sizeof(struct mt9p012_work), GFP_KERNEL);
-       if (!mt9p012_sensorw) {
-               CDBG("kzalloc failed.\n");
-               rc = -ENOMEM;
-               goto probe_failure;
-       }
-
-       i2c_set_clientdata(client, mt9p012_sensorw);
-       mt9p012_init_client(client);
-       mt9p012_client = client;
-
-       mdelay(50);
-
-       CDBG("mt9p012_probe successed! rc = %d\n", rc);
-       return 0;
-
-probe_failure:
-       CDBG("mt9p012_probe failed! rc = %d\n", rc);
-       return rc;
-}
-
-static const struct i2c_device_id mt9p012_i2c_id[] = {
-       { "mt9p012", 0},
-       { }
-};
-
-static struct i2c_driver mt9p012_i2c_driver = {
-       .id_table = mt9p012_i2c_id,
-       .probe  = mt9p012_i2c_probe,
-       .remove = __exit_p(mt9p012_i2c_remove),
-       .driver = {
-               .name = "mt9p012",
-       },
-};
-
-static int mt9p012_sensor_probe(const struct msm_camera_sensor_info *info,
-                               struct msm_sensor_ctrl *s)
-{
-       int rc = i2c_add_driver(&mt9p012_i2c_driver);
-       if (rc < 0 || mt9p012_client == NULL) {
-               rc = -ENOTSUPP;
-               goto probe_done;
-       }
-
-       msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
-       mdelay(20);
-
-       rc = mt9p012_probe_init_sensor(info);
-       if (rc < 0)
-               goto probe_done;
-
-       s->s_init = mt9p012_sensor_open_init;
-       s->s_release = mt9p012_sensor_release;
-       s->s_config  = mt9p012_sensor_config;
-       mt9p012_probe_init_done(info);
-
-probe_done:
-       CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
-       return rc;
-}
-
-static int __mt9p012_probe(struct platform_device *pdev)
-{
-       return msm_camera_drv_start(pdev, mt9p012_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-       .probe = __mt9p012_probe,
-       .driver = {
-               .name = "msm_camera_mt9p012",
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init mt9p012_init(void)
-{
-       return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9p012_init);
diff --git a/drivers/staging/dream/camera/mt9p012_reg.c b/drivers/staging/dream/camera/mt9p012_reg.c
deleted file mode 100644 (file)
index e5223d6..0000000
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (C) 2009 QUALCOMM Incorporated.
- */
-
-#include "mt9p012.h"
-#include <linux/kernel.h>
-
-/*Micron settings from Applications for lower power consumption.*/
-struct reg_struct mt9p012_reg_pat[2] = {
-       { /* Preview */
-               /* vt_pix_clk_div          REG=0x0300 */
-               6,  /* 5 */
-
-               /* vt_sys_clk_div          REG=0x0302 */
-               1,
-
-               /* pre_pll_clk_div         REG=0x0304 */
-               2,
-
-               /* pll_multiplier          REG=0x0306 */
-               60,
-
-               /* op_pix_clk_div          REG=0x0308 */
-               8,  /* 10 */
-
-               /* op_sys_clk_div          REG=0x030A */
-               1,
-
-               /* scale_m                 REG=0x0404 */
-               16,
-
-               /* row_speed               REG=0x3016 */
-               0x0111,
-
-               /* x_addr_start            REG=0x3004 */
-               8,
-
-               /* x_addr_end              REG=0x3008 */
-               2597,
-
-               /* y_addr_start            REG=0x3002 */
-               8,
-
-               /* y_addr_end              REG=0x3006 */
-               1949,
-
-               /* read_mode               REG=0x3040
-                * Preview 2x2 skipping */
-               0x00C3,
-
-               /* x_output_size           REG=0x034C */
-               1296,
-
-               /* y_output_size           REG=0x034E */
-               972,
-
-               /* line_length_pck         REG=0x300C */
-               3784,
-
-               /* frame_length_lines      REG=0x300A */
-               1057,
-
-               /* coarse_integration_time REG=0x3012 */
-               16,
-
-               /* fine_integration_time   REG=0x3014 */
-               1764
-       },
-       { /*Snapshot*/
-               /* vt_pix_clk_div          REG=0x0300 */
-               6,
-
-               /* vt_sys_clk_div          REG=0x0302 */
-               1,
-
-               /* pre_pll_clk_div         REG=0x0304 */
-               2,
-
-               /* pll_multiplier          REG=0x0306
-                * 60 for 10fps snapshot */
-               60,
-
-               /* op_pix_clk_div          REG=0x0308 */
-               8,
-
-               /* op_sys_clk_div          REG=0x030A */
-               1,
-
-               /* scale_m                 REG=0x0404 */
-               16,
-
-               /* row_speed               REG=0x3016 */
-               0x0111,
-
-               /* x_addr_start            REG=0x3004 */
-               8,
-
-               /* x_addr_end              REG=0x3008 */
-               2615,
-
-               /* y_addr_start            REG=0x3002 */
-               8,
-
-               /* y_addr_end              REG=0x3006 */
-               1967,
-
-               /* read_mode               REG=0x3040 */
-               0x0041,
-
-               /* x_output_size           REG=0x034C */
-               2608,
-
-               /* y_output_size           REG=0x034E */
-               1960,
-
-               /* line_length_pck         REG=0x300C */
-               3911,
-
-               /* frame_length_lines      REG=0x300A //10 fps snapshot */
-               2045,
-
-               /* coarse_integration_time REG=0x3012 */
-               16,
-
-               /* fine_integration_time   REG=0x3014 */
-               882
-       }
-};
-
-
-struct mt9p012_i2c_reg_conf mt9p012_test_tbl[] = {
-       {0x3044, 0x0544 & 0xFBFF},
-       {0x30CA, 0x0004 | 0x0001},
-       {0x30D4, 0x9020 & 0x7FFF},
-       {0x31E0, 0x0003 & 0xFFFE},
-       {0x3180, 0x91FF & 0x7FFF},
-       {0x301A, (0x10CC | 0x8000) & 0xFFF7},
-       {0x301E, 0x0000},
-       {0x3780, 0x0000},
-};
-
-
-struct mt9p012_i2c_reg_conf mt9p012_lc_tbl[] = {
-       /* [Lens shading 85 Percent TL84] */
-       /* P_RD_P0Q0 */
-       {0x360A, 0x7FEF},
-       /* P_RD_P0Q1 */
-       {0x360C, 0x232C},
-       /* P_RD_P0Q2 */
-       {0x360E, 0x7050},
-       /* P_RD_P0Q3 */
-       {0x3610, 0xF3CC},
-       /* P_RD_P0Q4 */
-       {0x3612, 0x89D1},
-       /* P_RD_P1Q0 */
-       {0x364A, 0xBE0D},
-       /* P_RD_P1Q1 */
-       {0x364C, 0x9ACB},
-       /* P_RD_P1Q2 */
-       {0x364E, 0x2150},
-       /* P_RD_P1Q3 */
-       {0x3650, 0xB26B},
-       /* P_RD_P1Q4 */
-       {0x3652, 0x9511},
-       /* P_RD_P2Q0 */
-       {0x368A, 0x2151},
-       /* P_RD_P2Q1 */
-       {0x368C, 0x00AD},
-       /* P_RD_P2Q2 */
-       {0x368E, 0x8334},
-       /* P_RD_P2Q3 */
-       {0x3690, 0x478E},
-       /* P_RD_P2Q4 */
-       {0x3692, 0x0515},
-       /* P_RD_P3Q0 */
-       {0x36CA, 0x0710},
-       /* P_RD_P3Q1 */
-       {0x36CC, 0x452D},
-       /* P_RD_P3Q2 */
-       {0x36CE, 0xF352},
-       /* P_RD_P3Q3 */
-       {0x36D0, 0x190F},
-       /* P_RD_P3Q4 */
-       {0x36D2, 0x4413},
-       /* P_RD_P4Q0 */
-       {0x370A, 0xD112},
-       /* P_RD_P4Q1 */
-       {0x370C, 0xF50F},
-       /* P_RD_P4Q2 */
-       {0x370C, 0xF50F},
-       /* P_RD_P4Q3 */
-       {0x3710, 0xDC11},
-       /* P_RD_P4Q4 */
-       {0x3712, 0xD776},
-       /* P_GR_P0Q0 */
-       {0x3600, 0x1750},
-       /* P_GR_P0Q1 */
-       {0x3602, 0xF0AC},
-       /* P_GR_P0Q2 */
-       {0x3604, 0x4711},
-       /* P_GR_P0Q3 */
-       {0x3606, 0x07CE},
-       /* P_GR_P0Q4 */
-       {0x3608, 0x96B2},
-       /* P_GR_P1Q0 */
-       {0x3640, 0xA9AE},
-       /* P_GR_P1Q1 */
-       {0x3642, 0xF9AC},
-       /* P_GR_P1Q2 */
-       {0x3644, 0x39F1},
-       /* P_GR_P1Q3 */
-       {0x3646, 0x016F},
-       /* P_GR_P1Q4 */
-       {0x3648, 0x8AB2},
-       /* P_GR_P2Q0 */
-       {0x3680, 0x1752},
-       /* P_GR_P2Q1 */
-       {0x3682, 0x70F0},
-       /* P_GR_P2Q2 */
-       {0x3684, 0x83F5},
-       /* P_GR_P2Q3 */
-       {0x3686, 0x8392},
-       /* P_GR_P2Q4 */
-       {0x3688, 0x1FD6},
-       /* P_GR_P3Q0 */
-       {0x36C0, 0x1131},
-       /* P_GR_P3Q1 */
-       {0x36C2, 0x3DAF},
-       /* P_GR_P3Q2 */
-       {0x36C4, 0x89B4},
-       /* P_GR_P3Q3 */
-       {0x36C6, 0xA391},
-       /* P_GR_P3Q4 */
-       {0x36C8, 0x1334},
-       /* P_GR_P4Q0 */
-       {0x3700, 0xDC13},
-       /* P_GR_P4Q1 */
-       {0x3702, 0xD052},
-       /* P_GR_P4Q2 */
-       {0x3704, 0x5156},
-       /* P_GR_P4Q3 */
-       {0x3706, 0x1F13},
-       /* P_GR_P4Q4 */
-       {0x3708, 0x8C38},
-       /* P_BL_P0Q0 */
-       {0x3614, 0x0050},
-       /* P_BL_P0Q1 */
-       {0x3616, 0xBD4C},
-       /* P_BL_P0Q2 */
-       {0x3618, 0x41B0},
-       /* P_BL_P0Q3 */
-       {0x361A, 0x660D},
-       /* P_BL_P0Q4 */
-       {0x361C, 0xC590},
-       /* P_BL_P1Q0 */
-       {0x3654, 0x87EC},
-       /* P_BL_P1Q1 */
-       {0x3656, 0xE44C},
-       /* P_BL_P1Q2 */
-       {0x3658, 0x302E},
-       /* P_BL_P1Q3 */
-       {0x365A, 0x106E},
-       /* P_BL_P1Q4 */
-       {0x365C, 0xB58E},
-       /* P_BL_P2Q0 */
-       {0x3694, 0x0DD1},
-       /* P_BL_P2Q1 */
-       {0x3696, 0x2A50},
-       /* P_BL_P2Q2 */
-       {0x3698, 0xC793},
-       /* P_BL_P2Q3 */
-       {0x369A, 0xE8F1},
-       /* P_BL_P2Q4 */
-       {0x369C, 0x4174},
-       /* P_BL_P3Q0 */
-       {0x36D4, 0x01EF},
-       /* P_BL_P3Q1 */
-       {0x36D6, 0x06CF},
-       /* P_BL_P3Q2 */
-       {0x36D8, 0x8D91},
-       /* P_BL_P3Q3 */
-       {0x36DA, 0x91F0},
-       /* P_BL_P3Q4 */
-       {0x36DC, 0x52EF},
-       /* P_BL_P4Q0 */
-       {0x3714, 0xA6D2},
-       /* P_BL_P4Q1 */
-       {0x3716, 0xA312},
-       /* P_BL_P4Q2 */
-       {0x3718, 0x2695},
-       /* P_BL_P4Q3 */
-       {0x371A, 0x3953},
-       /* P_BL_P4Q4 */
-       {0x371C, 0x9356},
-       /* P_GB_P0Q0 */
-       {0x361E, 0x7EAF},
-       /* P_GB_P0Q1 */
-       {0x3620, 0x2A4C},
-       /* P_GB_P0Q2 */
-       {0x3622, 0x49F0},
-       {0x3624, 0xF1EC},
-       /* P_GB_P0Q4 */
-       {0x3626, 0xC670},
-       /* P_GB_P1Q0 */
-       {0x365E, 0x8E0C},
-       /* P_GB_P1Q1 */
-       {0x3660, 0xC2A9},
-       /* P_GB_P1Q2 */
-       {0x3662, 0x274F},
-       /* P_GB_P1Q3 */
-       {0x3664, 0xADAB},
-       /* P_GB_P1Q4 */
-       {0x3666, 0x8EF0},
-       /* P_GB_P2Q0 */
-       {0x369E, 0x09B1},
-       /* P_GB_P2Q1 */
-       {0x36A0, 0xAA2E},
-       /* P_GB_P2Q2 */
-       {0x36A2, 0xC3D3},
-       /* P_GB_P2Q3 */
-       {0x36A4, 0x7FAF},
-       /* P_GB_P2Q4 */
-       {0x36A6, 0x3F34},
-       /* P_GB_P3Q0 */
-       {0x36DE, 0x4C8F},
-       /* P_GB_P3Q1 */
-       {0x36E0, 0x886E},
-       /* P_GB_P3Q2 */
-       {0x36E2, 0xE831},
-       /* P_GB_P3Q3 */
-       {0x36E4, 0x1FD0},
-       /* P_GB_P3Q4 */
-       {0x36E6, 0x1192},
-       /* P_GB_P4Q0 */
-       {0x371E, 0xB952},
-       /* P_GB_P4Q1 */
-       {0x3720, 0x6DCF},
-       /* P_GB_P4Q2 */
-       {0x3722, 0x1B55},
-       /* P_GB_P4Q3 */
-       {0x3724, 0xA112},
-       /* P_GB_P4Q4 */
-       {0x3726, 0x82F6},
-       /* POLY_ORIGIN_C */
-       {0x3782, 0x0510},
-       /* POLY_ORIGIN_R  */
-       {0x3784, 0x0390},
-       /* POLY_SC_ENABLE */
-       {0x3780, 0x8000},
-};
-
-/* rolloff table for illuminant A */
-struct mt9p012_i2c_reg_conf mt9p012_rolloff_tbl[] = {
-       /* P_RD_P0Q0 */
-       {0x360A, 0x7FEF},
-       /* P_RD_P0Q1 */
-       {0x360C, 0x232C},
-       /* P_RD_P0Q2 */
-       {0x360E, 0x7050},
-       /* P_RD_P0Q3 */
-       {0x3610, 0xF3CC},
-       /* P_RD_P0Q4 */
-       {0x3612, 0x89D1},
-       /* P_RD_P1Q0 */
-       {0x364A, 0xBE0D},
-       /* P_RD_P1Q1 */
-       {0x364C, 0x9ACB},
-       /* P_RD_P1Q2 */
-       {0x364E, 0x2150},
-       /* P_RD_P1Q3 */
-       {0x3650, 0xB26B},
-       /* P_RD_P1Q4 */
-       {0x3652, 0x9511},
-       /* P_RD_P2Q0 */
-       {0x368A, 0x2151},
-       /* P_RD_P2Q1 */
-       {0x368C, 0x00AD},
-       /* P_RD_P2Q2 */
-       {0x368E, 0x8334},
-       /* P_RD_P2Q3 */
-       {0x3690, 0x478E},
-       /* P_RD_P2Q4 */
-       {0x3692, 0x0515},
-       /* P_RD_P3Q0 */
-       {0x36CA, 0x0710},
-       /* P_RD_P3Q1 */
-       {0x36CC, 0x452D},
-       /* P_RD_P3Q2 */
-       {0x36CE, 0xF352},
-       /* P_RD_P3Q3 */
-       {0x36D0, 0x190F},
-       /* P_RD_P3Q4 */
-       {0x36D2, 0x4413},
-       /* P_RD_P4Q0 */
-       {0x370A, 0xD112},
-       /* P_RD_P4Q1 */
-       {0x370C, 0xF50F},
-       /* P_RD_P4Q2 */
-       {0x370E, 0x6375},
-       /* P_RD_P4Q3 */
-       {0x3710, 0xDC11},
-       /* P_RD_P4Q4 */
-       {0x3712, 0xD776},
-       /* P_GR_P0Q0 */
-       {0x3600, 0x1750},
-       /* P_GR_P0Q1 */
-       {0x3602, 0xF0AC},
-       /* P_GR_P0Q2 */
-       {0x3604, 0x4711},
-       /* P_GR_P0Q3 */
-       {0x3606, 0x07CE},
-       /* P_GR_P0Q4 */
-       {0x3608, 0x96B2},
-       /* P_GR_P1Q0 */
-       {0x3640, 0xA9AE},
-       /* P_GR_P1Q1 */
-       {0x3642, 0xF9AC},
-       /* P_GR_P1Q2 */
-       {0x3644, 0x39F1},
-       /* P_GR_P1Q3 */
-       {0x3646, 0x016F},
-       /* P_GR_P1Q4 */
-       {0x3648, 0x8AB2},
-       /* P_GR_P2Q0 */
-       {0x3680, 0x1752},
-       /* P_GR_P2Q1 */
-       {0x3682, 0x70F0},
-       /* P_GR_P2Q2 */
-       {0x3684, 0x83F5},
-       /* P_GR_P2Q3 */
-       {0x3686, 0x8392},
-       /* P_GR_P2Q4 */
-       {0x3688, 0x1FD6},
-       /* P_GR_P3Q0 */
-       {0x36C0, 0x1131},
-       /* P_GR_P3Q1 */
-       {0x36C2, 0x3DAF},
-       /* P_GR_P3Q2 */
-       {0x36C4, 0x89B4},
-       /* P_GR_P3Q3 */
-       {0x36C6, 0xA391},
-       /* P_GR_P3Q4 */
-       {0x36C8, 0x1334},
-       /* P_GR_P4Q0 */
-       {0x3700, 0xDC13},
-       /* P_GR_P4Q1 */
-       {0x3702, 0xD052},
-       /* P_GR_P4Q2 */
-       {0x3704, 0x5156},
-       /* P_GR_P4Q3 */
-       {0x3706, 0x1F13},
-       /* P_GR_P4Q4 */
-       {0x3708, 0x8C38},
-       /* P_BL_P0Q0 */
-       {0x3614, 0x0050},
-       /* P_BL_P0Q1 */
-       {0x3616, 0xBD4C},
-       /* P_BL_P0Q2 */
-       {0x3618, 0x41B0},
-       /* P_BL_P0Q3 */
-       {0x361A, 0x660D},
-       /* P_BL_P0Q4 */
-       {0x361C, 0xC590},
-       /* P_BL_P1Q0 */
-       {0x3654, 0x87EC},
-       /* P_BL_P1Q1 */
-       {0x3656, 0xE44C},
-       /* P_BL_P1Q2 */
-       {0x3658, 0x302E},
-       /* P_BL_P1Q3 */
-       {0x365A, 0x106E},
-       /* P_BL_P1Q4 */
-       {0x365C, 0xB58E},
-       /* P_BL_P2Q0 */
-       {0x3694, 0x0DD1},
-       /* P_BL_P2Q1 */
-       {0x3696, 0x2A50},
-       /* P_BL_P2Q2 */
-       {0x3698, 0xC793},
-       /* P_BL_P2Q3 */
-       {0x369A, 0xE8F1},
-       /* P_BL_P2Q4 */
-       {0x369C, 0x4174},
-       /* P_BL_P3Q0 */
-       {0x36D4, 0x01EF},
-       /* P_BL_P3Q1 */
-       {0x36D6, 0x06CF},
-       /* P_BL_P3Q2 */
-       {0x36D8, 0x8D91},
-       /* P_BL_P3Q3 */
-       {0x36DA, 0x91F0},
-       /* P_BL_P3Q4 */
-       {0x36DC, 0x52EF},
-       /* P_BL_P4Q0 */
-       {0x3714, 0xA6D2},
-       /* P_BL_P4Q1 */
-       {0x3716, 0xA312},
-       /* P_BL_P4Q2 */
-       {0x3718, 0x2695},
-       /* P_BL_P4Q3 */
-       {0x371A, 0x3953},
-       /* P_BL_P4Q4 */
-       {0x371C, 0x9356},
-       /* P_GB_P0Q0 */
-       {0x361E, 0x7EAF},
-       /* P_GB_P0Q1 */
-       {0x3620, 0x2A4C},
-       /* P_GB_P0Q2 */
-       {0x3622, 0x49F0},
-       {0x3624, 0xF1EC},
-       /* P_GB_P0Q4 */
-       {0x3626, 0xC670},
-       /* P_GB_P1Q0 */
-       {0x365E, 0x8E0C},
-       /* P_GB_P1Q1 */
-       {0x3660, 0xC2A9},
-       /* P_GB_P1Q2 */
-       {0x3662, 0x274F},
-       /* P_GB_P1Q3 */
-       {0x3664, 0xADAB},
-       /* P_GB_P1Q4 */
-       {0x3666, 0x8EF0},
-       /* P_GB_P2Q0 */
-       {0x369E, 0x09B1},
-       /* P_GB_P2Q1 */
-       {0x36A0, 0xAA2E},
-       /* P_GB_P2Q2 */
-       {0x36A2, 0xC3D3},
-       /* P_GB_P2Q3 */
-       {0x36A4, 0x7FAF},
-       /* P_GB_P2Q4 */
-       {0x36A6, 0x3F34},
-       /* P_GB_P3Q0 */
-       {0x36DE, 0x4C8F},
-       /* P_GB_P3Q1 */
-       {0x36E0, 0x886E},
-       /* P_GB_P3Q2 */
-       {0x36E2, 0xE831},
-       /* P_GB_P3Q3 */
-       {0x36E4, 0x1FD0},
-       /* P_GB_P3Q4 */
-       {0x36E6, 0x1192},
-       /* P_GB_P4Q0 */
-       {0x371E, 0xB952},
-       /* P_GB_P4Q1 */
-       {0x3720, 0x6DCF},
-       /* P_GB_P4Q2 */
-       {0x3722, 0x1B55},
-       /* P_GB_P4Q3 */
-       {0x3724, 0xA112},
-       /* P_GB_P4Q4 */
-       {0x3726, 0x82F6},
-       /* POLY_ORIGIN_C */
-       {0x3782, 0x0510},
-       /* POLY_ORIGIN_R  */
-       {0x3784, 0x0390},
-       /* POLY_SC_ENABLE */
-       {0x3780, 0x8000},
-};
-
-
-struct mt9p012_reg mt9p012_regs = {
-       .reg_pat = &mt9p012_reg_pat[0],
-       .reg_pat_size = ARRAY_SIZE(mt9p012_reg_pat),
-       .ttbl = &mt9p012_test_tbl[0],
-       .ttbl_size = ARRAY_SIZE(mt9p012_test_tbl),
-       .lctbl = &mt9p012_lc_tbl[0],
-       .lctbl_size = ARRAY_SIZE(mt9p012_lc_tbl),
-       .rftbl = &mt9p012_rolloff_tbl[0],
-       .rftbl_size = ARRAY_SIZE(mt9p012_rolloff_tbl)
-};
-
-
diff --git a/drivers/staging/dream/camera/mt9t013.c b/drivers/staging/dream/camera/mt9t013.c
deleted file mode 100644 (file)
index 8fd7727..0000000
+++ /dev/null
@@ -1,1497 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/kernel.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include <asm/mach-types.h>
-#include "mt9t013.h"
-
-/*=============================================================
-       SENSOR REGISTER DEFINES
-==============================================================*/
-#define MT9T013_REG_MODEL_ID            0x0000
-#define MT9T013_MODEL_ID                0x2600
-#define REG_GROUPED_PARAMETER_HOLD   0x0104
-#define GROUPED_PARAMETER_HOLD       0x0100
-#define GROUPED_PARAMETER_UPDATE     0x0000
-#define REG_COARSE_INT_TIME          0x3012
-#define REG_VT_PIX_CLK_DIV           0x0300
-#define REG_VT_SYS_CLK_DIV           0x0302
-#define REG_PRE_PLL_CLK_DIV          0x0304
-#define REG_PLL_MULTIPLIER           0x0306
-#define REG_OP_PIX_CLK_DIV           0x0308
-#define REG_OP_SYS_CLK_DIV           0x030A
-#define REG_SCALE_M                  0x0404
-#define REG_FRAME_LENGTH_LINES       0x300A
-#define REG_LINE_LENGTH_PCK          0x300C
-#define REG_X_ADDR_START             0x3004
-#define REG_Y_ADDR_START             0x3002
-#define REG_X_ADDR_END               0x3008
-#define REG_Y_ADDR_END               0x3006
-#define REG_X_OUTPUT_SIZE            0x034C
-#define REG_Y_OUTPUT_SIZE            0x034E
-#define REG_FINE_INT_TIME            0x3014
-#define REG_ROW_SPEED                0x3016
-#define MT9T013_REG_RESET_REGISTER   0x301A
-#define MT9T013_RESET_REGISTER_PWON  0x10CC
-#define MT9T013_RESET_REGISTER_PWOFF 0x1008 /* 0x10C8 stop streaming*/
-#define REG_READ_MODE                0x3040
-#define REG_GLOBAL_GAIN              0x305E
-#define REG_TEST_PATTERN_MODE        0x3070
-
-
-enum mt9t013_test_mode {
-       TEST_OFF,
-       TEST_1,
-       TEST_2,
-       TEST_3
-};
-
-enum mt9t013_resolution {
-       QTR_SIZE,
-       FULL_SIZE,
-       INVALID_SIZE
-};
-
-enum mt9t013_reg_update {
-       REG_INIT, /* registers that need to be updated during initialization */
-       UPDATE_PERIODIC, /* registers that needs periodic I2C writes */
-       UPDATE_ALL, /* all registers will be updated */
-       UPDATE_INVALID
-};
-
-enum mt9t013_setting {
-       RES_PREVIEW,
-       RES_CAPTURE
-};
-
-/* actuator's Slave Address */
-#define MT9T013_AF_I2C_ADDR   0x18
-
-/*
-* AF Total steps parameters
-*/
-#define MT9T013_TOTAL_STEPS_NEAR_TO_FAR    30
-
-/*
- * Time in milisecs for waiting for the sensor to reset.
- */
-#define MT9T013_RESET_DELAY_MSECS   66
-
-/* for 30 fps preview */
-#define MT9T013_DEFAULT_CLOCK_RATE  24000000
-#define MT9T013_DEFAULT_MAX_FPS     26
-
-
-/* FIXME: Changes from here */
-struct mt9t013_work {
-       struct work_struct work;
-};
-
-static struct  mt9t013_work *mt9t013_sensorw;
-static struct  i2c_client *mt9t013_client;
-
-struct mt9t013_ctrl {
-       const struct msm_camera_sensor_info *sensordata;
-
-       int sensormode;
-       uint32_t fps_divider;           /* init to 1 * 0x00000400 */
-       uint32_t pict_fps_divider;      /* init to 1 * 0x00000400 */
-
-       uint16_t curr_lens_pos;
-       uint16_t init_curr_lens_pos;
-       uint16_t my_reg_gain;
-       uint32_t my_reg_line_count;
-
-       enum mt9t013_resolution prev_res;
-       enum mt9t013_resolution pict_res;
-       enum mt9t013_resolution curr_res;
-       enum mt9t013_test_mode  set_test;
-
-       unsigned short imgaddr;
-};
-
-
-static struct mt9t013_ctrl *mt9t013_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(mt9t013_wait_queue);
-DECLARE_MUTEX(mt9t013_sem);
-
-extern struct mt9t013_reg mt9t013_regs; /* from mt9t013_reg.c */
-
-static int mt9t013_i2c_rxdata(unsigned short saddr,
-       unsigned char *rxdata, int length)
-{
-       struct i2c_msg msgs[] = {
-       {
-               .addr   = saddr,
-               .flags = 0,
-               .len   = 2,
-               .buf   = rxdata,
-       },
-       {
-               .addr  = saddr,
-               .flags = I2C_M_RD,
-               .len   = length,
-               .buf   = rxdata,
-       },
-       };
-
-       if (i2c_transfer(mt9t013_client->adapter, msgs, 2) < 0) {
-               pr_err("mt9t013_i2c_rxdata failed!\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int32_t mt9t013_i2c_read_w(unsigned short saddr,
-       unsigned short raddr, unsigned short *rdata)
-{
-       int32_t rc = 0;
-       unsigned char buf[4];
-
-       if (!rdata)
-               return -EIO;
-
-       memset(buf, 0, sizeof(buf));
-
-       buf[0] = (raddr & 0xFF00)>>8;
-       buf[1] = (raddr & 0x00FF);
-
-       rc = mt9t013_i2c_rxdata(saddr, buf, 2);
-       if (rc < 0)
-               return rc;
-
-       *rdata = buf[0] << 8 | buf[1];
-
-       if (rc < 0)
-               pr_err("mt9t013_i2c_read failed!\n");
-
-       return rc;
-}
-
-static int32_t mt9t013_i2c_txdata(unsigned short saddr,
-       unsigned char *txdata, int length)
-{
-       struct i2c_msg msg[] = {
-       {
-               .addr = saddr,
-               .flags = 0,
-               .len = length,
-               .buf = txdata,
-       },
-       };
-
-       if (i2c_transfer(mt9t013_client->adapter, msg, 1) < 0) {
-               pr_err("mt9t013_i2c_txdata failed\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int32_t mt9t013_i2c_write_b(unsigned short saddr,
-       unsigned short waddr, unsigned short wdata)
-{
-       int32_t rc = -EIO;
-       unsigned char buf[2];
-
-       memset(buf, 0, sizeof(buf));
-       buf[0] = waddr;
-       buf[1] = wdata;
-       rc = mt9t013_i2c_txdata(saddr, buf, 2);
-
-       if (rc < 0)
-               pr_err("i2c_write failed, addr = 0x%x, val = 0x%x!\n",
-               waddr, wdata);
-
-       return rc;
-}
-
-static int32_t mt9t013_i2c_write_w(unsigned short saddr,
-       unsigned short waddr, unsigned short wdata)
-{
-       int32_t rc = -EIO;
-       unsigned char buf[4];
-
-       memset(buf, 0, sizeof(buf));
-       buf[0] = (waddr & 0xFF00)>>8;
-       buf[1] = (waddr & 0x00FF);
-       buf[2] = (wdata & 0xFF00)>>8;
-       buf[3] = (wdata & 0x00FF);
-
-       rc = mt9t013_i2c_txdata(saddr, buf, 4);
-
-       if (rc < 0)
-               pr_err("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-               waddr, wdata);
-
-       return rc;
-}
-
-static int32_t mt9t013_i2c_write_w_table(
-       struct mt9t013_i2c_reg_conf *reg_conf_tbl, int num_of_items_in_table)
-{
-       int i;
-       int32_t rc = -EIO;
-
-       for (i = 0; i < num_of_items_in_table; i++) {
-               rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       reg_conf_tbl->waddr, reg_conf_tbl->wdata);
-               if (rc < 0)
-                       break;
-               reg_conf_tbl++;
-       }
-
-       return rc;
-}
-
-static int32_t mt9t013_test(enum mt9t013_test_mode mo)
-{
-       int32_t rc = 0;
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_HOLD);
-       if (rc < 0)
-               return rc;
-
-       if (mo == TEST_OFF)
-               return 0;
-       else {
-               rc = mt9t013_i2c_write_w_table(mt9t013_regs.ttbl,
-                               mt9t013_regs.ttbl_size);
-               if (rc < 0)
-                       return rc;
-               rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_TEST_PATTERN_MODE, (uint16_t)mo);
-               if (rc < 0)
-                       return rc;
-       }
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_UPDATE);
-       if (rc < 0)
-               return rc;
-
-       return rc;
-}
-
-static int32_t mt9t013_set_lc(void)
-{
-       int32_t rc;
-
-       rc = mt9t013_i2c_write_w_table(mt9t013_regs.lctbl, mt9t013_regs.lctbl_size);
-       if (rc < 0)
-               return rc;
-
-       return rc;
-}
-
-static int32_t mt9t013_set_default_focus(uint8_t af_step)
-{
-       int32_t rc = 0;
-       uint8_t code_val_msb, code_val_lsb;
-       code_val_msb = 0x01;
-       code_val_lsb = af_step;
-
-       /* Write the digital code for current to the actuator */
-       rc = mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
-                       code_val_msb, code_val_lsb);
-
-       mt9t013_ctrl->curr_lens_pos = 0;
-       mt9t013_ctrl->init_curr_lens_pos = 0;
-       return rc;
-}
-
-static void mt9t013_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-       /* input fps is preview fps in Q8 format */
-       uint32_t divider;   /*Q10 */
-       uint32_t pclk_mult; /*Q10 */
-
-       if (mt9t013_ctrl->prev_res == QTR_SIZE) {
-               divider =
-                       (uint32_t)(
-               ((mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines *
-               mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck) *
-               0x00000400) /
-               (mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines *
-               mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck));
-
-               pclk_mult =
-               (uint32_t) ((mt9t013_regs.reg_pat[RES_CAPTURE].pll_multiplier *
-               0x00000400) /
-               (mt9t013_regs.reg_pat[RES_PREVIEW].pll_multiplier));
-
-       } else {
-               /* full size resolution used for preview. */
-               divider   = 0x00000400;  /*1.0 */
-               pclk_mult = 0x00000400;  /*1.0 */
-       }
-
-       /* Verify PCLK settings and frame sizes. */
-       *pfps =
-               (uint16_t) (fps * divider * pclk_mult /
-               0x00000400 / 0x00000400);
-}
-
-static uint16_t mt9t013_get_prev_lines_pf(void)
-{
-       if (mt9t013_ctrl->prev_res == QTR_SIZE)
-               return mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines;
-       else
-               return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9t013_get_prev_pixels_pl(void)
-{
-       if (mt9t013_ctrl->prev_res == QTR_SIZE)
-               return mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck;
-       else
-               return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint16_t mt9t013_get_pict_lines_pf(void)
-{
-       return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
-}
-
-static uint16_t mt9t013_get_pict_pixels_pl(void)
-{
-       return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
-}
-
-static uint32_t mt9t013_get_pict_max_exp_lc(void)
-{
-       uint16_t snapshot_lines_per_frame;
-
-       if (mt9t013_ctrl->pict_res == QTR_SIZE) {
-               snapshot_lines_per_frame =
-               mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
-       } else  {
-               snapshot_lines_per_frame =
-               mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
-       }
-
-       return snapshot_lines_per_frame * 24;
-}
-
-static int32_t mt9t013_set_fps(struct fps_cfg *fps)
-{
-       /* input is new fps in Q8 format */
-       int32_t rc = 0;
-
-       mt9t013_ctrl->fps_divider = fps->fps_div;
-       mt9t013_ctrl->pict_fps_divider = fps->pict_fps_div;
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_HOLD);
-       if (rc < 0)
-               return -EBUSY;
-
-       CDBG("mt9t013_set_fps: fps_div is %d, frame_rate is %d\n",
-                       fps->fps_div,
-                       (uint16_t) (mt9t013_regs.reg_pat[RES_PREVIEW].
-                                               frame_length_lines *
-                                       fps->fps_div/0x00000400));
-
-       CDBG("mt9t013_set_fps: fps_mult is %d, frame_rate is %d\n",
-                       fps->f_mult,
-                       (uint16_t)(mt9t013_regs.reg_pat[RES_PREVIEW].
-                                       line_length_pck *
-                                       fps->f_mult / 0x00000400));
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_LINE_LENGTH_PCK,
-                       (uint16_t) (
-                       mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck *
-                       fps->f_mult / 0x00000400));
-       if (rc < 0)
-               return rc;
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_UPDATE);
-       if (rc < 0)
-               return rc;
-
-       return rc;
-}
-
-static int32_t mt9t013_write_exp_gain(uint16_t gain, uint32_t line)
-{
-       const uint16_t max_legal_gain = 0x01FF;
-       uint32_t line_length_ratio = 0x00000400;
-       enum mt9t013_setting setting;
-       int32_t rc = 0;
-
-       if (mt9t013_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-               mt9t013_ctrl->my_reg_gain = gain;
-               mt9t013_ctrl->my_reg_line_count = (uint16_t) line;
-       }
-
-       if (gain > max_legal_gain)
-               gain = max_legal_gain;
-
-       /* Verify no overflow */
-       if (mt9t013_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
-               line = (uint32_t) (line * mt9t013_ctrl->fps_divider /
-                       0x00000400);
-
-               setting = RES_PREVIEW;
-
-       } else {
-               line = (uint32_t) (line * mt9t013_ctrl->pict_fps_divider /
-                       0x00000400);
-
-               setting = RES_CAPTURE;
-       }
-
-       /*Set digital gain to 1 */
-       gain |= 0x0200;
-
-       if ((mt9t013_regs.reg_pat[setting].frame_length_lines - 1) < line) {
-
-               line_length_ratio =
-               (uint32_t) (line * 0x00000400) /
-               (mt9t013_regs.reg_pat[setting].frame_length_lines - 1);
-       } else
-               line_length_ratio = 0x00000400;
-
-       /* There used to be PARAMETER_HOLD register write before and
-        * after REG_GLOBAL_GAIN & REG_COARSE_INIT_TIME. This causes
-        * aec oscillation. Hence removed. */
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr, REG_GLOBAL_GAIN, gain);
-       if (rc < 0)
-               return rc;
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_COARSE_INT_TIME,
-                       (uint16_t)((uint32_t) line * 0x00000400 /
-                       line_length_ratio));
-       if (rc < 0)
-               return rc;
-
-       return rc;
-}
-
-static int32_t mt9t013_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-       int32_t rc = 0;
-
-       rc = mt9t013_write_exp_gain(gain, line);
-       if (rc < 0)
-               return rc;
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       MT9T013_REG_RESET_REGISTER,
-                       0x10CC | 0x0002);
-
-       mdelay(5);
-
-       /* camera_timed_wait(snapshot_wait*exposure_ratio); */
-       return rc;
-}
-
-static int32_t mt9t013_setting(enum mt9t013_reg_update rupdate,
-       enum mt9t013_setting rt)
-{
-       int32_t rc = 0;
-
-       switch (rupdate) {
-       case UPDATE_PERIODIC: {
-
-       if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-#if 0
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               MT9T013_REG_RESET_REGISTER,
-                               MT9T013_RESET_REGISTER_PWOFF);
-               if (rc < 0)
-                       return rc;
-#endif
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_VT_PIX_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_VT_SYS_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_PRE_PLL_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_PLL_MULTIPLIER,
-                               mt9t013_regs.reg_pat[rt].pll_multiplier);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_OP_PIX_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].op_pix_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_OP_SYS_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].op_sys_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               mdelay(5);
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_GROUPED_PARAMETER_HOLD,
-                               GROUPED_PARAMETER_HOLD);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_ROW_SPEED,
-                               mt9t013_regs.reg_pat[rt].row_speed);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_X_ADDR_START,
-                               mt9t013_regs.reg_pat[rt].x_addr_start);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_X_ADDR_END,
-                               mt9t013_regs.reg_pat[rt].x_addr_end);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_Y_ADDR_START,
-                               mt9t013_regs.reg_pat[rt].y_addr_start);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_Y_ADDR_END,
-                               mt9t013_regs.reg_pat[rt].y_addr_end);
-               if (rc < 0)
-                       return rc;
-
-               if (machine_is_sapphire()) {
-                       if (rt == 0)
-                               rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                                       REG_READ_MODE,
-                                       0x046F);
-                       else
-                               rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                                       REG_READ_MODE,
-                                       0x0027);
-               } else
-                       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                                       REG_READ_MODE,
-                                       mt9t013_regs.reg_pat[rt].read_mode);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_SCALE_M,
-                               mt9t013_regs.reg_pat[rt].scale_m);
-               if (rc < 0)
-                       return rc;
-
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_X_OUTPUT_SIZE,
-                               mt9t013_regs.reg_pat[rt].x_output_size);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_Y_OUTPUT_SIZE,
-                               mt9t013_regs.reg_pat[rt].y_output_size);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_LINE_LENGTH_PCK,
-                               mt9t013_regs.reg_pat[rt].line_length_pck);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_FRAME_LENGTH_LINES,
-                       (mt9t013_regs.reg_pat[rt].frame_length_lines *
-                       mt9t013_ctrl->fps_divider / 0x00000400));
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_COARSE_INT_TIME,
-                       mt9t013_regs.reg_pat[rt].coarse_int_time);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_FINE_INT_TIME,
-                       mt9t013_regs.reg_pat[rt].fine_int_time);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_UPDATE);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9t013_test(mt9t013_ctrl->set_test);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                       MT9T013_REG_RESET_REGISTER,
-                       MT9T013_RESET_REGISTER_PWON);
-               if (rc < 0)
-                       return rc;
-
-               mdelay(5);
-
-               return rc;
-       }
-       }
-               break;
-
-       /*CAMSENSOR_REG_UPDATE_PERIODIC */
-       case REG_INIT: {
-       if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               MT9T013_REG_RESET_REGISTER,
-                               MT9T013_RESET_REGISTER_PWOFF);
-               if (rc < 0)
-                       /* MODE_SELECT, stop streaming */
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_VT_PIX_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_VT_SYS_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_PRE_PLL_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_PLL_MULTIPLIER,
-                               mt9t013_regs.reg_pat[rt].pll_multiplier);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_OP_PIX_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].op_pix_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_OP_SYS_CLK_DIV,
-                               mt9t013_regs.reg_pat[rt].op_sys_clk_div);
-               if (rc < 0)
-                       return rc;
-
-               mdelay(5);
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_GROUPED_PARAMETER_HOLD,
-                               GROUPED_PARAMETER_HOLD);
-               if (rc < 0)
-                       return rc;
-
-               /* additional power saving mode ok around 38.2MHz */
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               0x3084, 0x2409);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               0x3092, 0x0A49);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               0x3094, 0x4949);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               0x3096, 0x4949);
-               if (rc < 0)
-                       return rc;
-
-               /* Set preview or snapshot mode */
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_ROW_SPEED,
-                               mt9t013_regs.reg_pat[rt].row_speed);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_X_ADDR_START,
-                               mt9t013_regs.reg_pat[rt].x_addr_start);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_X_ADDR_END,
-                               mt9t013_regs.reg_pat[rt].x_addr_end);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_Y_ADDR_START,
-                               mt9t013_regs.reg_pat[rt].y_addr_start);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_Y_ADDR_END,
-                               mt9t013_regs.reg_pat[rt].y_addr_end);
-               if (rc < 0)
-                       return rc;
-
-               if (machine_is_sapphire()) {
-                       if (rt == 0)
-                               rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                                       REG_READ_MODE,
-                                       0x046F);
-                       else
-                               rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                                       REG_READ_MODE,
-                                       0x0027);
-               } else
-                       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                                       REG_READ_MODE,
-                                       mt9t013_regs.reg_pat[rt].read_mode);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_SCALE_M,
-                               mt9t013_regs.reg_pat[rt].scale_m);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_X_OUTPUT_SIZE,
-                               mt9t013_regs.reg_pat[rt].x_output_size);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_Y_OUTPUT_SIZE,
-                               mt9t013_regs.reg_pat[rt].y_output_size);
-               if (rc < 0)
-                       return 0;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_LINE_LENGTH_PCK,
-                               mt9t013_regs.reg_pat[rt].line_length_pck);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_FRAME_LENGTH_LINES,
-                               mt9t013_regs.reg_pat[rt].frame_length_lines);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_COARSE_INT_TIME,
-                               mt9t013_regs.reg_pat[rt].coarse_int_time);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_FINE_INT_TIME,
-                               mt9t013_regs.reg_pat[rt].fine_int_time);
-               if (rc < 0)
-                       return rc;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_GROUPED_PARAMETER_HOLD,
-                               GROUPED_PARAMETER_UPDATE);
-                       if (rc < 0)
-                               return rc;
-
-               /* load lens shading */
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_GROUPED_PARAMETER_HOLD,
-                               GROUPED_PARAMETER_HOLD);
-               if (rc < 0)
-                       return rc;
-
-               /* most likely needs to be written only once. */
-               rc = mt9t013_set_lc();
-               if (rc < 0)
-                       return -EBUSY;
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_GROUPED_PARAMETER_HOLD,
-                               GROUPED_PARAMETER_UPDATE);
-               if (rc < 0)
-                       return rc;
-
-               rc = mt9t013_test(mt9t013_ctrl->set_test);
-               if (rc < 0)
-                       return rc;
-
-               mdelay(5);
-
-               rc =
-                       mt9t013_i2c_write_w(mt9t013_client->addr,
-                               MT9T013_REG_RESET_REGISTER,
-                               MT9T013_RESET_REGISTER_PWON);
-               if (rc < 0)
-                       /* MODE_SELECT, stop streaming */
-                       return rc;
-
-               CDBG("!!! mt9t013 !!! PowerOn is done!\n");
-               mdelay(5);
-               return rc;
-               }
-       } /* case CAMSENSOR_REG_INIT: */
-       break;
-
-       /*CAMSENSOR_REG_INIT */
-       default:
-               rc = -EINVAL;
-               break;
-       } /* switch (rupdate) */
-
-       return rc;
-}
-
-static int32_t mt9t013_video_config(int mode, int res)
-{
-       int32_t rc;
-
-       switch (res) {
-       case QTR_SIZE:
-               rc = mt9t013_setting(UPDATE_PERIODIC, RES_PREVIEW);
-               if (rc < 0)
-                       return rc;
-               CDBG("sensor configuration done!\n");
-               break;
-
-       case FULL_SIZE:
-               rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
-               if (rc < 0)
-                       return rc;
-               break;
-
-       default:
-               return -EINVAL;
-       } /* switch */
-
-       mt9t013_ctrl->prev_res = res;
-       mt9t013_ctrl->curr_res = res;
-       mt9t013_ctrl->sensormode = mode;
-
-       return mt9t013_write_exp_gain(mt9t013_ctrl->my_reg_gain,
-                       mt9t013_ctrl->my_reg_line_count);
-}
-
-static int32_t mt9t013_snapshot_config(int mode)
-{
-       int32_t rc = 0;
-
-       rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
-       if (rc < 0)
-               return rc;
-
-       mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
-       mt9t013_ctrl->sensormode = mode;
-       return rc;
-}
-
-static int32_t mt9t013_raw_snapshot_config(int mode)
-{
-       int32_t rc = 0;
-
-       rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
-       if (rc < 0)
-               return rc;
-
-       mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
-       mt9t013_ctrl->sensormode = mode;
-       return rc;
-}
-
-static int32_t mt9t013_power_down(void)
-{
-       int32_t rc = 0;
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       MT9T013_REG_RESET_REGISTER,
-                       MT9T013_RESET_REGISTER_PWOFF);
-       if (rc >= 0)
-               mdelay(5);
-       return rc;
-}
-
-static int32_t mt9t013_move_focus(int direction, int32_t num_steps)
-{
-       int16_t step_direction;
-       int16_t actual_step;
-       int16_t next_position;
-       int16_t break_steps[4];
-       uint8_t code_val_msb, code_val_lsb;
-       int16_t i;
-
-       if (num_steps > MT9T013_TOTAL_STEPS_NEAR_TO_FAR)
-               num_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
-       else if (num_steps == 0)
-               return -EINVAL;
-
-       if (direction == MOVE_NEAR)
-               step_direction = 4;
-       else if (direction == MOVE_FAR)
-               step_direction = -4;
-       else
-               return -EINVAL;
-
-       if (mt9t013_ctrl->curr_lens_pos < mt9t013_ctrl->init_curr_lens_pos)
-               mt9t013_ctrl->curr_lens_pos = mt9t013_ctrl->init_curr_lens_pos;
-
-       actual_step =
-               (int16_t) (step_direction *
-               (int16_t) num_steps);
-
-       for (i = 0; i < 4; i++)
-               break_steps[i] =
-                       actual_step / 4 * (i + 1) - actual_step / 4 * i;
-
-       for (i = 0; i < 4; i++) {
-               next_position =
-               (int16_t)
-               (mt9t013_ctrl->curr_lens_pos + break_steps[i]);
-
-               if (next_position > 255)
-                       next_position = 255;
-               else if (next_position < 0)
-                       next_position = 0;
-
-               code_val_msb =
-               ((next_position >> 4) << 2) |
-               ((next_position << 4) >> 6);
-
-               code_val_lsb =
-               ((next_position & 0x03) << 6);
-
-               /* Writing the digital code for current to the actuator */
-               if (mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
-                               code_val_msb, code_val_lsb) < 0)
-                       return -EBUSY;
-
-               /* Storing the current lens Position */
-               mt9t013_ctrl->curr_lens_pos = next_position;
-
-               if (i < 3)
-                       mdelay(1);
-       } /* for */
-
-       return 0;
-}
-
-static int mt9t013_sensor_init_done(const struct msm_camera_sensor_info *data)
-{
-       gpio_direction_output(data->sensor_reset, 0);
-       gpio_free(data->sensor_reset);
-       return 0;
-}
-
-static int mt9t013_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-       int rc;
-       uint16_t chipid;
-
-       rc = gpio_request(data->sensor_reset, "mt9t013");
-       if (!rc)
-               gpio_direction_output(data->sensor_reset, 1);
-       else
-               goto init_probe_done;
-
-       mdelay(20);
-
-       /* RESET the sensor image part via I2C command */
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-               MT9T013_REG_RESET_REGISTER, 0x1009);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       /* 3. Read sensor Model ID: */
-       rc = mt9t013_i2c_read_w(mt9t013_client->addr,
-               MT9T013_REG_MODEL_ID, &chipid);
-
-       if (rc < 0)
-               goto init_probe_fail;
-
-       CDBG("mt9t013 model_id = 0x%x\n", chipid);
-
-       /* 4. Compare sensor ID to MT9T012VC ID: */
-       if (chipid != MT9T013_MODEL_ID) {
-               rc = -ENODEV;
-               goto init_probe_fail;
-       }
-
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-               0x3064, 0x0805);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       mdelay(MT9T013_RESET_DELAY_MSECS);
-
-       goto init_probe_done;
-
-       /* sensor: output enable */
-#if 0
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-               MT9T013_REG_RESET_REGISTER,
-               MT9T013_RESET_REGISTER_PWON);
-
-       /* if this fails, the sensor is not the MT9T013 */
-       rc = mt9t013_set_default_focus(0);
-#endif
-
-init_probe_fail:
-       gpio_direction_output(data->sensor_reset, 0);
-       gpio_free(data->sensor_reset);
-init_probe_done:
-       return rc;
-}
-
-static int32_t mt9t013_poweron_af(void)
-{
-       int32_t rc = 0;
-
-       /* enable AF actuator */
-       CDBG("enable AF actuator, gpio = %d\n",
-                       mt9t013_ctrl->sensordata->vcm_pwd);
-       rc = gpio_request(mt9t013_ctrl->sensordata->vcm_pwd, "mt9t013");
-       if (!rc) {
-               gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 0);
-               mdelay(20);
-               rc = mt9t013_set_default_focus(0);
-       } else
-               pr_err("%s, gpio_request failed (%d)!\n", __func__, rc);
-       return rc;
-}
-
-static void mt9t013_poweroff_af(void)
-{
-       gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 1);
-       gpio_free(mt9t013_ctrl->sensordata->vcm_pwd);
-}
-
-int mt9t013_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-       int32_t  rc;
-
-       mt9t013_ctrl = kzalloc(sizeof(struct mt9t013_ctrl), GFP_KERNEL);
-       if (!mt9t013_ctrl) {
-               pr_err("mt9t013_init failed!\n");
-               rc = -ENOMEM;
-               goto init_done;
-       }
-
-       mt9t013_ctrl->fps_divider = 1 * 0x00000400;
-       mt9t013_ctrl->pict_fps_divider = 1 * 0x00000400;
-       mt9t013_ctrl->set_test = TEST_OFF;
-       mt9t013_ctrl->prev_res = QTR_SIZE;
-       mt9t013_ctrl->pict_res = FULL_SIZE;
-
-       if (data)
-               mt9t013_ctrl->sensordata = data;
-
-       /* enable mclk first */
-       msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
-       mdelay(20);
-
-       msm_camio_camif_pad_reg_reset();
-       mdelay(20);
-
-       rc = mt9t013_probe_init_sensor(data);
-       if (rc < 0)
-               goto init_fail;
-
-       if (mt9t013_ctrl->prev_res == QTR_SIZE)
-               rc = mt9t013_setting(REG_INIT, RES_PREVIEW);
-       else
-               rc = mt9t013_setting(REG_INIT, RES_CAPTURE);
-
-       if (rc >= 0)
-               rc = mt9t013_poweron_af();
-
-       if (rc < 0)
-               goto init_fail;
-       else
-               goto init_done;
-
-init_fail:
-       kfree(mt9t013_ctrl);
-init_done:
-       return rc;
-}
-
-static int mt9t013_init_client(struct i2c_client *client)
-{
-       /* Initialize the MSM_CAMI2C Chip */
-       init_waitqueue_head(&mt9t013_wait_queue);
-       return 0;
-}
-
-
-static int32_t mt9t013_set_sensor_mode(int mode, int res)
-{
-       int32_t rc = 0;
-       rc = mt9t013_i2c_write_w(mt9t013_client->addr,
-                       REG_GROUPED_PARAMETER_HOLD,
-                       GROUPED_PARAMETER_HOLD);
-       if (rc < 0)
-               return rc;
-
-       switch (mode) {
-       case SENSOR_PREVIEW_MODE:
-               rc = mt9t013_video_config(mode, res);
-               break;
-
-       case SENSOR_SNAPSHOT_MODE:
-               rc = mt9t013_snapshot_config(mode);
-               break;
-
-       case SENSOR_RAW_SNAPSHOT_MODE:
-               rc = mt9t013_raw_snapshot_config(mode);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       /* FIXME: what should we do if rc < 0? */
-       if (rc >= 0)
-               return mt9t013_i2c_write_w(mt9t013_client->addr,
-                               REG_GROUPED_PARAMETER_HOLD,
-                               GROUPED_PARAMETER_UPDATE);
-       return rc;
-}
-
-int mt9t013_sensor_config(void __user *argp)
-{
-       struct sensor_cfg_data cdata;
-       long   rc = 0;
-
-       if (copy_from_user(&cdata, (void *)argp,
-                       sizeof(struct sensor_cfg_data)))
-               return -EFAULT;
-
-       down(&mt9t013_sem);
-
-       CDBG("mt9t013_sensor_config: cfgtype = %d\n", cdata.cfgtype);
-       switch (cdata.cfgtype) {
-       case CFG_GET_PICT_FPS:
-               mt9t013_get_pict_fps(cdata.cfg.gfps.prevfps,
-                               &(cdata.cfg.gfps.pictfps));
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PREV_L_PF:
-               cdata.cfg.prevl_pf = mt9t013_get_prev_lines_pf();
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PREV_P_PL:
-               cdata.cfg.prevp_pl = mt9t013_get_prev_pixels_pl();
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PICT_L_PF:
-               cdata.cfg.pictl_pf = mt9t013_get_pict_lines_pf();
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PICT_P_PL:
-               cdata.cfg.pictp_pl =
-                       mt9t013_get_pict_pixels_pl();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PICT_MAX_EXP_LC:
-               cdata.cfg.pict_max_exp_lc =
-                       mt9t013_get_pict_max_exp_lc();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_SET_FPS:
-       case CFG_SET_PICT_FPS:
-               rc = mt9t013_set_fps(&(cdata.cfg.fps));
-               break;
-
-       case CFG_SET_EXP_GAIN:
-               rc = mt9t013_write_exp_gain(cdata.cfg.exp_gain.gain,
-                               cdata.cfg.exp_gain.line);
-               break;
-
-       case CFG_SET_PICT_EXP_GAIN:
-               rc = mt9t013_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
-                               cdata.cfg.exp_gain.line);
-               break;
-
-       case CFG_SET_MODE:
-               rc = mt9t013_set_sensor_mode(cdata.mode, cdata.rs);
-               break;
-
-       case CFG_PWR_DOWN:
-               rc = mt9t013_power_down();
-               break;
-
-       case CFG_MOVE_FOCUS:
-               rc = mt9t013_move_focus(cdata.cfg.focus.dir,
-                               cdata.cfg.focus.steps);
-               break;
-
-       case CFG_SET_DEFAULT_FOCUS:
-               rc = mt9t013_set_default_focus(cdata.cfg.focus.steps);
-               break;
-
-       case CFG_GET_AF_MAX_STEPS:
-               cdata.max_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_SET_EFFECT:
-       default:
-               rc = -EINVAL;
-               break;
-       }
-
-       up(&mt9t013_sem);
-       return rc;
-}
-
-int mt9t013_sensor_release(void)
-{
-       int rc = -EBADF;
-
-       down(&mt9t013_sem);
-
-       mt9t013_poweroff_af();
-       mt9t013_power_down();
-
-       gpio_direction_output(mt9t013_ctrl->sensordata->sensor_reset,
-                       0);
-       gpio_free(mt9t013_ctrl->sensordata->sensor_reset);
-
-       kfree(mt9t013_ctrl);
-
-       up(&mt9t013_sem);
-       CDBG("mt9t013_release completed!\n");
-       return rc;
-}
-
-static int mt9t013_i2c_probe(struct i2c_client *client,
-       const struct i2c_device_id *id)
-{
-       int rc = 0;
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-               rc = -ENOTSUPP;
-               goto probe_failure;
-       }
-
-       mt9t013_sensorw =
-               kzalloc(sizeof(struct mt9t013_work), GFP_KERNEL);
-
-       if (!mt9t013_sensorw) {
-               rc = -ENOMEM;
-               goto probe_failure;
-       }
-
-       i2c_set_clientdata(client, mt9t013_sensorw);
-       mt9t013_init_client(client);
-       mt9t013_client = client;
-       mt9t013_client->addr = mt9t013_client->addr >> 1;
-       mdelay(50);
-
-       CDBG("i2c probe ok\n");
-       return 0;
-
-probe_failure:
-       kfree(mt9t013_sensorw);
-       mt9t013_sensorw = NULL;
-       pr_err("i2c probe failure %d\n", rc);
-       return rc;
-}
-
-static const struct i2c_device_id mt9t013_i2c_id[] = {
-       { "mt9t013", 0},
-       { }
-};
-
-static struct i2c_driver mt9t013_i2c_driver = {
-       .id_table = mt9t013_i2c_id,
-       .probe  = mt9t013_i2c_probe,
-       .remove = __exit_p(mt9t013_i2c_remove),
-       .driver = {
-               .name = "mt9t013",
-       },
-};
-
-static int mt9t013_sensor_probe(
-               const struct msm_camera_sensor_info *info,
-               struct msm_sensor_ctrl *s)
-{
-       /* We expect this driver to match with the i2c device registered
-        * in the board file immediately. */
-       int rc = i2c_add_driver(&mt9t013_i2c_driver);
-       if (rc < 0 || mt9t013_client == NULL) {
-               rc = -ENOTSUPP;
-               goto probe_done;
-       }
-
-       /* enable mclk first */
-       msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
-       mdelay(20);
-
-       rc = mt9t013_probe_init_sensor(info);
-       if (rc < 0) {
-               i2c_del_driver(&mt9t013_i2c_driver);
-               goto probe_done;
-       }
-
-       s->s_init = mt9t013_sensor_open_init;
-       s->s_release = mt9t013_sensor_release;
-       s->s_config  = mt9t013_sensor_config;
-       mt9t013_sensor_init_done(info);
-
-probe_done:
-       return rc;
-}
-
-static int __mt9t013_probe(struct platform_device *pdev)
-{
-       return msm_camera_drv_start(pdev, mt9t013_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-       .probe = __mt9t013_probe,
-       .driver = {
-               .name = "msm_camera_mt9t013",
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init mt9t013_init(void)
-{
-       return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(mt9t013_init);
diff --git a/drivers/staging/dream/camera/mt9t013.h b/drivers/staging/dream/camera/mt9t013.h
deleted file mode 100644 (file)
index 9bce203..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#ifndef MT9T013_H
-#define MT9T013_H
-
-#include <linux/types.h>
-
-struct reg_struct {
-       uint16_t vt_pix_clk_div;        /*  0x0300 */
-       uint16_t vt_sys_clk_div;        /*  0x0302 */
-       uint16_t pre_pll_clk_div;       /*  0x0304 */
-       uint16_t pll_multiplier;        /*  0x0306 */
-       uint16_t op_pix_clk_div;        /*  0x0308 */
-       uint16_t op_sys_clk_div;        /*  0x030A */
-       uint16_t scale_m;               /*  0x0404 */
-       uint16_t row_speed;             /*  0x3016 */
-       uint16_t x_addr_start;          /*  0x3004 */
-       uint16_t x_addr_end;            /*  0x3008 */
-       uint16_t y_addr_start;          /*  0x3002 */
-       uint16_t y_addr_end;            /*  0x3006 */
-       uint16_t read_mode;             /*  0x3040 */
-       uint16_t x_output_size;         /*  0x034C */
-       uint16_t y_output_size;         /*  0x034E */
-       uint16_t line_length_pck;       /*  0x300C */
-       uint16_t frame_length_lines;    /*  0x300A */
-       uint16_t coarse_int_time;               /*  0x3012 */
-       uint16_t fine_int_time;                 /*  0x3014 */
-};
-
-struct mt9t013_i2c_reg_conf {
-       unsigned short waddr;
-       unsigned short wdata;
-};
-
-struct mt9t013_reg {
-       struct reg_struct *reg_pat;
-       uint16_t reg_pat_size;
-       struct mt9t013_i2c_reg_conf *ttbl;
-       uint16_t ttbl_size;
-       struct mt9t013_i2c_reg_conf *lctbl;
-       uint16_t lctbl_size;
-       struct mt9t013_i2c_reg_conf *rftbl;
-       uint16_t rftbl_size;
-};
-
-#endif /* #define MT9T013_H */
diff --git a/drivers/staging/dream/camera/mt9t013_reg.c b/drivers/staging/dream/camera/mt9t013_reg.c
deleted file mode 100644 (file)
index ba0a1d4..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2009 QUALCOMM Incorporated.
- */
-
-#include "mt9t013.h"
-#include <linux/kernel.h>
-
-struct reg_struct const mt9t013_reg_pat[2] = {
-       { /* Preview 2x2 binning 20fps, pclk MHz, MCLK 24MHz */
-       /* vt_pix_clk_div:REG=0x0300 update get_snapshot_fps
-       * if this change */
-       8,
-
-       /* vt_sys_clk_div: REG=0x0302  update get_snapshot_fps
-       * if this change */
-       1,
-
-       /* pre_pll_clk_div REG=0x0304  update get_snapshot_fps
-       * if this change */
-       2,
-
-       /* pll_multiplier  REG=0x0306 60 for 30fps preview, 40
-        * for 20fps preview
-        * 46 for 30fps preview, try 47/48 to increase further */
-       46,
-
-       /* op_pix_clk_div        REG=0x0308 */
-       8,
-
-       /* op_sys_clk_div        REG=0x030A */
-       1,
-
-       /* scale_m       REG=0x0404 */
-       16,
-
-       /* row_speed     REG=0x3016 */
-       0x0111,
-
-       /* x_addr_start  REG=0x3004 */
-       8,
-
-       /* x_addr_end    REG=0x3008 */
-       2053,
-
-       /* y_addr_start  REG=0x3002 */
-       8,
-
-       /* y_addr_end    REG=0x3006 */
-       1541,
-
-       /* read_mode     REG=0x3040 */
-       0x046C,
-
-       /* x_output_size REG=0x034C */
-       1024,
-
-       /* y_output_size REG=0x034E */
-       768,
-
-       /* line_length_pck    REG=0x300C */
-       2616,
-
-       /* frame_length_lines REG=0x300A */
-       916,
-
-       /* coarse_int_time REG=0x3012 */
-       16,
-
-       /* fine_int_time   REG=0x3014 */
-       1461
-       },
-       { /*Snapshot */
-       /* vt_pix_clk_div  REG=0x0300 update get_snapshot_fps
-       * if this change */
-       8,
-
-       /* vt_sys_clk_div  REG=0x0302 update get_snapshot_fps
-       * if this change */
-       1,
-
-       /* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
-        * if this change */
-       2,
-
-       /* pll_multiplier REG=0x0306 50 for 15fps snapshot,
-        * 40 for 10fps snapshot
-        * 46 for 30fps snapshot, try 47/48 to increase further */
-       46,
-
-       /* op_pix_clk_div        REG=0x0308 */
-       8,
-
-       /* op_sys_clk_div        REG=0x030A */
-       1,
-
-       /* scale_m       REG=0x0404 */
-       16,
-
-       /* row_speed     REG=0x3016 */
-       0x0111,
-
-       /* x_addr_start  REG=0x3004 */
-       8,
-
-       /* x_addr_end    REG=0x3008 */
-       2071,
-
-       /* y_addr_start  REG=0x3002 */
-       8,
-
-       /* y_addr_end    REG=0x3006 */
-       1551,
-
-       /* read_mode     REG=0x3040 */
-       0x0024,
-
-       /* x_output_size REG=0x034C */
-       2064,
-
-       /* y_output_size REG=0x034E */
-       1544,
-
-       /* line_length_pck REG=0x300C */
-       2952,
-
-       /* frame_length_lines    REG=0x300A */
-       1629,
-
-       /* coarse_int_time REG=0x3012 */
-       16,
-
-       /* fine_int_time REG=0x3014   */
-       733
-       }
-};
-
-struct mt9t013_i2c_reg_conf mt9t013_test_tbl[] = {
-       { 0x3044, 0x0544 & 0xFBFF },
-       { 0x30CA, 0x0004 | 0x0001 },
-       { 0x30D4, 0x9020 & 0x7FFF },
-       { 0x31E0, 0x0003 & 0xFFFE },
-       { 0x3180, 0x91FF & 0x7FFF },
-       { 0x301A, (0x10CC | 0x8000) & 0xFFF7 },
-       { 0x301E, 0x0000 },
-       { 0x3780, 0x0000 },
-};
-
-/* [Lens shading 85 Percent TL84] */
-struct mt9t013_i2c_reg_conf mt9t013_lc_tbl[] = {
-       { 0x360A, 0x0290 }, /* P_RD_P0Q0 */
-       { 0x360C, 0xC92D }, /* P_RD_P0Q1 */
-       { 0x360E, 0x0771 }, /* P_RD_P0Q2 */
-       { 0x3610, 0xE38C }, /* P_RD_P0Q3 */
-       { 0x3612, 0xD74F }, /* P_RD_P0Q4 */
-       { 0x364A, 0x168C }, /* P_RD_P1Q0 */
-       { 0x364C, 0xCACB }, /* P_RD_P1Q1 */
-       { 0x364E, 0x8C4C }, /* P_RD_P1Q2 */
-       { 0x3650, 0x0BEA }, /* P_RD_P1Q3 */
-       { 0x3652, 0xDC0F }, /* P_RD_P1Q4 */
-       { 0x368A, 0x70B0 }, /* P_RD_P2Q0 */
-       { 0x368C, 0x200B }, /* P_RD_P2Q1 */
-       { 0x368E, 0x30B2 }, /* P_RD_P2Q2 */
-       { 0x3690, 0xD04F }, /* P_RD_P2Q3 */
-       { 0x3692, 0xACF5 }, /* P_RD_P2Q4 */
-       { 0x36CA, 0xF7C9 }, /* P_RD_P3Q0 */
-       { 0x36CC, 0x2AED }, /* P_RD_P3Q1 */
-       { 0x36CE, 0xA652 }, /* P_RD_P3Q2 */
-       { 0x36D0, 0x8192 }, /* P_RD_P3Q3 */
-       { 0x36D2, 0x3A15 }, /* P_RD_P3Q4 */
-       { 0x370A, 0xDA30 }, /* P_RD_P4Q0 */
-       { 0x370C, 0x2E2F }, /* P_RD_P4Q1 */
-       { 0x370E, 0xBB56 }, /* P_RD_P4Q2 */
-       { 0x3710, 0x8195 }, /* P_RD_P4Q3 */
-       { 0x3712, 0x02F9 }, /* P_RD_P4Q4 */
-       { 0x3600, 0x0230 }, /* P_GR_P0Q0 */
-       { 0x3602, 0x58AD }, /* P_GR_P0Q1 */
-       { 0x3604, 0x18D1 }, /* P_GR_P0Q2 */
-       { 0x3606, 0x260D }, /* P_GR_P0Q3 */
-       { 0x3608, 0xF530 }, /* P_GR_P0Q4 */
-       { 0x3640, 0x17EB }, /* P_GR_P1Q0 */
-       { 0x3642, 0x3CAB }, /* P_GR_P1Q1 */
-       { 0x3644, 0x87CE }, /* P_GR_P1Q2 */
-       { 0x3646, 0xC02E }, /* P_GR_P1Q3 */
-       { 0x3648, 0xF48F }, /* P_GR_P1Q4 */
-       { 0x3680, 0x5350 }, /* P_GR_P2Q0 */
-       { 0x3682, 0x7EAF }, /* P_GR_P2Q1 */
-       { 0x3684, 0x4312 }, /* P_GR_P2Q2 */
-       { 0x3686, 0xC652 }, /* P_GR_P2Q3 */
-       { 0x3688, 0xBC15 }, /* P_GR_P2Q4 */
-       { 0x36C0, 0xB8AD }, /* P_GR_P3Q0 */
-       { 0x36C2, 0xBDCD }, /* P_GR_P3Q1 */
-       { 0x36C4, 0xE4B2 }, /* P_GR_P3Q2 */
-       { 0x36C6, 0xB50F }, /* P_GR_P3Q3 */
-       { 0x36C8, 0x5B95 }, /* P_GR_P3Q4 */
-       { 0x3700, 0xFC90 }, /* P_GR_P4Q0 */
-       { 0x3702, 0x8C51 }, /* P_GR_P4Q1 */
-       { 0x3704, 0xCED6 }, /* P_GR_P4Q2 */
-       { 0x3706, 0xB594 }, /* P_GR_P4Q3 */
-       { 0x3708, 0x0A39 }, /* P_GR_P4Q4 */
-       { 0x3614, 0x0230 }, /* P_BL_P0Q0 */
-       { 0x3616, 0x160D }, /* P_BL_P0Q1 */
-       { 0x3618, 0x08D1 }, /* P_BL_P0Q2 */
-       { 0x361A, 0x98AB }, /* P_BL_P0Q3 */
-       { 0x361C, 0xEA50 }, /* P_BL_P0Q4 */
-       { 0x3654, 0xB4EA }, /* P_BL_P1Q0 */
-       { 0x3656, 0xEA6C }, /* P_BL_P1Q1 */
-       { 0x3658, 0xFE08 }, /* P_BL_P1Q2 */
-       { 0x365A, 0x2C6E }, /* P_BL_P1Q3 */
-       { 0x365C, 0xEB0E }, /* P_BL_P1Q4 */
-       { 0x3694, 0x6DF0 }, /* P_BL_P2Q0 */
-       { 0x3696, 0x3ACF }, /* P_BL_P2Q1 */
-       { 0x3698, 0x3E0F }, /* P_BL_P2Q2 */
-       { 0x369A, 0xB2B1 }, /* P_BL_P2Q3 */
-       { 0x369C, 0xC374 }, /* P_BL_P2Q4 */
-       { 0x36D4, 0xF2AA }, /* P_BL_P3Q0 */
-       { 0x36D6, 0x8CCC }, /* P_BL_P3Q1 */
-       { 0x36D8, 0xDEF2 }, /* P_BL_P3Q2 */
-       { 0x36DA, 0xFA11 }, /* P_BL_P3Q3 */
-       { 0x36DC, 0x42F5 }, /* P_BL_P3Q4 */
-       { 0x3714, 0xF4F1 }, /* P_BL_P4Q0 */
-       { 0x3716, 0xF6F0 }, /* P_BL_P4Q1 */
-       { 0x3718, 0x8FD6 }, /* P_BL_P4Q2 */
-       { 0x371A, 0xEA14 }, /* P_BL_P4Q3 */
-       { 0x371C, 0x6338 }, /* P_BL_P4Q4 */
-       { 0x361E, 0x0350 }, /* P_GB_P0Q0 */
-       { 0x3620, 0x91AE }, /* P_GB_P0Q1 */
-       { 0x3622, 0x0571 }, /* P_GB_P0Q2 */
-       { 0x3624, 0x100D }, /* P_GB_P0Q3 */
-       { 0x3626, 0xCA70 }, /* P_GB_P0Q4 */
-       { 0x365E, 0xE6CB }, /* P_GB_P1Q0 */
-       { 0x3660, 0x50ED }, /* P_GB_P1Q1 */
-       { 0x3662, 0x3DAE }, /* P_GB_P1Q2 */
-       { 0x3664, 0xAA4F }, /* P_GB_P1Q3 */
-       { 0x3666, 0xDC50 }, /* P_GB_P1Q4 */
-       { 0x369E, 0x5470 }, /* P_GB_P2Q0 */
-       { 0x36A0, 0x1F6E }, /* P_GB_P2Q1 */
-       { 0x36A2, 0x6671 }, /* P_GB_P2Q2 */
-       { 0x36A4, 0xC010 }, /* P_GB_P2Q3 */
-       { 0x36A6, 0x8DF5 }, /* P_GB_P2Q4 */
-       { 0x36DE, 0x0B0C }, /* P_GB_P3Q0 */
-       { 0x36E0, 0x84CE }, /* P_GB_P3Q1 */
-       { 0x36E2, 0x8493 }, /* P_GB_P3Q2 */
-       { 0x36E4, 0xA610 }, /* P_GB_P3Q3 */
-       { 0x36E6, 0x50B5 }, /* P_GB_P3Q4 */
-       { 0x371E, 0x9651 }, /* P_GB_P4Q0 */
-       { 0x3720, 0x1EAB }, /* P_GB_P4Q1 */
-       { 0x3722, 0xAF76 }, /* P_GB_P4Q2 */
-       { 0x3724, 0xE4F4 }, /* P_GB_P4Q3 */
-       { 0x3726, 0x79F8 }, /* P_GB_P4Q4 */
-       { 0x3782, 0x0410 }, /* POLY_ORIGIN_C */
-       { 0x3784, 0x0320 }, /* POLY_ORIGIN_R  */
-       { 0x3780, 0x8000 } /* POLY_SC_ENABLE */
-};
-
-struct mt9t013_reg mt9t013_regs = {
-       .reg_pat = &mt9t013_reg_pat[0],
-       .reg_pat_size = ARRAY_SIZE(mt9t013_reg_pat),
-       .ttbl = &mt9t013_test_tbl[0],
-       .ttbl_size = ARRAY_SIZE(mt9t013_test_tbl),
-       .lctbl = &mt9t013_lc_tbl[0],
-       .lctbl_size = ARRAY_SIZE(mt9t013_lc_tbl),
-       .rftbl = &mt9t013_lc_tbl[0],    /* &mt9t013_rolloff_tbl[0], */
-       .rftbl_size = ARRAY_SIZE(mt9t013_lc_tbl)
-};
-
-
diff --git a/drivers/staging/dream/camera/s5k3e2fx.c b/drivers/staging/dream/camera/s5k3e2fx.c
deleted file mode 100644 (file)
index 1459903..0000000
+++ /dev/null
@@ -1,1307 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <media/msm_camera.h>
-#include <mach/gpio.h>
-#include <mach/camera.h>
-#include "s5k3e2fx.h"
-
-#define S5K3E2FX_REG_MODEL_ID   0x0000
-#define S5K3E2FX_MODEL_ID              0x3E2F
-
-/* PLL Registers */
-#define REG_PRE_PLL_CLK_DIV                    0x0305
-#define REG_PLL_MULTIPLIER_MSB                 0x0306
-#define REG_PLL_MULTIPLIER_LSB                 0x0307
-#define REG_VT_PIX_CLK_DIV                     0x0301
-#define REG_VT_SYS_CLK_DIV                     0x0303
-#define REG_OP_PIX_CLK_DIV                     0x0309
-#define REG_OP_SYS_CLK_DIV                     0x030B
-
-/* Data Format Registers */
-#define REG_CCP_DATA_FORMAT_MSB                0x0112
-#define REG_CCP_DATA_FORMAT_LSB                0x0113
-
-/* Output Size */
-#define REG_X_OUTPUT_SIZE_MSB                  0x034C
-#define REG_X_OUTPUT_SIZE_LSB                  0x034D
-#define REG_Y_OUTPUT_SIZE_MSB                  0x034E
-#define REG_Y_OUTPUT_SIZE_LSB                  0x034F
-
-/* Binning */
-#define REG_X_EVEN_INC                         0x0381
-#define REG_X_ODD_INC                          0x0383
-#define REG_Y_EVEN_INC                         0x0385
-#define REG_Y_ODD_INC                          0x0387
-/*Reserved register */
-#define REG_BINNING_ENABLE                     0x3014
-
-/* Frame Fotmat */
-#define REG_FRAME_LENGTH_LINES_MSB             0x0340
-#define REG_FRAME_LENGTH_LINES_LSB             0x0341
-#define REG_LINE_LENGTH_PCK_MSB                0x0342
-#define REG_LINE_LENGTH_PCK_LSB                0x0343
-
-/* MSR setting */
-/* Reserved registers */
-#define REG_SHADE_CLK_ENABLE                   0x30AC
-#define REG_SEL_CCP                            0x30C4
-#define REG_VPIX                               0x3024
-#define REG_CLAMP_ON                           0x3015
-#define REG_OFFSET                             0x307E
-
-/* CDS timing settings */
-/* Reserved registers */
-#define REG_LD_START                           0x3000
-#define REG_LD_END                             0x3001
-#define REG_SL_START                           0x3002
-#define REG_SL_END                             0x3003
-#define REG_RX_START                           0x3004
-#define REG_S1_START                           0x3005
-#define REG_S1_END                             0x3006
-#define REG_S1S_START                          0x3007
-#define REG_S1S_END                            0x3008
-#define REG_S3_START                           0x3009
-#define REG_S3_END                             0x300A
-#define REG_CMP_EN_START                       0x300B
-#define REG_CLP_SL_START                       0x300C
-#define REG_CLP_SL_END                         0x300D
-#define REG_OFF_START                          0x300E
-#define REG_RMP_EN_START                       0x300F
-#define REG_TX_START                           0x3010
-#define REG_TX_END                             0x3011
-#define REG_STX_WIDTH                          0x3012
-#define REG_TYPE1_AF_ENABLE                    0x3130
-#define DRIVER_ENABLED                         0x0001
-#define AUTO_START_ENABLED                     0x0010
-#define REG_NEW_POSITION                       0x3131
-#define REG_3152_RESERVED                      0x3152
-#define REG_315A_RESERVED                      0x315A
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB 0x0204
-#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB 0x0205
-#define REG_FINE_INTEGRATION_TIME              0x0200
-#define REG_COARSE_INTEGRATION_TIME            0x0202
-#define REG_COARSE_INTEGRATION_TIME_LSB   0x0203
-
-/* Mode select register */
-#define S5K3E2FX_REG_MODE_SELECT               0x0100
-#define S5K3E2FX_MODE_SELECT_STREAM            0x01   /* start streaming */
-#define S5K3E2FX_MODE_SELECT_SW_STANDBY 0x00   /* software standby */
-#define S5K3E2FX_REG_SOFTWARE_RESET   0x0103
-#define S5K3E2FX_SOFTWARE_RESET                0x01
-#define REG_TEST_PATTERN_MODE                  0x0601
-
-struct reg_struct {
-       uint8_t pre_pll_clk_div;               /* 0x0305 */
-       uint8_t pll_multiplier_msb;            /* 0x0306 */
-       uint8_t pll_multiplier_lsb;            /* 0x0307 */
-       uint8_t vt_pix_clk_div;                /* 0x0301 */
-       uint8_t vt_sys_clk_div;                /* 0x0303 */
-       uint8_t op_pix_clk_div;                /* 0x0309 */
-       uint8_t op_sys_clk_div;                /* 0x030B */
-       uint8_t ccp_data_format_msb;           /* 0x0112 */
-       uint8_t ccp_data_format_lsb;           /* 0x0113 */
-       uint8_t x_output_size_msb;             /* 0x034C */
-       uint8_t x_output_size_lsb;             /* 0x034D */
-       uint8_t y_output_size_msb;             /* 0x034E */
-       uint8_t y_output_size_lsb;             /* 0x034F */
-       uint8_t x_even_inc;                    /* 0x0381 */
-       uint8_t x_odd_inc;                     /* 0x0383 */
-       uint8_t y_even_inc;                    /* 0x0385 */
-       uint8_t y_odd_inc;                     /* 0x0387 */
-       uint8_t binning_enable;                /* 0x3014 */
-       uint8_t frame_length_lines_msb;        /* 0x0340 */
-       uint8_t frame_length_lines_lsb;        /* 0x0341 */
-       uint8_t line_length_pck_msb;           /* 0x0342 */
-       uint8_t line_length_pck_lsb;           /* 0x0343 */
-       uint8_t shade_clk_enable ;             /* 0x30AC */
-       uint8_t sel_ccp;                       /* 0x30C4 */
-       uint8_t vpix;                          /* 0x3024 */
-       uint8_t clamp_on;                      /* 0x3015 */
-       uint8_t offset;                        /* 0x307E */
-       uint8_t ld_start;                      /* 0x3000 */
-       uint8_t ld_end;                        /* 0x3001 */
-       uint8_t sl_start;                      /* 0x3002 */
-       uint8_t sl_end;                        /* 0x3003 */
-       uint8_t rx_start;                      /* 0x3004 */
-       uint8_t s1_start;                      /* 0x3005 */
-       uint8_t s1_end;                        /* 0x3006 */
-       uint8_t s1s_start;                     /* 0x3007 */
-       uint8_t s1s_end;                       /* 0x3008 */
-       uint8_t s3_start;                      /* 0x3009 */
-       uint8_t s3_end;                        /* 0x300A */
-       uint8_t cmp_en_start;                  /* 0x300B */
-       uint8_t clp_sl_start;                  /* 0x300C */
-       uint8_t clp_sl_end;                    /* 0x300D */
-       uint8_t off_start;                     /* 0x300E */
-       uint8_t rmp_en_start;                  /* 0x300F */
-       uint8_t tx_start;                      /* 0x3010 */
-       uint8_t tx_end;                        /* 0x3011 */
-       uint8_t stx_width;                     /* 0x3012 */
-       uint8_t reg_3152_reserved;             /* 0x3152 */
-       uint8_t reg_315A_reserved;             /* 0x315A */
-       uint8_t analogue_gain_code_global_msb; /* 0x0204 */
-       uint8_t analogue_gain_code_global_lsb; /* 0x0205 */
-       uint8_t fine_integration_time;         /* 0x0200 */
-       uint8_t coarse_integration_time;       /* 0x0202 */
-       uint32_t size_h;
-       uint32_t blk_l;
-       uint32_t size_w;
-       uint32_t blk_p;
-};
-
-struct reg_struct s5k3e2fx_reg_pat[2] = {
-       { /* Preview */
-               0x06,  /* pre_pll_clk_div       REG=0x0305 */
-               0x00,  /* pll_multiplier_msb    REG=0x0306 */
-               0x88,  /* pll_multiplier_lsb    REG=0x0307 */
-               0x0a,  /* vt_pix_clk_div        REG=0x0301 */
-               0x01,  /* vt_sys_clk_div        REG=0x0303 */
-               0x0a,  /* op_pix_clk_div        REG=0x0309 */
-               0x01,  /* op_sys_clk_div        REG=0x030B */
-               0x0a,  /* ccp_data_format_msb   REG=0x0112 */
-               0x0a,  /* ccp_data_format_lsb   REG=0x0113 */
-               0x05,  /* x_output_size_msb     REG=0x034C */
-               0x10,  /* x_output_size_lsb     REG=0x034D */
-               0x03,  /* y_output_size_msb     REG=0x034E */
-               0xcc,  /* y_output_size_lsb     REG=0x034F */
-
-       /* enable binning for preview */
-               0x01,  /* x_even_inc             REG=0x0381 */
-               0x01,  /* x_odd_inc              REG=0x0383 */
-               0x01,  /* y_even_inc             REG=0x0385 */
-               0x03,  /* y_odd_inc              REG=0x0387 */
-               0x06,  /* binning_enable         REG=0x3014 */
-
-               0x03,  /* frame_length_lines_msb        REG=0x0340 */
-               0xde,  /* frame_length_lines_lsb        REG=0x0341 */
-               0x0a,  /* line_length_pck_msb           REG=0x0342 */
-               0xac,  /* line_length_pck_lsb           REG=0x0343 */
-               0x81,  /* shade_clk_enable              REG=0x30AC */
-               0x01,  /* sel_ccp                       REG=0x30C4 */
-               0x04,  /* vpix                          REG=0x3024 */
-               0x00,  /* clamp_on                      REG=0x3015 */
-               0x02,  /* offset                        REG=0x307E */
-               0x03,  /* ld_start                      REG=0x3000 */
-               0x9c,  /* ld_end                        REG=0x3001 */
-               0x02,  /* sl_start                      REG=0x3002 */
-               0x9e,  /* sl_end                        REG=0x3003 */
-               0x05,  /* rx_start                      REG=0x3004 */
-               0x0f,  /* s1_start                      REG=0x3005 */
-               0x24,  /* s1_end                        REG=0x3006 */
-               0x7c,  /* s1s_start                     REG=0x3007 */
-               0x9a,  /* s1s_end                       REG=0x3008 */
-               0x10,  /* s3_start                      REG=0x3009 */
-               0x14,  /* s3_end                        REG=0x300A */
-               0x10,  /* cmp_en_start                  REG=0x300B */
-               0x04,  /* clp_sl_start                  REG=0x300C */
-               0x26,  /* clp_sl_end                    REG=0x300D */
-               0x02,  /* off_start                     REG=0x300E */
-               0x0e,  /* rmp_en_start                  REG=0x300F */
-               0x30,  /* tx_start                      REG=0x3010 */
-               0x4e,  /* tx_end                        REG=0x3011 */
-               0x1E,  /* stx_width                     REG=0x3012 */
-               0x08,  /* reg_3152_reserved             REG=0x3152 */
-               0x10,  /* reg_315A_reserved             REG=0x315A */
-               0x00,  /* analogue_gain_code_global_msb REG=0x0204 */
-               0x80,  /* analogue_gain_code_global_lsb REG=0x0205 */
-               0x02,  /* fine_integration_time         REG=0x0200 */
-               0x03,  /* coarse_integration_time       REG=0x0202 */
-               972,
-               18,
-               1296,
-               1436
-       },
-       { /* Snapshot */
-               0x06,  /* pre_pll_clk_div               REG=0x0305 */
-               0x00,  /* pll_multiplier_msb            REG=0x0306 */
-               0x88,  /* pll_multiplier_lsb            REG=0x0307 */
-               0x0a,  /* vt_pix_clk_div                REG=0x0301 */
-               0x01,  /* vt_sys_clk_div                REG=0x0303 */
-               0x0a,  /* op_pix_clk_div                REG=0x0309 */
-               0x01,  /* op_sys_clk_div                REG=0x030B */
-               0x0a,  /* ccp_data_format_msb           REG=0x0112 */
-               0x0a,  /* ccp_data_format_lsb           REG=0x0113 */
-               0x0a,  /* x_output_size_msb             REG=0x034C */
-               0x30,  /* x_output_size_lsb             REG=0x034D */
-               0x07,  /* y_output_size_msb             REG=0x034E */
-               0xa8,  /* y_output_size_lsb             REG=0x034F */
-
-       /* disable binning for snapshot */
-               0x01,  /* x_even_inc                    REG=0x0381 */
-               0x01,  /* x_odd_inc                     REG=0x0383 */
-               0x01,  /* y_even_inc                    REG=0x0385 */
-               0x01,  /* y_odd_inc                     REG=0x0387 */
-               0x00,  /* binning_enable                REG=0x3014 */
-
-               0x07,  /* frame_length_lines_msb        REG=0x0340 */
-               0xb6,  /* frame_length_lines_lsb        REG=0x0341 */
-               0x0a,  /* line_length_pck_msb           REG=0x0342 */
-               0xac,  /* line_length_pck_lsb           REG=0x0343 */
-               0x81,  /* shade_clk_enable              REG=0x30AC */
-               0x01,  /* sel_ccp                       REG=0x30C4 */
-               0x04,  /* vpix                          REG=0x3024 */
-               0x00,  /* clamp_on                      REG=0x3015 */
-               0x02,  /* offset                        REG=0x307E */
-               0x03,  /* ld_start                      REG=0x3000 */
-               0x9c,  /* ld_end                        REG=0x3001 */
-               0x02,  /* sl_start                      REG=0x3002 */
-               0x9e,  /* sl_end                        REG=0x3003 */
-               0x05,  /* rx_start                      REG=0x3004 */
-               0x0f,  /* s1_start                      REG=0x3005 */
-               0x24,  /* s1_end                        REG=0x3006 */
-               0x7c,  /* s1s_start                     REG=0x3007 */
-               0x9a,  /* s1s_end                       REG=0x3008 */
-               0x10,  /* s3_start                      REG=0x3009 */
-               0x14,  /* s3_end                        REG=0x300A */
-               0x10,  /* cmp_en_start                  REG=0x300B */
-               0x04,  /* clp_sl_start                  REG=0x300C */
-               0x26,  /* clp_sl_end                    REG=0x300D */
-               0x02,  /* off_start                     REG=0x300E */
-               0x0e,  /* rmp_en_start                  REG=0x300F */
-               0x30,  /* tx_start                      REG=0x3010 */
-               0x4e,  /* tx_end                        REG=0x3011 */
-               0x1E,  /* stx_width                     REG=0x3012 */
-               0x08,  /* reg_3152_reserved             REG=0x3152 */
-               0x10,  /* reg_315A_reserved             REG=0x315A */
-               0x00,  /* analogue_gain_code_global_msb REG=0x0204 */
-               0x80,  /* analogue_gain_code_global_lsb REG=0x0205 */
-               0x02,  /* fine_integration_time         REG=0x0200 */
-               0x03,  /* coarse_integration_time       REG=0x0202 */
-               1960,
-               14,
-               2608,
-               124
-       }
-};
-
-struct s5k3e2fx_work {
-       struct work_struct work;
-};
-static struct s5k3e2fx_work *s5k3e2fx_sensorw;
-static struct i2c_client *s5k3e2fx_client;
-
-struct s5k3e2fx_ctrl {
-       const struct msm_camera_sensor_info *sensordata;
-
-       int sensormode;
-       uint32_t fps_divider; /* init to 1 * 0x00000400 */
-       uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */
-
-       uint16_t curr_lens_pos;
-       uint16_t init_curr_lens_pos;
-       uint16_t my_reg_gain;
-       uint32_t my_reg_line_count;
-
-       enum msm_s_resolution prev_res;
-       enum msm_s_resolution pict_res;
-       enum msm_s_resolution curr_res;
-       enum msm_s_test_mode  set_test;
-};
-
-struct s5k3e2fx_i2c_reg_conf {
-       unsigned short waddr;
-       unsigned char  bdata;
-};
-
-static struct s5k3e2fx_ctrl *s5k3e2fx_ctrl;
-static DECLARE_WAIT_QUEUE_HEAD(s5k3e2fx_wait_queue);
-DECLARE_MUTEX(s5k3e2fx_sem);
-
-static int s5k3e2fx_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
-       int length)
-{
-       struct i2c_msg msgs[] = {
-               {
-                       .addr   = saddr,
-                       .flags = 0,
-                       .len   = 2,
-                       .buf   = rxdata,
-               },
-               {
-                       .addr   = saddr,
-                       .flags = I2C_M_RD,
-                       .len   = length,
-                       .buf   = rxdata,
-               },
-       };
-
-       if (i2c_transfer(s5k3e2fx_client->adapter, msgs, 2) < 0) {
-               CDBG("s5k3e2fx_i2c_rxdata failed!\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int32_t s5k3e2fx_i2c_txdata(unsigned short saddr,
-       unsigned char *txdata, int length)
-{
-       struct i2c_msg msg[] = {
-               {
-               .addr  = saddr,
-               .flags = 0,
-               .len = length,
-               .buf = txdata,
-               },
-       };
-
-       if (i2c_transfer(s5k3e2fx_client->adapter, msg, 1) < 0) {
-               CDBG("s5k3e2fx_i2c_txdata failed\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int32_t s5k3e2fx_i2c_write_b(unsigned short saddr, unsigned short waddr,
-       unsigned char bdata)
-{
-       int32_t rc = -EIO;
-       unsigned char buf[4];
-
-       memset(buf, 0, sizeof(buf));
-       buf[0] = (waddr & 0xFF00)>>8;
-       buf[1] = (waddr & 0x00FF);
-       buf[2] = bdata;
-
-       rc = s5k3e2fx_i2c_txdata(saddr, buf, 3);
-
-       if (rc < 0)
-               CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
-                       waddr, bdata);
-
-       return rc;
-}
-
-static int32_t s5k3e2fx_i2c_write_table(
-       struct s5k3e2fx_i2c_reg_conf *reg_cfg_tbl, int num)
-{
-       int i;
-       int32_t rc = -EIO;
-       for (i = 0; i < num; i++) {
-               if (rc < 0)
-                       break;
-               reg_cfg_tbl++;
-       }
-
-       return rc;
-}
-
-static int32_t s5k3e2fx_i2c_read_w(unsigned short saddr, unsigned short raddr,
-       unsigned short *rdata)
-{
-       int32_t rc = 0;
-       unsigned char buf[4];
-
-       if (!rdata)
-               return -EIO;
-
-       memset(buf, 0, sizeof(buf));
-
-       buf[0] = (raddr & 0xFF00)>>8;
-       buf[1] = (raddr & 0x00FF);
-
-       rc = s5k3e2fx_i2c_rxdata(saddr, buf, 2);
-       if (rc < 0)
-               return rc;
-
-       *rdata = buf[0] << 8 | buf[1];
-
-       if (rc < 0)
-               CDBG("s5k3e2fx_i2c_read failed!\n");
-
-       return rc;
-}
-
-static int s5k3e2fx_probe_init_done(const struct msm_camera_sensor_info *data)
-{
-       gpio_direction_output(data->sensor_reset, 0);
-       gpio_free(data->sensor_reset);
-       return 0;
-}
-
-static int s5k3e2fx_probe_init_sensor(const struct msm_camera_sensor_info *data)
-{
-       int32_t  rc;
-       uint16_t chipid = 0;
-
-       rc = gpio_request(data->sensor_reset, "s5k3e2fx");
-       if (!rc)
-               gpio_direction_output(data->sensor_reset, 1);
-       else
-               goto init_probe_done;
-
-       mdelay(20);
-
-       CDBG("s5k3e2fx_sensor_init(): reseting sensor.\n");
-
-       rc = s5k3e2fx_i2c_read_w(s5k3e2fx_client->addr,
-               S5K3E2FX_REG_MODEL_ID, &chipid);
-       if (rc < 0)
-               goto init_probe_fail;
-
-       if (chipid != S5K3E2FX_MODEL_ID) {
-               CDBG("S5K3E2FX wrong model_id = 0x%x\n", chipid);
-               rc = -ENODEV;
-               goto init_probe_fail;
-       }
-
-       goto init_probe_done;
-
-init_probe_fail:
-       s5k3e2fx_probe_init_done(data);
-init_probe_done:
-       return rc;
-}
-
-static int s5k3e2fx_init_client(struct i2c_client *client)
-{
-       /* Initialize the MSM_CAMI2C Chip */
-       init_waitqueue_head(&s5k3e2fx_wait_queue);
-       return 0;
-}
-
-static const struct i2c_device_id s5k3e2fx_i2c_id[] = {
-       { "s5k3e2fx", 0},
-       { }
-};
-
-static int s5k3e2fx_i2c_probe(struct i2c_client *client,
-       const struct i2c_device_id *id)
-{
-       int rc = 0;
-       CDBG("s5k3e2fx_probe called!\n");
-
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-               CDBG("i2c_check_functionality failed\n");
-               goto probe_failure;
-       }
-
-       s5k3e2fx_sensorw = kzalloc(sizeof(struct s5k3e2fx_work), GFP_KERNEL);
-       if (!s5k3e2fx_sensorw) {
-               CDBG("kzalloc failed.\n");
-               rc = -ENOMEM;
-               goto probe_failure;
-       }
-
-       i2c_set_clientdata(client, s5k3e2fx_sensorw);
-       s5k3e2fx_init_client(client);
-       s5k3e2fx_client = client;
-
-       mdelay(50);
-
-       CDBG("s5k3e2fx_probe successed! rc = %d\n", rc);
-       return 0;
-
-probe_failure:
-       CDBG("s5k3e2fx_probe failed! rc = %d\n", rc);
-       return rc;
-}
-
-static struct i2c_driver s5k3e2fx_i2c_driver = {
-       .id_table = s5k3e2fx_i2c_id,
-       .probe  = s5k3e2fx_i2c_probe,
-       .remove = __exit_p(s5k3e2fx_i2c_remove),
-       .driver = {
-               .name = "s5k3e2fx",
-       },
-};
-
-static int32_t s5k3e2fx_test(enum msm_s_test_mode mo)
-{
-       int32_t rc = 0;
-
-       if (mo == S_TEST_OFF)
-               rc = 0;
-       else
-               rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-                       REG_TEST_PATTERN_MODE, (uint16_t)mo);
-
-       return rc;
-}
-
-static int32_t s5k3e2fx_setting(enum msm_s_reg_update rupdate,
-       enum msm_s_setting rt)
-{
-       int32_t rc = 0;
-       uint16_t num_lperf;
-
-       switch (rupdate) {
-       case S_UPDATE_PERIODIC:
-       if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
-
-               struct s5k3e2fx_i2c_reg_conf tbl_1[] = {
-               {REG_CCP_DATA_FORMAT_MSB, s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
-               {REG_CCP_DATA_FORMAT_LSB, s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
-               {REG_X_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].x_output_size_msb},
-               {REG_X_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].x_output_size_lsb},
-               {REG_Y_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].y_output_size_msb},
-               {REG_Y_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].y_output_size_lsb},
-               {REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc},
-               {REG_X_ODD_INC,  s5k3e2fx_reg_pat[rt].x_odd_inc},
-               {REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc},
-               {REG_Y_ODD_INC,  s5k3e2fx_reg_pat[rt].y_odd_inc},
-               {REG_BINNING_ENABLE, s5k3e2fx_reg_pat[rt].binning_enable},
-               };
-
-               struct s5k3e2fx_i2c_reg_conf tbl_2[] = {
-                       {REG_FRAME_LENGTH_LINES_MSB, 0},
-                       {REG_FRAME_LENGTH_LINES_LSB, 0},
-                       {REG_LINE_LENGTH_PCK_MSB, s5k3e2fx_reg_pat[rt].line_length_pck_msb},
-                       {REG_LINE_LENGTH_PCK_LSB, s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
-                       {REG_SHADE_CLK_ENABLE, s5k3e2fx_reg_pat[rt].shade_clk_enable},
-                       {REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
-                       {REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
-                       {REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
-                       {REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
-                       {REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
-                       {REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
-                       {REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
-                       {REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
-                       {REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
-                       {REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
-                       {REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
-                       {REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
-                       {REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
-                       {REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
-                       {REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
-                       {REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
-                       {REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
-                       {REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
-                       {REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
-                       {REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
-                       {REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
-                       {REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
-                       {REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
-                       {REG_3152_RESERVED, s5k3e2fx_reg_pat[rt].reg_3152_reserved},
-                       {REG_315A_RESERVED, s5k3e2fx_reg_pat[rt].reg_315A_reserved},
-                       {REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_msb},
-                       {REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_lsb},
-                       {REG_FINE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].fine_integration_time},
-                       {REG_COARSE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].coarse_integration_time},
-                       {S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
-               };
-
-               rc = s5k3e2fx_i2c_write_table(&tbl_1[0],
-                       ARRAY_SIZE(tbl_1));
-               if (rc < 0)
-                       return rc;
-
-               num_lperf =
-                       (uint16_t)((s5k3e2fx_reg_pat[rt].frame_length_lines_msb << 8) & 0xFF00) +
-                               s5k3e2fx_reg_pat[rt].frame_length_lines_lsb;
-
-               num_lperf = num_lperf * s5k3e2fx_ctrl->fps_divider / 0x0400;
-
-               tbl_2[0] = (struct s5k3e2fx_i2c_reg_conf) {REG_FRAME_LENGTH_LINES_MSB, (num_lperf & 0xFF00) >> 8};
-               tbl_2[1] = (struct s5k3e2fx_i2c_reg_conf) {REG_FRAME_LENGTH_LINES_LSB, (num_lperf & 0x00FF)};
-
-               rc = s5k3e2fx_i2c_write_table(&tbl_2[0],
-                       ARRAY_SIZE(tbl_2));
-               if (rc < 0)
-                       return rc;
-
-               mdelay(5);
-
-               rc = s5k3e2fx_test(s5k3e2fx_ctrl->set_test);
-               if (rc < 0)
-                       return rc;
-       }
-       break; /* UPDATE_PERIODIC */
-
-       case S_REG_INIT:
-       if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
-
-               struct s5k3e2fx_i2c_reg_conf tbl_3[] = {
-                       {S5K3E2FX_REG_SOFTWARE_RESET, S5K3E2FX_SOFTWARE_RESET},
-                       {S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_SW_STANDBY},
-                       /* PLL setting */
-                       {REG_PRE_PLL_CLK_DIV, s5k3e2fx_reg_pat[rt].pre_pll_clk_div},
-                       {REG_PLL_MULTIPLIER_MSB, s5k3e2fx_reg_pat[rt].pll_multiplier_msb},
-                       {REG_PLL_MULTIPLIER_LSB, s5k3e2fx_reg_pat[rt].pll_multiplier_lsb},
-                       {REG_VT_PIX_CLK_DIV, s5k3e2fx_reg_pat[rt].vt_pix_clk_div},
-                       {REG_VT_SYS_CLK_DIV, s5k3e2fx_reg_pat[rt].vt_sys_clk_div},
-                       {REG_OP_PIX_CLK_DIV, s5k3e2fx_reg_pat[rt].op_pix_clk_div},
-                       {REG_OP_SYS_CLK_DIV, s5k3e2fx_reg_pat[rt].op_sys_clk_div},
-                       /*Data Format */
-                       {REG_CCP_DATA_FORMAT_MSB, s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
-                       {REG_CCP_DATA_FORMAT_LSB, s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
-                       /*Output Size */
-                       {REG_X_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].x_output_size_msb},
-                       {REG_X_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].x_output_size_lsb},
-                       {REG_Y_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].y_output_size_msb},
-                       {REG_Y_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].y_output_size_lsb},
-                       /* Binning */
-                       {REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc},
-                       {REG_X_ODD_INC, s5k3e2fx_reg_pat[rt].x_odd_inc },
-                       {REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc},
-                       {REG_Y_ODD_INC, s5k3e2fx_reg_pat[rt].y_odd_inc},
-                       {REG_BINNING_ENABLE, s5k3e2fx_reg_pat[rt].binning_enable},
-                       /* Frame format */
-                       {REG_FRAME_LENGTH_LINES_MSB, s5k3e2fx_reg_pat[rt].frame_length_lines_msb},
-                       {REG_FRAME_LENGTH_LINES_LSB, s5k3e2fx_reg_pat[rt].frame_length_lines_lsb},
-                       {REG_LINE_LENGTH_PCK_MSB, s5k3e2fx_reg_pat[rt].line_length_pck_msb},
-                       {REG_LINE_LENGTH_PCK_LSB, s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
-                       /* MSR setting */
-                       {REG_SHADE_CLK_ENABLE, s5k3e2fx_reg_pat[rt].shade_clk_enable},
-                       {REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
-                       {REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
-                       {REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
-                       {REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
-                       /* CDS timing setting */
-                       {REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
-                       {REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
-                       {REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
-                       {REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
-                       {REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
-                       {REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
-                       {REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
-                       {REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
-                       {REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
-                       {REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
-                       {REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
-                       {REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
-                       {REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
-                       {REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
-                       {REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
-                       {REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
-                       {REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
-                       {REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
-                       {REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
-                       {REG_3152_RESERVED, s5k3e2fx_reg_pat[rt].reg_3152_reserved},
-                       {REG_315A_RESERVED, s5k3e2fx_reg_pat[rt].reg_315A_reserved},
-                       {REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_msb},
-                       {REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_lsb},
-                       {REG_FINE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].fine_integration_time},
-                       {REG_COARSE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].coarse_integration_time},
-                       {S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
-               };
-
-               /* reset fps_divider */
-               s5k3e2fx_ctrl->fps_divider = 1 * 0x0400;
-               rc = s5k3e2fx_i2c_write_table(&tbl_3[0],
-                       ARRAY_SIZE(tbl_3));
-               if (rc < 0)
-                       return rc;
-       }
-       break; /* case REG_INIT: */
-
-       default:
-               rc = -EINVAL;
-               break;
-       } /* switch (rupdate) */
-
-       return rc;
-}
-
-static int s5k3e2fx_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-       int32_t  rc;
-
-       s5k3e2fx_ctrl = kzalloc(sizeof(struct s5k3e2fx_ctrl), GFP_KERNEL);
-       if (!s5k3e2fx_ctrl) {
-               CDBG("s5k3e2fx_init failed!\n");
-               rc = -ENOMEM;
-               goto init_done;
-       }
-
-       s5k3e2fx_ctrl->fps_divider = 1 * 0x00000400;
-       s5k3e2fx_ctrl->pict_fps_divider = 1 * 0x00000400;
-       s5k3e2fx_ctrl->set_test = S_TEST_OFF;
-       s5k3e2fx_ctrl->prev_res = S_QTR_SIZE;
-       s5k3e2fx_ctrl->pict_res = S_FULL_SIZE;
-
-       if (data)
-               s5k3e2fx_ctrl->sensordata = data;
-
-       /* enable mclk first */
-       msm_camio_clk_rate_set(24000000);
-       mdelay(20);
-
-       msm_camio_camif_pad_reg_reset();
-       mdelay(20);
-
-       rc = s5k3e2fx_probe_init_sensor(data);
-       if (rc < 0)
-               goto init_fail1;
-
-       if (s5k3e2fx_ctrl->prev_res == S_QTR_SIZE)
-               rc = s5k3e2fx_setting(S_REG_INIT, S_RES_PREVIEW);
-       else
-               rc = s5k3e2fx_setting(S_REG_INIT, S_RES_CAPTURE);
-
-       if (rc < 0) {
-               CDBG("s5k3e2fx_setting failed. rc = %d\n", rc);
-               goto init_fail1;
-       }
-
-       /* initialize AF */
-       rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3146, 0x3A);
-       if (rc < 0)
-               goto init_fail1;
-
-       rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3130, 0x03);
-       if (rc < 0)
-               goto init_fail1;
-
-       goto init_done;
-
-init_fail1:
-       s5k3e2fx_probe_init_done(data);
-       kfree(s5k3e2fx_ctrl);
-init_done:
-       return rc;
-}
-
-static int32_t s5k3e2fx_power_down(void)
-{
-       int32_t rc = 0;
-       return rc;
-}
-
-static int s5k3e2fx_sensor_release(void)
-{
-       int rc = -EBADF;
-
-       down(&s5k3e2fx_sem);
-
-       s5k3e2fx_power_down();
-
-       gpio_direction_output(s5k3e2fx_ctrl->sensordata->sensor_reset,
-               0);
-       gpio_free(s5k3e2fx_ctrl->sensordata->sensor_reset);
-
-       kfree(s5k3e2fx_ctrl);
-       s5k3e2fx_ctrl = NULL;
-
-       CDBG("s5k3e2fx_release completed\n");
-
-       up(&s5k3e2fx_sem);
-       return rc;
-}
-
-static void s5k3e2fx_get_pict_fps(uint16_t fps, uint16_t *pfps)
-{
-       /* input fps is preview fps in Q8 format */
-       uint32_t divider;   /* Q10 */
-
-       divider = (uint32_t)
-               ((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-                       s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
-                (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
-                       s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p)) * 0x00000400 /
-               ((s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
-                       s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l) *
-                (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
-                       s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p));
-
-       /* Verify PCLK settings and frame sizes. */
-       *pfps = (uint16_t)(fps * divider / 0x00000400);
-}
-
-static uint16_t s5k3e2fx_get_prev_lines_pf(void)
-{
-       return (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-               s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l);
-}
-
-static uint16_t s5k3e2fx_get_prev_pixels_pl(void)
-{
-       return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
-               s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p;
-}
-
-static uint16_t s5k3e2fx_get_pict_lines_pf(void)
-{
-       return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
-               s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
-}
-
-static uint16_t s5k3e2fx_get_pict_pixels_pl(void)
-{
-       return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
-               s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
-}
-
-static uint32_t s5k3e2fx_get_pict_max_exp_lc(void)
-{
-       uint32_t snapshot_lines_per_frame;
-
-       if (s5k3e2fx_ctrl->pict_res == S_QTR_SIZE)
-               snapshot_lines_per_frame =
-               s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-               s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l;
-       else
-               snapshot_lines_per_frame = 3961 * 3;
-
-       return snapshot_lines_per_frame;
-}
-
-static int32_t s5k3e2fx_set_fps(struct fps_cfg *fps)
-{
-       /* input is new fps in Q10 format */
-       int32_t rc = 0;
-
-       s5k3e2fx_ctrl->fps_divider = fps->fps_div;
-
-       rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-               REG_FRAME_LENGTH_LINES_MSB,
-               (((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-                       s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
-                       s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00) >> 8);
-       if (rc < 0)
-               goto set_fps_done;
-
-       rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-               REG_FRAME_LENGTH_LINES_LSB,
-               (((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-                       s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
-                       s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00));
-
-set_fps_done:
-       return rc;
-}
-
-static int32_t s5k3e2fx_write_exp_gain(uint16_t gain, uint32_t line)
-{
-       int32_t rc = 0;
-
-       uint16_t max_legal_gain = 0x0200;
-       uint32_t ll_ratio; /* Q10 */
-       uint16_t ll_pck, fl_lines;
-       uint16_t offset = 4;
-       uint8_t  gain_msb, gain_lsb;
-       uint8_t  intg_t_msb, intg_t_lsb;
-       uint8_t  ll_pck_msb, ll_pck_lsb, tmp;
-
-       struct s5k3e2fx_i2c_reg_conf tbl[2];
-
-       CDBG("Line:%d s5k3e2fx_write_exp_gain \n", __LINE__);
-
-       if (s5k3e2fx_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
-
-               s5k3e2fx_ctrl->my_reg_gain = gain;
-               s5k3e2fx_ctrl->my_reg_line_count = (uint16_t)line;
-
-               fl_lines = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
-                       s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
-
-               ll_pck = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
-                       s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
-
-       } else {
-
-               fl_lines = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
-                       s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
-
-               ll_pck = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
-                       s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
-       }
-
-       if (gain > max_legal_gain)
-               gain = max_legal_gain;
-
-       /* in Q10 */
-       line = (line * s5k3e2fx_ctrl->fps_divider);
-
-       if (fl_lines < (line / 0x400))
-               ll_ratio = (line / (fl_lines - offset));
-       else
-               ll_ratio = 0x400;
-
-       /* update gain registers */
-       gain_msb = (gain & 0xFF00) >> 8;
-       gain_lsb = gain & 0x00FF;
-       tbl[0].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB;
-       tbl[0].bdata = gain_msb;
-       tbl[1].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB;
-       tbl[1].bdata = gain_lsb;
-       rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
-       if (rc < 0)
-               goto write_gain_done;
-
-       ll_pck = ll_pck * ll_ratio;
-       ll_pck_msb = ((ll_pck / 0x400) & 0xFF00) >> 8;
-       ll_pck_lsb = (ll_pck / 0x400) & 0x00FF;
-       tbl[0].waddr = REG_LINE_LENGTH_PCK_MSB;
-       tbl[0].bdata = s5k3e2fx_reg_pat[S_RES_PREVIEW].line_length_pck_msb;
-       tbl[1].waddr = REG_LINE_LENGTH_PCK_LSB;
-       tbl[1].bdata = s5k3e2fx_reg_pat[S_RES_PREVIEW].line_length_pck_lsb;
-       rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
-       if (rc < 0)
-               goto write_gain_done;
-
-       tmp = (ll_pck * 0x400) / ll_ratio;
-       intg_t_msb = (tmp & 0xFF00) >> 8;
-       intg_t_lsb = (tmp & 0x00FF);
-       tbl[0].waddr = REG_COARSE_INTEGRATION_TIME;
-       tbl[0].bdata = intg_t_msb;
-       tbl[1].waddr = REG_COARSE_INTEGRATION_TIME_LSB;
-       tbl[1].bdata = intg_t_lsb;
-       rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
-
-write_gain_done:
-       return rc;
-}
-
-static int32_t s5k3e2fx_set_pict_exp_gain(uint16_t gain, uint32_t line)
-{
-       int32_t rc = 0;
-
-       CDBG("Line:%d s5k3e2fx_set_pict_exp_gain \n", __LINE__);
-
-       rc =
-               s5k3e2fx_write_exp_gain(gain, line);
-
-       return rc;
-}
-
-static int32_t s5k3e2fx_video_config(int mode, int res)
-{
-       int32_t rc;
-
-       switch (res) {
-       case S_QTR_SIZE:
-               rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_PREVIEW);
-               if (rc < 0)
-                       return rc;
-
-               CDBG("s5k3e2fx sensor configuration done!\n");
-               break;
-
-       case S_FULL_SIZE:
-               rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
-               if (rc < 0)
-                       return rc;
-
-               break;
-
-       default:
-               return 0;
-       } /* switch */
-
-       s5k3e2fx_ctrl->prev_res = res;
-       s5k3e2fx_ctrl->curr_res = res;
-       s5k3e2fx_ctrl->sensormode = mode;
-
-       rc =
-               s5k3e2fx_write_exp_gain(s5k3e2fx_ctrl->my_reg_gain,
-                       s5k3e2fx_ctrl->my_reg_line_count);
-
-       return rc;
-}
-
-static int32_t s5k3e2fx_snapshot_config(int mode)
-{
-       int32_t rc = 0;
-
-       rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
-       if (rc < 0)
-               return rc;
-
-       s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
-       s5k3e2fx_ctrl->sensormode = mode;
-
-       return rc;
-}
-
-static int32_t s5k3e2fx_raw_snapshot_config(int mode)
-{
-       int32_t rc = 0;
-
-       rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
-       if (rc < 0)
-               return rc;
-
-       s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
-       s5k3e2fx_ctrl->sensormode = mode;
-
-       return rc;
-}
-
-static int32_t s5k3e2fx_set_sensor_mode(int mode, int res)
-{
-       int32_t rc = 0;
-
-       switch (mode) {
-       case SENSOR_PREVIEW_MODE:
-               rc = s5k3e2fx_video_config(mode, res);
-               break;
-
-       case SENSOR_SNAPSHOT_MODE:
-               rc = s5k3e2fx_snapshot_config(mode);
-               break;
-
-       case SENSOR_RAW_SNAPSHOT_MODE:
-               rc = s5k3e2fx_raw_snapshot_config(mode);
-               break;
-
-       default:
-               rc = -EINVAL;
-               break;
-       }
-
-       return rc;
-}
-
-static int32_t s5k3e2fx_set_default_focus(void)
-{
-       int32_t rc = 0;
-
-       rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-                       0x3131, 0);
-       if (rc < 0)
-               return rc;
-
-       rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
-                       0x3132, 0);
-       if (rc < 0)
-               return rc;
-
-       s5k3e2fx_ctrl->curr_lens_pos = 0;
-
-       return rc;
-}
-
-static int32_t s5k3e2fx_move_focus(int direction, int32_t num_steps)
-{
-       int32_t rc = 0;
-       int32_t i;
-       int16_t step_direction;
-       int16_t actual_step;
-       int16_t next_pos, pos_offset;
-       int16_t init_code = 50;
-       uint8_t next_pos_msb, next_pos_lsb;
-       int16_t s_move[5];
-       uint32_t gain; /* Q10 format */
-
-       if (direction == MOVE_NEAR)
-               step_direction = 20;
-       else if (direction == MOVE_FAR)
-               step_direction = -20;
-       else {
-               CDBG("s5k3e2fx_move_focus failed at line %d ...\n", __LINE__);
-               return -EINVAL;
-       }
-
-       actual_step = step_direction * (int16_t)num_steps;
-       pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos;
-       gain = ((actual_step << 10) / 5) >> 10;
-
-       for (i = 0; i <= 4; i++)
-               s_move[i] = gain;
-
-       /* Ring Damping Code */
-       for (i = 0; i <= 4; i++) {
-               next_pos = (int16_t)(pos_offset + s_move[i]);
-
-               if (next_pos > (738 + init_code))
-                       next_pos = 738 + init_code;
-               else if (next_pos < 0)
-                       next_pos = 0;
-
-               CDBG("next_position in damping mode = %d\n", next_pos);
-               /* Writing the Values to the actuator */
-               if (next_pos == init_code)
-                       next_pos = 0x00;
-
-               next_pos_msb = next_pos >> 8;
-               next_pos_lsb = next_pos & 0x00FF;
-
-               rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3131, next_pos_msb);
-               if (rc < 0)
-                       break;
-
-               rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3132, next_pos_lsb);
-               if (rc < 0)
-                       break;
-
-               pos_offset = next_pos;
-               s5k3e2fx_ctrl->curr_lens_pos = pos_offset - init_code;
-               if (i < 4)
-                       mdelay(3);
-       }
-
-       return rc;
-}
-
-static int s5k3e2fx_sensor_config(void __user *argp)
-{
-       struct sensor_cfg_data cdata;
-       long   rc = 0;
-
-       if (copy_from_user(&cdata,
-                       (void *)argp,
-                       sizeof(struct sensor_cfg_data)))
-               return -EFAULT;
-
-       down(&s5k3e2fx_sem);
-
-       CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
-       switch (cdata.cfgtype) {
-       case CFG_GET_PICT_FPS:
-               s5k3e2fx_get_pict_fps(cdata.cfg.gfps.prevfps,
-                       &(cdata.cfg.gfps.pictfps));
-
-               if (copy_to_user((void *)argp, &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PREV_L_PF:
-               cdata.cfg.prevl_pf = s5k3e2fx_get_prev_lines_pf();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PREV_P_PL:
-               cdata.cfg.prevp_pl = s5k3e2fx_get_prev_pixels_pl();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PICT_L_PF:
-               cdata.cfg.pictl_pf = s5k3e2fx_get_pict_lines_pf();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PICT_P_PL:
-               cdata.cfg.pictp_pl = s5k3e2fx_get_pict_pixels_pl();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_GET_PICT_MAX_EXP_LC:
-               cdata.cfg.pict_max_exp_lc =
-                       s5k3e2fx_get_pict_max_exp_lc();
-
-               if (copy_to_user((void *)argp,
-                               &cdata,
-                               sizeof(struct sensor_cfg_data)))
-                       rc = -EFAULT;
-               break;
-
-       case CFG_SET_FPS:
-       case CFG_SET_PICT_FPS:
-               rc = s5k3e2fx_set_fps(&(cdata.cfg.fps));
-               break;
-
-       case CFG_SET_EXP_GAIN:
-               rc =
-                       s5k3e2fx_write_exp_gain(cdata.cfg.exp_gain.gain,
-                               cdata.cfg.exp_gain.line);
-               break;
-
-       case CFG_SET_PICT_EXP_GAIN:
-               CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
-               rc =
-                       s5k3e2fx_set_pict_exp_gain(
-                               cdata.cfg.exp_gain.gain,
-                               cdata.cfg.exp_gain.line);
-               break;
-
-       case CFG_SET_MODE:
-               rc =
-                       s5k3e2fx_set_sensor_mode(
-                       cdata.mode, cdata.rs);
-               break;
-
-       case CFG_PWR_DOWN:
-               rc = s5k3e2fx_power_down();
-               break;
-
-       case CFG_MOVE_FOCUS:
-               rc =
-                       s5k3e2fx_move_focus(
-                       cdata.cfg.focus.dir,
-                       cdata.cfg.focus.steps);
-               break;
-
-       case CFG_SET_DEFAULT_FOCUS:
-               rc =
-                       s5k3e2fx_set_default_focus();
-               break;
-
-       case CFG_GET_AF_MAX_STEPS:
-       case CFG_SET_EFFECT:
-       case CFG_SET_LENS_SHADING:
-       default:
-               rc = -EINVAL;
-               break;
-       }
-
-       up(&s5k3e2fx_sem);
-       return rc;
-}
-
-static int s5k3e2fx_sensor_probe(const struct msm_camera_sensor_info *info,
-               struct msm_sensor_ctrl *s)
-{
-       int rc = 0;
-
-       rc = i2c_add_driver(&s5k3e2fx_i2c_driver);
-       if (rc < 0 || s5k3e2fx_client == NULL) {
-               rc = -ENOTSUPP;
-               goto probe_fail;
-       }
-
-       msm_camio_clk_rate_set(24000000);
-       mdelay(20);
-
-       rc = s5k3e2fx_probe_init_sensor(info);
-       if (rc < 0)
-               goto probe_fail;
-
-       s->s_init = s5k3e2fx_sensor_open_init;
-       s->s_release = s5k3e2fx_sensor_release;
-       s->s_config  = s5k3e2fx_sensor_config;
-       s5k3e2fx_probe_init_done(info);
-
-       return rc;
-
-probe_fail:
-       CDBG("SENSOR PROBE FAILS!\n");
-       return rc;
-}
-
-static int __s5k3e2fx_probe(struct platform_device *pdev)
-{
-       return msm_camera_drv_start(pdev, s5k3e2fx_sensor_probe);
-}
-
-static struct platform_driver msm_camera_driver = {
-       .probe = __s5k3e2fx_probe,
-       .driver = {
-               .name = "msm_camera_s5k3e2fx",
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init s5k3e2fx_init(void)
-{
-       return platform_driver_register(&msm_camera_driver);
-}
-
-module_init(s5k3e2fx_init);
-
diff --git a/drivers/staging/dream/camera/s5k3e2fx.h b/drivers/staging/dream/camera/s5k3e2fx.h
deleted file mode 100644 (file)
index 69bc750..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#ifndef CAMSENSOR_S5K3E2FX
-#define CAMSENSOR_S5K3E2FX
-
-#include <mach/board.h>
-#endif /* CAMSENSOR_S5K3E2FX */
diff --git a/drivers/staging/dream/generic_gpio.c b/drivers/staging/dream/generic_gpio.c
deleted file mode 100644 (file)
index fe24d38..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/* arch/arm/mach-msm/generic_gpio.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <asm/gpio.h>
-#include "gpio_chip.h"
-
-#define GPIO_NUM_TO_CHIP_INDEX(gpio) ((gpio)>>5)
-
-struct gpio_state {
-       unsigned long flags;
-       int refcount;
-};
-
-static DEFINE_SPINLOCK(gpio_chips_lock);
-static LIST_HEAD(gpio_chip_list);
-static struct gpio_chip **gpio_chip_array;
-static unsigned long gpio_chip_array_size;
-
-int register_gpio_chip(struct gpio_chip *new_gpio_chip)
-{
-       int err = 0;
-       struct gpio_chip *gpio_chip;
-       int i;
-       unsigned long irq_flags;
-       unsigned int chip_array_start_index, chip_array_end_index;
-
-       new_gpio_chip->state = kzalloc((new_gpio_chip->end + 1 - new_gpio_chip->start) * sizeof(new_gpio_chip->state[0]), GFP_KERNEL);
-       if (new_gpio_chip->state == NULL) {
-               printk(KERN_ERR "register_gpio_chip: failed to allocate state\n");
-               return -ENOMEM;
-       }
-
-       spin_lock_irqsave(&gpio_chips_lock, irq_flags);
-       chip_array_start_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->start);
-       chip_array_end_index = GPIO_NUM_TO_CHIP_INDEX(new_gpio_chip->end);
-       if (chip_array_end_index >= gpio_chip_array_size) {
-               struct gpio_chip **new_gpio_chip_array;
-               unsigned long new_gpio_chip_array_size = chip_array_end_index + 1;
-
-               new_gpio_chip_array = kmalloc(new_gpio_chip_array_size * sizeof(new_gpio_chip_array[0]), GFP_ATOMIC);
-               if (new_gpio_chip_array == NULL) {
-                       printk(KERN_ERR "register_gpio_chip: failed to allocate array\n");
-                       err = -ENOMEM;
-                       goto failed;
-               }
-               for (i = 0; i < gpio_chip_array_size; i++)
-                       new_gpio_chip_array[i] = gpio_chip_array[i];
-               for (i = gpio_chip_array_size; i < new_gpio_chip_array_size; i++)
-                       new_gpio_chip_array[i] = NULL;
-               gpio_chip_array = new_gpio_chip_array;
-               gpio_chip_array_size = new_gpio_chip_array_size;
-       }
-       list_for_each_entry(gpio_chip, &gpio_chip_list, list) {
-               if (gpio_chip->start > new_gpio_chip->end) {
-                       list_add_tail(&new_gpio_chip->list, &gpio_chip->list);
-                       goto added;
-               }
-               if (gpio_chip->end >= new_gpio_chip->start) {
-                       printk(KERN_ERR "register_gpio_source %u-%u overlaps with %u-%u\n",
-                              new_gpio_chip->start, new_gpio_chip->end,
-                              gpio_chip->start, gpio_chip->end);
-                       err = -EBUSY;
-                       goto failed;
-               }
-       }
-       list_add_tail(&new_gpio_chip->list, &gpio_chip_list);
-added:
-       for (i = chip_array_start_index; i <= chip_array_end_index; i++) {
-               if (gpio_chip_array[i] == NULL || gpio_chip_array[i]->start > new_gpio_chip->start)
-                       gpio_chip_array[i] = new_gpio_chip;
-       }
-failed:
-       spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
-       if (err)
-               kfree(new_gpio_chip->state);
-       return err;
-}
-
-static struct gpio_chip *get_gpio_chip_locked(unsigned int gpio)
-{
-       unsigned long i;
-       struct gpio_chip *chip;
-
-       i = GPIO_NUM_TO_CHIP_INDEX(gpio);
-       if (i >= gpio_chip_array_size)
-               return NULL;
-       chip = gpio_chip_array[i];
-       if (chip == NULL)
-               return NULL;
-       list_for_each_entry_from(chip, &gpio_chip_list, list) {
-               if (gpio < chip->start)
-                       return NULL;
-               if (gpio <= chip->end)
-                       return chip;
-       }
-       return NULL;
-}
-
-static int request_gpio(unsigned int gpio, unsigned long flags)
-{
-       int err = 0;
-       struct gpio_chip *chip;
-       unsigned long irq_flags;
-       unsigned long chip_index;
-
-       spin_lock_irqsave(&gpio_chips_lock, irq_flags);
-       chip = get_gpio_chip_locked(gpio);
-       if (chip == NULL) {
-               err = -EINVAL;
-               goto err;
-       }
-       chip_index = gpio - chip->start;
-       if (chip->state[chip_index].refcount == 0) {
-               chip->configure(chip, gpio, flags);
-               chip->state[chip_index].flags = flags;
-               chip->state[chip_index].refcount++;
-       } else if ((flags & IRQF_SHARED) && (chip->state[chip_index].flags & IRQF_SHARED))
-               chip->state[chip_index].refcount++;
-       else
-               err = -EBUSY;
-err:
-       spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
-       return err;
-}
-
-int gpio_request(unsigned gpio, const char *label)
-{
-       return request_gpio(gpio, 0);
-}
-EXPORT_SYMBOL(gpio_request);
-
-void gpio_free(unsigned gpio)
-{
-       struct gpio_chip *chip;
-       unsigned long irq_flags;
-       unsigned long chip_index;
-
-       spin_lock_irqsave(&gpio_chips_lock, irq_flags);
-       chip = get_gpio_chip_locked(gpio);
-       if (chip) {
-               chip_index = gpio - chip->start;
-               chip->state[chip_index].refcount--;
-       }
-       spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
-}
-EXPORT_SYMBOL(gpio_free);
-
-static int gpio_get_irq_num(unsigned int gpio, unsigned int *irqp, unsigned long *irqnumflagsp)
-{
-       int ret = -ENOTSUPP;
-       struct gpio_chip *chip;
-       unsigned long irq_flags;
-
-       spin_lock_irqsave(&gpio_chips_lock, irq_flags);
-       chip = get_gpio_chip_locked(gpio);
-       if (chip && chip->get_irq_num)
-               ret = chip->get_irq_num(chip, gpio, irqp, irqnumflagsp);
-       spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
-       return ret;
-}
-
-int gpio_to_irq(unsigned gpio)
-{
-       int ret, irq;
-       ret = gpio_get_irq_num(gpio, &irq, NULL);
-       if (ret)
-               return ret;
-       return irq;
-}
-EXPORT_SYMBOL(gpio_to_irq);
-
-int gpio_configure(unsigned int gpio, unsigned long flags)
-{
-       int ret = -ENOTSUPP;
-       struct gpio_chip *chip;
-       unsigned long irq_flags;
-
-       spin_lock_irqsave(&gpio_chips_lock, irq_flags);
-       chip = get_gpio_chip_locked(gpio);
-       if (chip)
-               ret = chip->configure(chip, gpio, flags);
-       spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
-       return ret;
-}
-EXPORT_SYMBOL(gpio_configure);
-
-int gpio_direction_input(unsigned gpio)
-{
-       return gpio_configure(gpio, GPIOF_INPUT);
-}
-EXPORT_SYMBOL(gpio_direction_input);
-
-int gpio_direction_output(unsigned gpio, int value)
-{
-       gpio_set_value(gpio, value);
-       return gpio_configure(gpio, GPIOF_DRIVE_OUTPUT);
-}
-EXPORT_SYMBOL(gpio_direction_output);
-
-int gpio_get_value(unsigned gpio)
-{
-       int ret = -ENOTSUPP;
-       struct gpio_chip *chip;
-       unsigned long irq_flags;
-
-       spin_lock_irqsave(&gpio_chips_lock, irq_flags);
-       chip = get_gpio_chip_locked(gpio);
-       if (chip && chip->read)
-               ret = chip->read(chip, gpio);
-       spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
-       return ret;
-}
-EXPORT_SYMBOL(gpio_get_value);
-
-void gpio_set_value(unsigned gpio, int on)
-{
-       int ret = -ENOTSUPP;
-       struct gpio_chip *chip;
-       unsigned long irq_flags;
-
-       spin_lock_irqsave(&gpio_chips_lock, irq_flags);
-       chip = get_gpio_chip_locked(gpio);
-       if (chip && chip->write)
-               ret = chip->write(chip, gpio, on);
-       spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
-}
-EXPORT_SYMBOL(gpio_set_value);
-
-int gpio_read_detect_status(unsigned int gpio)
-{
-       int ret = -ENOTSUPP;
-       struct gpio_chip *chip;
-       unsigned long irq_flags;
-
-       spin_lock_irqsave(&gpio_chips_lock, irq_flags);
-       chip = get_gpio_chip_locked(gpio);
-       if (chip && chip->read_detect_status)
-               ret = chip->read_detect_status(chip, gpio);
-       spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
-       return ret;
-}
-EXPORT_SYMBOL(gpio_read_detect_status);
-
-int gpio_clear_detect_status(unsigned int gpio)
-{
-       int ret = -ENOTSUPP;
-       struct gpio_chip *chip;
-       unsigned long irq_flags;
-
-       spin_lock_irqsave(&gpio_chips_lock, irq_flags);
-       chip = get_gpio_chip_locked(gpio);
-       if (chip && chip->clear_detect_status)
-               ret = chip->clear_detect_status(chip, gpio);
-       spin_unlock_irqrestore(&gpio_chips_lock, irq_flags);
-       return ret;
-}
-EXPORT_SYMBOL(gpio_clear_detect_status);
diff --git a/drivers/staging/dream/gpio_axis.c b/drivers/staging/dream/gpio_axis.c
deleted file mode 100644 (file)
index eb54724..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/* drivers/input/misc/gpio_axis.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/gpio_event.h>
-#include <linux/interrupt.h>
-
-struct gpio_axis_state {
-       struct input_dev *input_dev;
-       struct gpio_event_axis_info *info;
-       uint32_t pos;
-};
-
-uint16_t gpio_axis_4bit_gray_map_table[] = {
-       [0x0] = 0x0, [0x1] = 0x1, /* 0000 0001 */
-       [0x3] = 0x2, [0x2] = 0x3, /* 0011 0010 */
-       [0x6] = 0x4, [0x7] = 0x5, /* 0110 0111 */
-       [0x5] = 0x6, [0x4] = 0x7, /* 0101 0100 */
-       [0xc] = 0x8, [0xd] = 0x9, /* 1100 1101 */
-       [0xf] = 0xa, [0xe] = 0xb, /* 1111 1110 */
-       [0xa] = 0xc, [0xb] = 0xd, /* 1010 1011 */
-       [0x9] = 0xe, [0x8] = 0xf, /* 1001 1000 */
-};
-uint16_t gpio_axis_4bit_gray_map(struct gpio_event_axis_info *info, uint16_t in)
-{
-       return gpio_axis_4bit_gray_map_table[in];
-}
-
-uint16_t gpio_axis_5bit_singletrack_map_table[] = {
-       [0x10] = 0x00, [0x14] = 0x01, [0x1c] = 0x02, /*     10000 10100 11100 */
-       [0x1e] = 0x03, [0x1a] = 0x04, [0x18] = 0x05, /*     11110 11010 11000 */
-       [0x08] = 0x06, [0x0a] = 0x07, [0x0e] = 0x08, /*    01000 01010 01110  */
-       [0x0f] = 0x09, [0x0d] = 0x0a, [0x0c] = 0x0b, /*    01111 01101 01100  */
-       [0x04] = 0x0c, [0x05] = 0x0d, [0x07] = 0x0e, /*   00100 00101 00111   */
-       [0x17] = 0x0f, [0x16] = 0x10, [0x06] = 0x11, /*   10111 10110 00110   */
-       [0x02] = 0x12, [0x12] = 0x13, [0x13] = 0x14, /*  00010 10010 10011    */
-       [0x1b] = 0x15, [0x0b] = 0x16, [0x03] = 0x17, /*  11011 01011 00011    */
-       [0x01] = 0x18, [0x09] = 0x19, [0x19] = 0x1a, /* 00001 01001 11001     */
-       [0x1d] = 0x1b, [0x15] = 0x1c, [0x11] = 0x1d, /* 11101 10101 10001     */
-};
-uint16_t gpio_axis_5bit_singletrack_map(
-       struct gpio_event_axis_info *info, uint16_t in)
-{
-       return gpio_axis_5bit_singletrack_map_table[in];
-}
-
-static void gpio_event_update_axis(struct gpio_axis_state *as, int report)
-{
-       struct gpio_event_axis_info *ai = as->info;
-       int i;
-       int change;
-       uint16_t state = 0;
-       uint16_t pos;
-       uint16_t old_pos = as->pos;
-       for (i = ai->count - 1; i >= 0; i--)
-               state = (state << 1) | gpio_get_value(ai->gpio[i]);
-       pos = ai->map(ai, state);
-       if (ai->flags & GPIOEAF_PRINT_RAW)
-               pr_info("axis %d-%d raw %x, pos %d -> %d\n",
-                       ai->type, ai->code, state, old_pos, pos);
-       if (report && pos != old_pos) {
-               if (ai->type == EV_REL) {
-                       change = (ai->decoded_size + pos - old_pos) %
-                                 ai->decoded_size;
-                       if (change > ai->decoded_size / 2)
-                               change -= ai->decoded_size;
-                       if (change == ai->decoded_size / 2) {
-                               if (ai->flags & GPIOEAF_PRINT_EVENT)
-                                       pr_info("axis %d-%d unknown direction, "
-                                               "pos %d -> %d\n", ai->type,
-                                               ai->code, old_pos, pos);
-                               change = 0; /* no closest direction */
-                       }
-                       if (ai->flags & GPIOEAF_PRINT_EVENT)
-                               pr_info("axis %d-%d change %d\n",
-                                       ai->type, ai->code, change);
-                       input_report_rel(as->input_dev, ai->code, change);
-               } else {
-                       if (ai->flags & GPIOEAF_PRINT_EVENT)
-                               pr_info("axis %d-%d now %d\n",
-                                       ai->type, ai->code, pos);
-                       input_event(as->input_dev, ai->type, ai->code, pos);
-               }
-               input_sync(as->input_dev);
-       }
-       as->pos = pos;
-}
-
-static irqreturn_t gpio_axis_irq_handler(int irq, void *dev_id)
-{
-       struct gpio_axis_state *as = dev_id;
-       gpio_event_update_axis(as, 1);
-       return IRQ_HANDLED;
-}
-
-int gpio_event_axis_func(struct input_dev *input_dev,
-                        struct gpio_event_info *info, void **data, int func)
-{
-       int ret;
-       int i;
-       int irq;
-       struct gpio_event_axis_info *ai;
-       struct gpio_axis_state *as;
-
-       ai = container_of(info, struct gpio_event_axis_info, info);
-       if (func == GPIO_EVENT_FUNC_SUSPEND) {
-               for (i = 0; i < ai->count; i++)
-                       disable_irq(gpio_to_irq(ai->gpio[i]));
-               return 0;
-       }
-       if (func == GPIO_EVENT_FUNC_RESUME) {
-               for (i = 0; i < ai->count; i++)
-                       enable_irq(gpio_to_irq(ai->gpio[i]));
-               return 0;
-       }
-
-       if (func == GPIO_EVENT_FUNC_INIT) {
-               *data = as = kmalloc(sizeof(*as), GFP_KERNEL);
-               if (as == NULL) {
-                       ret = -ENOMEM;
-                       goto err_alloc_axis_state_failed;
-               }
-               as->input_dev = input_dev;
-               as->info = ai;
-
-               input_set_capability(input_dev, ai->type, ai->code);
-               if (ai->type == EV_ABS) {
-                       input_set_abs_params(input_dev, ai->code, 0,
-                                            ai->decoded_size - 1, 0, 0);
-               }
-               for (i = 0; i < ai->count; i++) {
-                       ret = gpio_request(ai->gpio[i], "gpio_event_axis");
-                       if (ret < 0)
-                               goto err_request_gpio_failed;
-                       ret = gpio_direction_input(ai->gpio[i]);
-                       if (ret < 0)
-                               goto err_gpio_direction_input_failed;
-                       ret = irq = gpio_to_irq(ai->gpio[i]);
-                       if (ret < 0)
-                               goto err_get_irq_num_failed;
-                       ret = request_irq(irq, gpio_axis_irq_handler,
-                                         IRQF_TRIGGER_RISING |
-                                         IRQF_TRIGGER_FALLING,
-                                         "gpio_event_axis", as);
-                       if (ret < 0)
-                               goto err_request_irq_failed;
-               }
-               gpio_event_update_axis(as, 0);
-               return 0;
-       }
-
-       ret = 0;
-       as = *data;
-       for (i = ai->count - 1; i >= 0; i--) {
-               free_irq(gpio_to_irq(ai->gpio[i]), as);
-err_request_irq_failed:
-err_get_irq_num_failed:
-err_gpio_direction_input_failed:
-               gpio_free(ai->gpio[i]);
-err_request_gpio_failed:
-               ;
-       }
-       kfree(as);
-       *data = NULL;
-err_alloc_axis_state_failed:
-       return ret;
-}
diff --git a/drivers/staging/dream/gpio_event.c b/drivers/staging/dream/gpio_event.c
deleted file mode 100644 (file)
index 97a511d..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/* drivers/input/misc/gpio_event.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/input.h>
-#include <linux/gpio_event.h>
-#include <linux/hrtimer.h>
-#include <linux/platform_device.h>
-
-struct gpio_event {
-       struct input_dev *input_dev;
-       const struct gpio_event_platform_data *info;
-       void *state[0];
-};
-
-static int gpio_input_event(
-       struct input_dev *dev, unsigned int type, unsigned int code, int value)
-{
-       int i;
-       int ret = 0;
-       int tmp_ret;
-       struct gpio_event_info **ii;
-       struct gpio_event *ip = input_get_drvdata(dev);
-
-       for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) {
-               if ((*ii)->event) {
-                       tmp_ret = (*ii)->event(ip->input_dev, *ii,
-                                       &ip->state[i], type, code, value);
-                       if (tmp_ret)
-                               ret = tmp_ret;
-               }
-       }
-       return ret;
-}
-
-static int gpio_event_call_all_func(struct gpio_event *ip, int func)
-{
-       int i;
-       int ret;
-       struct gpio_event_info **ii;
-
-       if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) {
-               ii = ip->info->info;
-               for (i = 0; i < ip->info->info_count; i++, ii++) {
-                       if ((*ii)->func == NULL) {
-                               ret = -ENODEV;
-                               pr_err("gpio_event_probe: Incomplete pdata, "
-                                       "no function\n");
-                               goto err_no_func;
-                       }
-                       ret = (*ii)->func(ip->input_dev, *ii, &ip->state[i],
-                                         func);
-                       if (ret) {
-                               pr_err("gpio_event_probe: function failed\n");
-                               goto err_func_failed;
-                       }
-               }
-               return 0;
-       }
-
-       ret = 0;
-       i = ip->info->info_count;
-       ii = ip->info->info + i;
-       while (i > 0) {
-               i--;
-               ii--;
-               (*ii)->func(ip->input_dev, *ii, &ip->state[i], func & ~1);
-err_func_failed:
-err_no_func:
-               ;
-       }
-       return ret;
-}
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-void gpio_event_suspend(struct early_suspend *h)
-{
-       struct gpio_event *ip;
-       ip = container_of(h, struct gpio_event, early_suspend);
-       gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND);
-       ip->info->power(ip->info, 0);
-}
-
-void gpio_event_resume(struct early_suspend *h)
-{
-       struct gpio_event *ip;
-       ip = container_of(h, struct gpio_event, early_suspend);
-       ip->info->power(ip->info, 1);
-       gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME);
-}
-#endif
-
-static int __init gpio_event_probe(struct platform_device *pdev)
-{
-       int err;
-       struct gpio_event *ip;
-       struct input_dev *input_dev;
-       struct gpio_event_platform_data *event_info;
-
-       event_info = pdev->dev.platform_data;
-       if (event_info == NULL) {
-               pr_err("gpio_event_probe: No pdata\n");
-               return -ENODEV;
-       }
-       if (event_info->name == NULL ||
-          event_info->info == NULL ||
-          event_info->info_count == 0) {
-               pr_err("gpio_event_probe: Incomplete pdata\n");
-               return -ENODEV;
-       }
-       ip = kzalloc(sizeof(*ip) +
-                    sizeof(ip->state[0]) * event_info->info_count, GFP_KERNEL);
-       if (ip == NULL) {
-               err = -ENOMEM;
-               pr_err("gpio_event_probe: Failed to allocate private data\n");
-               goto err_kp_alloc_failed;
-       }
-       platform_set_drvdata(pdev, ip);
-
-       input_dev = input_allocate_device();
-       if (input_dev == NULL) {
-               err = -ENOMEM;
-               pr_err("gpio_event_probe: Failed to allocate input device\n");
-               goto err_input_dev_alloc_failed;
-       }
-       input_set_drvdata(input_dev, ip);
-       ip->input_dev = input_dev;
-       ip->info = event_info;
-       if (event_info->power) {
-#ifdef CONFIG_HAS_EARLYSUSPEND
-               ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
-               ip->early_suspend.suspend = gpio_event_suspend;
-               ip->early_suspend.resume = gpio_event_resume;
-               register_early_suspend(&ip->early_suspend);
-#endif
-               ip->info->power(ip->info, 1);
-       }
-
-       input_dev->name = ip->info->name;
-       input_dev->event = gpio_input_event;
-
-       err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT);
-       if (err)
-               goto err_call_all_func_failed;
-
-       err = input_register_device(input_dev);
-       if (err) {
-               pr_err("gpio_event_probe: Unable to register %s input device\n",
-                       input_dev->name);
-               goto err_input_register_device_failed;
-       }
-
-       return 0;
-
-err_input_register_device_failed:
-       gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
-err_call_all_func_failed:
-       if (event_info->power) {
-#ifdef CONFIG_HAS_EARLYSUSPEND
-               unregister_early_suspend(&ip->early_suspend);
-#endif
-               ip->info->power(ip->info, 0);
-       }
-       input_free_device(input_dev);
-err_input_dev_alloc_failed:
-       kfree(ip);
-err_kp_alloc_failed:
-       return err;
-}
-
-static int gpio_event_remove(struct platform_device *pdev)
-{
-       struct gpio_event *ip = platform_get_drvdata(pdev);
-
-       gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
-       if (ip->info->power) {
-#ifdef CONFIG_HAS_EARLYSUSPEND
-               unregister_early_suspend(&ip->early_suspend);
-#endif
-               ip->info->power(ip->info, 0);
-       }
-       input_unregister_device(ip->input_dev);
-       kfree(ip);
-       return 0;
-}
-
-static struct platform_driver gpio_event_driver = {
-       .probe          = gpio_event_probe,
-       .remove         = gpio_event_remove,
-       .driver         = {
-               .name   = GPIO_EVENT_DEV_NAME,
-       },
-};
-
-static int __devinit gpio_event_init(void)
-{
-       return platform_driver_register(&gpio_event_driver);
-}
-
-static void __exit gpio_event_exit(void)
-{
-       platform_driver_unregister(&gpio_event_driver);
-}
-
-module_init(gpio_event_init);
-module_exit(gpio_event_exit);
-
-MODULE_DESCRIPTION("GPIO Event Driver");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/staging/dream/gpio_input.c b/drivers/staging/dream/gpio_input.c
deleted file mode 100644 (file)
index ca29e5e..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/* drivers/input/misc/gpio_input.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/gpio_event.h>
-#include <linux/hrtimer.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-enum {
-       DEBOUNCE_UNSTABLE     = BIT(0), /* Got irq, while debouncing */
-       DEBOUNCE_PRESSED      = BIT(1),
-       DEBOUNCE_NOTPRESSED   = BIT(2),
-       DEBOUNCE_WAIT_IRQ     = BIT(3), /* Stable irq state */
-       DEBOUNCE_POLL         = BIT(4), /* Stable polling state */
-
-       DEBOUNCE_UNKNOWN =
-               DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
-};
-
-struct gpio_key_state {
-       struct gpio_input_state *ds;
-       uint8_t debounce;
-};
-
-struct gpio_input_state {
-       struct input_dev *input_dev;
-       const struct gpio_event_input_info *info;
-       struct hrtimer timer;
-       int use_irq;
-       int debounce_count;
-       spinlock_t irq_lock;
-       struct gpio_key_state key_state[0];
-};
-
-static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
-{
-       int i;
-       int pressed;
-       struct gpio_input_state *ds =
-               container_of(timer, struct gpio_input_state, timer);
-       unsigned gpio_flags = ds->info->flags;
-       unsigned npolarity;
-       int nkeys = ds->info->keymap_size;
-       const struct gpio_event_direct_entry *key_entry;
-       struct gpio_key_state *key_state;
-       unsigned long irqflags;
-       uint8_t debounce;
-
-#if 0
-       key_entry = kp->keys_info->keymap;
-       key_state = kp->key_state;
-       for (i = 0; i < nkeys; i++, key_entry++, key_state++)
-               pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
-                       gpio_read_detect_status(key_entry->gpio));
-#endif
-       key_entry = ds->info->keymap;
-       key_state = ds->key_state;
-       spin_lock_irqsave(&ds->irq_lock, irqflags);
-       for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
-               debounce = key_state->debounce;
-               if (debounce & DEBOUNCE_WAIT_IRQ)
-                       continue;
-               if (key_state->debounce & DEBOUNCE_UNSTABLE) {
-                       debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
-                       enable_irq(gpio_to_irq(key_entry->gpio));
-                       pr_info("gpio_keys_scan_keys: key %x-%x, %d "
-                               "(%d) continue debounce\n",
-                               ds->info->type, key_entry->code,
-                               i, key_entry->gpio);
-               }
-               npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
-               pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
-               if (debounce & DEBOUNCE_POLL) {
-                       if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
-                               ds->debounce_count++;
-                               key_state->debounce = DEBOUNCE_UNKNOWN;
-                               if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
-                                       pr_info("gpio_keys_scan_keys: key %x-"
-                                               "%x, %d (%d) start debounce\n",
-                                               ds->info->type, key_entry->code,
-                                               i, key_entry->gpio);
-                       }
-                       continue;
-               }
-               if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
-                       if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
-                               pr_info("gpio_keys_scan_keys: key %x-%x, %d "
-                                       "(%d) debounce pressed 1\n",
-                                       ds->info->type, key_entry->code,
-                                       i, key_entry->gpio);
-                       key_state->debounce = DEBOUNCE_PRESSED;
-                       continue;
-               }
-               if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
-                       if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
-                               pr_info("gpio_keys_scan_keys: key %x-%x, %d "
-                                       "(%d) debounce pressed 0\n",
-                                       ds->info->type, key_entry->code,
-                                       i, key_entry->gpio);
-                       key_state->debounce = DEBOUNCE_NOTPRESSED;
-                       continue;
-               }
-               /* key is stable */
-               ds->debounce_count--;
-               if (ds->use_irq)
-                       key_state->debounce |= DEBOUNCE_WAIT_IRQ;
-               else
-                       key_state->debounce |= DEBOUNCE_POLL;
-               if (gpio_flags & GPIOEDF_PRINT_KEYS)
-                       pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
-                               "changed to %d\n", ds->info->type,
-                               key_entry->code, i, key_entry->gpio, pressed);
-               input_event(ds->input_dev, ds->info->type,
-                           key_entry->code, pressed);
-       }
-
-#if 0
-       key_entry = kp->keys_info->keymap;
-       key_state = kp->key_state;
-       for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
-               pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
-                       gpio_read_detect_status(key_entry->gpio));
-       }
-#endif
-
-       if (ds->debounce_count)
-               hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
-       else if (!ds->use_irq)
-               hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
-
-       spin_unlock_irqrestore(&ds->irq_lock, irqflags);
-
-       return HRTIMER_NORESTART;
-}
-
-static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
-{
-       struct gpio_key_state *ks = dev_id;
-       struct gpio_input_state *ds = ks->ds;
-       int keymap_index = ks - ds->key_state;
-       const struct gpio_event_direct_entry *key_entry;
-       unsigned long irqflags;
-       int pressed;
-
-       if (!ds->use_irq)
-               return IRQ_HANDLED;
-
-       key_entry = &ds->info->keymap[keymap_index];
-
-       if (ds->info->debounce_time.tv64) {
-               spin_lock_irqsave(&ds->irq_lock, irqflags);
-               if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
-                       ks->debounce = DEBOUNCE_UNKNOWN;
-                       if (ds->debounce_count++ == 0) {
-                               hrtimer_start(
-                                       &ds->timer, ds->info->debounce_time,
-                                       HRTIMER_MODE_REL);
-                       }
-                       if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
-                               pr_info("gpio_event_input_irq_handler: "
-                                       "key %x-%x, %d (%d) start debounce\n",
-                                       ds->info->type, key_entry->code,
-                                       keymap_index, key_entry->gpio);
-               } else {
-                       disable_irq(irq);
-                       ks->debounce = DEBOUNCE_UNSTABLE;
-               }
-               spin_unlock_irqrestore(&ds->irq_lock, irqflags);
-       } else {
-               pressed = gpio_get_value(key_entry->gpio) ^
-                       !(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
-               if (ds->info->flags & GPIOEDF_PRINT_KEYS)
-                       pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
-                               "(%d) changed to %d\n",
-                               ds->info->type, key_entry->code, keymap_index,
-                               key_entry->gpio, pressed);
-               input_event(ds->input_dev, ds->info->type,
-                           key_entry->code, pressed);
-       }
-       return IRQ_HANDLED;
-}
-
-static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
-{
-       int i;
-       int err;
-       unsigned int irq;
-       unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
-
-       for (i = 0; i < ds->info->keymap_size; i++) {
-               err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
-               if (err < 0)
-                       goto err_gpio_get_irq_num_failed;
-               err = request_irq(irq, gpio_event_input_irq_handler,
-                                 req_flags, "gpio_keys", &ds->key_state[i]);
-               if (err) {
-                       pr_err("gpio_event_input_request_irqs: request_irq "
-                               "failed for input %d, irq %d\n",
-                               ds->info->keymap[i].gpio, irq);
-                       goto err_request_irq_failed;
-               }
-               enable_irq_wake(irq);
-       }
-       return 0;
-
-       for (i = ds->info->keymap_size - 1; i >= 0; i--) {
-               free_irq(gpio_to_irq(ds->info->keymap[i].gpio),
-                        &ds->key_state[i]);
-err_request_irq_failed:
-err_gpio_get_irq_num_failed:
-               ;
-       }
-       return err;
-}
-
-int gpio_event_input_func(struct input_dev *input_dev,
-                       struct gpio_event_info *info, void **data, int func)
-{
-       int ret;
-       int i;
-       unsigned long irqflags;
-       struct gpio_event_input_info *di;
-       struct gpio_input_state *ds = *data;
-
-       di = container_of(info, struct gpio_event_input_info, info);
-
-       if (func == GPIO_EVENT_FUNC_SUSPEND) {
-               spin_lock_irqsave(&ds->irq_lock, irqflags);
-               if (ds->use_irq)
-                       for (i = 0; i < di->keymap_size; i++)
-                               disable_irq(gpio_to_irq(di->keymap[i].gpio));
-               spin_unlock_irqrestore(&ds->irq_lock, irqflags);
-               hrtimer_cancel(&ds->timer);
-               return 0;
-       }
-       if (func == GPIO_EVENT_FUNC_RESUME) {
-               spin_lock_irqsave(&ds->irq_lock, irqflags);
-               if (ds->use_irq)
-                       for (i = 0; i < di->keymap_size; i++)
-                               enable_irq(gpio_to_irq(di->keymap[i].gpio));
-               hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
-               spin_unlock_irqrestore(&ds->irq_lock, irqflags);
-               return 0;
-       }
-
-       if (func == GPIO_EVENT_FUNC_INIT) {
-               if (ktime_to_ns(di->poll_time) <= 0)
-                       di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
-
-               *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
-                                       di->keymap_size, GFP_KERNEL);
-               if (ds == NULL) {
-                       ret = -ENOMEM;
-                       pr_err("gpio_event_input_func: "
-                               "Failed to allocate private data\n");
-                       goto err_ds_alloc_failed;
-               }
-               ds->debounce_count = di->keymap_size;
-               ds->input_dev = input_dev;
-               ds->info = di;
-               spin_lock_init(&ds->irq_lock);
-
-               for (i = 0; i < di->keymap_size; i++) {
-                       input_set_capability(input_dev, di->type,
-                                            di->keymap[i].code);
-                       ds->key_state[i].ds = ds;
-                       ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
-               }
-
-               for (i = 0; i < di->keymap_size; i++) {
-                       ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
-                       if (ret) {
-                               pr_err("gpio_event_input_func: gpio_request "
-                                       "failed for %d\n", di->keymap[i].gpio);
-                               goto err_gpio_request_failed;
-                       }
-                       ret = gpio_direction_input(di->keymap[i].gpio);
-                       if (ret) {
-                               pr_err("gpio_event_input_func: "
-                                       "gpio_direction_input failed for %d\n",
-                                       di->keymap[i].gpio);
-                               goto err_gpio_configure_failed;
-                       }
-               }
-
-               ret = gpio_event_input_request_irqs(ds);
-
-               spin_lock_irqsave(&ds->irq_lock, irqflags);
-               ds->use_irq = ret == 0;
-
-               pr_info("GPIO Input Driver: Start gpio inputs for %s in %s "
-                       "mode\n",
-                       input_dev->name, ret == 0 ? "interrupt" : "polling");
-
-               hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-               ds->timer.function = gpio_event_input_timer_func;
-               hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
-               spin_unlock_irqrestore(&ds->irq_lock, irqflags);
-               return 0;
-       }
-
-       ret = 0;
-       spin_lock_irqsave(&ds->irq_lock, irqflags);
-       hrtimer_cancel(&ds->timer);
-       if (ds->use_irq) {
-               for (i = di->keymap_size - 1; i >= 0; i--) {
-                       free_irq(gpio_to_irq(di->keymap[i].gpio),
-                                &ds->key_state[i]);
-               }
-       }
-       spin_unlock_irqrestore(&ds->irq_lock, irqflags);
-
-       for (i = di->keymap_size - 1; i >= 0; i--) {
-err_gpio_configure_failed:
-               gpio_free(di->keymap[i].gpio);
-err_gpio_request_failed:
-               ;
-       }
-       kfree(ds);
-err_ds_alloc_failed:
-       return ret;
-}
diff --git a/drivers/staging/dream/gpio_matrix.c b/drivers/staging/dream/gpio_matrix.c
deleted file mode 100644 (file)
index b377ee1..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-/* drivers/input/misc/gpio_matrix.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/gpio.h>
-#include <linux/gpio_event.h>
-#include <linux/hrtimer.h>
-#include <linux/interrupt.h>
-
-struct gpio_kp {
-       struct input_dev *input_dev;
-       struct gpio_event_matrix_info *keypad_info;
-       struct hrtimer timer;
-       int current_output;
-       unsigned int use_irq:1;
-       unsigned int key_state_changed:1;
-       unsigned int last_key_state_changed:1;
-       unsigned int some_keys_pressed:2;
-       unsigned long keys_pressed[0];
-};
-
-static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
-{
-       struct gpio_event_matrix_info *mi = kp->keypad_info;
-       int key_index = out * mi->ninputs + in;
-       unsigned short keycode = mi->keymap[key_index];;
-
-       if (!test_bit(keycode, kp->input_dev->key)) {
-               if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
-                       pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
-                               "cleared\n", keycode, out, in,
-                               mi->output_gpios[out], mi->input_gpios[in]);
-               __clear_bit(key_index, kp->keys_pressed);
-       } else {
-               if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
-                       pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
-                               "not cleared\n", keycode, out, in,
-                               mi->output_gpios[out], mi->input_gpios[in]);
-       }
-}
-
-static int restore_keys_for_input(struct gpio_kp *kp, int out, int in)
-{
-       int rv = 0;
-       int key_index;
-
-       key_index = out * kp->keypad_info->ninputs + in;
-       while (out < kp->keypad_info->noutputs) {
-               if (test_bit(key_index, kp->keys_pressed)) {
-                       rv = 1;
-                       clear_phantom_key(kp, out, in);
-               }
-               key_index += kp->keypad_info->ninputs;
-               out++;
-       }
-       return rv;
-}
-
-static void remove_phantom_keys(struct gpio_kp *kp)
-{
-       int out, in, inp;
-       int key_index;
-
-       if (kp->some_keys_pressed < 3)
-               return;
-
-       for (out = 0; out < kp->keypad_info->noutputs; out++) {
-               inp = -1;
-               key_index = out * kp->keypad_info->ninputs;
-               for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) {
-                       if (test_bit(key_index, kp->keys_pressed)) {
-                               if (inp == -1) {
-                                       inp = in;
-                                       continue;
-                               }
-                               if (inp >= 0) {
-                                       if (!restore_keys_for_input(kp, out + 1,
-                                                                       inp))
-                                               break;
-                                       clear_phantom_key(kp, out, inp);
-                                       inp = -2;
-                               }
-                               restore_keys_for_input(kp, out, in);
-                       }
-               }
-       }
-}
-
-static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
-{
-       struct gpio_event_matrix_info *mi = kp->keypad_info;
-       int pressed = test_bit(key_index, kp->keys_pressed);
-       unsigned short keycode = mi->keymap[key_index];
-       if (pressed != test_bit(keycode, kp->input_dev->key)) {
-               if (keycode == KEY_RESERVED) {
-                       if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS)
-                               pr_info("gpiomatrix: unmapped key, %d-%d "
-                                       "(%d-%d) changed to %d\n",
-                                       out, in, mi->output_gpios[out],
-                                       mi->input_gpios[in], pressed);
-               } else {
-                       if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS)
-                               pr_info("gpiomatrix: key %x, %d-%d (%d-%d) "
-                                       "changed to %d\n", keycode,
-                                       out, in, mi->output_gpios[out],
-                                       mi->input_gpios[in], pressed);
-                       input_report_key(kp->input_dev, keycode, pressed);
-               }
-       }
-}
-
-static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer)
-{
-       int out, in;
-       int key_index;
-       int gpio;
-       struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer);
-       struct gpio_event_matrix_info *mi = kp->keypad_info;
-       unsigned gpio_keypad_flags = mi->flags;
-       unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH);
-
-       out = kp->current_output;
-       if (out == mi->noutputs) {
-               out = 0;
-               kp->last_key_state_changed = kp->key_state_changed;
-               kp->key_state_changed = 0;
-               kp->some_keys_pressed = 0;
-       } else {
-               key_index = out * mi->ninputs;
-               for (in = 0; in < mi->ninputs; in++, key_index++) {
-                       gpio = mi->input_gpios[in];
-                       if (gpio_get_value(gpio) ^ !polarity) {
-                               if (kp->some_keys_pressed < 3)
-                                       kp->some_keys_pressed++;
-                               kp->key_state_changed |= !__test_and_set_bit(
-                                               key_index, kp->keys_pressed);
-                       } else
-                               kp->key_state_changed |= __test_and_clear_bit(
-                                               key_index, kp->keys_pressed);
-               }
-               gpio = mi->output_gpios[out];
-               if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
-                       gpio_set_value(gpio, !polarity);
-               else
-                       gpio_direction_input(gpio);
-               out++;
-       }
-       kp->current_output = out;
-       if (out < mi->noutputs) {
-               gpio = mi->output_gpios[out];
-               if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
-                       gpio_set_value(gpio, polarity);
-               else
-                       gpio_direction_output(gpio, polarity);
-               hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL);
-               return HRTIMER_NORESTART;
-       }
-       if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) {
-               if (kp->key_state_changed) {
-                       hrtimer_start(&kp->timer, mi->debounce_delay,
-                                     HRTIMER_MODE_REL);
-                       return HRTIMER_NORESTART;
-               }
-               kp->key_state_changed = kp->last_key_state_changed;
-       }
-       if (kp->key_state_changed) {
-               if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS)
-                       remove_phantom_keys(kp);
-               key_index = 0;
-               for (out = 0; out < mi->noutputs; out++)
-                       for (in = 0; in < mi->ninputs; in++, key_index++)
-                               report_key(kp, key_index, out, in);
-       }
-       if (!kp->use_irq || kp->some_keys_pressed) {
-               hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL);
-               return HRTIMER_NORESTART;
-       }
-
-       /* No keys are pressed, reenable interrupt */
-       for (out = 0; out < mi->noutputs; out++) {
-               if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
-                       gpio_set_value(mi->output_gpios[out], polarity);
-               else
-                       gpio_direction_output(mi->output_gpios[out], polarity);
-       }
-       for (in = 0; in < mi->ninputs; in++)
-               enable_irq(gpio_to_irq(mi->input_gpios[in]));
-       return HRTIMER_NORESTART;
-}
-
-static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id)
-{
-       int i;
-       struct gpio_kp *kp = dev_id;
-       struct gpio_event_matrix_info *mi = kp->keypad_info;
-       unsigned gpio_keypad_flags = mi->flags;
-
-       if (!kp->use_irq) /* ignore interrupt while registering the handler */
-               return IRQ_HANDLED;
-
-       for (i = 0; i < mi->ninputs; i++)
-               disable_irq(gpio_to_irq(mi->input_gpios[i]));
-       for (i = 0; i < mi->noutputs; i++) {
-               if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
-                       gpio_set_value(mi->output_gpios[i],
-                               !(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH));
-               else
-                       gpio_direction_input(mi->output_gpios[i]);
-       }
-       hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
-       return IRQ_HANDLED;
-}
-
-static int gpio_keypad_request_irqs(struct gpio_kp *kp)
-{
-       int i;
-       int err;
-       unsigned int irq;
-       unsigned long request_flags;
-       struct gpio_event_matrix_info *mi = kp->keypad_info;
-
-       switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
-       default:
-               request_flags = IRQF_TRIGGER_FALLING;
-               break;
-       case GPIOKPF_ACTIVE_HIGH:
-               request_flags = IRQF_TRIGGER_RISING;
-               break;
-       case GPIOKPF_LEVEL_TRIGGERED_IRQ:
-               request_flags = IRQF_TRIGGER_LOW;
-               break;
-       case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
-               request_flags = IRQF_TRIGGER_HIGH;
-               break;
-       }
-
-       for (i = 0; i < mi->ninputs; i++) {
-               err = irq = gpio_to_irq(mi->input_gpios[i]);
-               if (err < 0)
-                       goto err_gpio_get_irq_num_failed;
-               err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
-                                 "gpio_kp", kp);
-               if (err) {
-                       pr_err("gpiomatrix: request_irq failed for input %d, "
-                               "irq %d\n", mi->input_gpios[i], irq);
-                       goto err_request_irq_failed;
-               }
-               err = set_irq_wake(irq, 1);
-               if (err) {
-                       pr_err("gpiomatrix: set_irq_wake failed for input %d, "
-                               "irq %d\n", mi->input_gpios[i], irq);
-               }
-               disable_irq(irq);
-       }
-       return 0;
-
-       for (i = mi->noutputs - 1; i >= 0; i--) {
-               free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
-err_request_irq_failed:
-err_gpio_get_irq_num_failed:
-               ;
-       }
-       return err;
-}
-
-int gpio_event_matrix_func(struct input_dev *input_dev,
-       struct gpio_event_info *info, void **data, int func)
-{
-       int i;
-       int err;
-       int key_count;
-       struct gpio_kp *kp;
-       struct gpio_event_matrix_info *mi;
-
-       mi = container_of(info, struct gpio_event_matrix_info, info);
-       if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
-               /* TODO: disable scanning */
-               return 0;
-       }
-
-       if (func == GPIO_EVENT_FUNC_INIT) {
-               if (mi->keymap == NULL ||
-                  mi->input_gpios == NULL ||
-                  mi->output_gpios == NULL) {
-                       err = -ENODEV;
-                       pr_err("gpiomatrix: Incomplete pdata\n");
-                       goto err_invalid_platform_data;
-               }
-               key_count = mi->ninputs * mi->noutputs;
-
-               *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
-                                    BITS_TO_LONGS(key_count), GFP_KERNEL);
-               if (kp == NULL) {
-                       err = -ENOMEM;
-                       pr_err("gpiomatrix: Failed to allocate private data\n");
-                       goto err_kp_alloc_failed;
-               }
-               kp->input_dev = input_dev;
-               kp->keypad_info = mi;
-               set_bit(EV_KEY, input_dev->evbit);
-               for (i = 0; i < key_count; i++) {
-                       if (mi->keymap[i])
-                               set_bit(mi->keymap[i] & KEY_MAX,
-                                       input_dev->keybit);
-               }
-
-               for (i = 0; i < mi->noutputs; i++) {
-                       if (gpio_cansleep(mi->output_gpios[i])) {
-                               pr_err("gpiomatrix: unsupported output gpio %d,"
-                                       " can sleep\n", mi->output_gpios[i]);
-                               err = -EINVAL;
-                               goto err_request_output_gpio_failed;
-                       }
-                       err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
-                       if (err) {
-                               pr_err("gpiomatrix: gpio_request failed for "
-                                       "output %d\n", mi->output_gpios[i]);
-                               goto err_request_output_gpio_failed;
-                       }
-                       if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
-                               err = gpio_direction_output(mi->output_gpios[i],
-                                       !(mi->flags & GPIOKPF_ACTIVE_HIGH));
-                       else
-                               err = gpio_direction_input(mi->output_gpios[i]);
-                       if (err) {
-                               pr_err("gpiomatrix: gpio_configure failed for "
-                                       "output %d\n", mi->output_gpios[i]);
-                               goto err_output_gpio_configure_failed;
-                       }
-               }
-               for (i = 0; i < mi->ninputs; i++) {
-                       err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
-                       if (err) {
-                               pr_err("gpiomatrix: gpio_request failed for "
-                                       "input %d\n", mi->input_gpios[i]);
-                               goto err_request_input_gpio_failed;
-                       }
-                       err = gpio_direction_input(mi->input_gpios[i]);
-                       if (err) {
-                               pr_err("gpiomatrix: gpio_direction_input failed"
-                                       " for input %d\n", mi->input_gpios[i]);
-                               goto err_gpio_direction_input_failed;
-                       }
-               }
-               kp->current_output = mi->noutputs;
-               kp->key_state_changed = 1;
-
-               hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-               kp->timer.function = gpio_keypad_timer_func;
-               err = gpio_keypad_request_irqs(kp);
-               kp->use_irq = err == 0;
-
-               pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for %s "
-                       "in %s mode\n", input_dev->name,
-                       kp->use_irq ? "interrupt" : "polling");
-
-               hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
-
-               return 0;
-       }
-
-       err = 0;
-       kp = *data;
-
-       if (kp->use_irq)
-               for (i = mi->noutputs - 1; i >= 0; i--)
-                       free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
-
-       hrtimer_cancel(&kp->timer);
-       for (i = mi->noutputs - 1; i >= 0; i--) {
-err_gpio_direction_input_failed:
-               gpio_free(mi->input_gpios[i]);
-err_request_input_gpio_failed:
-               ;
-       }
-       for (i = mi->noutputs - 1; i >= 0; i--) {
-err_output_gpio_configure_failed:
-               gpio_free(mi->output_gpios[i]);
-err_request_output_gpio_failed:
-               ;
-       }
-       kfree(kp);
-err_kp_alloc_failed:
-err_invalid_platform_data:
-       return err;
-}
diff --git a/drivers/staging/dream/gpio_output.c b/drivers/staging/dream/gpio_output.c
deleted file mode 100644 (file)
index 6f8453c..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* drivers/input/misc/gpio_output.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/gpio_event.h>
-
-int gpio_event_output_event(
-       struct input_dev *input_dev, struct gpio_event_info *info, void **data,
-       unsigned int type, unsigned int code, int value)
-{
-       int i;
-       struct gpio_event_output_info *oi;
-       oi = container_of(info, struct gpio_event_output_info, info);
-       if (type != oi->type)
-               return 0;
-       if (!(oi->flags & GPIOEDF_ACTIVE_HIGH))
-               value = !value;
-       for (i = 0; i < oi->keymap_size; i++)
-               if (code == oi->keymap[i].code)
-                       gpio_set_value(oi->keymap[i].gpio, value);
-       return 0;
-}
-
-int gpio_event_output_func(
-       struct input_dev *input_dev, struct gpio_event_info *info, void **data,
-       int func)
-{
-       int ret;
-       int i;
-       struct gpio_event_output_info *oi;
-       oi = container_of(info, struct gpio_event_output_info, info);
-
-       if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME)
-               return 0;
-
-       if (func == GPIO_EVENT_FUNC_INIT) {
-               int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH);
-               for (i = 0; i < oi->keymap_size; i++)
-                       input_set_capability(input_dev, oi->type,
-                                            oi->keymap[i].code);
-
-               for (i = 0; i < oi->keymap_size; i++) {
-                       ret = gpio_request(oi->keymap[i].gpio,
-                                          "gpio_event_output");
-                       if (ret) {
-                               pr_err("gpio_event_output_func: gpio_request "
-                                       "failed for %d\n", oi->keymap[i].gpio);
-                               goto err_gpio_request_failed;
-                       }
-                       ret = gpio_direction_output(oi->keymap[i].gpio,
-                                                   output_level);
-                       if (ret) {
-                               pr_err("gpio_event_output_func: "
-                                       "gpio_direction_output failed for %d\n",
-                                       oi->keymap[i].gpio);
-                               goto err_gpio_direction_output_failed;
-                       }
-               }
-               return 0;
-       }
-
-       ret = 0;
-       for (i = oi->keymap_size - 1; i >= 0; i--) {
-err_gpio_direction_output_failed:
-               gpio_free(oi->keymap[i].gpio);
-err_gpio_request_failed:
-               ;
-       }
-       return ret;
-}
-
diff --git a/drivers/staging/dream/include/linux/android_pmem.h b/drivers/staging/dream/include/linux/android_pmem.h
deleted file mode 100644 (file)
index 2fc05d7..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* drivers/staging/dream/include/linux/android_pmem.h
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _ANDROID_PMEM_H_
-#define _ANDROID_PMEM_H_
-
-#define PMEM_IOCTL_MAGIC 'p'
-#define PMEM_GET_PHYS          _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
-#define PMEM_MAP               _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
-#define PMEM_GET_SIZE          _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
-#define PMEM_UNMAP             _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
-/* This ioctl will allocate pmem space, backing the file, it will fail
- * if the file already has an allocation, pass it the len as the argument
- * to the ioctl */
-#define PMEM_ALLOCATE          _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
-/* This will connect a one pmem file to another, pass the file that is already
- * backed in memory as the argument to the ioctl
- */
-#define PMEM_CONNECT           _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
-/* Returns the total size of the pmem region it is sent to as a pmem_region
- * struct (with offset set to 0).
- */
-#define PMEM_GET_TOTAL_SIZE    _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
-/* Revokes gpu registers and resets the gpu.  Pass a pointer to the
- * start of the mapped gpu regs (the vaddr returned by mmap) as the argument.
- */
-#define HW3D_REVOKE_GPU                _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
-#define HW3D_GRANT_GPU         _IOW(PMEM_IOCTL_MAGIC, 9, unsigned int)
-#define HW3D_WAIT_FOR_INTERRUPT        _IOW(PMEM_IOCTL_MAGIC, 10, unsigned int)
-
-int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
-                 unsigned long *end, struct file **filp);
-int get_pmem_user_addr(struct file *file, unsigned long *start,
-                      unsigned long *end);
-void put_pmem_file(struct file* file);
-void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
-
-struct android_pmem_platform_data
-{
-       const char* name;
-       /* starting physical address of memory region */
-       unsigned long start;
-       /* size of memory region */
-       unsigned long size;
-       /* set to indicate the region should not be managed with an allocator */
-       unsigned no_allocator;
-       /* set to indicate maps of this region should be cached, if a mix of
-        * cached and uncached is desired, set this and open the device with
-        * O_SYNC to get an uncached region */
-       unsigned cached;
-       /* The MSM7k has bits to enable a write buffer in the bus controller*/
-       unsigned buffered;
-};
-
-struct pmem_region {
-       unsigned long offset;
-       unsigned long len;
-};
-
-int pmem_setup(struct android_pmem_platform_data *pdata,
-              long (*ioctl)(struct file *, unsigned int, unsigned long),
-              int (*release)(struct inode *, struct file *));
-
-int pmem_remap(struct pmem_region *region, struct file *file,
-              unsigned operation);
-
-#endif //_ANDROID_PPP_H_
-
diff --git a/drivers/staging/dream/include/linux/gpio_event.h b/drivers/staging/dream/include/linux/gpio_event.h
deleted file mode 100644 (file)
index ffc5da3..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/* drivers/staging/dream/include/linux/gpio_event.h
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _LINUX_GPIO_EVENT_H
-#define _LINUX_GPIO_EVENT_H
-
-#include <linux/input.h>
-
-enum {
-       GPIO_EVENT_FUNC_UNINIT  = 0x0,
-       GPIO_EVENT_FUNC_INIT    = 0x1,
-       GPIO_EVENT_FUNC_SUSPEND = 0x2,
-       GPIO_EVENT_FUNC_RESUME  = 0x3,
-};
-struct gpio_event_info {
-       int (*func)(struct input_dev *input_dev,
-                   struct gpio_event_info *info,
-                   void **data, int func);
-       int (*event)(struct input_dev *input_dev,
-                    struct gpio_event_info *info,
-                    void **data, unsigned int type,
-                    unsigned int code, int value); /* out events */
-};
-
-struct gpio_event_platform_data {
-       const char *name;
-       struct gpio_event_info **info;
-       size_t info_count;
-       int (*power)(const struct gpio_event_platform_data *pdata, bool on);
-};
-
-#define GPIO_EVENT_DEV_NAME "gpio-event"
-
-/* Key matrix */
-
-enum gpio_event_matrix_flags {
-       /* unset: drive active output low, set: drive active output high */
-       GPIOKPF_ACTIVE_HIGH              = 1U << 0,
-       GPIOKPF_DEBOUNCE                 = 1U << 1,
-       GPIOKPF_REMOVE_SOME_PHANTOM_KEYS = 1U << 2,
-       GPIOKPF_REMOVE_PHANTOM_KEYS      = GPIOKPF_REMOVE_SOME_PHANTOM_KEYS |
-                                          GPIOKPF_DEBOUNCE,
-       GPIOKPF_DRIVE_INACTIVE           = 1U << 3,
-       GPIOKPF_LEVEL_TRIGGERED_IRQ      = 1U << 4,
-       GPIOKPF_PRINT_UNMAPPED_KEYS      = 1U << 16,
-       GPIOKPF_PRINT_MAPPED_KEYS        = 1U << 17,
-       GPIOKPF_PRINT_PHANTOM_KEYS       = 1U << 18,
-};
-
-extern int gpio_event_matrix_func(struct input_dev *input_dev,
-                       struct gpio_event_info *info, void **data, int func);
-struct gpio_event_matrix_info {
-       /* initialize to gpio_event_matrix_func */
-       struct gpio_event_info info;
-       /* size must be ninputs * noutputs */
-       const unsigned short *keymap;
-       unsigned int *input_gpios;
-       unsigned int *output_gpios;
-       unsigned int ninputs;
-       unsigned int noutputs;
-       /* time to wait before reading inputs after driving each output */
-       ktime_t settle_time;
-       /* time to wait before scanning the keypad a second time */
-       ktime_t debounce_delay;
-       ktime_t poll_time;
-       unsigned flags;
-};
-
-/* Directly connected inputs and outputs */
-
-enum gpio_event_direct_flags {
-       GPIOEDF_ACTIVE_HIGH         = 1U << 0,
-/*     GPIOEDF_USE_DOWN_IRQ        = 1U << 1, */
-/*     GPIOEDF_USE_IRQ             = (1U << 2) | GPIOIDF_USE_DOWN_IRQ, */
-       GPIOEDF_PRINT_KEYS          = 1U << 8,
-       GPIOEDF_PRINT_KEY_DEBOUNCE  = 1U << 9,
-};
-
-struct gpio_event_direct_entry {
-       uint32_t gpio:23;
-       uint32_t code:9;
-};
-
-/* inputs */
-extern int gpio_event_input_func(struct input_dev *input_dev,
-                       struct gpio_event_info *info, void **data, int func);
-struct gpio_event_input_info {
-       /* initialize to gpio_event_input_func */
-       struct gpio_event_info info;
-       ktime_t debounce_time;
-       ktime_t poll_time;
-       uint16_t flags;
-       uint16_t type;
-       const struct gpio_event_direct_entry *keymap;
-       size_t keymap_size;
-};
-
-/* outputs */
-extern int gpio_event_output_func(struct input_dev *input_dev,
-                       struct gpio_event_info *info, void **data, int func);
-extern int gpio_event_output_event(struct input_dev *input_dev,
-                       struct gpio_event_info *info, void **data,
-                       unsigned int type, unsigned int code, int value);
-struct gpio_event_output_info {
-       /* initialize to gpio_event_output_func and gpio_event_output_event */
-       struct gpio_event_info info;
-       uint16_t flags;
-       uint16_t type;
-       const struct gpio_event_direct_entry *keymap;
-       size_t keymap_size;
-};
-
-
-/* axes */
-
-enum gpio_event_axis_flags {
-       GPIOEAF_PRINT_UNKNOWN_DIRECTION  = 1U << 16,
-       GPIOEAF_PRINT_RAW                = 1U << 17,
-       GPIOEAF_PRINT_EVENT              = 1U << 18,
-};
-
-extern int gpio_event_axis_func(struct input_dev *input_dev,
-                       struct gpio_event_info *info, void **data, int func);
-struct gpio_event_axis_info {
-       /* initialize to gpio_event_axis_func */
-       struct gpio_event_info info;
-       uint8_t  count;
-       uint8_t  type; /* EV_REL or EV_ABS */
-       uint16_t code;
-       uint16_t decoded_size;
-       uint16_t (*map)(struct gpio_event_axis_info *info, uint16_t in);
-       uint32_t *gpio;
-       uint32_t flags;
-};
-#define gpio_axis_2bit_gray_map gpio_axis_4bit_gray_map
-#define gpio_axis_3bit_gray_map gpio_axis_4bit_gray_map
-uint16_t gpio_axis_4bit_gray_map(
-                       struct gpio_event_axis_info *info, uint16_t in);
-uint16_t gpio_axis_5bit_singletrack_map(
-                       struct gpio_event_axis_info *info, uint16_t in);
-
-#endif
diff --git a/drivers/staging/dream/include/linux/msm_adsp.h b/drivers/staging/dream/include/linux/msm_adsp.h
deleted file mode 100644 (file)
index e775f3e..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* drivers/staging/dream/include/linux/msm_adsp.h
- *
- * Copyright (c) QUALCOMM Incorporated
- * Copyright (C) 2007 Google, Inc.
- * Author: Iliyan Malchev <ibm@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-#ifndef __LINUX_MSM_ADSP_H
-#define __LINUX_MSM_ADSP_H
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-
-#define ADSP_IOCTL_MAGIC 'q'
-
-/* ADSP_IOCTL_WRITE_COMMAND */
-struct adsp_command_t {
-       uint16_t queue;
-       uint32_t len;           /* bytes */
-       uint8_t *data;
-};
-
-/* ADSP_IOCTL_GET_EVENT */
-struct adsp_event_t {
-       uint16_t type;          /* 1 == event (RPC), 0 == message (adsp) */
-       uint32_t timeout_ms;    /* -1 for infinite, 0 for immediate return */
-       uint16_t msg_id;
-       uint16_t flags;         /* 1 == 16--bit event, 0 == 32-bit event */
-       uint32_t len;           /* size in, number of bytes out */
-       uint8_t *data;
-};
-
-#define ADSP_IOCTL_ENABLE \
-       _IOR(ADSP_IOCTL_MAGIC, 1, unsigned)
-
-#define ADSP_IOCTL_DISABLE \
-       _IOR(ADSP_IOCTL_MAGIC, 2, unsigned)
-
-#define ADSP_IOCTL_DISABLE_ACK \
-       _IOR(ADSP_IOCTL_MAGIC, 3, unsigned)
-
-#define ADSP_IOCTL_WRITE_COMMAND \
-       _IOR(ADSP_IOCTL_MAGIC, 4, struct adsp_command_t *)
-
-#define ADSP_IOCTL_GET_EVENT \
-       _IOWR(ADSP_IOCTL_MAGIC, 5, struct adsp_event_data_t *)
-
-#define ADSP_IOCTL_SET_CLKRATE \
-       _IOR(ADSP_IOCTL_MAGIC, 6, unsigned)
-
-#define ADSP_IOCTL_DISABLE_EVENT_RSP \
-       _IOR(ADSP_IOCTL_MAGIC, 10, unsigned)
-
-struct adsp_pmem_info {
-        int fd;
-        void *vaddr;
-};
-
-#define ADSP_IOCTL_REGISTER_PMEM \
-       _IOW(ADSP_IOCTL_MAGIC, 13, unsigned)
-
-#define ADSP_IOCTL_UNREGISTER_PMEM \
-       _IOW(ADSP_IOCTL_MAGIC, 14, unsigned)
-
-/* Cause any further GET_EVENT ioctls to fail (-ENODEV)
- * until the device is closed and reopened.  Useful for
- * terminating event dispatch threads
- */
-#define ADSP_IOCTL_ABORT_EVENT_READ \
-       _IOW(ADSP_IOCTL_MAGIC, 15, unsigned)
-
-#define ADSP_IOCTL_LINK_TASK \
-       _IOW(ADSP_IOCTL_MAGIC, 16, unsigned)
-
-#endif
diff --git a/drivers/staging/dream/include/linux/msm_audio.h b/drivers/staging/dream/include/linux/msm_audio.h
deleted file mode 100644 (file)
index cfbdaa0..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* drivers/staging/dream/include/linux/msm_audio.h
- *
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef __LINUX_MSM_AUDIO_H
-#define __LINUX_MSM_AUDIO_H
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <asm/sizes.h>
-
-/* PCM Audio */
-
-#define AUDIO_IOCTL_MAGIC 'a'
-
-#define AUDIO_START        _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
-#define AUDIO_STOP         _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
-#define AUDIO_FLUSH        _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
-#define AUDIO_GET_CONFIG   _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
-#define AUDIO_SET_CONFIG   _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
-#define AUDIO_GET_STATS    _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
-#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
-#define AUDIO_SET_ADRC     _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
-#define AUDIO_SET_EQ       _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
-#define AUDIO_SET_RX_IIR   _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
-#define AUDIO_SET_VOLUME   _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
-#define AUDIO_ENABLE_AUDPRE  _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
-#define AUDIO_SET_AGC        _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
-#define AUDIO_SET_NS         _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
-#define AUDIO_SET_TX_IIR     _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
-#define AUDIO_PAUSE         _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
-#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned)
-#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned)
-#define AUDIO_SWITCH_DEVICE  _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned)
-
-#define        AUDIO_MAX_COMMON_IOCTL_NUM      100
-
-#define        AUDIO_MAX_COMMON_IOCTL_NUM      100
-
-struct msm_audio_config {
-       uint32_t buffer_size;
-       uint32_t buffer_count;
-       uint32_t channel_count;
-       uint32_t sample_rate;
-       uint32_t type;
-       uint32_t unused[3];
-};
-
-struct msm_audio_stats {
-       uint32_t byte_count;
-       uint32_t sample_count;
-       uint32_t unused[2];
-};
-
-/* Audio routing */
-
-#define SND_IOCTL_MAGIC 's'
-
-#define SND_MUTE_UNMUTED 0
-#define SND_MUTE_MUTED   1
-
-struct msm_snd_device_config {
-       uint32_t device;
-       uint32_t ear_mute;
-       uint32_t mic_mute;
-};
-
-#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
-
-#define SND_METHOD_VOICE 0
-
-struct msm_snd_volume_config {
-       uint32_t device;
-       uint32_t method;
-       uint32_t volume;
-};
-
-#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
-
-/* Returns the number of SND endpoints supported. */
-
-#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
-
-struct msm_snd_endpoint {
-       int id; /* input and output */
-       char name[64]; /* output only */
-};
-
-/* Takes an index between 0 and one less than the number returned by
- * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a
- * SND endpoint.  On input, the .id field contains the number of the
- * endpoint, and on exit it contains the SND index, while .name contains
- * the description of the endpoint.
- */
-
-#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)
-
-struct msm_audio_pcm_config {
-       uint32_t pcm_feedback;  /* 0 - disable > 0 - enable */
-       uint32_t buffer_count;  /* Number of buffers to allocate */
-       uint32_t buffer_size;   /* Size of buffer for capturing of
-                                  PCM samples */
-};
-#endif
diff --git a/drivers/staging/dream/include/linux/msm_rpcrouter.h b/drivers/staging/dream/include/linux/msm_rpcrouter.h
deleted file mode 100644 (file)
index 64845fb..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* drivers/staging/dream/include/linux/msm_rpcrouter.h
- *
- * Copyright (c) QUALCOMM Incorporated
- * Copyright (C) 2007 Google, Inc.
- * Author: San Mehat <san@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-#ifndef __LINUX_MSM_RPCROUTER_H
-#define __LINUX_MSM_RPCROUTER_H
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-
-#define RPC_ROUTER_VERSION_V1 0x00010000
-
-struct rpcrouter_ioctl_server_args {
-       uint32_t prog;
-       uint32_t vers;
-};
-
-#define RPC_ROUTER_IOCTL_MAGIC (0xC1)
-
-#define RPC_ROUTER_IOCTL_GET_VERSION \
-       _IOR(RPC_ROUTER_IOCTL_MAGIC, 0, unsigned int)
-
-#define RPC_ROUTER_IOCTL_GET_MTU \
-       _IOR(RPC_ROUTER_IOCTL_MAGIC, 1, unsigned int)
-
-#define RPC_ROUTER_IOCTL_REGISTER_SERVER \
-       _IOWR(RPC_ROUTER_IOCTL_MAGIC, 2, unsigned int)
-
-#define RPC_ROUTER_IOCTL_UNREGISTER_SERVER \
-       _IOWR(RPC_ROUTER_IOCTL_MAGIC, 3, unsigned int)
-
-#define RPC_ROUTER_IOCTL_GET_MINOR_VERSION \
-       _IOW(RPC_ROUTER_IOCTL_MAGIC, 4, unsigned int)
-
-#endif
diff --git a/drivers/staging/dream/include/linux/wakelock.h b/drivers/staging/dream/include/linux/wakelock.h
deleted file mode 100644 (file)
index 93c31a4..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* drivers/staging/dream/include/linux/wakelock.h
- *
- * Copyright (C) 2007-2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _LINUX_WAKELOCK_H
-#define _LINUX_WAKELOCK_H
-
-#include <linux/list.h>
-#include <linux/ktime.h>
-
-/* A wake_lock prevents the system from entering suspend or other low power
- * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
- * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
- * states that cause large interrupt latencies or that disable a set of
- * interrupts will not entered from idle until the wake_locks are released.
- */
-
-enum {
-       WAKE_LOCK_SUSPEND, /* Prevent suspend */
-       WAKE_LOCK_IDLE,    /* Prevent low power idle */
-       WAKE_LOCK_TYPE_COUNT
-};
-
-struct wake_lock {
-#ifdef CONFIG_HAS_WAKELOCK
-       struct list_head    link;
-       int                 flags;
-       const char         *name;
-       unsigned long       expires;
-#ifdef CONFIG_WAKELOCK_STAT
-       struct {
-               int             count;
-               int             expire_count;
-               int             wakeup_count;
-               ktime_t         total_time;
-               ktime_t         prevent_suspend_time;
-               ktime_t         max_time;
-               ktime_t         last_time;
-       } stat;
-#endif
-#endif
-};
-
-#ifdef CONFIG_HAS_WAKELOCK
-
-void wake_lock_init(struct wake_lock *lock, int type, const char *name);
-void wake_lock_destroy(struct wake_lock *lock);
-void wake_lock(struct wake_lock *lock);
-void wake_lock_timeout(struct wake_lock *lock, long timeout);
-void wake_unlock(struct wake_lock *lock);
-
-/* wake_lock_active returns a non-zero value if the wake_lock is currently
- * locked. If the wake_lock has a timeout, it does not check the timeout
- * but if the timeout had aready been checked it will return 0.
- */
-int wake_lock_active(struct wake_lock *lock);
-
-/* has_wake_lock returns 0 if no wake locks of the specified type are active,
- * and non-zero if one or more wake locks are held. Specifically it returns
- * -1 if one or more wake locks with no timeout are active or the
- * number of jiffies until all active wake locks time out.
- */
-long has_wake_lock(int type);
-
-#else
-
-static inline void wake_lock_init(struct wake_lock *lock, int type,
-                                       const char *name) {}
-static inline void wake_lock_destroy(struct wake_lock *lock) {}
-static inline void wake_lock(struct wake_lock *lock) {}
-static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {}
-static inline void wake_unlock(struct wake_lock *lock) {}
-
-static inline int wake_lock_active(struct wake_lock *lock) { return 0; }
-static inline long has_wake_lock(int type) { return 0; }
-
-#endif
-
-#endif
-
diff --git a/drivers/staging/dream/include/mach/camera.h b/drivers/staging/dream/include/mach/camera.h
deleted file mode 100644 (file)
index c20f042..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-
-#ifndef __ASM__ARCH_CAMERA_H
-#define __ASM__ARCH_CAMERA_H
-
-#include <linux/list.h>
-#include <linux/poll.h>
-#include <linux/cdev.h>
-#include <linux/platform_device.h>
-#include "linux/types.h"
-
-#include <mach/board.h>
-#include <media/msm_camera.h>
-
-#ifdef CONFIG_MSM_CAMERA_DEBUG
-#define CDBG(fmt, args...) printk(KERN_INFO "msm_camera: " fmt, ##args)
-#else
-#define CDBG(fmt, args...) do { } while (0)
-#endif
-
-#define MSM_CAMERA_MSG 0
-#define MSM_CAMERA_EVT 1
-#define NUM_WB_EXP_NEUTRAL_REGION_LINES 4
-#define NUM_WB_EXP_STAT_OUTPUT_BUFFERS  3
-#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16
-#define NUM_AF_STAT_OUTPUT_BUFFERS      3
-
-enum msm_queue {
-       MSM_CAM_Q_CTRL,     /* control command or control command status */
-       MSM_CAM_Q_VFE_EVT,  /* adsp event */
-       MSM_CAM_Q_VFE_MSG,  /* adsp message */
-       MSM_CAM_Q_V4L2_REQ, /* v4l2 request */
-};
-
-enum vfe_resp_msg {
-       VFE_EVENT,
-       VFE_MSG_GENERAL,
-       VFE_MSG_SNAPSHOT,
-       VFE_MSG_OUTPUT1,
-       VFE_MSG_OUTPUT2,
-       VFE_MSG_STATS_AF,
-       VFE_MSG_STATS_WE,
-};
-
-struct msm_vfe_phy_info {
-       uint32_t sbuf_phy;
-       uint32_t y_phy;
-       uint32_t cbcr_phy;
-};
-
-struct msm_vfe_resp {
-       enum vfe_resp_msg type;
-       struct msm_vfe_evt_msg evt_msg;
-       struct msm_vfe_phy_info phy;
-       void    *extdata;
-       int32_t extlen;
-};
-
-struct msm_vfe_callback {
-       void (*vfe_resp)(struct msm_vfe_resp *,
-               enum msm_queue, void *syncdata);
-       void* (*vfe_alloc)(int, void *syncdata);
-};
-
-struct msm_camvfe_fn {
-       int (*vfe_init)(struct msm_vfe_callback *, struct platform_device *);
-       int (*vfe_enable)(struct camera_enable_cmd *);
-       int (*vfe_config)(struct msm_vfe_cfg_cmd *, void *);
-       int (*vfe_disable)(struct camera_enable_cmd *,
-               struct platform_device *dev);
-       void (*vfe_release)(struct platform_device *);
-};
-
-struct msm_sensor_ctrl {
-       int (*s_init)(const struct msm_camera_sensor_info *);
-       int (*s_release)(void);
-       int (*s_config)(void __user *);
-};
-
-struct msm_sync {
-       /* These two queues are accessed from a process context only. */
-       struct hlist_head frame; /* most-frequently accessed */
-       struct hlist_head stats;
-
-       /* The message queue is used by the control thread to send commands
-        * to the config thread, and also by the DSP to send messages to the
-        * config thread.  Thus it is the only queue that is accessed from
-        * both interrupt and process context.
-        */
-       spinlock_t msg_event_q_lock;
-       struct list_head msg_event_q;
-       wait_queue_head_t msg_event_wait;
-
-       /* This queue contains preview frames. It is accessed by the DSP (in
-        * in interrupt context, and by the frame thread.
-        */
-       spinlock_t prev_frame_q_lock;
-       struct list_head prev_frame_q;
-       wait_queue_head_t prev_frame_wait;
-       int unblock_poll_frame;
-
-       /* This queue contains snapshot frames.  It is accessed by the DSP (in
-        * interrupt context, and by the control thread.
-        */
-       spinlock_t pict_frame_q_lock;
-       struct list_head pict_frame_q;
-       wait_queue_head_t pict_frame_wait;
-
-       struct msm_camera_sensor_info *sdata;
-       struct msm_camvfe_fn vfefn;
-       struct msm_sensor_ctrl sctrl;
-       struct platform_device *pdev;
-       uint8_t opencnt;
-       void *cropinfo;
-       int  croplen;
-       unsigned pict_pp;
-
-       const char *apps_id;
-
-       struct mutex lock;
-       struct list_head list;
-};
-
-#define MSM_APPS_ID_V4L2 "msm_v4l2"
-#define MSM_APPS_ID_PROP "msm_qct"
-
-struct msm_device {
-       struct msm_sync *sync; /* most-frequently accessed */
-       struct device *device;
-       struct cdev cdev;
-       /* opened is meaningful only for the config and frame nodes,
-        * which may be opened only once.
-        */
-       atomic_t opened;
-};
-
-struct msm_control_device_queue {
-       spinlock_t ctrl_status_q_lock;
-       struct list_head ctrl_status_q;
-       wait_queue_head_t ctrl_status_wait;
-};
-
-struct msm_control_device {
-       struct msm_device *pmsm;
-
-       /* This queue used by the config thread to send responses back to the
-        * control thread.  It is accessed only from a process context.
-        */
-       struct msm_control_device_queue ctrl_q;
-};
-
-/* this structure is used in kernel */
-struct msm_queue_cmd {
-       struct list_head list;
-       enum msm_queue type;
-       void *command;
-};
-
-struct register_address_value_pair {
-       uint16_t register_address;
-       uint16_t register_value;
-};
-
-struct msm_pmem_region {
-       struct hlist_node list;
-       int type;
-       void *vaddr;
-       unsigned long paddr;
-       unsigned long len;
-       struct file *file;
-       uint32_t y_off;
-       uint32_t cbcr_off;
-       int fd;
-       uint8_t  active;
-};
-
-struct axidata {
-       uint32_t bufnum1;
-       uint32_t bufnum2;
-       struct msm_pmem_region *region;
-};
-
-#ifdef CONFIG_MSM_CAMERA_FLASH
-int msm_camera_flash_set_led_state(unsigned led_state);
-#else
-static inline int msm_camera_flash_set_led_state(unsigned led_state)
-{
-       return -ENOTSUPP;
-}
-#endif
-
-/* Below functions are added for V4L2 kernel APIs */
-struct msm_v4l2_driver {
-       struct msm_sync *sync;
-       int (*open)(struct msm_sync *, const char *apps_id);
-       int (*release)(struct msm_sync *);
-       int (*ctrl)(struct msm_sync *, struct msm_ctrl_cmd *);
-       int (*reg_pmem)(struct msm_sync *, struct msm_pmem_info *);
-       int (*get_frame) (struct msm_sync *, struct msm_frame *);
-       int (*put_frame) (struct msm_sync *, struct msm_frame *);
-       int (*get_pict) (struct msm_sync *, struct msm_ctrl_cmd *);
-       unsigned int (*drv_poll) (struct msm_sync *, struct file *,
-                               struct poll_table_struct *);
-};
-
-int msm_v4l2_register(struct msm_v4l2_driver *);
-int msm_v4l2_unregister(struct msm_v4l2_driver *);
-
-void msm_camvfe_init(void);
-int msm_camvfe_check(void *);
-void msm_camvfe_fn_init(struct msm_camvfe_fn *, void *);
-int msm_camera_drv_start(struct platform_device *dev,
-               int (*sensor_probe)(const struct msm_camera_sensor_info *,
-                                       struct msm_sensor_ctrl *));
-
-enum msm_camio_clk_type {
-       CAMIO_VFE_MDC_CLK,
-       CAMIO_MDC_CLK,
-       CAMIO_VFE_CLK,
-       CAMIO_VFE_AXI_CLK,
-
-       CAMIO_MAX_CLK
-};
-
-enum msm_camio_clk_src_type {
-       MSM_CAMIO_CLK_SRC_INTERNAL,
-       MSM_CAMIO_CLK_SRC_EXTERNAL,
-       MSM_CAMIO_CLK_SRC_MAX
-};
-
-enum msm_s_test_mode {
-       S_TEST_OFF,
-       S_TEST_1,
-       S_TEST_2,
-       S_TEST_3
-};
-
-enum msm_s_resolution {
-       S_QTR_SIZE,
-       S_FULL_SIZE,
-       S_INVALID_SIZE
-};
-
-enum msm_s_reg_update {
-       /* Sensor egisters that need to be updated during initialization */
-       S_REG_INIT,
-       /* Sensor egisters that needs periodic I2C writes */
-       S_UPDATE_PERIODIC,
-       /* All the sensor Registers will be updated */
-       S_UPDATE_ALL,
-       /* Not valid update */
-       S_UPDATE_INVALID
-};
-
-enum msm_s_setting {
-       S_RES_PREVIEW,
-       S_RES_CAPTURE
-};
-
-int msm_camio_enable(struct platform_device *dev);
-
-int  msm_camio_clk_enable(enum msm_camio_clk_type clk);
-int  msm_camio_clk_disable(enum msm_camio_clk_type clk);
-int  msm_camio_clk_config(uint32_t freq);
-void msm_camio_clk_rate_set(int rate);
-void msm_camio_clk_axi_rate_set(int rate);
-
-void msm_camio_camif_pad_reg_reset(void);
-void msm_camio_camif_pad_reg_reset_2(void);
-
-void msm_camio_vfe_blk_reset(void);
-
-void msm_camio_clk_sel(enum msm_camio_clk_src_type);
-void msm_camio_disable(struct platform_device *);
-int msm_camio_probe_on(struct platform_device *);
-int msm_camio_probe_off(struct platform_device *);
-#endif
diff --git a/drivers/staging/dream/include/mach/msm_adsp.h b/drivers/staging/dream/include/mach/msm_adsp.h
deleted file mode 100644 (file)
index a081683..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/* include/asm-arm/arch-msm/msm_adsp.h
- *
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef __ASM__ARCH_MSM_ADSP_H
-#define __ASM__ARCH_MSM_ADSP_H
-
-struct msm_adsp_module;
-
-struct msm_adsp_ops {
-       /* event is called from interrupt context when a message
-        * arrives from the DSP.  Use the provided function pointer
-        * to copy the message into a local buffer.  Do NOT call
-        * it multiple times.
-        */
-       void (*event)(void *driver_data, unsigned id, size_t len,
-                     void (*getevent)(void *ptr, size_t len));
-};
-
-/* Get, Put, Enable, and Disable are synchronous and must only
- * be called from thread context.  Enable and Disable will block
- * up to one second in the event of a fatal DSP error but are
- * much faster otherwise.
- */
-int msm_adsp_get(const char *name, struct msm_adsp_module **module,
-                struct msm_adsp_ops *ops, void *driver_data);
-void msm_adsp_put(struct msm_adsp_module *module);
-int msm_adsp_enable(struct msm_adsp_module *module);
-int msm_adsp_disable(struct msm_adsp_module *module);
-int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate);
-
-/* Write is safe to call from interrupt context.
- */
-int msm_adsp_write(struct msm_adsp_module *module,
-                  unsigned queue_id,
-                  void *data, size_t len);
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-/* Command Queue Indexes */
-#define QDSP_lpmCommandQueue              0
-#define QDSP_mpuAfeQueue                  1
-#define QDSP_mpuGraphicsCmdQueue          2
-#define QDSP_mpuModmathCmdQueue           3
-#define QDSP_mpuVDecCmdQueue              4
-#define QDSP_mpuVDecPktQueue              5
-#define QDSP_mpuVEncCmdQueue              6
-#define QDSP_rxMpuDecCmdQueue             7
-#define QDSP_rxMpuDecPktQueue             8
-#define QDSP_txMpuEncQueue                9
-#define QDSP_uPAudPPCmd1Queue             10
-#define QDSP_uPAudPPCmd2Queue             11
-#define QDSP_uPAudPPCmd3Queue             12
-#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
-#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
-#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
-#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
-#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
-#define QDSP_uPAudPreProcCmdQueue         18
-#define QDSP_uPAudRecBitStreamQueue       19
-#define QDSP_uPAudRecCmdQueue             20
-#define QDSP_uPDiagQueue                  21
-#define QDSP_uPJpegActionCmdQueue         22
-#define QDSP_uPJpegCfgCmdQueue            23
-#define QDSP_uPVocProcQueue               24
-#define QDSP_vfeCommandQueue              25
-#define QDSP_vfeCommandScaleQueue         26
-#define QDSP_vfeCommandTableQueue         27
-#define QDSP_MAX_NUM_QUEUES               28
-#else
-/* Command Queue Indexes */
-#define QDSP_lpmCommandQueue              0
-#define QDSP_mpuAfeQueue                  1
-#define QDSP_mpuGraphicsCmdQueue          2
-#define QDSP_mpuModmathCmdQueue           3
-#define QDSP_mpuVDecCmdQueue              4
-#define QDSP_mpuVDecPktQueue              5
-#define QDSP_mpuVEncCmdQueue              6
-#define QDSP_rxMpuDecCmdQueue             7
-#define QDSP_rxMpuDecPktQueue             8
-#define QDSP_txMpuEncQueue                9
-#define QDSP_uPAudPPCmd1Queue             10
-#define QDSP_uPAudPPCmd2Queue             11
-#define QDSP_uPAudPPCmd3Queue             12
-#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
-#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
-#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
-#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
-#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
-#define QDSP_uPAudPreProcCmdQueue         18
-#define QDSP_uPAudRecBitStreamQueue       19
-#define QDSP_uPAudRecCmdQueue             20
-#define QDSP_uPJpegActionCmdQueue         21
-#define QDSP_uPJpegCfgCmdQueue            22
-#define QDSP_uPVocProcQueue               23
-#define QDSP_vfeCommandQueue              24
-#define QDSP_vfeCommandScaleQueue         25
-#define QDSP_vfeCommandTableQueue         26
-#define QDSP_QUEUE_MAX                    26
-#endif
-
-#endif
diff --git a/drivers/staging/dream/include/mach/msm_rpcrouter.h b/drivers/staging/dream/include/mach/msm_rpcrouter.h
deleted file mode 100644 (file)
index 9724ece..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/** include/asm-arm/arch-msm/msm_rpcrouter.h
- *
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2009 QUALCOMM Incorporated
- * Author: San Mehat <san@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef __ASM__ARCH_MSM_RPCROUTER_H
-#define __ASM__ARCH_MSM_RPCROUTER_H
-
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/platform_device.h>
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-/* RPC API version structure
- * Version bit 31 : 1->hashkey versioning,
- *                  0->major-minor (backward compatible) versioning
- * hashkey versioning:
- *   Version bits 31-0 hashkey
- * major-minor (backward compatible) versioning
- *   Version bits 30-28 reserved (no match)
- *   Version bits 27-16 major (must match)
- *   Version bits 15-0  minor (greater or equal)
- */
-#define RPC_VERSION_MODE_MASK  0x80000000
-#define RPC_VERSION_MAJOR_MASK 0x0fff0000
-#define RPC_VERSION_MAJOR_OFFSET 16
-#define RPC_VERSION_MINOR_MASK 0x0000ffff
-
-#define MSM_RPC_VERS(major, minor)                                     \
-       ((uint32_t)((((major) << RPC_VERSION_MAJOR_OFFSET) &            \
-               RPC_VERSION_MAJOR_MASK) |                               \
-       ((minor) & RPC_VERSION_MINOR_MASK)))
-#define MSM_RPC_GET_MAJOR(vers) (((vers) & RPC_VERSION_MAJOR_MASK) >>  \
-                                       RPC_VERSION_MAJOR_OFFSET)
-#define MSM_RPC_GET_MINOR(vers) ((vers) & RPC_VERSION_MINOR_MASK)
-#else
-#define MSM_RPC_VERS(major, minor) (major)
-#define MSM_RPC_GET_MAJOR(vers) (vers)
-#define MSM_RPC_GET_MINOR(vers) 0
-#endif
-
-struct msm_rpc_endpoint;
-
-struct rpcsvr_platform_device
-{
-       struct platform_device base;
-       uint32_t prog;
-       uint32_t vers;
-};
-
-#define RPC_DATA_IN    0
-/*
- * Structures for sending / receiving direct RPC requests
- * XXX: Any cred/verif lengths > 0 not supported
- */
-
-struct rpc_request_hdr
-{
-       uint32_t xid;
-       uint32_t type;  /* 0 */
-       uint32_t rpc_vers; /* 2 */
-       uint32_t prog;
-       uint32_t vers;
-       uint32_t procedure;
-       uint32_t cred_flavor;
-       uint32_t cred_length;
-       uint32_t verf_flavor;
-       uint32_t verf_length;
-};
-
-typedef struct
-{
-       uint32_t low;
-       uint32_t high;
-} rpc_reply_progmismatch_data;
-
-typedef struct
-{
-} rpc_denied_reply_hdr;
-
-typedef struct
-{
-       uint32_t verf_flavor;
-       uint32_t verf_length;
-       uint32_t accept_stat;
-#define RPC_ACCEPTSTAT_SUCCESS 0
-#define RPC_ACCEPTSTAT_PROG_UNAVAIL 1
-#define RPC_ACCEPTSTAT_PROG_MISMATCH 2
-#define RPC_ACCEPTSTAT_PROC_UNAVAIL 3
-#define RPC_ACCEPTSTAT_GARBAGE_ARGS 4
-#define RPC_ACCEPTSTAT_SYSTEM_ERR 5
-#define RPC_ACCEPTSTAT_PROG_LOCKED 6
-       /*
-        * Following data is dependant on accept_stat
-        * If ACCEPTSTAT == PROG_MISMATCH then there is a
-        * 'rpc_reply_progmismatch_data' structure following the header.
-        * Otherwise the data is procedure specific
-        */
-} rpc_accepted_reply_hdr;
-
-struct rpc_reply_hdr
-{
-       uint32_t xid;
-       uint32_t type;
-       uint32_t reply_stat;
-#define RPCMSG_REPLYSTAT_ACCEPTED 0
-#define RPCMSG_REPLYSTAT_DENIED 1
-       union {
-               rpc_accepted_reply_hdr acc_hdr;
-               rpc_denied_reply_hdr dny_hdr;
-       } data;
-};
-
-/* flags for msm_rpc_connect() */
-#define MSM_RPC_UNINTERRUPTIBLE 0x0001
-
-/* use IS_ERR() to check for failure */
-struct msm_rpc_endpoint *msm_rpc_open(void);
-/* Connect with the specified server version */
-struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags);
-uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept);
-/* check if server version can handle client requested version */
-int msm_rpc_is_compatible_version(uint32_t server_version,
-                                 uint32_t client_version);
-
-int msm_rpc_close(struct msm_rpc_endpoint *ept);
-int msm_rpc_write(struct msm_rpc_endpoint *ept,
-                 void *data, int len);
-int msm_rpc_read(struct msm_rpc_endpoint *ept,
-                void **data, unsigned len, long timeout);
-void msm_rpc_setup_req(struct rpc_request_hdr *hdr,
-                      uint32_t prog, uint32_t vers, uint32_t proc);
-int msm_rpc_register_server(struct msm_rpc_endpoint *ept,
-                           uint32_t prog, uint32_t vers);
-int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept,
-                             uint32_t prog, uint32_t vers);
-
-/* simple blocking rpc call
- *
- * request is mandatory and must have a rpc_request_hdr
- * at the start.  The header will be filled out for you.
- *
- * reply provides a buffer for replies of reply_max_size
- */
-int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc,
-                      void *request, int request_size,
-                      void *reply, int reply_max_size,
-                      long timeout);
-int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc,
-                void *request, int request_size,
-                long timeout);
-
-struct msm_rpc_server
-{
-       struct list_head list;
-       uint32_t flags;
-
-       uint32_t prog;
-       uint32_t vers;
-
-       int (*rpc_call)(struct msm_rpc_server *server,
-                       struct rpc_request_hdr *req, unsigned len);
-};
-
-int msm_rpc_create_server(struct msm_rpc_server *server);
-
-#endif
diff --git a/drivers/staging/dream/include/mach/msm_smd.h b/drivers/staging/dream/include/mach/msm_smd.h
deleted file mode 100644 (file)
index bdf7731..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* linux/include/asm-arm/arch-msm/msm_smd.h
- *
- * Copyright (C) 2007 Google, Inc.
- * Author: Brian Swetland <swetland@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef __ASM_ARCH_MSM_SMD_H
-#define __ASM_ARCH_MSM_SMD_H
-
-typedef struct smd_channel smd_channel_t;
-
-/* warning: notify() may be called before open returns */
-int smd_open(const char *name, smd_channel_t **ch, void *priv,
-            void (*notify)(void *priv, unsigned event));
-
-#define SMD_EVENT_DATA 1
-#define SMD_EVENT_OPEN 2
-#define SMD_EVENT_CLOSE 3
-
-int smd_close(smd_channel_t *ch);
-
-/* passing a null pointer for data reads and discards */
-int smd_read(smd_channel_t *ch, void *data, int len);
-
-/* Write to stream channels may do a partial write and return
-** the length actually written.
-** Write to packet channels will never do a partial write --
-** it will return the requested length written or an error.
-*/
-int smd_write(smd_channel_t *ch, const void *data, int len);
-
-int smd_write_avail(smd_channel_t *ch);
-int smd_read_avail(smd_channel_t *ch);
-
-/* Returns the total size of the current packet being read.
-** Returns 0 if no packets available or a stream channel.
-*/
-int smd_cur_packet_size(smd_channel_t *ch);
-
-/* used for tty unthrottling and the like -- causes the notify()
-** callback to be called from the same lock context as is used
-** when it is called from channel updates
-*/
-void smd_kick(smd_channel_t *ch);
-
-
-#if 0
-/* these are interruptable waits which will block you until the specified
-** number of bytes are readable or writable.
-*/
-int smd_wait_until_readable(smd_channel_t *ch, int bytes);
-int smd_wait_until_writable(smd_channel_t *ch, int bytes);
-#endif
-
-typedef enum
-{
-       SMD_PORT_DS = 0,
-       SMD_PORT_DIAG,
-       SMD_PORT_RPC_CALL,
-       SMD_PORT_RPC_REPLY,
-       SMD_PORT_BT,
-       SMD_PORT_CONTROL,
-       SMD_PORT_MEMCPY_SPARE1,
-       SMD_PORT_DATA1,
-       SMD_PORT_DATA2,
-       SMD_PORT_DATA3,
-       SMD_PORT_DATA4,
-       SMD_PORT_DATA5,
-       SMD_PORT_DATA6,
-       SMD_PORT_DATA7,
-       SMD_PORT_DATA8,
-       SMD_PORT_DATA9,
-       SMD_PORT_DATA10,
-       SMD_PORT_DATA11,
-       SMD_PORT_DATA12,
-       SMD_PORT_DATA13,
-       SMD_PORT_DATA14,
-       SMD_PORT_DATA15,
-       SMD_PORT_DATA16,
-       SMD_PORT_DATA17,
-       SMD_PORT_DATA18,
-       SMD_PORT_DATA19,
-       SMD_PORT_DATA20,
-       SMD_PORT_GPS_NMEA,
-       SMD_PORT_BRIDGE_1,
-       SMD_PORT_BRIDGE_2,
-       SMD_PORT_BRIDGE_3,
-       SMD_PORT_BRIDGE_4,
-       SMD_PORT_BRIDGE_5,
-       SMD_PORT_LOOPBACK,
-       SMD_PORT_CS_APPS_MODEM,
-       SMD_PORT_CS_APPS_DSP,
-       SMD_PORT_CS_MODEM_DSP,
-       SMD_NUM_PORTS,
-} smd_port_id_type;
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h
deleted file mode 100644 (file)
index 0b6a312..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef QDSP5AUDPLAYCMDI_H
-#define QDSP5AUDPLAYCMDI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-       Q D S P 5  A U D I O   P L A Y  T A S K   C O M M A N D S
-
-GENERAL DESCRIPTION
-  Command Interface for AUDPLAYTASK on QDSP5
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-
-  audplay_cmd_dec_data_avail
-    Send buffer to AUDPLAY task
-
-
-Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaycmdi.h#2 $
-
-===========================================================================*/
-
-#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL               0x0000
-#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN   \
-       sizeof(audplay_cmd_bitstream_data_avail)
-
-/* Type specification of dec_data_avail message sent to AUDPLAYTASK
-*/
-typedef struct {
-       /*command ID*/
-       unsigned int cmd_id;
-
-       /* Decoder ID for which message is being sent */
-       unsigned int decoder_id;
-
-       /* Start address of data in ARM global memory */
-       unsigned int buf_ptr;
-
-       /* Number of 16-bit words of bit-stream data contiguously available at the
-        * above-mentioned address. */
-       unsigned int buf_size;
-
-       /* Partition number used by audPlayTask to communicate with DSP's RTOS
-        * kernel */
-       unsigned int partition_number;
-} __attribute__((packed)) audplay_cmd_bitstream_data_avail;
-
-#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003
-#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \
-       sizeof(struct audplay_cmd_hpcm_buf_cfg)
-
-struct audplay_cmd_hpcm_buf_cfg {
-       unsigned int cmd_id;
-       unsigned int hostpcm_config;
-       unsigned int feedback_frequency;
-       unsigned int byte_swap;
-       unsigned int max_buffers;
-       unsigned int partition_number;
-} __attribute__((packed));
-
-#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004
-#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \
-       sizeof(struct audplay_cmd_buffer_update)
-
-struct audplay_cmd_buffer_refresh {
-       unsigned int cmd_id;
-       unsigned int num_buffers;
-       unsigned int buf_read_count;
-       unsigned int buf0_address;
-       unsigned int buf0_length;
-       unsigned int buf1_address;
-       unsigned int buf1_length;
-} __attribute__((packed));
-#endif /* QDSP5AUDPLAYCMD_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h
deleted file mode 100644 (file)
index c63034b..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef QDSP5AUDPLAYMSG_H
-#define QDSP5AUDPLAYMSG_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-       Q D S P 5  A U D I O   P L A Y  T A S K   M S G
-
-GENERAL DESCRIPTION
-  Message sent by AUDPLAY task
-
-REFERENCES
-  None
-
-
-Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaymsg.h#3 $
-
-===========================================================================*/
-#define AUDPLAY_MSG_DEC_NEEDS_DATA             0x0001
-#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN     \
-       sizeof(audplay_msg_dec_needs_data)
-
-typedef struct{
-       /* reserved*/
-       unsigned int dec_id;
-
-       /* The read pointer offset of external memory until which the
-        * bitstream has been DMAed in. */
-       unsigned int adecDataReadPtrOffset;
-
-       /* The buffer size of external memory. */
-       unsigned int adecDataBufSize;
-
-       unsigned int bitstream_free_len;
-       unsigned int bitstream_write_ptr;
-       unsigned int bitstarem_buf_start;
-       unsigned int bitstream_buf_len;
-} __attribute__((packed)) audplay_msg_dec_needs_data;
-
-#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004
-#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \
-       sizeof(struct audplay_msg_buffer_update)
-
-struct audplay_msg_buffer_update {
-       unsigned int buffer_write_count;
-       unsigned int num_of_buffer;
-       unsigned int buf0_address;
-       unsigned int buf0_length;
-       unsigned int buf1_address;
-       unsigned int buf1_length;
-} __attribute__((packed));
-#endif /* QDSP5AUDPLAYMSG_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h
deleted file mode 100644 (file)
index 8bee9c6..0000000
+++ /dev/null
@@ -1,914 +0,0 @@
-#ifndef QDSP5AUDPPCMDI_H
-#define QDSP5AUDPPCMDI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    A U D I O   P O S T   P R O C E S S I N G  I N T E R N A L  C O M M A N D S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are accepted by AUDPP Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppcmdi.h#2 $
-
-===========================================================================*/
-
-/*
- * ARM to AUDPPTASK Commands
- *
- * ARM uses three command queues to communicate with AUDPPTASK
- * 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands
- *     Location : MEMA
- *     Buffer Size : 6 words
- *     No of buffers in a queue : 20 for gaming audio and 5 for other images
- * 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier
- *     Location : MEMA
- *     Buffer Size : 23
- *     No of buffers in a queue : 2
- * 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands
- *     Location : MEMA
- *     Buffer Size : 145
- *     No of buffers in a queue : 3
- */
-
-/*
- * Commands Related to uPAudPPCmd1Queue
- */
-
-/*
- * Command Structure to enable or disable the active decoders
- */
-
-#define AUDPP_CMD_CFG_DEC_TYPE                 0x0001
-#define AUDPP_CMD_CFG_DEC_TYPE_LEN     sizeof(audpp_cmd_cfg_dec_type)
-
-/* Enable the decoder */
-#define AUDPP_CMD_DEC_TYPE_M                   0x000F
-
-#define AUDPP_CMD_ENA_DEC_V            0x4000
-#define AUDPP_CMD_DIS_DEC_V            0x0000
-#define AUDPP_CMD_DEC_STATE_M                  0x4000
-
-#define AUDPP_CMD_UPDATDE_CFG_DEC      0x8000
-#define AUDPP_CMD_DONT_UPDATE_CFG_DEC  0x0000
-
-
-/* Type specification of cmd_cfg_dec */
-
-typedef struct {
-       unsigned short cmd_id;
-       unsigned short dec0_cfg;
-       unsigned short dec1_cfg;
-       unsigned short dec2_cfg;
-       unsigned short dec3_cfg;
-       unsigned short dec4_cfg;
-} __attribute__((packed)) audpp_cmd_cfg_dec_type;
-
-/*
- * Command Structure to Pause , Resume and flushes the selected audio decoders
- */
-
-#define AUDPP_CMD_DEC_CTRL             0x0002
-#define AUDPP_CMD_DEC_CTRL_LEN         sizeof(audpp_cmd_dec_ctrl)
-
-/* Decoder control commands for pause, resume and flush */
-#define AUDPP_CMD_FLUSH_V                      0x2000
-
-#define AUDPP_CMD_PAUSE_V                      0x4000
-#define AUDPP_CMD_RESUME_V                     0x0000
-
-#define AUDPP_CMD_UPDATE_V                     0x8000
-#define AUDPP_CMD_IGNORE_V                     0x0000
-
-
-/* Type Spec for decoder control command*/
-
-typedef struct {
-       unsigned short cmd_id;
-       unsigned short dec0_ctrl;
-       unsigned short dec1_ctrl;
-       unsigned short dec2_ctrl;
-       unsigned short dec3_ctrl;
-       unsigned short dec4_ctrl;
-} __attribute__((packed)) audpp_cmd_dec_ctrl;
-
-/*
- * Command Structure to Configure the AVSync FeedBack Mechanism
- */
-
-#define AUDPP_CMD_AVSYNC       0x0003
-#define AUDPP_CMD_AVSYNC_LEN   sizeof(audpp_cmd_avsync)
-
-typedef struct {
-       unsigned short cmd_id;
-       unsigned short object_number;
-       unsigned short interrupt_interval_lsw;
-       unsigned short interrupt_interval_msw;
-} __attribute__((packed)) audpp_cmd_avsync;
-
-/*
- * Command Structure to enable or disable(sleep) the   AUDPPTASK
- */
-
-#define AUDPP_CMD_CFG  0x0004
-#define AUDPP_CMD_CFG_LEN      sizeof(audpp_cmd_cfg)
-
-#define AUDPP_CMD_CFG_SLEEP                            0x0000
-#define AUDPP_CMD_CFG_ENABLE                           0xFFFF
-
-typedef struct {
-       unsigned short cmd_id;
-       unsigned short cfg;
-} __attribute__((packed)) audpp_cmd_cfg;
-
-/*
- * Command Structure to Inject or drop the specified no of samples
- */
-
-#define AUDPP_CMD_ADJUST_SAMP          0x0005
-#define AUDPP_CMD_ADJUST_SAMP_LEN      sizeof(audpp_cmd_adjust_samp)
-
-#define AUDPP_CMD_SAMP_DROP            -1
-#define AUDPP_CMD_SAMP_INSERT          0x0001
-
-#define AUDPP_CMD_NUM_SAMPLES          0x0001
-
-typedef struct {
-       unsigned short cmd_id;
-       unsigned short object_no;
-       signed short sample_insert_or_drop;
-       unsigned short num_samples;
-} __attribute__((packed)) audpp_cmd_adjust_samp;
-
-/*
- * Command Structure to Configure AVSync Feedback Mechanism
- */
-
-#define AUDPP_CMD_AVSYNC_CMD_2         0x0006
-#define AUDPP_CMD_AVSYNC_CMD_2_LEN     sizeof(audpp_cmd_avsync_cmd_2)
-
-typedef struct {
-       unsigned short cmd_id;
-       unsigned short object_number;
-       unsigned short interrupt_interval_lsw;
-       unsigned short interrupt_interval_msw;
-       unsigned short sample_counter_dlsw;
-       unsigned short sample_counter_dmsw;
-       unsigned short sample_counter_msw;
-       unsigned short byte_counter_dlsw;
-       unsigned short byte_counter_dmsw;
-       unsigned short byte_counter_msw;
-} __attribute__((packed)) audpp_cmd_avsync_cmd_2;
-
-/*
- * Command Structure to Configure AVSync Feedback Mechanism
- */
-
-#define AUDPP_CMD_AVSYNC_CMD_3         0x0007
-#define AUDPP_CMD_AVSYNC_CMD_3_LEN     sizeof(audpp_cmd_avsync_cmd_3)
-
-typedef struct {
-       unsigned short cmd_id;
-       unsigned short object_number;
-       unsigned short interrupt_interval_lsw;
-       unsigned short interrupt_interval_msw;
-       unsigned short sample_counter_dlsw;
-       unsigned short sample_counter_dmsw;
-       unsigned short sample_counter_msw;
-       unsigned short byte_counter_dlsw;
-       unsigned short byte_counter_dmsw;
-       unsigned short byte_counter_msw;
-} __attribute__((packed)) audpp_cmd_avsync_cmd_3;
-
-#define AUDPP_CMD_ROUTING_MODE      0x0008
-#define AUDPP_CMD_ROUTING_MODE_LEN  \
-sizeof(struct audpp_cmd_routing_mode)
-
-struct audpp_cmd_routing_mode {
-       unsigned short cmd_id;
-       unsigned short object_number;
-       unsigned short routing_mode;
-} __attribute__((packed));
-
-/*
- * Commands Related to uPAudPPCmd2Queue
- */
-
-/*
- * Command Structure to configure Per decoder Parameters (Common)
- */
-
-#define AUDPP_CMD_CFG_ADEC_PARAMS              0x0000
-#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN   \
-       sizeof(audpp_cmd_cfg_adec_params_common)
-
-#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM      0x4000
-#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM      0x0000
-
-#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM      0x8000
-#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM      0x0000
-
-/* Sampling frequency*/
-#define  AUDPP_CMD_SAMP_RATE_96000     0x0000
-#define  AUDPP_CMD_SAMP_RATE_88200     0x0001
-#define  AUDPP_CMD_SAMP_RATE_64000     0x0002
-#define  AUDPP_CMD_SAMP_RATE_48000     0x0003
-#define  AUDPP_CMD_SAMP_RATE_44100     0x0004
-#define  AUDPP_CMD_SAMP_RATE_32000     0x0005
-#define  AUDPP_CMD_SAMP_RATE_24000     0x0006
-#define  AUDPP_CMD_SAMP_RATE_22050     0x0007
-#define  AUDPP_CMD_SAMP_RATE_16000     0x0008
-#define  AUDPP_CMD_SAMP_RATE_12000     0x0009
-#define  AUDPP_CMD_SAMP_RATE_11025     0x000A
-#define  AUDPP_CMD_SAMP_RATE_8000      0x000B
-
-
-/*
- * Type specification of cmd_adec_cfg sent to all decoder
- */
-
-typedef struct {
-  unsigned short cmd_id;
-  unsigned short  length;
-  unsigned short  dec_id;
-  unsigned short  status_msg_flag;
-  unsigned short  decoder_frame_counter_msg_period;
-  unsigned short  input_sampling_frequency;
-} __attribute__((packed)) audpp_cmd_cfg_adec_params_common;
-
-/*
- * Command Structure to configure Per decoder Parameters (Wav)
- */
-
-#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN      \
-       sizeof(audpp_cmd_cfg_adec_params_wav)
-
-
-#define AUDPP_CMD_WAV_STEREO_CFG_MONO  0x0001
-#define AUDPP_CMD_WAV_STEREO_CFG_STEREO        0x0002
-
-#define AUDPP_CMD_WAV_PCM_WIDTH_8      0x0000
-#define AUDPP_CMD_WAV_PCM_WIDTH_16     0x0001
-#define AUDPP_CMD_WAV_PCM_WIDTH_32     0x0002
-
-typedef struct {
-       audpp_cmd_cfg_adec_params_common                common;
-       unsigned short                                  stereo_cfg;
-       unsigned short                                  pcm_width;
-       unsigned short                                  sign;
-} __attribute__((packed)) audpp_cmd_cfg_adec_params_wav;
-
-/*
- * Command Structure to configure Per decoder Parameters (ADPCM)
- */
-
-#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN    \
-       sizeof(audpp_cmd_cfg_adec_params_adpcm)
-
-
-#define        AUDPP_CMD_ADPCM_STEREO_CFG_MONO         0x0001
-#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO      0x0002
-
-typedef struct {
-       audpp_cmd_cfg_adec_params_common                common;
-       unsigned short                                  stereo_cfg;
-       unsigned short                                  block_size;
-} __attribute__((packed)) audpp_cmd_cfg_adec_params_adpcm;
-
-/*
- * Command Structure to configure Per decoder Parameters (MP3)
- */
-
-#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN      \
-       sizeof(audpp_cmd_cfg_adec_params_mp3)
-
-typedef struct {
-   audpp_cmd_cfg_adec_params_common    common;
-} __attribute__((packed)) audpp_cmd_cfg_adec_params_mp3;
-
-
-/*
- * Command Structure to configure Per decoder Parameters (AAC)
- */
-
-#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN      \
-       sizeof(audpp_cmd_cfg_adec_params_aac)
-
-
-#define AUDPP_CMD_AAC_FORMAT_ADTS              -1
-#define        AUDPP_CMD_AAC_FORMAT_RAW                0x0000
-#define        AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW         0x0001
-#define        AUDPP_CMD_AAC_FORMAT_LOAS               0x0002
-
-#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC          0x0002
-#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP         0x0004
-#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC        0x0011
-
-#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON           0x0001
-#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF          0x0000
-
-#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON                0x0001
-#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF       0x0000
-
-typedef struct {
-  audpp_cmd_cfg_adec_params_common     common;
-  signed short                         format;
-  unsigned short                       audio_object;
-  unsigned short                       ep_config;
-  unsigned short                        aac_section_data_resilience_flag;
-  unsigned short                        aac_scalefactor_data_resilience_flag;
-  unsigned short                        aac_spectral_data_resilience_flag;
-  unsigned short                        sbr_on_flag;
-  unsigned short                        sbr_ps_on_flag;
-  unsigned short                        dual_mono_mode;
-  unsigned short                        channel_configuration;
-} __attribute__((packed)) audpp_cmd_cfg_adec_params_aac;
-
-/*
- * Command Structure to configure Per decoder Parameters (V13K)
- */
-
-#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN     \
-       sizeof(struct audpp_cmd_cfg_adec_params_v13k)
-
-
-#define AUDPP_CMD_STEREO_CFG_MONO              0x0001
-#define AUDPP_CMD_STEREO_CFG_STEREO            0x0002
-
-struct audpp_cmd_cfg_adec_params_v13k {
-   audpp_cmd_cfg_adec_params_common            common;
-   unsigned short                      stereo_cfg;
-} __attribute__((packed));
-
-#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \
-       sizeof(struct audpp_cmd_cfg_adec_params_evrc)
-
-struct audpp_cmd_cfg_adec_params_evrc {
-       audpp_cmd_cfg_adec_params_common common;
-       unsigned short stereo_cfg;
-} __attribute__ ((packed));
-
-/*
- * Command Structure to configure the  HOST PCM interface
- */
-
-#define AUDPP_CMD_PCM_INTF     0x0001
-#define AUDPP_CMD_PCM_INTF_2   0x0002
-#define AUDPP_CMD_PCM_INTF_LEN sizeof(audpp_cmd_pcm_intf)
-
-#define AUDPP_CMD_PCM_INTF_MONO_V                      0x0001
-#define AUDPP_CMD_PCM_INTF_STEREO_V            0x0002
-
-/* These two values differentiate the two types of commands that could be issued
- * Interface configuration command and Buffer update command */
-
-#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V                0x0000
-#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V                -1
-
-#define AUDPP_CMD_PCM_INTF_RX_ENA_M              0x000F
-#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V     0x0008
-#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V     0x0004
-
-/* These flags control the enabling and disabling of the interface together
- *  with host interface bit mask. */
-
-#define AUDPP_CMD_PCM_INTF_ENA_V            -1
-#define AUDPP_CMD_PCM_INTF_DIS_V            0x0000
-
-
-#define  AUDPP_CMD_PCM_INTF_FULL_DUPLEX           0x0
-#define  AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP     0x1
-
-
-#define  AUDPP_CMD_PCM_INTF_OBJECT_NUM           0x5
-#define  AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM    0x6
-
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  object_num;
-       signed short  config;
-       unsigned short  intf_type;
-
-       /* DSP -> ARM Configuration */
-       unsigned short  read_buf1LSW;
-       unsigned short  read_buf1MSW;
-       unsigned short  read_buf1_len;
-
-       unsigned short  read_buf2LSW;
-       unsigned short  read_buf2MSW;
-       unsigned short  read_buf2_len;
-       /*   0:HOST_PCM_INTF disable
-       **  0xFFFF: HOST_PCM_INTF enable
-       */
-       signed short  dsp_to_arm_flag;
-       unsigned short  partition_number;
-
-       /* ARM -> DSP Configuration */
-       unsigned short  write_buf1LSW;
-       unsigned short  write_buf1MSW;
-       unsigned short  write_buf1_len;
-
-       unsigned short  write_buf2LSW;
-       unsigned short  write_buf2MSW;
-       unsigned short  write_buf2_len;
-
-       /*   0:HOST_PCM_INTF disable
-       **  0xFFFF: HOST_PCM_INTF enable
-       */
-       signed short  arm_to_rx_flag;
-       unsigned short  weight_decoder_to_rx;
-       unsigned short  weight_arm_to_rx;
-
-       unsigned short  partition_number_arm_to_dsp;
-       unsigned short  sample_rate;
-       unsigned short  channel_mode;
-} __attribute__((packed)) audpp_cmd_pcm_intf;
-
-/*
- **  BUFFER UPDATE COMMAND
- */
-#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN \
-       sizeof(audpp_cmd_pcm_intf_send_buffer)
-
-typedef struct {
-  unsigned short  cmd_id;
-  unsigned short  host_pcm_object;
-  /* set config = 0xFFFF for configuration*/
-  signed short  config;
-  unsigned short  intf_type;
-  unsigned short  dsp_to_arm_buf_id;
-  unsigned short  arm_to_dsp_buf_id;
-  unsigned short  arm_to_dsp_buf_len;
-} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer;
-
-
-/*
- * Commands Related to uPAudPPCmd3Queue
- */
-
-/*
- * Command Structure to configure post processing params (Commmon)
- */
-
-#define AUDPP_CMD_CFG_OBJECT_PARAMS            0x0000
-#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN         \
-       sizeof(audpp_cmd_cfg_object_params_common)
-
-#define AUDPP_CMD_OBJ0_UPDATE          0x8000
-#define AUDPP_CMD_OBJ0_DONT_UPDATE     0x0000
-
-#define AUDPP_CMD_OBJ1_UPDATE          0x8000
-#define AUDPP_CMD_OBJ1_DONT_UPDATE     0x0000
-
-#define AUDPP_CMD_OBJ2_UPDATE          0x8000
-#define AUDPP_CMD_OBJ2_DONT_UPDATE     0x0000
-
-#define AUDPP_CMD_OBJ3_UPDATE          0x8000
-#define AUDPP_CMD_OBJ3_DONT_UPDATE     0x0000
-
-#define AUDPP_CMD_OBJ4_UPDATE          0x8000
-#define AUDPP_CMD_OBJ4_DONT_UPDATE     0x0000
-
-#define AUDPP_CMD_HPCM_UPDATE          0x8000
-#define AUDPP_CMD_HPCM_DONT_UPDATE     0x0000
-
-#define AUDPP_CMD_COMMON_CFG_UPDATE            0x8000
-#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE       0x0000
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  obj0_cfg;
-       unsigned short  obj1_cfg;
-       unsigned short  obj2_cfg;
-       unsigned short  obj3_cfg;
-       unsigned short  obj4_cfg;
-       unsigned short  host_pcm_obj_cfg;
-       unsigned short  comman_cfg;
-       unsigned short  command_type;
-} __attribute__((packed)) audpp_cmd_cfg_object_params_common;
-
-/*
- * Command Structure to configure post processing params (Volume)
- */
-
-#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN         \
-       sizeof(audpp_cmd_cfg_object_params_volume)
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common      common;
-       unsigned short                                  volume;
-       unsigned short                                  pan;
-} __attribute__((packed)) audpp_cmd_cfg_object_params_volume;
-
-/*
- * Command Structure to configure post processing params (PCM Filter) --DOUBT
- */
-
-typedef struct {
-       unsigned short                  numerator_b0_filter_lsw;
-       unsigned short                  numerator_b0_filter_msw;
-       unsigned short                  numerator_b1_filter_lsw;
-       unsigned short                  numerator_b1_filter_msw;
-       unsigned short                  numerator_b2_filter_lsw;
-       unsigned short                  numerator_b2_filter_msw;
-} __attribute__((packed)) numerator;
-
-typedef struct {
-       unsigned short                  denominator_a0_filter_lsw;
-       unsigned short                  denominator_a0_filter_msw;
-       unsigned short                  denominator_a1_filter_lsw;
-       unsigned short                  denominator_a1_filter_msw;
-} __attribute__((packed)) denominator;
-
-typedef struct {
-       unsigned short                  shift_factor_0;
-} __attribute__((packed)) shift_factor;
-
-typedef struct {
-       unsigned short                  pan_filter_0;
-} __attribute__((packed)) pan;
-
-typedef struct {
-               numerator               numerator_filter;
-               denominator             denominator_filter;
-               shift_factor            shift_factor_filter;
-               pan                     pan_filter;
-} __attribute__((packed)) filter_1;
-
-typedef struct {
-               numerator               numerator_filter[2];
-               denominator             denominator_filter[2];
-               shift_factor            shift_factor_filter[2];
-               pan                     pan_filter[2];
-} __attribute__((packed)) filter_2;
-
-typedef struct {
-               numerator               numerator_filter[3];
-               denominator             denominator_filter[3];
-               shift_factor            shift_factor_filter[3];
-               pan                     pan_filter[3];
-} __attribute__((packed)) filter_3;
-
-typedef struct {
-               numerator               numerator_filter[4];
-               denominator             denominator_filter[4];
-               shift_factor            shift_factor_filter[4];
-               pan                     pan_filter[4];
-} __attribute__((packed)) filter_4;
-
-#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN            \
-       sizeof(audpp_cmd_cfg_object_params_pcm)
-
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common      common;
-       unsigned short                          active_flag;
-       unsigned short                          num_bands;
-       union {
-               filter_1                        filter_1_params;
-               filter_2                        filter_2_params;
-               filter_3                        filter_3_params;
-               filter_4                        filter_4_params;
-       } __attribute__((packed)) params_filter;
-} __attribute__((packed)) audpp_cmd_cfg_object_params_pcm;
-
-
-/*
- * Command Structure to configure post processing parameters (equalizer)
- */
-
-#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN               \
-       sizeof(audpp_cmd_cfg_object_params_eqalizer)
-
-typedef struct {
-       unsigned short                  numerator_coeff_0_lsw;
-       unsigned short                  numerator_coeff_0_msw;
-       unsigned short                  numerator_coeff_1_lsw;
-       unsigned short                  numerator_coeff_1_msw;
-       unsigned short                  numerator_coeff_2_lsw;
-       unsigned short                  numerator_coeff_2_msw;
-} __attribute__((packed)) eq_numerator;
-
-typedef struct {
-       unsigned short                  denominator_coeff_0_lsw;
-       unsigned short                  denominator_coeff_0_msw;
-       unsigned short                  denominator_coeff_1_lsw;
-       unsigned short                  denominator_coeff_1_msw;
-} __attribute__((packed)) eq_denominator;
-
-typedef struct {
-       unsigned short                  shift_factor;
-} __attribute__((packed)) eq_shiftfactor;
-
-typedef struct {
-       eq_numerator    numerator;
-       eq_denominator  denominator;
-       eq_shiftfactor  shiftfactor;
-} __attribute__((packed)) eq_coeff_1;
-
-typedef struct {
-       eq_numerator    numerator[2];
-       eq_denominator  denominator[2];
-       eq_shiftfactor  shiftfactor[2];
-} __attribute__((packed)) eq_coeff_2;
-
-typedef struct {
-       eq_numerator    numerator[3];
-       eq_denominator  denominator[3];
-       eq_shiftfactor  shiftfactor[3];
-} __attribute__((packed)) eq_coeff_3;
-
-typedef struct {
-       eq_numerator    numerator[4];
-       eq_denominator  denominator[4];
-       eq_shiftfactor  shiftfactor[4];
-} __attribute__((packed)) eq_coeff_4;
-
-typedef struct {
-       eq_numerator    numerator[5];
-       eq_denominator  denominator[5];
-       eq_shiftfactor  shiftfactor[5];
-} __attribute__((packed)) eq_coeff_5;
-
-typedef struct {
-       eq_numerator    numerator[6];
-       eq_denominator  denominator[6];
-       eq_shiftfactor  shiftfactor[6];
-} __attribute__((packed)) eq_coeff_6;
-
-typedef struct {
-       eq_numerator    numerator[7];
-       eq_denominator  denominator[7];
-       eq_shiftfactor  shiftfactor[7];
-} __attribute__((packed)) eq_coeff_7;
-
-typedef struct {
-       eq_numerator    numerator[8];
-       eq_denominator  denominator[8];
-       eq_shiftfactor  shiftfactor[8];
-} __attribute__((packed)) eq_coeff_8;
-
-typedef struct {
-       eq_numerator    numerator[9];
-       eq_denominator  denominator[9];
-       eq_shiftfactor  shiftfactor[9];
-} __attribute__((packed)) eq_coeff_9;
-
-typedef struct {
-       eq_numerator    numerator[10];
-       eq_denominator  denominator[10];
-       eq_shiftfactor  shiftfactor[10];
-} __attribute__((packed)) eq_coeff_10;
-
-typedef struct {
-       eq_numerator    numerator[11];
-       eq_denominator  denominator[11];
-       eq_shiftfactor  shiftfactor[11];
-} __attribute__((packed)) eq_coeff_11;
-
-typedef struct {
-       eq_numerator    numerator[12];
-       eq_denominator  denominator[12];
-       eq_shiftfactor  shiftfactor[12];
-} __attribute__((packed)) eq_coeff_12;
-
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common      common;
-       unsigned short                          eq_flag;
-       unsigned short                          num_bands;
-       union {
-               eq_coeff_1      eq_coeffs_1;
-               eq_coeff_2      eq_coeffs_2;
-               eq_coeff_3      eq_coeffs_3;
-               eq_coeff_4      eq_coeffs_4;
-               eq_coeff_5      eq_coeffs_5;
-               eq_coeff_6      eq_coeffs_6;
-               eq_coeff_7      eq_coeffs_7;
-               eq_coeff_8      eq_coeffs_8;
-               eq_coeff_9      eq_coeffs_9;
-               eq_coeff_10     eq_coeffs_10;
-               eq_coeff_11     eq_coeffs_11;
-               eq_coeff_12     eq_coeffs_12;
-       } __attribute__((packed)) eq_coeff;
-} __attribute__((packed)) audpp_cmd_cfg_object_params_eqalizer;
-
-
-/*
- * Command Structure to configure post processing parameters (ADRC)
- */
-
-#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN           \
-       sizeof(audpp_cmd_cfg_object_params_adrc)
-
-
-#define AUDPP_CMD_ADRC_FLAG_DIS                0x0000
-#define AUDPP_CMD_ADRC_FLAG_ENA                -1
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common      common;
-       signed short                            adrc_flag;
-       unsigned short                          compression_th;
-       unsigned short                          compression_slope;
-       unsigned short                          rms_time;
-       unsigned short                          attack_const_lsw;
-       unsigned short                          attack_const_msw;
-       unsigned short                          release_const_lsw;
-       unsigned short                          release_const_msw;
-       unsigned short                          adrc_system_delay;
-} __attribute__((packed)) audpp_cmd_cfg_object_params_adrc;
-
-/*
- * Command Structure to configure post processing parameters(Spectrum Analizer)
- */
-
-#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN               \
-       sizeof(audpp_cmd_cfg_object_params_spectram)
-
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common      common;
-       unsigned short                          sample_interval;
-       unsigned short                          num_coeff;
-} __attribute__((packed)) audpp_cmd_cfg_object_params_spectram;
-
-/*
- * Command Structure to configure post processing parameters (QConcert)
- */
-
-#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN               \
-       sizeof(audpp_cmd_cfg_object_params_qconcert)
-
-
-#define AUDPP_CMD_QCON_ENA_FLAG_ENA            -1
-#define AUDPP_CMD_QCON_ENA_FLAG_DIS            0x0000
-
-#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE       -1
-#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT   0x0000
-#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE    0x0001
-#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP 0x0002
-
-#define AUDPP_CMD_QCON_GAIN_UNIT                       0x7FFF
-#define AUDPP_CMD_QCON_GAIN_SIX_DB                     0x4027
-
-
-#define AUDPP_CMD_QCON_EXPANSION_MAX           0x7FFF
-
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common      common;
-       signed short                            enable_flag;
-       signed short                            output_mode;
-       signed short                            gain;
-       signed short                            expansion;
-       signed short                            delay;
-       unsigned short                          stages_per_mode;
-} __attribute__((packed)) audpp_cmd_cfg_object_params_qconcert;
-
-/*
- * Command Structure to configure post processing parameters (Side Chain)
- */
-
-#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN              \
-       sizeof(audpp_cmd_cfg_object_params_sidechain)
-
-
-#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS    0x0000
-#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA    -1
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common      common;
-       signed short                            active_flag;
-       unsigned short                          num_bands;
-       union {
-               filter_1                        filter_1_params;
-               filter_2                        filter_2_params;
-               filter_3                        filter_3_params;
-               filter_4                        filter_4_params;
-       } __attribute__((packed)) params_filter;
-} __attribute__((packed)) audpp_cmd_cfg_object_params_sidechain;
-
-
-/*
- * Command Structure to configure post processing parameters (QAFX)
- */
-
-#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN           \
-       sizeof(audpp_cmd_cfg_object_params_qafx)
-
-#define AUDPP_CMD_QAFX_ENA_DISA                0x0000
-#define AUDPP_CMD_QAFX_ENA_ENA_CFG     -1
-#define AUDPP_CMD_QAFX_ENA_DIS_CFG     0x0001
-
-#define AUDPP_CMD_QAFX_CMD_TYPE_ENV    0x0100
-#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ    0x0010
-#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY  0x1000
-
-#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE        0x0100
-#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS        0x0101
-#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI        0x0102
-#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL        0X0103
-#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES        0x0107
-
-#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ      0x0010
-#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL            0x0011
-#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST           0x0012
-#define AUDPP_CMD_QAFX_CMDS_OBJ_POS            0x0013
-#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL            0x0014
-
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common      common;
-       signed short                            enable;
-       unsigned short                          command_type;
-       unsigned short                          num_commands;
-       unsigned short                          commands;
-} __attribute__((packed)) audpp_cmd_cfg_object_params_qafx;
-
-/*
- * Command Structure to enable , disable or configure the reverberation effect
- * (Common)
- */
-
-#define AUDPP_CMD_REVERB_CONFIG                0x0001
-#define        AUDPP_CMD_REVERB_CONFIG_COMMON_LEN      \
-       sizeof(audpp_cmd_reverb_config_common)
-
-#define AUDPP_CMD_ENA_ENA      0xFFFF
-#define AUDPP_CMD_ENA_DIS      0x0000
-#define AUDPP_CMD_ENA_CFG      0x0001
-
-#define AUDPP_CMD_CMD_TYPE_ENV         0x0104
-#define AUDPP_CMD_CMD_TYPE_OBJ         0x0015
-#define AUDPP_CMD_CMD_TYPE_QUERY       0x1000
-
-
-typedef struct {
-       unsigned short                  cmd_id;
-       unsigned short                  enable;
-       unsigned short                  cmd_type;
-} __attribute__((packed)) audpp_cmd_reverb_config_common;
-
-/*
- * Command Structure to enable , disable or configure the reverberation effect
- * (ENV-0x0104)
- */
-
-#define        AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN     \
-       sizeof(audpp_cmd_reverb_config_env_104)
-
-typedef struct {
-       audpp_cmd_reverb_config_common  common;
-       unsigned short                  env_gain;
-       unsigned short                  decay_msw;
-       unsigned short                  decay_lsw;
-       unsigned short                  decay_timeratio_msw;
-       unsigned short                  decay_timeratio_lsw;
-       unsigned short                  delay_time;
-       unsigned short                  reverb_gain;
-       unsigned short                  reverb_delay;
-} __attribute__((packed)) audpp_cmd_reverb_config_env_104;
-
-/*
- * Command Structure to enable , disable or configure the reverberation effect
- * (ENV-0x0015)
- */
-
-#define        AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN      \
-       sizeof(audpp_cmd_reverb_config_env_15)
-
-typedef struct {
-       audpp_cmd_reverb_config_common  common;
-       unsigned short                  object_num;
-       unsigned short                  absolute_gain;
-} __attribute__((packed)) audpp_cmd_reverb_config_env_15;
-
-
-#endif /* QDSP5AUDPPCMDI_H */
-
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h
deleted file mode 100644 (file)
index 44fea22..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-#ifndef QDSP5AUDPPMSG_H
-#define QDSP5AUDPPMSG_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-       Q D S P 5  A U D I O   P O S T   P R O C E S S I N G   M S G
-
-GENERAL DESCRIPTION
-  Messages sent by AUDPPTASK to ARM
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
- $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppmsg.h#4 $
-
-===========================================================================*/
-
-/*
- * AUDPPTASK uses audPPuPRlist to send messages to the ARM
- * Location : MEMA
- * Buffer Size : 45
- * No of Buffers in a queue : 5 for gaming audio and 1 for other images
- */
-
-/*
- * MSG to Informs the ARM os Success/Failure of bringing up the decoder
- */
-
-#define AUDPP_MSG_STATUS_MSG           0x0001
-#define AUDPP_MSG_STATUS_MSG_LEN       \
-       sizeof(audpp_msg_status_msg)
-
-#define AUDPP_MSG_STATUS_SLEEP         0x0000
-#define AUDPP_MSG__STATUS_INIT         0x0001
-#define AUDPP_MSG_MSG_STATUS_CFG       0x0002
-#define AUDPP_MSG_STATUS_PLAY          0x0003
-
-#define AUDPP_MSG_REASON_MIPS  0x0000
-#define AUDPP_MSG_REASON_MEM   0x0001
-
-typedef struct{
-       unsigned short dec_id;
-       unsigned short status;
-       unsigned short reason;
-} __attribute__((packed)) audpp_msg_status_msg;
-
-/*
- * MSG to communicate the spectrum analyzer output bands to the ARM
- */
-#define AUDPP_MSG_SPA_BANDS            0x0002
-#define AUDPP_MSG_SPA_BANDS_LEN        \
-       sizeof(audpp_msg_spa_bands)
-
-typedef struct {
-       unsigned short                  current_object;
-       unsigned short                  spa_band_1;
-       unsigned short                  spa_band_2;
-       unsigned short                  spa_band_3;
-       unsigned short                  spa_band_4;
-       unsigned short                  spa_band_5;
-       unsigned short                  spa_band_6;
-       unsigned short                  spa_band_7;
-       unsigned short                  spa_band_8;
-       unsigned short                  spa_band_9;
-       unsigned short                  spa_band_10;
-       unsigned short                  spa_band_11;
-       unsigned short                  spa_band_12;
-       unsigned short                  spa_band_13;
-       unsigned short                  spa_band_14;
-       unsigned short                  spa_band_15;
-       unsigned short                  spa_band_16;
-       unsigned short                  spa_band_17;
-       unsigned short                  spa_band_18;
-       unsigned short                  spa_band_19;
-       unsigned short                  spa_band_20;
-       unsigned short                  spa_band_21;
-       unsigned short                  spa_band_22;
-       unsigned short                  spa_band_23;
-       unsigned short                  spa_band_24;
-       unsigned short                  spa_band_25;
-       unsigned short                  spa_band_26;
-       unsigned short                  spa_band_27;
-       unsigned short                  spa_band_28;
-       unsigned short                  spa_band_29;
-       unsigned short                  spa_band_30;
-       unsigned short                  spa_band_31;
-       unsigned short                  spa_band_32;
-} __attribute__((packed)) audpp_msg_spa_bands;
-
-/*
- * MSG to communicate the PCM I/O buffer status to ARM
- */
-#define  AUDPP_MSG_HOST_PCM_INTF_MSG           0x0003
-#define  AUDPP_MSG_HOST_PCM_INTF_MSG_LEN       \
-       sizeof(audpp_msg_host_pcm_intf_msg)
-
-#define AUDPP_MSG_HOSTPCM_ID_TX_ARM    0x0000
-#define AUDPP_MSG_HOSTPCM_ID_ARM_TX    0x0001
-#define AUDPP_MSG_HOSTPCM_ID_RX_ARM    0x0002
-#define AUDPP_MSG_HOSTPCM_ID_ARM_RX    0x0003
-
-#define AUDPP_MSG_SAMP_FREQ_INDX_96000 0x0000
-#define AUDPP_MSG_SAMP_FREQ_INDX_88200 0x0001
-#define AUDPP_MSG_SAMP_FREQ_INDX_64000 0x0002
-#define AUDPP_MSG_SAMP_FREQ_INDX_48000 0x0003
-#define AUDPP_MSG_SAMP_FREQ_INDX_44100 0x0004
-#define AUDPP_MSG_SAMP_FREQ_INDX_32000 0x0005
-#define AUDPP_MSG_SAMP_FREQ_INDX_24000 0x0006
-#define AUDPP_MSG_SAMP_FREQ_INDX_22050 0x0007
-#define AUDPP_MSG_SAMP_FREQ_INDX_16000 0x0008
-#define AUDPP_MSG_SAMP_FREQ_INDX_12000 0x0009
-#define AUDPP_MSG_SAMP_FREQ_INDX_11025 0x000A
-#define AUDPP_MSG_SAMP_FREQ_INDX_8000  0x000B
-
-#define AUDPP_MSG_CHANNEL_MODE_MONO            0x0001
-#define AUDPP_MSG_CHANNEL_MODE_STEREO  0x0002
-
-typedef struct{
-       unsigned short obj_num;
-       unsigned short numbers_of_samples;
-       unsigned short host_pcm_id;
-       unsigned short buf_indx;
-       unsigned short samp_freq_indx;
-       unsigned short channel_mode;
-} __attribute__((packed)) audpp_msg_host_pcm_intf_msg;
-
-
-/*
- * MSG to communicate 3D position of the source and listener , source volume
- * source rolloff, source orientation
- */
-
-#define AUDPP_MSG_QAFX_POS             0x0004
-#define AUDPP_MSG_QAFX_POS_LEN         \
-       sizeof(audpp_msg_qafx_pos)
-
-typedef struct {
-       unsigned short  current_object;
-       unsigned short  x_pos_lis_msw;
-       unsigned short  x_pos_lis_lsw;
-       unsigned short  y_pos_lis_msw;
-       unsigned short  y_pos_lis_lsw;
-       unsigned short  z_pos_lis_msw;
-       unsigned short  z_pos_lis_lsw;
-       unsigned short  x_fwd_msw;
-       unsigned short  x_fwd_lsw;
-       unsigned short  y_fwd_msw;
-       unsigned short  y_fwd_lsw;
-       unsigned short  z_fwd_msw;
-       unsigned short  z_fwd_lsw;
-       unsigned short  x_up_msw;
-       unsigned short  x_up_lsw;
-       unsigned short  y_up_msw;
-       unsigned short  y_up_lsw;
-       unsigned short  z_up_msw;
-       unsigned short  z_up_lsw;
-       unsigned short  x_vel_lis_msw;
-       unsigned short  x_vel_lis_lsw;
-       unsigned short  y_vel_lis_msw;
-       unsigned short  y_vel_lis_lsw;
-       unsigned short  z_vel_lis_msw;
-       unsigned short  z_vel_lis_lsw;
-       unsigned short  threed_enable_flag;
-       unsigned short  volume;
-       unsigned short  x_pos_source_msw;
-       unsigned short  x_pos_source_lsw;
-       unsigned short  y_pos_source_msw;
-       unsigned short  y_pos_source_lsw;
-       unsigned short  z_pos_source_msw;
-       unsigned short  z_pos_source_lsw;
-       unsigned short  max_dist_0_msw;
-       unsigned short  max_dist_0_lsw;
-       unsigned short  min_dist_0_msw;
-       unsigned short  min_dist_0_lsw;
-       unsigned short  roll_off_factor;
-       unsigned short  mute_after_max_flag;
-       unsigned short  x_vel_source_msw;
-       unsigned short  x_vel_source_lsw;
-       unsigned short  y_vel_source_msw;
-       unsigned short  y_vel_source_lsw;
-       unsigned short  z_vel_source_msw;
-       unsigned short  z_vel_source_lsw;
-} __attribute__((packed)) audpp_msg_qafx_pos;
-
-/*
- * MSG to provide AVSYNC feedback from DSP to ARM
- */
-
-#define AUDPP_MSG_AVSYNC_MSG           0x0005
-#define AUDPP_MSG_AVSYNC_MSG_LEN       \
-       sizeof(audpp_msg_avsync_msg)
-
-typedef struct {
-       unsigned short  active_flag;
-       unsigned short  num_samples_counter0_HSW;
-       unsigned short  num_samples_counter0_MSW;
-       unsigned short  num_samples_counter0_LSW;
-       unsigned short  num_bytes_counter0_HSW;
-       unsigned short  num_bytes_counter0_MSW;
-       unsigned short  num_bytes_counter0_LSW;
-       unsigned short  samp_freq_obj_0;
-       unsigned short  samp_freq_obj_1;
-       unsigned short  samp_freq_obj_2;
-       unsigned short  samp_freq_obj_3;
-       unsigned short  samp_freq_obj_4;
-       unsigned short  samp_freq_obj_5;
-       unsigned short  samp_freq_obj_6;
-       unsigned short  samp_freq_obj_7;
-       unsigned short  samp_freq_obj_8;
-       unsigned short  samp_freq_obj_9;
-       unsigned short  samp_freq_obj_10;
-       unsigned short  samp_freq_obj_11;
-       unsigned short  samp_freq_obj_12;
-       unsigned short  samp_freq_obj_13;
-       unsigned short  samp_freq_obj_14;
-       unsigned short  samp_freq_obj_15;
-       unsigned short  num_samples_counter4_HSW;
-       unsigned short  num_samples_counter4_MSW;
-       unsigned short  num_samples_counter4_LSW;
-       unsigned short  num_bytes_counter4_HSW;
-       unsigned short  num_bytes_counter4_MSW;
-       unsigned short  num_bytes_counter4_LSW;
-} __attribute__((packed)) audpp_msg_avsync_msg;
-
-/*
- * MSG to provide PCM DMA Missed feedback from the DSP to ARM
- */
-
-#define  AUDPP_MSG_PCMDMAMISSED        0x0006
-#define  AUDPP_MSG_PCMDMAMISSED_LEN    \
-       sizeof(audpp_msg_pcmdmamissed);
-
-typedef struct{
-       /*
-       ** Bit 0        0 = PCM DMA not missed for object 0
-       **        1 = PCM DMA missed for object0
-       ** Bit 1        0 = PCM DMA not missed for object 1
-       **        1 = PCM DMA missed for object1
-       ** Bit 2        0 = PCM DMA not missed for object 2
-       **        1 = PCM DMA missed for object2
-       ** Bit 3        0 = PCM DMA not missed for object 3
-       **        1 = PCM DMA missed for object3
-       ** Bit 4        0 = PCM DMA not missed for object 4
-       **        1 = PCM DMA missed for object4
-       */
-       unsigned short pcmdmamissed;
-} __attribute__((packed)) audpp_msg_pcmdmamissed;
-
-/*
- * MSG to AUDPP enable or disable feedback form DSP to ARM
- */
-
-#define AUDPP_MSG_CFG_MSG      0x0007
-#define AUDPP_MSG_CFG_MSG_LEN  \
-    sizeof(audpp_msg_cfg_msg)
-
-#define AUDPP_MSG_ENA_ENA      0xFFFF
-#define AUDPP_MSG_ENA_DIS      0x0000
-
-typedef struct{
-       /*   Enabled  - 0xffff
-       **  Disabled - 0
-       */
-       unsigned short enabled;
-} __attribute__((packed)) audpp_msg_cfg_msg;
-
-/*
- * MSG to communicate the reverb  per object volume
- */
-
-#define AUDPP_MSG_QREVERB_VOLUME       0x0008
-#define AUDPP_MSG_QREVERB_VOLUME_LEN   \
-       sizeof(audpp_msg_qreverb_volume)
-
-
-typedef struct {
-       unsigned short  obj_0_gain;
-       unsigned short  obj_1_gain;
-       unsigned short  obj_2_gain;
-       unsigned short  obj_3_gain;
-       unsigned short  obj_4_gain;
-       unsigned short  hpcm_obj_volume;
-} __attribute__((packed)) audpp_msg_qreverb_volume;
-
-#define AUDPP_MSG_ROUTING_ACK 0x0009
-#define AUDPP_MSG_ROUTING_ACK_LEN \
-  sizeof(struct audpp_msg_routing_ack)
-
-struct audpp_msg_routing_ack {
-       unsigned short dec_id;
-       unsigned short routing_mode;
-} __attribute__((packed));
-
-#define AUDPP_MSG_FLUSH_ACK 0x000A
-
-#endif /* QDSP5AUDPPMSG_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h
deleted file mode 100644 (file)
index 06d33d5..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-#ifndef QDSP5AUDPREPROCCMDI_H
-#define QDSP5AUDPREPROCCMDI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    A U D I O   P R E   P R O C E S S I N G  I N T E R N A L  C O M M A N D S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are accepted by AUDPREPROC Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreproccmdi.h#2 $
-
-===========================================================================*/
-
-/*
- * AUDIOPREPROC COMMANDS:
- * ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK
- * Location : MEMB
- * Buffer size : 51
- * Number of buffers in a queue : 3
- */
-
-/*
- * Command to configure the parameters of AGC
- */
-
-#define        AUDPREPROC_CMD_CFG_AGC_PARAMS   0x0000
-#define        AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN       \
-       sizeof(audpreproc_cmd_cfg_agc_params)
-
-#define        AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE     0x0009
-#define        AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH        0x000A
-#define        AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE      0x000B
-#define        AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH         0x000C
-#define        AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG          0x000D
-#define        AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN       0x000E
-#define        AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG        0x000F
-
-#define        AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA      -1
-#define        AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS      0x0000
-
-#define        AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN       -1
-#define        AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN    0x0000
-
-#define        AUDPREPROC_CMD_PARAM_MASK_RMS_TAY       0x0004
-#define        AUDPREPROC_CMD_PARAM_MASK_RELEASEK      0x0005
-#define        AUDPREPROC_CMD_PARAM_MASK_DELAY         0x0006
-#define        AUDPREPROC_CMD_PARAM_MASK_ATTACKK       0x0007
-#define        AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW 0x0008
-#define        AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST 0x0009
-#define        AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK  0x000A
-#define        AUDPREPROC_CMD_PARAM_MASK_AIG_MIN       0x000B
-#define        AUDPREPROC_CMD_PARAM_MASK_AIG_MAX       0x000C
-#define        AUDPREPROC_CMD_PARAM_MASK_LEAK_UP       0x000D
-#define        AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN     0x000E
-#define        AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK   0x000F
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  tx_agc_param_mask;
-       unsigned short  tx_agc_enable_flag;
-       unsigned short  static_gain;
-       signed short    adaptive_gain_flag;
-       unsigned short  expander_th;
-       unsigned short  expander_slope;
-       unsigned short  compressor_th;
-       unsigned short  compressor_slope;
-       unsigned short  param_mask;
-       unsigned short  aig_attackk;
-       unsigned short  aig_leak_down;
-       unsigned short  aig_leak_up;
-       unsigned short  aig_max;
-       unsigned short  aig_min;
-       unsigned short  aig_releasek;
-       unsigned short  aig_leakrate_fast;
-       unsigned short  aig_leakrate_slow;
-       unsigned short  attackk_msw;
-       unsigned short  attackk_lsw;
-       unsigned short  delay;
-       unsigned short  releasek_msw;
-       unsigned short  releasek_lsw;
-       unsigned short  rms_tav;
-} __attribute__((packed)) audpreproc_cmd_cfg_agc_params;
-
-
-/*
- * Command to configure the params of Advanved AGC
- */
-
-#define        AUDPREPROC_CMD_CFG_AGC_PARAMS_2         0x0001
-#define        AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN             \
-       sizeof(audpreproc_cmd_cfg_agc_params_2)
-
-#define        AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA    -1;
-#define        AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS    0x0000;
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  agc_param_mask;
-       signed short    tx_agc_enable_flag;
-       unsigned short  comp_static_gain;
-       unsigned short  exp_th;
-       unsigned short  exp_slope;
-       unsigned short  comp_th;
-       unsigned short  comp_slope;
-       unsigned short  comp_rms_tav;
-       unsigned short  comp_samp_mask;
-       unsigned short  comp_attackk_msw;
-       unsigned short  comp_attackk_lsw;
-       unsigned short  comp_releasek_msw;
-       unsigned short  comp_releasek_lsw;
-       unsigned short  comp_delay;
-       unsigned short  comp_makeup_gain;
-} __attribute__((packed)) audpreproc_cmd_cfg_agc_params_2;
-
-/*
- * Command to configure params for ns
- */
-
-#define        AUDPREPROC_CMD_CFG_NS_PARAMS            0x0002
-#define        AUDPREPROC_CMD_CFG_NS_PARAMS_LEN        \
-       sizeof(audpreproc_cmd_cfg_ns_params)
-
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NLMS_ENA     0x0001
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS     0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_DES_ENA      0x0002
-#define        AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS      0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA       0x0004
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS       0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_CNI_ENA      0x0008
-#define        AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS      0x0000
-
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NLES_ENA     0x0010
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS     0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA       0x0020
-#define        AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS       0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA       0x0040
-#define        AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS       0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_PCD_ENA      0x0080
-#define        AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS      0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_FEHI_ENA     0x0100
-#define        AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS     0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NEHI_ENA     0x0200
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS     0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NLPP_ENA     0x0400
-#define        AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS     0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_FNE_ENA      0x0800
-#define        AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS      0x0000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_ENA  0x1000
-#define        AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS  0x0000
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  ec_mode_new;
-       unsigned short  dens_gamma_n;
-       unsigned short  dens_nfe_block_size;
-       unsigned short  dens_limit_ns;
-       unsigned short  dens_limit_ns_d;
-       unsigned short  wb_gamma_e;
-       unsigned short  wb_gamma_n;
-} __attribute__((packed)) audpreproc_cmd_cfg_ns_params;
-
-/*
- * Command to configure parameters for IIR tuning filter
- */
-
-#define        AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS             0x0003
-#define        AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN \
-       sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params)
-
-#define        AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS      0x0000
-#define        AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA      0x0001
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  active_flag;
-       unsigned short  num_bands;
-       unsigned short  numerator_coeff_b0_filter0_lsw;
-       unsigned short  numerator_coeff_b0_filter0_msw;
-       unsigned short  numerator_coeff_b1_filter0_lsw;
-       unsigned short  numerator_coeff_b1_filter0_msw;
-       unsigned short  numerator_coeff_b2_filter0_lsw;
-       unsigned short  numerator_coeff_b2_filter0_msw;
-       unsigned short  numerator_coeff_b0_filter1_lsw;
-       unsigned short  numerator_coeff_b0_filter1_msw;
-       unsigned short  numerator_coeff_b1_filter1_lsw;
-       unsigned short  numerator_coeff_b1_filter1_msw;
-       unsigned short  numerator_coeff_b2_filter1_lsw;
-       unsigned short  numerator_coeff_b2_filter1_msw;
-       unsigned short  numerator_coeff_b0_filter2_lsw;
-       unsigned short  numerator_coeff_b0_filter2_msw;
-       unsigned short  numerator_coeff_b1_filter2_lsw;
-       unsigned short  numerator_coeff_b1_filter2_msw;
-       unsigned short  numerator_coeff_b2_filter2_lsw;
-       unsigned short  numerator_coeff_b2_filter2_msw;
-       unsigned short  numerator_coeff_b0_filter3_lsw;
-       unsigned short  numerator_coeff_b0_filter3_msw;
-       unsigned short  numerator_coeff_b1_filter3_lsw;
-       unsigned short  numerator_coeff_b1_filter3_msw;
-       unsigned short  numerator_coeff_b2_filter3_lsw;
-       unsigned short  numerator_coeff_b2_filter3_msw;
-       unsigned short  denominator_coeff_a0_filter0_lsw;
-       unsigned short  denominator_coeff_a0_filter0_msw;
-       unsigned short  denominator_coeff_a1_filter0_lsw;
-       unsigned short  denominator_coeff_a1_filter0_msw;
-       unsigned short  denominator_coeff_a0_filter1_lsw;
-       unsigned short  denominator_coeff_a0_filter1_msw;
-       unsigned short  denominator_coeff_a1_filter1_lsw;
-       unsigned short  denominator_coeff_a1_filter1_msw;
-  unsigned short       denominator_coeff_a0_filter2_lsw;
-       unsigned short  denominator_coeff_a0_filter2_msw;
-       unsigned short  denominator_coeff_a1_filter2_lsw;
-       unsigned short  denominator_coeff_a1_filter2_msw;
-  unsigned short       denominator_coeff_a0_filter3_lsw;
-       unsigned short  denominator_coeff_a0_filter3_msw;
-       unsigned short  denominator_coeff_a1_filter3_lsw;
-       unsigned short  denominator_coeff_a1_filter3_msw;
-
-       unsigned short  shift_factor_filter0;
-       unsigned short  shift_factor_filter1;
-       unsigned short  shift_factor_filter2;
-       unsigned short  shift_factor_filter3;
-
-       unsigned short  channel_selected0;
-       unsigned short  channel_selected1;
-       unsigned short  channel_selected2;
-       unsigned short  channel_selected3;
-} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params;
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h
deleted file mode 100644 (file)
index f40e41e..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef QDSP5AUDPREPROCMSG_H
-#define QDSP5AUDPREPROCMSG_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    A U D I O   P R E   P R O C E S S I N G  M E S S A G E S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of messages
-  that are rcvd by AUDPREPROC Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
- $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreprocmsg.h#3 $
-
-===========================================================================*/
-
-/*
- * ADSPREPROCTASK Messages
- * AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM
- * Location    : MEMA
- * Message Length  : 2
- */
-
-/*
- * Message to indicate particular feature has been enabled or disabled
- */
-
-
-#define        AUDPREPROC_MSG_CMD_CFG_DONE_MSG 0x0000
-#define        AUDPREPROC_MSG_CMD_CFG_DONE_MSG_LEN     \
-       sizeof(audpreproc_msg_cmd_cfg_done_msg)
-
-#define        AUDPREPROC_MSG_TYPE_AGC                 0x0000
-#define        AUDPREPROC_MSG_TYPE_NOISE_REDUCTION     0x0001
-#define        AUDPREPROC_MSG_TYPE_IIR_FILTER          0x0002
-
-
-#define        AUDPREPROC_MSG_STATUS_FLAG_ENA          -1
-#define        AUDPREPROC_MSG_STATUS_FLAG_DIS          0x0000
-
-typedef struct {
-       unsigned short  type;
-       signed short    status_flag;
-} __attribute__((packed)) audpreproc_msg_cmd_cfg_done_msg;
-
-
-/*
- * Message to indicate particular feature has selected for wrong samp freq
- */
-
-#define        AUDPREPROC_MSG_ERROR_MSG_ID             0x0001
-#define        AUDPREPROC_MSG_ERROR_MSG_ID_LEN \
-       sizeof(audpreproc_msg_error_msg_id)
-
-#define        AUDPREPROC_MSG_ERR_INDEX_NS             0x0000
-
-typedef struct {
-        unsigned short err_index;
-} __attribute__((packed)) audpreproc_msg_error_msg_id;
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h
deleted file mode 100644 (file)
index d03ee02..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-#ifndef QDSP5AUDRECCMDI_H
-#define QDSP5AUDRECCMDI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    A U D I O   R E C O R D  I N T E R N A L  C O M M A N D S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are accepted by AUDREC Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
- $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audreccmdi.h#3 $
-
-============================================================================*/
-
-/*
- * AUDRECTASK COMMANDS
- * ARM uses 2 queues to communicate with the AUDRECTASK
- * 1.uPAudRecCmdQueue
- * Location :MEMC
- * Buffer Size : 8
- * No of Buffers in a queue : 3
- * 2.audRecUpBitStreamQueue
- * Location : MEMC
- * Buffer Size : 4
- * No of buffers in a queue : 2
- */
-
-/*
- * Commands on uPAudRecCmdQueue
- */
-
-/*
- * Command to initiate and terminate the audio recording section
- */
-
-#define AUDREC_CMD_CFG         0x0000
-#define        AUDREC_CMD_CFG_LEN      sizeof(audrec_cmd_cfg)
-
-#define        AUDREC_CMD_TYPE_0_INDEX_WAV     0x0000
-#define        AUDREC_CMD_TYPE_0_INDEX_AAC     0x0001
-
-#define AUDREC_CMD_TYPE_0_ENA          0x4000
-#define AUDREC_CMD_TYPE_0_DIS          0x0000
-
-#define AUDREC_CMD_TYPE_0_NOUPDATE     0x0000
-#define AUDREC_CMD_TYPE_0_UPDATE       0x8000
-
-#define        AUDREC_CMD_TYPE_1_INDEX_SBC     0x0002
-
-#define AUDREC_CMD_TYPE_1_ENA          0x4000
-#define AUDREC_CMD_TYPE_1_DIS          0x0000
-
-#define AUDREC_CMD_TYPE_1_NOUPDATE     0x0000
-#define AUDREC_CMD_TYPE_1_UPDATE       0x8000
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  type_0;
-       unsigned short  type_1;
-} __attribute__((packed)) audrec_cmd_cfg;
-
-
-/*
- * Command to configure the recording parameters for RecType0(AAC/WAV) encoder
- */
-
-#define        AUDREC_CMD_AREC0PARAM_CFG       0x0001
-#define        AUDREC_CMD_AREC0PARAM_CFG_LEN   \
-       sizeof(audrec_cmd_arec0param_cfg)
-
-#define        AUDREC_CMD_SAMP_RATE_INDX_8000          0x000B
-#define        AUDREC_CMD_SAMP_RATE_INDX_11025         0x000A
-#define        AUDREC_CMD_SAMP_RATE_INDX_12000         0x0009
-#define        AUDREC_CMD_SAMP_RATE_INDX_16000         0x0008
-#define        AUDREC_CMD_SAMP_RATE_INDX_22050         0x0007
-#define        AUDREC_CMD_SAMP_RATE_INDX_24000         0x0006
-#define        AUDREC_CMD_SAMP_RATE_INDX_32000         0x0005
-#define        AUDREC_CMD_SAMP_RATE_INDX_44100         0x0004
-#define        AUDREC_CMD_SAMP_RATE_INDX_48000         0x0003
-
-#define AUDREC_CMD_STEREO_MODE_MONO            0x0000
-#define AUDREC_CMD_STEREO_MODE_STEREO          0x0001
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  ptr_to_extpkt_buffer_msw;
-       unsigned short  ptr_to_extpkt_buffer_lsw;
-       unsigned short  buf_len;
-       unsigned short  samp_rate_index;
-       unsigned short  stereo_mode;
-       unsigned short  rec_quality;
-} __attribute__((packed)) audrec_cmd_arec0param_cfg;
-
-/*
- * Command to configure the recording parameters for RecType1(SBC) encoder
- */
-
-#define AUDREC_CMD_AREC1PARAM_CFG      0x0002
-#define AUDREC_CMD_AREC1PARAM_CFG_LEN  \
-       sizeof(audrec_cmd_arec1param_cfg)
-
-#define AUDREC_CMD_PARAM_BUF_BLOCKS_4  0x0000
-#define AUDREC_CMD_PARAM_BUF_BLOCKS_8  0x0001
-#define AUDREC_CMD_PARAM_BUF_BLOCKS_12 0x0002
-#define AUDREC_CMD_PARAM_BUF_BLOCKS_16 0x0003
-
-#define AUDREC_CMD_PARAM_BUF_SUB_BANDS_8       0x0010
-#define AUDREC_CMD_PARAM_BUF_MODE_MONO         0x0000
-#define AUDREC_CMD_PARAM_BUF_MODE_DUAL         0x0040
-#define AUDREC_CMD_PARAM_BUF_MODE_STEREO       0x0050
-#define AUDREC_CMD_PARAM_BUF_MODE_JSTEREO      0x0060
-#define AUDREC_CMD_PARAM_BUF_LOUDNESS          0x0000
-#define AUDREC_CMD_PARAM_BUF_SNR               0x0100
-#define AUDREC_CMD_PARAM_BUF_BASIC_VER         0x0000
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  ptr_to_extpkt_buffer_msw;
-       unsigned short  ptr_to_extpkt_buffer_lsw;
-       unsigned short  buf_len;
-       unsigned short  param_buf;
-       unsigned short  bit_rate_0;
-       unsigned short  bit_rate_1;
-} __attribute__((packed)) audrec_cmd_arec1param_cfg;
-
-
-/*
- * Commands on audRecUpBitStreamQueue
- */
-
-/*
- * Command to indicate the current packet read count
- */
-
-#define AUDREC_CMD_PACKET_EXT_PTR              0x0000
-#define AUDREC_CMD_PACKET_EXT_PTR_LEN  \
-       sizeof(audrec_cmd_packet_ext_ptr)
-
-#define AUDREC_CMD_TYPE_0      0x0000
-#define AUDREC_CMD_TYPE_1      0x0001
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  type;
-       unsigned short  curr_rec_count_msw;
-       unsigned short  curr_rec_count_lsw;
-} __attribute__((packed)) audrec_cmd_packet_ext_ptr;
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h
deleted file mode 100644 (file)
index bb6eb50..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef QDSP5AUDRECMSGI_H
-#define QDSP5AUDRECMSGI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    A U D I O   R E C O R D  M E S S A G E S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of messages
-  that are sent by AUDREC Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
- $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audrecmsg.h#3 $
-
-============================================================================*/
-
-/*
- * AUDRECTASK MESSAGES
- * AUDRECTASK uses audRecUpRlist to communicate with ARM
- * Location : MEMC
- * Buffer size : 4
- * No of buffers in a queue : 2
- */
-
-/*
- * Message to notify that config command is done
- */
-
-#define AUDREC_MSG_CMD_CFG_DONE_MSG    0x0002
-#define AUDREC_MSG_CMD_CFG_DONE_MSG_LEN        \
-       sizeof(audrec_msg_cmd_cfg_done_msg)
-
-
-#define AUDREC_MSG_CFG_DONE_TYPE_0_ENA         0x4000
-#define AUDREC_MSG_CFG_DONE_TYPE_0_DIS         0x0000
-
-#define AUDREC_MSG_CFG_DONE_TYPE_0_NO_UPDATE   0x0000
-#define AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE      0x8000
-
-#define AUDREC_MSG_CFG_DONE_TYPE_1_ENA         0x4000
-#define AUDREC_MSG_CFG_DONE_TYPE_1_DIS         0x0000
-
-#define AUDREC_MSG_CFG_DONE_TYPE_1_NO_UPDATE   0x0000
-#define AUDREC_MSG_CFG_DONE_TYPE_1_UPDATE      0x8000
-
-typedef struct {
-       unsigned short  type_0;
-       unsigned short  type_1;
-} __attribute__((packed))audrec_msg_cmd_cfg_done_msg;
-
-
-/*
- * Message to notify arec0/1 cfg done and recording params revd by task
- */
-
-#define        AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG          0x0003
-#define        AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG_LEN      \
-       sizeof(audrec_msg_cmd_arec_param_cfg_done_msg)
-
-#define        AUDREC_MSG_AREC_PARAM_TYPE_0    0x0000
-#define        AUDREC_MSG_AREC_PARAM_TYPE_1    0x0001
-
-typedef struct {
-       unsigned short  type;
-} __attribute__((packed))audrec_msg_cmd_arec_param_cfg_done_msg;
-
-
-/*
- * Message to notify no more buffers are available in ext mem to DME
- */
-
-#define AUDREC_MSG_FATAL_ERR_MSG               0x0004
-#define AUDREC_MSG_FATAL_ERR_MSG_LEN   \
-       sizeof(audrec_msg_fatal_err_msg)
-
-#define AUDREC_MSG_FATAL_ERR_TYPE_0    0x0000
-#define AUDREC_MSG_FATAL_ERR_TYPE_1    0x0001
-
-typedef struct {
-       unsigned short  type;
-} __attribute__((packed))audrec_msg_fatal_err_msg;
-
-/*
- * Message to notify DME deliverd the encoded pkt to ext pkt buffer
- */
-
-#define AUDREC_MSG_PACKET_READY_MSG            0x0005
-#define AUDREC_MSG_PACKET_READY_MSG_LEN        \
-       sizeof(audrec_msg_packet_ready_msg)
-
-#define AUDREC_MSG_PACKET_READY_TYPE_0 0x0000
-#define AUDREC_MSG_PACKET_READY_TYPE_1 0x0001
-
-typedef struct {
-       unsigned short  type;
-       unsigned short  pkt_counter_msw;
-       unsigned short  pkt_counter_lsw;
-       unsigned short  pkt_read_cnt_msw;
-       unsigned short  pkt_read_cnt_lsw;
-} __attribute__((packed))audrec_msg_packet_ready_msg;
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h
deleted file mode 100644 (file)
index 574ad6b..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-#ifndef QDSP5VIDJPEGCMDI_H
-#define QDSP5VIDJPEGCMDI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    J P E G  I N T E R N A L  C O M M A N D S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are accepted by JPEG Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
-Revision History:
-when       who     what, where, why
---------   ---     ----------------------------------------------------------
-06/09/08   sv      initial version
-===========================================================================*/
-
-/*
- * ARM to JPEG configuration commands are passed through the
- * uPJpegCfgCmdQueue
- */
-
-/*
- * Command to configure JPEG Encoder
- */
-
-#define        JPEG_CMD_ENC_CFG                0x0000
-#define        JPEG_CMD_ENC_CFG_LEN    sizeof(jpeg_cmd_enc_cfg)
-
-#define        JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_0          0x0000
-#define        JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_90         0x0100
-#define        JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_180        0x0200
-#define        JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_270        0x0300
-#define        JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M       0x0003
-#define        JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2    0x0000
-#define        JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V1    0x0001
-#define        JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H1V2    0x0002
-
-#define        JPEG_CMD_IP_SIZE_CFG_LUMA_HEIGHT_M              0x0000FFFF
-#define        JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M               0xFFFF0000
-#define        JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_ENA             0x0001
-#define        JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_DIS             0x0000
-
-#define        JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M                0xFFFF
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    process_cfg;
-       unsigned int    ip_size_cfg;
-       unsigned int    op_size_cfg;
-       unsigned int    frag_cfg;
-       unsigned int    frag_cfg_part[16];
-
-       unsigned int    part_num;
-
-       unsigned int    op_buf_0_cfg_part1;
-       unsigned int    op_buf_0_cfg_part2;
-       unsigned int    op_buf_1_cfg_part1;
-       unsigned int    op_buf_1_cfg_part2;
-
-       unsigned int    luma_qunt_table[32];
-       unsigned int    chroma_qunt_table[32];
-
-       unsigned int    upsamp_ip_size_cfg;
-       unsigned int    upsamp_ip_frame_off;
-       unsigned int    upsamp_pp_filter_coeff[64];
-} __attribute__((packed)) jpeg_cmd_enc_cfg;
-
-/*
- * Command to configure JPEG Decoder
- */
-
-#define        JPEG_CMD_DEC_CFG                0x0001
-#define        JPEG_CMD_DEC_CFG_LEN            sizeof(jpeg_cmd_dec_cfg)
-
-#define        JPEG_CMD_DEC_OP_DATA_FORMAT_M           0x0001
-#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2       0x0000
-#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V1       0x0001
-
-#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_8     0x000000
-#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_4     0x010000
-#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_2     0x020000
-#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_1     0x030000
-
-#define        JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_NOT_FINAL  0x0000
-#define        JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_FINAL      0x0001
-
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    img_dimension_cfg;
-       unsigned int    op_data_format;
-       unsigned int    restart_interval;
-       unsigned int    ip_buf_partition_num;
-       unsigned int    ip_stream_buf_cfg_part1;
-       unsigned int    ip_stream_buf_cfg_part2;
-       unsigned int    ip_stream_buf_cfg_part3;
-       unsigned int    op_stream_buf_0_cfg_part1;
-       unsigned int    op_stream_buf_0_cfg_part2;
-       unsigned int    op_stream_buf_0_cfg_part3;
-       unsigned int    op_stream_buf_1_cfg_part1;
-       unsigned int    op_stream_buf_1_cfg_part2;
-       unsigned int    op_stream_buf_1_cfg_part3;
-       unsigned int    luma_qunt_table_0_3;
-       unsigned int    luma_qunt_table_4_7;
-       unsigned int    luma_qunt_table_8_11;
-       unsigned int    luma_qunt_table_12_15;
-       unsigned int    luma_qunt_table_16_19;
-       unsigned int    luma_qunt_table_20_23;
-       unsigned int    luma_qunt_table_24_27;
-       unsigned int    luma_qunt_table_28_31;
-       unsigned int    luma_qunt_table_32_35;
-       unsigned int    luma_qunt_table_36_39;
-       unsigned int    luma_qunt_table_40_43;
-       unsigned int    luma_qunt_table_44_47;
-       unsigned int    luma_qunt_table_48_51;
-       unsigned int    luma_qunt_table_52_55;
-       unsigned int    luma_qunt_table_56_59;
-       unsigned int    luma_qunt_table_60_63;
-       unsigned int    chroma_qunt_table_0_3;
-       unsigned int    chroma_qunt_table_4_7;
-       unsigned int    chroma_qunt_table_8_11;
-       unsigned int    chroma_qunt_table_12_15;
-       unsigned int    chroma_qunt_table_16_19;
-       unsigned int    chroma_qunt_table_20_23;
-       unsigned int    chroma_qunt_table_24_27;
-       unsigned int    chroma_qunt_table_28_31;
-       unsigned int    chroma_qunt_table_32_35;
-       unsigned int    chroma_qunt_table_36_39;
-       unsigned int    chroma_qunt_table_40_43;
-       unsigned int    chroma_qunt_table_44_47;
-       unsigned int    chroma_qunt_table_48_51;
-       unsigned int    chroma_qunt_table_52_55;
-       unsigned int    chroma_qunt_table_56_59;
-       unsigned int    chroma_qunt_table_60_63;
-       unsigned int    luma_dc_hm_code_cnt_table_0_3;
-       unsigned int    luma_dc_hm_code_cnt_table_4_7;
-       unsigned int    luma_dc_hm_code_cnt_table_8_11;
-       unsigned int    luma_dc_hm_code_cnt_table_12_15;
-       unsigned int    luma_dc_hm_code_val_table_0_3;
-       unsigned int    luma_dc_hm_code_val_table_4_7;
-       unsigned int    luma_dc_hm_code_val_table_8_11;
-       unsigned int    chroma_dc_hm_code_cnt_table_0_3;
-       unsigned int    chroma_dc_hm_code_cnt_table_4_7;
-       unsigned int    chroma_dc_hm_code_cnt_table_8_11;
-       unsigned int    chroma_dc_hm_code_cnt_table_12_15;
-       unsigned int    chroma_dc_hm_code_val_table_0_3;
-       unsigned int    chroma_dc_hm_code_val_table_4_7;
-       unsigned int    chroma_dc_hm_code_val_table_8_11;
-       unsigned int    luma_ac_hm_code_cnt_table_0_3;
-       unsigned int    luma_ac_hm_code_cnt_table_4_7;
-       unsigned int    luma_ac_hm_code_cnt_table_8_11;
-       unsigned int    luma_ac_hm_code_cnt_table_12_15;
-       unsigned int    luma_ac_hm_code_val_table_0_3;
-       unsigned int    luma_ac_hm_code_val_table_4_7;
-       unsigned int    luma_ac_hm_code_val_table_8_11;
-       unsigned int    luma_ac_hm_code_val_table_12_15;
-       unsigned int    luma_ac_hm_code_val_table_16_19;
-       unsigned int    luma_ac_hm_code_val_table_20_23;
-       unsigned int    luma_ac_hm_code_val_table_24_27;
-       unsigned int    luma_ac_hm_code_val_table_28_31;
-       unsigned int    luma_ac_hm_code_val_table_32_35;
-       unsigned int    luma_ac_hm_code_val_table_36_39;
-       unsigned int    luma_ac_hm_code_val_table_40_43;
-       unsigned int    luma_ac_hm_code_val_table_44_47;
-       unsigned int    luma_ac_hm_code_val_table_48_51;
-       unsigned int    luma_ac_hm_code_val_table_52_55;
-       unsigned int    luma_ac_hm_code_val_table_56_59;
-       unsigned int    luma_ac_hm_code_val_table_60_63;
-       unsigned int    luma_ac_hm_code_val_table_64_67;
-       unsigned int    luma_ac_hm_code_val_table_68_71;
-       unsigned int    luma_ac_hm_code_val_table_72_75;
-       unsigned int    luma_ac_hm_code_val_table_76_79;
-       unsigned int    luma_ac_hm_code_val_table_80_83;
-       unsigned int    luma_ac_hm_code_val_table_84_87;
-       unsigned int    luma_ac_hm_code_val_table_88_91;
-       unsigned int    luma_ac_hm_code_val_table_92_95;
-       unsigned int    luma_ac_hm_code_val_table_96_99;
-       unsigned int    luma_ac_hm_code_val_table_100_103;
-       unsigned int    luma_ac_hm_code_val_table_104_107;
-       unsigned int    luma_ac_hm_code_val_table_108_111;
-       unsigned int    luma_ac_hm_code_val_table_112_115;
-       unsigned int    luma_ac_hm_code_val_table_116_119;
-       unsigned int    luma_ac_hm_code_val_table_120_123;
-       unsigned int    luma_ac_hm_code_val_table_124_127;
-       unsigned int    luma_ac_hm_code_val_table_128_131;
-       unsigned int    luma_ac_hm_code_val_table_132_135;
-       unsigned int    luma_ac_hm_code_val_table_136_139;
-       unsigned int    luma_ac_hm_code_val_table_140_143;
-       unsigned int    luma_ac_hm_code_val_table_144_147;
-       unsigned int    luma_ac_hm_code_val_table_148_151;
-       unsigned int    luma_ac_hm_code_val_table_152_155;
-       unsigned int    luma_ac_hm_code_val_table_156_159;
-       unsigned int    luma_ac_hm_code_val_table_160_161;
-       unsigned int    chroma_ac_hm_code_cnt_table_0_3;
-       unsigned int    chroma_ac_hm_code_cnt_table_4_7;
-       unsigned int    chroma_ac_hm_code_cnt_table_8_11;
-       unsigned int    chroma_ac_hm_code_cnt_table_12_15;
-       unsigned int    chroma_ac_hm_code_val_table_0_3;
-       unsigned int    chroma_ac_hm_code_val_table_4_7;
-       unsigned int    chroma_ac_hm_code_val_table_8_11;
-       unsigned int    chroma_ac_hm_code_val_table_12_15;
-       unsigned int    chroma_ac_hm_code_val_table_16_19;
-       unsigned int    chroma_ac_hm_code_val_table_20_23;
-       unsigned int    chroma_ac_hm_code_val_table_24_27;
-       unsigned int    chroma_ac_hm_code_val_table_28_31;
-       unsigned int    chroma_ac_hm_code_val_table_32_35;
-       unsigned int    chroma_ac_hm_code_val_table_36_39;
-       unsigned int    chroma_ac_hm_code_val_table_40_43;
-       unsigned int    chroma_ac_hm_code_val_table_44_47;
-       unsigned int    chroma_ac_hm_code_val_table_48_51;
-       unsigned int    chroma_ac_hm_code_val_table_52_55;
-       unsigned int    chroma_ac_hm_code_val_table_56_59;
-       unsigned int    chroma_ac_hm_code_val_table_60_63;
-       unsigned int    chroma_ac_hm_code_val_table_64_67;
-       unsigned int    chroma_ac_hm_code_val_table_68_71;
-       unsigned int    chroma_ac_hm_code_val_table_72_75;
-       unsigned int    chroma_ac_hm_code_val_table_76_79;
-       unsigned int    chroma_ac_hm_code_val_table_80_83;
-       unsigned int    chroma_ac_hm_code_val_table_84_87;
-       unsigned int    chroma_ac_hm_code_val_table_88_91;
-       unsigned int    chroma_ac_hm_code_val_table_92_95;
-       unsigned int    chroma_ac_hm_code_val_table_96_99;
-       unsigned int    chroma_ac_hm_code_val_table_100_103;
-       unsigned int    chroma_ac_hm_code_val_table_104_107;
-       unsigned int    chroma_ac_hm_code_val_table_108_111;
-       unsigned int    chroma_ac_hm_code_val_table_112_115;
-       unsigned int    chroma_ac_hm_code_val_table_116_119;
-       unsigned int    chroma_ac_hm_code_val_table_120_123;
-       unsigned int    chroma_ac_hm_code_val_table_124_127;
-       unsigned int    chroma_ac_hm_code_val_table_128_131;
-       unsigned int    chroma_ac_hm_code_val_table_132_135;
-       unsigned int    chroma_ac_hm_code_val_table_136_139;
-       unsigned int    chroma_ac_hm_code_val_table_140_143;
-       unsigned int    chroma_ac_hm_code_val_table_144_147;
-       unsigned int    chroma_ac_hm_code_val_table_148_151;
-       unsigned int    chroma_ac_hm_code_val_table_152_155;
-       unsigned int    chroma_ac_hm_code_val_table_156_159;
-       unsigned int    chroma_ac_hm_code_val_table_160_161;
-} __attribute__((packed)) jpeg_cmd_dec_cfg;
-
-
-/*
- * ARM to JPEG configuration commands are passed through the
- * uPJpegActionCmdQueue
- */
-
-/*
- * Command to start the encode process
- */
-
-#define        JPEG_CMD_ENC_ENCODE             0x0000
-#define        JPEG_CMD_ENC_ENCODE_LEN         sizeof(jpeg_cmd_enc_encode)
-
-
-typedef struct {
-       unsigned short  cmd_id;
-} __attribute__((packed)) jpeg_cmd_enc_encode;
-
-
-/*
- * Command to transition from current state of encoder to IDLE state
- */
-
-#define        JPEG_CMD_ENC_IDLE               0x0001
-#define        JPEG_CMD_ENC_IDLE_LEN           sizeof(jpeg_cmd_enc_idle)
-
-
-typedef struct {
-       unsigned short  cmd_id;
-} __attribute__((packed)) jpeg_cmd_enc_idle;
-
-
-/*
- * Command to inform the encoder that another buffer is ready
- */
-
-#define        JPEG_CMD_ENC_OP_CONSUMED        0x0002
-#define        JPEG_CMD_ENC_OP_CONSUMED_LEN    sizeof(jpeg_cmd_enc_op_consumed)
-
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    op_buf_addr;
-       unsigned int    op_buf_size;
-} __attribute__((packed)) jpeg_cmd_enc_op_consumed;
-
-
-/*
- * Command to start the decoding process
- */
-
-#define        JPEG_CMD_DEC_DECODE             0x0003
-#define        JPEG_CMD_DEC_DECODE_LEN sizeof(jpeg_cmd_dec_decode)
-
-
-typedef struct {
-       unsigned short  cmd_id;
-} __attribute__((packed)) jpeg_cmd_dec_decode;
-
-
-/*
- * Command to transition from the current state of decoder to IDLE
- */
-
-#define        JPEG_CMD_DEC_IDLE       0x0004
-#define        JPEG_CMD_DEC_IDLE_LEN   sizeof(jpeg_cmd_dec_idle)
-
-
-typedef struct {
-       unsigned short  cmd_id;
-} __attribute__((packed)) jpeg_cmd_dec_idle;
-
-
-/*
- * Command to inform that an op buffer is ready for use
- */
-
-#define        JPEG_CMD_DEC_OP_CONSUMED        0x0005
-#define        JPEG_CMD_DEC_OP_CONSUMED_LEN    sizeof(jpeg_cmd_dec_op_consumed)
-
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    luma_op_buf_addr;
-       unsigned int    luma_op_buf_size;
-       unsigned int    chroma_op_buf_addr;
-} __attribute__((packed)) jpeg_cmd_dec_op_consumed;
-
-
-/*
- * Command to pass a new ip buffer to the jpeg decoder
- */
-
-#define        JPEG_CMD_DEC_IP 0x0006
-#define        JPEG_CMD_DEC_IP_LEN     sizeof(jpeg_cmd_dec_ip_len)
-
-#define        JPEG_CMD_EOI_INDICATOR_NOT_END  0x0000
-#define        JPEG_CMD_EOI_INDICATOR_END      0x0001
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    ip_buf_addr;
-       unsigned int    ip_buf_size;
-       unsigned int    eoi_indicator;
-} __attribute__((packed)) jpeg_cmd_dec_ip;
-
-
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h
deleted file mode 100644 (file)
index d11aa3f..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-#ifndef QDSP5VIDJPEGMSGI_H
-#define QDSP5VIDJPEGMSGI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-   J P E G  I N T E R N A L  M E S S A G E S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of messages
-  that are sent by JPEG Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
-Revision History:
-
-when       who     what, where, why
---------   ---     ----------------------------------------------------------
-05/10/08   sv      initial version
-===========================================================================*/
-
-/*
- * Messages from JPEG task to ARM through jpeguPMsgQueue
- */
-
-/*
- * Message is ACK for CMD_JPEGE_ENCODE cmd
- */
-
-#define        JPEG_MSG_ENC_ENCODE_ACK 0x0000
-#define        JPEG_MSG_ENC_ENCODE_ACK_LEN     \
-       sizeof(jpeg_msg_enc_encode_ack)
-
-typedef struct {
-} __attribute__((packed)) jpeg_msg_enc_encode_ack;
-
-
-/*
- * Message informs the up when op buffer is ready for consumption and
- * when encoding is complete or errors
- */
-
-#define        JPEG_MSG_ENC_OP_PRODUCED        0x0001
-#define        JPEG_MSG_ENC_OP_PRODUCED_LEN    \
-       sizeof(jpeg_msg_enc_op_produced)
-
-#define        JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_PROGRESS      0x0000
-#define        JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_COMPLETE      0x0001
-#define        JPEG_MSGOP_OP_BUF_STATUS_ENC_ERR                0x10000
-
-typedef struct {
-       unsigned int    op_buf_addr;
-       unsigned int    op_buf_size;
-       unsigned int    op_buf_status;
-} __attribute__((packed)) jpeg_msg_enc_op_produced;
-
-
-/*
- * Message to ack CMD_JPEGE_IDLE
- */
-
-#define        JPEG_MSG_ENC_IDLE_ACK   0x0002
-#define        JPEG_MSG_ENC_IDLE_ACK_LEN       sizeof(jpeg_msg_enc_idle_ack)
-
-
-typedef struct {
-} __attribute__ ((packed)) jpeg_msg_enc_idle_ack;
-
-
-/*
- * Message to indicate the illegal command
- */
-
-#define        JPEG_MSG_ENC_ILLEGAL_COMMAND    0x0003
-#define        JPEG_MSG_ENC_ILLEGAL_COMMAND_LEN        \
-       sizeof(jpeg_msg_enc_illegal_command)
-
-typedef struct {
-       unsigned int    status;
-} __attribute__((packed)) jpeg_msg_enc_illegal_command;
-
-
-/*
- * Message to ACK CMD_JPEGD_DECODE
- */
-
-#define        JPEG_MSG_DEC_DECODE_ACK         0x0004
-#define        JPEG_MSG_DEC_DECODE_ACK_LEN     \
-       sizeof(jpeg_msg_dec_decode_ack)
-
-
-typedef struct {
-} __attribute__((packed)) jpeg_msg_dec_decode_ack;
-
-
-/*
- * Message to inform up that an op buffer is ready for consumption and when
- * decoding is complete or an error occurs
- */
-
-#define        JPEG_MSG_DEC_OP_PRODUCED                0x0005
-#define        JPEG_MSG_DEC_OP_PRODUCED_LEN    \
-       sizeof(jpeg_msg_dec_op_produced)
-
-#define        JPEG_MSG_DEC_OP_BUF_STATUS_PROGRESS     0x0000
-#define        JPEG_MSG_DEC_OP_BUF_STATUS_DONE         0x0001
-
-typedef struct {
-       unsigned int    luma_op_buf_addr;
-       unsigned int    chroma_op_buf_addr;
-       unsigned int    num_mcus;
-       unsigned int    op_buf_status;
-} __attribute__((packed)) jpeg_msg_dec_op_produced;
-
-/*
- * Message to ack CMD_JPEGD_IDLE cmd
- */
-
-#define        JPEG_MSG_DEC_IDLE_ACK   0x0006
-#define        JPEG_MSG_DEC_IDLE_ACK_LEN       sizeof(jpeg_msg_dec_idle_ack)
-
-
-typedef struct {
-} __attribute__((packed)) jpeg_msg_dec_idle_ack;
-
-
-/*
- * Message to indicate illegal cmd was received
- */
-
-#define        JPEG_MSG_DEC_ILLEGAL_COMMAND    0x0007
-#define        JPEG_MSG_DEC_ILLEGAL_COMMAND_LEN        \
-       sizeof(jpeg_msg_dec_illegal_command)
-
-
-typedef struct {
-       unsigned int    status;
-} __attribute__((packed)) jpeg_msg_dec_illegal_command;
-
-/*
- * Message to request up for the next segment of ip bit stream
- */
-
-#define        JPEG_MSG_DEC_IP_REQUEST         0x0008
-#define        JPEG_MSG_DEC_IP_REQUEST_LEN     \
-       sizeof(jpeg_msg_dec_ip_request)
-
-
-typedef struct {
-} __attribute__((packed)) jpeg_msg_dec_ip_request;
-
-
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h
deleted file mode 100644 (file)
index 6c76e2c..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef QDSP5LPMCMDI_H
-#define QDSP5LPMCMDI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    L P M   I N T E R N A L   C O M M A N D S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are accepted by LPM Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-
-$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
-Revision History:
-
-when       who     what, where, why
---------   ---     ----------------------------------------------------------
-06/12/08   sv      initial version
-===========================================================================*/
-
-
-/*
- * Command to start LPM processing based on the config params
- */
-
-#define        LPM_CMD_START           0x0000
-#define        LPM_CMD_START_LEN       sizeof(lpm_cmd_start)
-
-#define        LPM_CMD_SPATIAL_FILTER_PART_OPMODE_0    0x00000000
-#define        LPM_CMD_SPATIAL_FILTER_PART_OPMODE_1    0x00010000
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    ip_data_cfg_part1;
-       unsigned int    ip_data_cfg_part2;
-       unsigned int    ip_data_cfg_part3;
-       unsigned int    ip_data_cfg_part4;
-       unsigned int    op_data_cfg_part1;
-       unsigned int    op_data_cfg_part2;
-       unsigned int    op_data_cfg_part3;
-       unsigned int    spatial_filter_part[32];
-} __attribute__((packed)) lpm_cmd_start;
-
-
-
-/*
- * Command to stop LPM processing
- */
-
-#define        LPM_CMD_IDLE            0x0001
-#define        LPM_CMD_IDLE_LEN        sizeof(lpm_cmd_idle)
-
-typedef struct {
-       unsigned int    cmd_id;
-} __attribute__((packed)) lpm_cmd_idle;
-
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h
deleted file mode 100644 (file)
index 3d1039d..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef QDSP5LPMMSGI_H
-#define QDSP5LPMMSGI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    L P M   I N T E R N A L   M E S S A G E S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are accepted by LPM Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
-Revision History:
-
-when       who     what, where, why
---------   ---     ----------------------------------------------------------
-06/12/08   sv      initial version
-===========================================================================*/
-
-/*
- * Message to acknowledge CMD_LPM_IDLE command
- */
-
-#define        LPM_MSG_IDLE_ACK        0x0000
-#define        LPM_MSG_IDLE_ACK_LEN    sizeof(lpm_msg_idle_ack)
-
-typedef struct {
-} __attribute__((packed)) lpm_msg_idle_ack;
-
-
-/*
- * Message to acknowledge CMD_LPM_START command
- */
-
-
-#define        LPM_MSG_START_ACK       0x0001
-#define        LPM_MSG_START_ACK_LEN   sizeof(lpm_msg_start_ack)
-
-
-typedef struct {
-} __attribute__((packed)) lpm_msg_start_ack;
-
-
-/*
- * Message to notify the ARM that LPM processing is complete
- */
-
-#define        LPM_MSG_DONE            0x0002
-#define        LPM_MSG_DONE_LEN        sizeof(lpm_msg_done)
-
-typedef struct {
-} __attribute__((packed)) lpm_msg_done;
-
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h
deleted file mode 100644 (file)
index 3a32ee9..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-#ifndef QDSP5VIDDECCMDI_H
-#define QDSP5VIDDECCMDI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    V I D E O  D E C O D E R  I N T E R N A L  C O M M A N D S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are accepted by VIDDEC Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdeccmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
-Revision History:
-
-when       who     what, where, why
---------   ---     ----------------------------------------------------------
-05/10/08   ac      initial version
-===========================================================================*/
-
-
-/*
- * Command to inform VIDDEC that new subframe packet is ready
- */
-
-#define        VIDDEC_CMD_SUBFRAME_PKT         0x0000
-#define        VIDDEC_CMD_SUBFRAME_PKT_LEN \
-       sizeof(viddec_cmd_subframe_pkt)
-
-#define        VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DM              0x0000
-#define        VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DMA     0x0001
-
-#define        VIDDEC_CMD_SF_INFO_0_SUBFRAME_CONTI             0x0000
-#define        VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST             0x0001
-#define        VIDDEC_CMD_SF_INFO_0_SUBFRAME_LAST              0x0002
-#define        VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST_AND_LAST    0x0003
-
-#define        VIDDEC_CMD_CODEC_SELECTION_WORD_MPEG_4          0x0000
-#define        VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_P0        0x0001
-#define        VIDDEC_CMD_CODEC_SELECTION_WORD_H_264           0x0002
-#define        VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_p3        0x0003
-#define        VIDDEC_CMD_CODEC_SELECTION_WORD_RV9             0x0004
-#define        VIDDEC_CMD_CODEC_SELECTION_WORD_WMV9            0x0005
-#define        VIDDEC_CMD_CODEC_SELECTION_WORD_SMCDB           0x0006
-#define        VIDDEC_CMD_CODEC_SELECTION_WORD_QFRE            0x0007
-#define        VIDDEC_CMD_CODEC_SELECTION_WORD_VLD             0x0008
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  packet_seq_number;
-       unsigned short  codec_instance_id;
-       unsigned short  subframe_packet_size_high;
-       unsigned short  subframe_packet_size_low;
-       unsigned short  subframe_packet_high;
-       unsigned short  subframe_packet_low;
-       unsigned short  subframe_packet_partition;
-       unsigned short  statistics_packet_size_high;
-       unsigned short  statistics_packet_size_low;
-       unsigned short  statistics_packet_high;
-       unsigned short  statistics_packet_low;
-       unsigned short  statistics_partition;
-       unsigned short  subframe_info_1;
-       unsigned short  subframe_info_0;
-       unsigned short  codec_selection_word;
-       unsigned short  num_mbs;
-} __attribute__((packed)) viddec_cmd_subframe_pkt;
-
-
-/*
- * Command to inform VIDDEC task that post processing is required for the frame
- */
-
-#define        VIDDEC_CMD_PP_ENABLE            0x0001
-#define        VIDDEC_CMD_PP_ENABLE_LEN \
-       sizeof(viddec_cmd_pp_enable)
-
-#define        VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DM         0x0000
-#define        VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DMA        0x0001
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  packet_seq_num;
-       unsigned short  codec_instance_id;
-       unsigned short  postproc_info_0;
-       unsigned short  codec_selection_word;
-       unsigned short  pp_output_addr_high;
-       unsigned short  pp_output_addr_low;
-       unsigned short  postproc_info_1;
-       unsigned short  load_sharing_packet_size_high;
-       unsigned short  load_sharing_packet_size_low;
-       unsigned short  load_sharing_packet_high;
-       unsigned short  load_sharing_packet_low;
-       unsigned short  load_sharing_partition;
-       unsigned short  pp_param_0;
-       unsigned short  pp_param_1;
-       unsigned short  pp_param_2;
-       unsigned short  pp_param_3;
-} __attribute__((packed)) viddec_cmd_pp_enable;
-
-
-/*
- * FRAME Header Packet : It is at the start of new frame
- */
-
-#define        VIDDEC_CMD_FRAME_HEADER_PACKET  0x0002
-#define        VIDDEC_CMD_FRAME_HEADER_PACKET_LEN      \
-       sizeof(viddec_cmd_frame_header_packet)
-
-#define        VIDDEC_CMD_FRAME_INFO_0_ERROR_SKIP      0x0000
-#define        VIDDEC_CMD_FRAME_INFO_0_ERROR_BLACK     0x0800
-
-typedef struct {
-       unsigned short  packet_id;
-       unsigned short  x_dimension;
-       unsigned short  y_dimension;
-       unsigned short  line_width;
-       unsigned short  frame_info_0;
-       unsigned short  frame_buffer_0_high;
-       unsigned short  frame_buffer_0_low;
-       unsigned short  frame_buffer_1_high;
-       unsigned short  frame_buffer_1_low;
-       unsigned short  frame_buffer_2_high;
-       unsigned short  frame_buffer_2_low;
-       unsigned short  frame_buffer_3_high;
-       unsigned short  frame_buffer_3_low;
-       unsigned short  frame_buffer_4_high;
-       unsigned short  frame_buffer_4_low;
-       unsigned short  frame_buffer_5_high;
-       unsigned short  frame_buffer_5_low;
-       unsigned short  frame_buffer_6_high;
-       unsigned short  frame_buffer_6_low;
-       unsigned short  frame_buffer_7_high;
-       unsigned short  frame_buffer_7_low;
-       unsigned short  frame_buffer_8_high;
-       unsigned short  frame_buffer_8_low;
-       unsigned short  frame_buffer_9_high;
-       unsigned short  frame_buffer_9_low;
-       unsigned short  frame_buffer_10_high;
-       unsigned short  frame_buffer_10_low;
-       unsigned short  frame_buffer_11_high;
-       unsigned short  frame_buffer_11_low;
-       unsigned short  frame_buffer_12_high;
-       unsigned short  frame_buffer_12_low;
-       unsigned short  frame_buffer_13_high;
-       unsigned short  frame_buffer_13_low;
-       unsigned short  frame_buffer_14_high;
-       unsigned short  frame_buffer_14_low;
-       unsigned short  frame_buffer_15_high;
-       unsigned short  frame_buffer_15_low;
-       unsigned short  output_frame_buffer_high;
-       unsigned short  output_frame_buffer_low;
-       unsigned short  end_of_packet_marker;
-} __attribute__((packed)) viddec_cmd_frame_header_packet;
-
-
-/*
- * SLICE HEADER PACKET
- * I-Slice and P-Slice
- */
-
-#define        VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE              0x0003
-#define        VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE_LEN  \
-       sizeof(viddec_cmd_slice_header_pkt_islice)
-
-#define        VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_PSLICE  0x0000
-#define        VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_BSLICE  0x0100
-#define        VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_ISLICE  0x0200
-#define        VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SPSLICE 0x0300
-#define        VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SISLICE 0x0400
-#define        VIDDEC_CMD_ISLICE_INFO_1_NOPADDING      0x0000
-#define        VIDDEC_CMD_ISLICE_INFO_1_PADDING        0x0800
-
-#define        VIDDEC_CMD_ISLICE_EOP_MARKER            0x7FFF
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  packet_id;
-       unsigned short  slice_info_0;
-       unsigned short  slice_info_1;
-       unsigned short  slice_info_2;
-       unsigned short  num_bytes_in_rbsp_high;
-       unsigned short  num_bytes_in_rbsp_low;
-       unsigned short  num_bytes_in_rbsp_consumed;
-       unsigned short  end_of_packet_marker;
-} __attribute__((packed)) viddec_cmd_slice_header_pkt_islice;
-
-
-#define        VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE              0x0003
-#define        VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE_LEN  \
-       sizeof(viddec_cmd_slice_header_pkt_pslice)
-
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  packet_id;
-       unsigned short  slice_info_0;
-       unsigned short  slice_info_1;
-       unsigned short  slice_info_2;
-       unsigned short  slice_info_3;
-       unsigned short  refidx_l0_map_tab_info_0;
-       unsigned short  refidx_l0_map_tab_info_1;
-       unsigned short  refidx_l0_map_tab_info_2;
-       unsigned short  refidx_l0_map_tab_info_3;
-       unsigned short  num_bytes_in_rbsp_high;
-       unsigned short  num_bytes_in_rbsp_low;
-       unsigned short  num_bytes_in_rbsp_consumed;
-       unsigned short  end_of_packet_marker;
-} __attribute__((packed)) viddec_cmd_slice_header_pkt_pslice;
-
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h
deleted file mode 100644 (file)
index c1744c1..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef QDSP5VIDDECMSGI_H
-#define QDSP5VIDDECMSGI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    V I D E O  D E C O D E R   I N T E R N A L  M E S S A G E S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of messages
-  that are sent by VIDDEC Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdecmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
-Revision History:
-
-when       who     what, where, why
---------   ---     ----------------------------------------------------------
-05/10/08   ac      initial version
-===========================================================================*/
-
-/*
- * Message to inform ARM which VDEC_SUBFRAME_PKT_CMD processed by VIDDEC TASK
- */
-
-#define        VIDDEC_MSG_SUBF_DONE    0x0000
-#define        VIDDEC_MSG_SUBF_DONE_LEN        \
-       sizeof(viddec_msg_subf_done)
-
-typedef struct {
-       unsigned short  packet_seq_number;
-       unsigned short  codec_instance_id;
-} __attribute__((packed)) viddec_msg_subf_done;
-
-
-/*
- * Message to inform ARM one frame has been decoded
- */
-
-#define        VIDDEC_MSG_FRAME_DONE   0x0001
-#define        VIDDEC_MSG_FRAME_DONE_LEN       \
-       sizeof(viddec_msg_frame_done)
-
-typedef struct {
-       unsigned short  packet_seq_number;
-       unsigned short  codec_instance_id;
-} __attribute__((packed)) viddec_msg_frame_done;
-
-
-/*
- * Message to inform ARM that post processing frame has been decoded
- */
-
-#define        VIDDEC_MSG_PP_ENABLE_CMD_DONE   0x0002
-#define        VIDDEC_MSG_PP_ENABLE_CMD_DONE_LEN       \
-       sizeof(viddec_msg_pp_enable_cmd_done)
-
-typedef struct {
-       unsigned short  packet_seq_number;
-       unsigned short  codec_instance_id;
-} __attribute__((packed)) viddec_msg_pp_enable_cmd_done;
-
-
-/*
- * Message to inform ARM that one post processing frame has been decoded
- */
-
-
-#define        VIDDEC_MSG_PP_FRAME_DONE                0x0003
-#define        VIDDEC_MSG_PP_FRAME_DONE_LEN    \
-       sizeof(viddec_msg_pp_frame_done)
-
-#define        VIDDEC_MSG_DISP_WORTHY_DISP             0x0000
-#define        VIDDEC_MSG_DISP_WORTHY_DISP_NONE        0xFFFF
-
-
-typedef struct {
-       unsigned short  packet_seq_number;
-       unsigned short  codec_instance_id;
-       unsigned short  display_worthy;
-} __attribute__((packed)) viddec_msg_pp_frame_done;
-
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h
deleted file mode 100644 (file)
index 819544d..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-#ifndef QDSP5VIDENCCMDI_H
-#define QDSP5VIDENCCMDI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    V I D E O  E N C O D E R  I N T E R N A L  C O M M A N D S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are accepted by VIDENC Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 2008 by QUALCOMM, Incorporated.
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                       EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-Revision History:
-
-when       who     what, where, why
---------   ---     ----------------------------------------------------------
-09/25/08   umeshp      initial version
-===========================================================================*/
-
-  #define VIDENC_CMD_CFG           0x0000
-  #define VIDENC_CMD_ACTIVE        0x0001
-  #define VIDENC_CMD_IDLE          0x0002
-  #define VIDENC_CMD_FRAME_START   0x0003
-  #define VIDENC_CMD_STATUS_QUERY  0x0004
-  #define VIDENC_CMD_RC_CFG        0x0005
-  #define VIDENC_CMD_DIS_CFG       0x0006
-  #define VIDENC_CMD_DIS           0x0007
-  #define VIDENC_CMD_INTRA_REFRESH 0x0008
-  #define VIDENC_CMD_DIGITAL_ZOOM  0x0009
-
-
-/*
- * Command to pass the frame message information to VIDENC
- */
-
-
-#define VIDENC_CMD_FRAME_START_LEN \
-       sizeof(videnc_cmd_frame_start)
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  frame_info;
-       unsigned short  frame_rho_budget_word_high;
-       unsigned short  frame_rho_budget_word_low;
-       unsigned short  input_luma_addr_high;
-       unsigned short  input_luma_addr_low;
-       unsigned short  input_chroma_addr_high;
-       unsigned short  input_chroma_addr_low;
-       unsigned short  ref_vop_buf_ptr_high;
-       unsigned short  ref_vop_buf_ptr_low;
-       unsigned short  enc_pkt_buf_ptr_high;
-       unsigned short  enc_pkt_buf_ptr_low;
-       unsigned short  enc_pkt_buf_size_high;
-       unsigned short  enc_pkt_buf_size_low;
-       unsigned short  unfilt_recon_vop_buf_ptr_high;
-       unsigned short  unfilt_recon_vop_buf_ptr_low;
-       unsigned short  filt_recon_vop_buf_ptr_high;
-       unsigned short  filt_recon_vop_buf_ptr_low;
-} __attribute__((packed)) videnc_cmd_frame_start;
-
-/*
- * Command to pass the frame-level digital stabilization parameters to VIDENC
- */
-
-
-#define VIDENC_CMD_DIS_LEN \
-    sizeof(videnc_cmd_dis)
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  vfe_out_prev_luma_addr_high;
-       unsigned short  vfe_out_prev_luma_addr_low;
-       unsigned short  stabilization_info;
-} __attribute__((packed)) videnc_cmd_dis;
-
-/*
- * Command to pass the codec related parameters to VIDENC
- */
-
-
-#define VIDENC_CMD_CFG_LEN \
-    sizeof(videnc_cmd_cfg)
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  cfg_info_0;
-       unsigned short  cfg_info_1;
-       unsigned short  four_mv_threshold;
-       unsigned short  ise_fse_mv_cost_fac;
-       unsigned short  venc_frame_dim;
-       unsigned short  venc_DM_partition;
-} __attribute__((packed)) videnc_cmd_cfg;
-
-/*
- * Command to start the video encoding
- */
-
-
-#define VIDENC_CMD_ACTIVE_LEN \
-    sizeof(videnc_cmd_active)
-
-typedef struct {
-    unsigned short  cmd_id;
-} __attribute__((packed)) videnc_cmd_active;
-
-/*
- * Command to stop the video encoding
- */
-
-
-#define VIDENC_CMD_IDLE_LEN \
-    sizeof(videnc_cmd_idle)
-
-typedef struct {
-       unsigned short  cmd_id;
-} __attribute__((packed)) videnc_cmd_idle;
-
-/*
- * Command to query staus of VIDENC
- */
-
-
-#define VIDENC_CMD_STATUS_QUERY_LEN \
-    sizeof(videnc_cmd_status_query)
-
-typedef struct {
-       unsigned short  cmd_id;
-} __attribute__((packed)) videnc_cmd_status_query;
-
-/*
- * Command to set rate control for a frame
- */
-
-
-#define VIDENC_CMD_RC_CFG_LEN \
-    sizeof(videnc_cmd_rc_cfg)
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  max_frame_qp_delta;
-       unsigned short  max_min_frame_qp;
-} __attribute__((packed)) videnc_cmd_rc_cfg;
-
-/*
- * Command to set intra-refreshing
- */
-
-
-#define VIDENC_CMD_INTRA_REFRESH_LEN \
-    sizeof(videnc_cmd_intra_refresh)
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  num_mb_refresh;
-       unsigned short  mb_index[15];
-} __attribute__((packed)) videnc_cmd_intra_refresh;
-
-/*
- * Command to pass digital zoom information to the VIDENC
- */
-#define VIDENC_CMD_DIGITAL_ZOOM_LEN \
-    sizeof(videnc_cmd_digital_zoom)
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  digital_zoom_en;
-       unsigned short  luma_frame_shift_X;
-       unsigned short  luma_frame_shift_Y;
-       unsigned short  up_ip_luma_rows;
-       unsigned short  up_ip_luma_cols;
-       unsigned short  up_ip_chroma_rows;
-       unsigned short  up_ip_chroma_cols;
-       unsigned short  luma_ph_incr_V_low;
-       unsigned short  luma_ph_incr_V_high;
-       unsigned short  luma_ph_incr_H_low;
-       unsigned short  luma_ph_incr_H_high;
-       unsigned short  chroma_ph_incr_V_low;
-       unsigned short  chroma_ph_incr_V_high;
-       unsigned short  chroma_ph_incr_H_low;
-       unsigned short  chroma_ph_incr_H_high;
-} __attribute__((packed)) videnc_cmd_digital_zoom;
-
-/*
- * Command to configure digital stabilization parameters
- */
-
-#define VIDENC_CMD_DIS_CFG_LEN \
-    sizeof(videnc_cmd_dis_cfg)
-
-typedef struct {
-       unsigned short  cmd_id;
-       unsigned short  image_stab_subf_start_row_col;
-       unsigned short  image_stab_subf_dim;
-       unsigned short  image_stab_info_0;
-} __attribute__((packed)) videnc_cmd_dis_cfg;
-
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h
deleted file mode 100644 (file)
index 55e8fc2..0000000
+++ /dev/null
@@ -1,910 +0,0 @@
-#ifndef QDSP5VFECMDI_H
-#define QDSP5VFECMDI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    V F E   I N T E R N A L   C O M M A N D S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are accepted by VFE Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfecmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
-Revision History:
-
-when       who     what, where, why
---------   ---     ----------------------------------------------------------
-06/12/08   sv      initial version
-===========================================================================*/
-
-/******************************************************************************
- * Commands through vfeCommandScaleQueue
- *****************************************************************************/
-
-/*
- * Command to program scaler for op1 . max op of scaler is VGA
- */
-
-
-#define        VFE_CMD_SCALE_OP1_CFG           0x0000
-#define        VFE_CMD_SCALE_OP1_CFG_LEN       \
-       sizeof(vfe_cmd_scale_op1_cfg)
-
-#define        VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_STANDARD 0x0000
-#define        VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_CASCADED 0x0001
-#define        VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_DIS    0x0000
-#define        VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_ENA    0x0002
-#define        VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_DIS 0x0000
-#define        VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_ENA 0x0004
-#define        VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_DIS    0x0000
-#define        VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_ENA    0x0008
-#define        VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_DIS 0x0000
-#define        VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_ENA 0x0010
-#define        VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_STANDARD      0x0000
-#define        VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_CASCADED      0x0020
-#define        VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_DIS         0x0000
-#define        VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_ENA         0x0040
-#define        VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_DIS         0x0000
-#define        VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_ENA         0x0080
-
-#define        VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS      0x80000000
-#define        VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS   0x80000000
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    scale_op1_sel;
-       unsigned int    y_scaler_cfg_part1;
-       unsigned int    y_scaler_cfg_part2;
-       unsigned int    cbcr_scaler_cfg_part1;
-       unsigned int    cbcr_scaler_cfg_part2;
-       unsigned int    cbcr_scaler_cfg_part3;
-       unsigned int    pp_y_scaler_cfg_part1;
-       unsigned int    pp_y_scaler_cfg_part2;
-       unsigned int    y_scaler_v_coeff_bank_part1[16];
-       unsigned int    y_scaler_v_coeff_bank_part2[16];
-       unsigned int    y_scaler_h_coeff_bank_part1[16];
-       unsigned int    y_scaler_h_coeff_bank_part2[16];
-} __attribute__((packed)) vfe_cmd_scale_op1_cfg;
-
-
-/*
- * Command to program scaler for op2
- */
-
-#define        VFE_CMD_SCALE_OP2_CFG           0x0001
-#define        VFE_CMD_SCALE_OP2_CFG_LEN       \
-       sizeof(vfe_cmd_scale_op2_cfg)
-
-#define        VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_STANDARD 0x0000
-#define        VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_CASCADED 0x0001
-#define        VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_DIS    0x0000
-#define        VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_ENA    0x0002
-#define        VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_DIS 0x0000
-#define        VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_ENA 0x0004
-#define        VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_DIS    0x0000
-#define        VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_ENA    0x0008
-#define        VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_DIS 0x0000
-#define        VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_ENA 0x0010
-#define        VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_STANDARD      0x0000
-#define        VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_CASCADED      0x0020
-#define        VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_DIS         0x0000
-#define        VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_ENA         0x0040
-#define        VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_DIS         0x0000
-#define        VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_ENA         0x0080
-
-#define        VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS      0x80000000
-#define        VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS           0x80000000
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    scale_op2_sel;
-       unsigned int    y_scaler_cfg_part1;
-       unsigned int    y_scaler_cfg_part2;
-       unsigned int    cbcr_scaler_cfg_part1;
-       unsigned int    cbcr_scaler_cfg_part2;
-       unsigned int    cbcr_scaler_cfg_part3;
-       unsigned int    pp_y_scaler_cfg_part1;
-       unsigned int    pp_y_scaler_cfg_part2;
-       unsigned int    y_scaler_v_coeff_bank_part1[16];
-       unsigned int    y_scaler_v_coeff_bank_part2[16];
-       unsigned int    y_scaler_h_coeff_bank_part1[16];
-       unsigned int    y_scaler_h_coeff_bank_part2[16];
-} __attribute__((packed)) vfe_cmd_scale_op2_cfg;
-
-
-/******************************************************************************
- * Commands through vfeCommandTableQueue
- *****************************************************************************/
-
-/*
- * Command to program the AXI ip paths
- */
-
-#define        VFE_CMD_AXI_IP_CFG              0x0000
-#define        VFE_CMD_AXI_IP_CFG_LEN          sizeof(vfe_cmd_axi_ip_cfg)
-
-#define        VFE_CMD_IP_SEL_IP_FORMAT_8      0x0000
-#define        VFE_CMD_IP_SEL_IP_FORMAT_10     0x0001
-#define        VFE_CMD_IP_SEL_IP_FORMAT_12     0x0002
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    ip_sel;
-       unsigned int    ip_cfg_part1;
-       unsigned int    ip_cfg_part2;
-       unsigned int    ip_unpack_cfg_part[6];
-       unsigned int    ip_buf_addr[8];
-} __attribute__ ((packed)) vfe_cmd_axi_ip_cfg;
-
-
-/*
- * Command to program axi op paths
- */
-
-#define        VFE_CMD_AXI_OP_CFG      0x0001
-#define        VFE_CMD_AXI_OP_CFG_LEN  sizeof(vfe_cmd_axi_op_cfg)
-
-#define        VFE_CMD_OP_SEL_OP1              0x0000
-#define        VFE_CMD_OP_SEL_OP2              0x0001
-#define        VFE_CMD_OP_SEL_OP1_OP2          0x0002
-#define        VFE_CMD_OP_SEL_CTOA             0x0003
-#define        VFE_CMD_OP_SEL_CTOA_OP1         0x0004
-#define        VFE_CMD_OP_SEL_CTOA_OP2         0x0005
-#define        VFE_CMD_OP_SEL_OP_FORMAT_8      0x0000
-#define        VFE_CMD_OP_SEL_OP_FORMAT_10     0x0008
-#define        VFE_CMD_OP_SEL_OP_FORMAT_12     0x0010
-
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    op_sel;
-       unsigned int    op1_y_cfg_part1;
-       unsigned int    op1_y_cfg_part2;
-       unsigned int    op1_cbcr_cfg_part1;
-       unsigned int    op1_cbcr_cfg_part2;
-       unsigned int    op2_y_cfg_part1;
-       unsigned int    op2_y_cfg_part2;
-       unsigned int    op2_cbcr_cfg_part1;
-       unsigned int    op2_cbcr_cfg_part2;
-       unsigned int    op1_buf1_addr[16];
-       unsigned int    op2_buf1_addr[16];
-} __attribute__((packed)) vfe_cmd_axi_op_cfg;
-
-
-
-
-/*
- * Command to program the roll off correction module
- */
-
-#define        VFE_CMD_ROLLOFF_CFG     0x0002
-#define        VFE_CMD_ROLLOFF_CFG_LEN \
-       sizeof(vfe_cmd_rolloff_cfg)
-
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    correction_opt_center_pos;
-       unsigned int    radius_square_entry[32];
-       unsigned int    red_table_entry[32];
-       unsigned int    green_table_entry[32];
-       unsigned int    blue_table_entry[32];
-} __attribute__((packed)) vfe_cmd_rolloff_cfg;
-
-/*
- * Command to program RGB gamma table
- */
-
-#define        VFE_CMD_RGB_GAMMA_CFG           0x0003
-#define        VFE_CMD_RGB_GAMMA_CFG_LEN       \
-       sizeof(vfe_cmd_rgb_gamma_cfg)
-
-#define        VFE_CMD_RGB_GAMMA_SEL_LINEAR            0x0000
-#define        VFE_CMD_RGB_GAMMA_SEL_PW_LINEAR         0x0001
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    rgb_gamma_sel;
-       unsigned int    rgb_gamma_entry[256];
-} __attribute__((packed)) vfe_cmd_rgb_gamma_cfg;
-
-
-/*
- * Command to program luma gamma table for the noise reduction path
- */
-
-#define        VFE_CMD_Y_GAMMA_CFG             0x0004
-#define        VFE_CMD_Y_GAMMA_CFG_LEN         \
-       sizeof(vfe_cmd_y_gamma_cfg)
-
-#define        VFE_CMD_Y_GAMMA_SEL_LINEAR      0x0000
-#define        VFE_CMD_Y_GAMMA_SEL_PW_LINEAR   0x0001
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    y_gamma_sel;
-       unsigned int    y_gamma_entry[256];
-} __attribute__((packed)) vfe_cmd_y_gamma_cfg;
-
-
-
-/******************************************************************************
- * Commands through vfeCommandQueue
- *****************************************************************************/
-
-/*
- * Command to reset the VFE to a known good state.All previously programmed
- * Params will be lost
- */
-
-
-#define        VFE_CMD_RESET           0x0000
-#define        VFE_CMD_RESET_LEN       sizeof(vfe_cmd_reset)
-
-
-typedef struct {
-       unsigned short  cmd_id;
-} __attribute__((packed)) vfe_cmd_reset;
-
-
-/*
- * Command to start VFE processing based on the config params
- */
-
-
-#define        VFE_CMD_START           0x0001
-#define        VFE_CMD_START_LEN       sizeof(vfe_cmd_start)
-
-#define        VFE_CMD_STARTUP_PARAMS_SRC_CAMIF        0x0000
-#define        VFE_CMD_STARTUP_PARAMS_SRC_AXI          0x0001
-#define        VFE_CMD_STARTUP_PARAMS_MODE_CONTINUOUS  0x0000
-#define        VFE_CMD_STARTUP_PARAMS_MODE_SNAPSHOT    0x0002
-
-#define        VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_DIS     0x0000
-#define        VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_ENA     0x0001
-#define        VFE_CMD_IMAGE_PL_ROLLOFF_CORR_DIS       0x0000
-#define        VFE_CMD_IMAGE_PL_ROLLOFF_CORR_ENA       0x0002
-#define        VFE_CMD_IMAGE_PL_WHITE_BAL_DIS          0x0000
-#define        VFE_CMD_IMAGE_PL_WHITE_BAL_ENA          0x0004
-#define        VFE_CMD_IMAGE_PL_RGB_GAMMA_DIS          0x0000
-#define        VFE_CMD_IMAGE_PL_RGB_GAMMA_ENA          0x0008
-#define        VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_DIS        0x0000
-#define        VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_ENA        0x0010
-#define        VFE_CMD_IMAGE_PL_ADP_FILTER_DIS         0x0000
-#define        VFE_CMD_IMAGE_PL_ADP_FILTER_ENA         0x0020
-#define        VFE_CMD_IMAGE_PL_CHROMA_SAMP_DIS        0x0000
-#define        VFE_CMD_IMAGE_PL_CHROMA_SAMP_ENA        0x0040
-
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    startup_params;
-       unsigned int    image_pipeline;
-       unsigned int    frame_dimension;
-} __attribute__((packed)) vfe_cmd_start;
-
-
-/*
- * Command to halt all processing
- */
-
-#define        VFE_CMD_STOP            0x0002
-#define        VFE_CMD_STOP_LEN        sizeof(vfe_cmd_stop)
-
-typedef struct {
-       unsigned short  cmd_id;
-} __attribute__((packed)) vfe_cmd_stop;
-
-
-/*
- * Command to commit the params that have been programmed to take
- * effect on the next frame
- */
-
-#define        VFE_CMD_UPDATE          0x0003
-#define        VFE_CMD_UPDATE_LEN      sizeof(vfe_cmd_update)
-
-
-typedef struct {
-       unsigned short  cmd_id;
-} __attribute__((packed)) vfe_cmd_update;
-
-
-/*
- * Command to program CAMIF module
- */
-
-#define        VFE_CMD_CAMIF_CFG       0x0004
-#define        VFE_CMD_CAMIF_CFG_LEN   sizeof(vfe_cmd_camif_cfg)
-
-#define        VFE_CMD_CFG_VSYNC_SYNC_EDGE_HIGH        0x0000
-#define        VFE_CMD_CFG_VSYNC_SYNC_EDGE_LOW         0x0002
-#define        VFE_CMD_CFG_HSYNC_SYNC_EDGE_HIGH        0x0000
-#define        VFE_CMD_CFG_HSYNC_SYNC_EDGE_LOW         0x0004
-#define        VFE_CMD_CFG_SYNC_MODE_APS               0x0000
-#define        VFE_CMD_CFG_SYNC_MODE_EFS               0X0008
-#define        VFE_CMD_CFG_SYNC_MODE_ELS               0x0010
-#define        VFE_CMD_CFG_SYNC_MODE_RVD               0x0018
-#define        VFE_CMD_CFG_VFE_SUBSAMP_EN_DIS          0x0000
-#define        VFE_CMD_CFG_VFE_SUBSAMP_EN_ENA          0x0020
-#define        VFE_CMD_CFG_BUS_SUBSAMP_EN_DIS          0x0000
-#define        VFE_CMD_CFG_BUS_SUBSAMP_EN_ENA          0x0080
-#define        VFE_CMD_CFG_IRQ_SUBSAMP_EN_DIS          0x0000
-#define        VFE_CMD_CFG_IRQ_SUBSAMP_EN_ENA          0x0800
-
-#define        VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_16      0x0000
-#define        VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_12      0x0010
-
-#define        VFE_CMD_EPOCH_IRQ_1_DIS                 0x0000
-#define        VFE_CMD_EPOCH_IRQ_1_ENA                 0x4000
-#define        VFE_CMD_EPOCH_IRQ_2_DIS                 0x0000
-#define        VFE_CMD_EPOCH_IRQ_2_ENA                 0x8000
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    cfg;
-       unsigned int    efs_cfg;
-       unsigned int    frame_cfg;
-       unsigned int    window_width_cfg;
-       unsigned int    window_height_cfg;
-       unsigned int    subsamp1_cfg;
-       unsigned int    subsamp2_cfg;
-       unsigned int    epoch_irq;
-} __attribute__((packed)) vfe_cmd_camif_cfg;
-
-
-
-/*
- * Command to program the black level module
- */
-
-#define        VFE_CMD_BLACK_LVL_CFG           0x0005
-#define        VFE_CMD_BLACK_LVL_CFG_LEN       sizeof(vfe_cmd_black_lvl_cfg)
-
-#define        VFE_CMD_BL_SEL_MANUAL           0x0000
-#define        VFE_CMD_BL_SEL_AUTO             0x0001
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    black_lvl_sel;
-       unsigned int    cfg_part[3];
-} __attribute__((packed)) vfe_cmd_black_lvl_cfg;
-
-
-/*
- * Command to program the active region by cropping the region of interest
- */
-
-#define        VFE_CMD_ACTIVE_REGION_CFG       0x0006
-#define        VFE_CMD_ACTIVE_REGION_CFG_LEN   \
-       sizeof(vfe_cmd_active_region_cfg)
-
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    cfg_part1;
-       unsigned int    cfg_part2;
-} __attribute__((packed)) vfe_cmd_active_region_cfg;
-
-
-
-/*
- * Command to program the defective pixel correction(DPC) ,
- * adaptive bayer filter (ABF) and demosaic modules
- */
-
-#define        VFE_CMD_DEMOSAIC_CFG            0x0007
-#define        VFE_CMD_DEMOSAIC_CFG_LEN        sizeof(vfe_cmd_demosaic_cfg)
-
-#define        VFE_CMD_DEMOSAIC_PART1_ABF_EN_DIS       0x0000
-#define        VFE_CMD_DEMOSAIC_PART1_ABF_EN_ENA       0x0001
-#define        VFE_CMD_DEMOSAIC_PART1_DPC_EN_DIS       0x0000
-#define        VFE_CMD_DEMOSAIC_PART1_DPC_EN_ENA       0x0002
-#define        VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_OFF    0x0000
-#define        VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_ON     0x0004
-#define        VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1    0x00000000
-#define        VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_2    0x10000000
-#define        VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_4    0x20000000
-#define        VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_8    0x30000000
-#define        VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_2  0x50000000
-#define        VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_4  0x60000000
-#define        VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_8  0x70000000
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    demosaic_part1;
-       unsigned int    demosaic_part2;
-       unsigned int    demosaic_part3;
-       unsigned int    demosaic_part4;
-       unsigned int    demosaic_part5;
-} __attribute__((packed)) vfe_cmd_demosaic_cfg;
-
-
-/*
- * Command to program the ip format
- */
-
-#define        VFE_CMD_IP_FORMAT_CFG           0x0008
-#define        VFE_CMD_IP_FORMAT_CFG_LEN       \
-       sizeof(vfe_cmd_ip_format_cfg)
-
-#define        VFE_CMD_IP_FORMAT_SEL_RGRG      0x0000
-#define        VFE_CMD_IP_FORMAT_SEL_GRGR      0x0001
-#define        VFE_CMD_IP_FORMAT_SEL_BGBG      0x0002
-#define        VFE_CMD_IP_FORMAT_SEL_GBGB      0x0003
-#define        VFE_CMD_IP_FORMAT_SEL_YCBYCR    0x0004
-#define        VFE_CMD_IP_FORMAT_SEL_YCRYCB    0x0005
-#define        VFE_CMD_IP_FORMAT_SEL_CBYCRY    0x0006
-#define        VFE_CMD_IP_FORMAT_SEL_CRYCBY    0x0007
-#define        VFE_CMD_IP_FORMAT_SEL_NO_CHROMA 0x0000
-#define        VFE_CMD_IP_FORMAT_SEL_CHROMA    0x0008
-
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    ip_format_sel;
-       unsigned int    balance_gains_part1;
-       unsigned int    balance_gains_part2;
-} __attribute__((packed)) vfe_cmd_ip_format_cfg;
-
-
-
-/*
- * Command to program max and min allowed op values
- */
-
-#define        VFE_CMD_OP_CLAMP_CFG            0x0009
-#define        VFE_CMD_OP_CLAMP_CFG_LEN        \
-       sizeof(vfe_cmd_op_clamp_cfg)
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    op_clamp_max;
-       unsigned int    op_clamp_min;
-} __attribute__((packed)) vfe_cmd_op_clamp_cfg;
-
-
-/*
- * Command to program chroma sub sample module
- */
-
-#define        VFE_CMD_CHROMA_SUBSAMPLE_CFG            0x000A
-#define        VFE_CMD_CHROMA_SUBSAMPLE_CFG_LEN        \
-       sizeof(vfe_cmd_chroma_subsample_cfg)
-
-#define        VFE_CMD_CHROMA_SUBSAMP_SEL_H_INTERESTIAL_SAMPS  0x0000
-#define        VFE_CMD_CHROMA_SUBSAMP_SEL_H_COSITED_SAMPS      0x0001
-#define        VFE_CMD_CHROMA_SUBSAMP_SEL_V_INTERESTIAL_SAMPS  0x0000
-#define        VFE_CMD_CHROMA_SUBSAMP_SEL_V_COSITED_SAMPS      0x0002
-#define        VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_DIS        0x0000
-#define        VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_ENA        0x0004
-#define        VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_DIS        0x0000
-#define        VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_ENA        0x0008
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    chroma_subsamp_sel;
-} __attribute__((packed)) vfe_cmd_chroma_subsample_cfg;
-
-
-/*
- * Command to program the white balance module
- */
-
-#define        VFE_CMD_WHITE_BALANCE_CFG       0x000B
-#define        VFE_CMD_WHITE_BALANCE_CFG_LEN   \
-       sizeof(vfe_cmd_white_balance_cfg)
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    white_balance_gains;
-} __attribute__((packed)) vfe_cmd_white_balance_cfg;
-
-
-/*
- * Command to program the color processing module
- */
-
-#define        VFE_CMD_COLOR_PROCESS_CFG       0x000C
-#define        VFE_CMD_COLOR_PROCESS_CFG_LEN   \
-       sizeof(vfe_cmd_color_process_cfg)
-
-#define        VFE_CMD_COLOR_CORRE_PART7_Q7_FACTORS    0x0000
-#define        VFE_CMD_COLOR_CORRE_PART7_Q8_FACTORS    0x0001
-#define        VFE_CMD_COLOR_CORRE_PART7_Q9_FACTORS    0x0002
-#define        VFE_CMD_COLOR_CORRE_PART7_Q10_FACTORS   0x0003
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    color_correction_part1;
-       unsigned int    color_correction_part2;
-       unsigned int    color_correction_part3;
-       unsigned int    color_correction_part4;
-       unsigned int    color_correction_part5;
-       unsigned int    color_correction_part6;
-       unsigned int    color_correction_part7;
-       unsigned int    chroma_enhance_part1;
-       unsigned int    chroma_enhance_part2;
-       unsigned int    chroma_enhance_part3;
-       unsigned int    chroma_enhance_part4;
-       unsigned int    chroma_enhance_part5;
-       unsigned int    luma_calc_part1;
-       unsigned int    luma_calc_part2;
-} __attribute__((packed)) vfe_cmd_color_process_cfg;
-
-
-/*
- * Command to program adaptive filter module
- */
-
-#define        VFE_CMD_ADP_FILTER_CFG          0x000D
-#define        VFE_CMD_ADP_FILTER_CFG_LEN      \
-       sizeof(vfe_cmd_adp_filter_cfg)
-
-#define        VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_DIS          0x0000
-#define        VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_ENA          0x0001
-#define        VFE_CMD_ASF_CFG_PART_NO_SHARP_MODE              0x0000
-#define        VFE_CMD_ASF_CFG_PART_SINGLE_FILTER              0x0002
-#define        VFE_CMD_ASF_CFG_PART_DUAL_FILTER                0x0004
-#define        VFE_CMD_ASF_CFG_PART_SHARP_MODE                 0x0007
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    asf_cfg_part[7];
-} __attribute__((packed)) vfe_cmd_adp_filter_cfg;
-
-
-/*
- * Command to program for frame skip pattern for op1 and op2
- */
-
-#define        VFE_CMD_FRAME_SKIP_CFG          0x000E
-#define        VFE_CMD_FRAME_SKIP_CFG_LEN      \
-       sizeof(vfe_cmd_frame_skip_cfg)
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    frame_skip_pattern_op1;
-       unsigned int    frame_skip_pattern_op2;
-} __attribute__((packed)) vfe_cmd_frame_skip_cfg;
-
-
-/*
- * Command to program field-of-view crop for digital zoom
- */
-
-#define        VFE_CMD_FOV_CROP        0x000F
-#define        VFE_CMD_FOV_CROP_LEN    sizeof(vfe_cmd_fov_crop)
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    fov_crop_part1;
-       unsigned int    fov_crop_part2;
-} __attribute__((packed)) vfe_cmd_fov_crop;
-
-
-
-/*
- * Command to program auto focus(AF) statistics module
- */
-
-#define        VFE_CMD_STATS_AUTOFOCUS_CFG     0x0010
-#define        VFE_CMD_STATS_AUTOFOCUS_CFG_LEN \
-       sizeof(vfe_cmd_stats_autofocus_cfg)
-
-#define        VFE_CMD_AF_STATS_SEL_STATS_DIS  0x0000
-#define        VFE_CMD_AF_STATS_SEL_STATS_ENA  0x0001
-#define        VFE_CMD_AF_STATS_SEL_PRI_FIXED  0x0000
-#define        VFE_CMD_AF_STATS_SEL_PRI_VAR    0x0002
-#define        VFE_CMD_AF_STATS_CFG_PART_METRIC_SUM    0x00000000
-#define        VFE_CMD_AF_STATS_CFG_PART_METRIC_MAX    0x00200000
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    af_stats_sel;
-       unsigned int    af_stats_cfg_part[8];
-       unsigned int    af_stats_op_buf_hdr;
-       unsigned int    af_stats_op_buf[3];
-} __attribute__((packed)) vfe_cmd_stats_autofocus_cfg;
-
-
-/*
- * Command to program White balance(wb) and exposure (exp)
- * statistics module
- */
-
-#define        VFE_CMD_STATS_WB_EXP_CFG        0x0011
-#define        VFE_CMD_STATS_WB_EXP_CFG_LEN    \
-       sizeof(vfe_cmd_stats_wb_exp_cfg)
-
-#define        VFE_CMD_WB_EXP_STATS_SEL_STATS_DIS      0x0000
-#define        VFE_CMD_WB_EXP_STATS_SEL_STATS_ENA      0x0001
-#define        VFE_CMD_WB_EXP_STATS_SEL_PRI_FIXED      0x0000
-#define        VFE_CMD_WB_EXP_STATS_SEL_PRI_VAR        0x0002
-
-#define        VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_8_8      0x0000
-#define        VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_16_16    0x0001
-#define        VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_8_8     0x0000
-#define        VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_4_4     0x0002
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    wb_exp_stats_sel;
-       unsigned int    wb_exp_stats_cfg_part1;
-       unsigned int    wb_exp_stats_cfg_part2;
-       unsigned int    wb_exp_stats_cfg_part3;
-       unsigned int    wb_exp_stats_cfg_part4;
-       unsigned int    wb_exp_stats_op_buf_hdr;
-       unsigned int    wb_exp_stats_op_buf[3];
-} __attribute__((packed)) vfe_cmd_stats_wb_exp_cfg;
-
-
-/*
- * Command to program histogram(hg) stats module
- */
-
-#define        VFE_CMD_STATS_HG_CFG            0x0012
-#define        VFE_CMD_STATS_HG_CFG_LEN        \
-       sizeof(vfe_cmd_stats_hg_cfg)
-
-#define        VFE_CMD_HG_STATS_SEL_PRI_FIXED  0x0000
-#define        VFE_CMD_HG_STATS_SEL_PRI_VAR    0x0002
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    hg_stats_sel;
-       unsigned int    hg_stats_cfg_part1;
-       unsigned int    hg_stats_cfg_part2;
-       unsigned int    hg_stats_op_buf_hdr;
-       unsigned int    hg_stats_op_buf;
-} __attribute__((packed)) vfe_cmd_stats_hg_cfg;
-
-
-/*
- * Command to acknowledge last MSG_VFE_OP1 message
- */
-
-#define        VFE_CMD_OP1_ACK         0x0013
-#define        VFE_CMD_OP1_ACK_LEN     sizeof(vfe_cmd_op1_ack)
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    op1_buf_y_addr;
-       unsigned int    op1_buf_cbcr_addr;
-} __attribute__((packed)) vfe_cmd_op1_ack;
-
-
-
-/*
- * Command to acknowledge last MSG_VFE_OP2 message
- */
-
-#define        VFE_CMD_OP2_ACK         0x0014
-#define        VFE_CMD_OP2_ACK_LEN     sizeof(vfe_cmd_op2_ack)
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    op2_buf_y_addr;
-       unsigned int    op2_buf_cbcr_addr;
-} __attribute__((packed)) vfe_cmd_op2_ack;
-
-
-
-/*
- * Command to acknowledge MSG_VFE_STATS_AUTOFOCUS msg
- */
-
-#define        VFE_CMD_STATS_AF_ACK            0x0015
-#define        VFE_CMD_STATS_AF_ACK_LEN        sizeof(vfe_cmd_stats_af_ack)
-
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    af_stats_op_buf;
-} __attribute__((packed)) vfe_cmd_stats_af_ack;
-
-
-/*
- * Command to acknowledge MSG_VFE_STATS_WB_EXP msg
- */
-
-#define        VFE_CMD_STATS_WB_EXP_ACK        0x0016
-#define        VFE_CMD_STATS_WB_EXP_ACK_LEN    sizeof(vfe_cmd_stats_wb_exp_ack)
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    wb_exp_stats_op_buf;
-} __attribute__((packed)) vfe_cmd_stats_wb_exp_ack;
-
-
-/*
- * Command to acknowledge MSG_VFE_EPOCH1 message
- */
-
-#define        VFE_CMD_EPOCH1_ACK      0x0017
-#define        VFE_CMD_EPOCH1_ACK_LEN  sizeof(vfe_cmd_epoch1_ack)
-
-typedef struct {
-       unsigned short cmd_id;
-} __attribute__((packed)) vfe_cmd_epoch1_ack;
-
-
-/*
- * Command to acknowledge MSG_VFE_EPOCH2 message
- */
-
-#define        VFE_CMD_EPOCH2_ACK      0x0018
-#define        VFE_CMD_EPOCH2_ACK_LEN  sizeof(vfe_cmd_epoch2_ack)
-
-typedef struct {
-       unsigned short cmd_id;
-} __attribute__((packed)) vfe_cmd_epoch2_ack;
-
-
-
-/*
- * Command to configure, enable or disable synchronous timer1
- */
-
-#define        VFE_CMD_SYNC_TIMER1_CFG         0x0019
-#define        VFE_CMD_SYNC_TIMER1_CFG_LEN     \
-       sizeof(vfe_cmd_sync_timer1_cfg)
-
-#define        VFE_CMD_SYNC_T1_CFG_PART1_TIMER_DIS     0x0000
-#define        VFE_CMD_SYNC_T1_CFG_PART1_TIMER_ENA     0x0001
-#define        VFE_CMD_SYNC_T1_CFG_PART1_POL_HIGH      0x0000
-#define        VFE_CMD_SYNC_T1_CFG_PART1_POL_LOW       0x0002
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    sync_t1_cfg_part1;
-       unsigned int    sync_t1_h_sync_countdown;
-       unsigned int    sync_t1_pclk_countdown;
-       unsigned int    sync_t1_duration;
-} __attribute__((packed)) vfe_cmd_sync_timer1_cfg;
-
-
-/*
- * Command to configure, enable or disable synchronous timer1
- */
-
-#define        VFE_CMD_SYNC_TIMER2_CFG         0x001A
-#define        VFE_CMD_SYNC_TIMER2_CFG_LEN     \
-       sizeof(vfe_cmd_sync_timer2_cfg)
-
-#define        VFE_CMD_SYNC_T2_CFG_PART1_TIMER_DIS     0x0000
-#define        VFE_CMD_SYNC_T2_CFG_PART1_TIMER_ENA     0x0001
-#define        VFE_CMD_SYNC_T2_CFG_PART1_POL_HIGH      0x0000
-#define        VFE_CMD_SYNC_T2_CFG_PART1_POL_LOW       0x0002
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    sync_t2_cfg_part1;
-       unsigned int    sync_t2_h_sync_countdown;
-       unsigned int    sync_t2_pclk_countdown;
-       unsigned int    sync_t2_duration;
-} __attribute__((packed)) vfe_cmd_sync_timer2_cfg;
-
-
-/*
- * Command to configure and start asynchronous timer1
- */
-
-#define        VFE_CMD_ASYNC_TIMER1_START      0x001B
-#define        VFE_CMD_ASYNC_TIMER1_START_LEN  \
-       sizeof(vfe_cmd_async_timer1_start)
-
-#define        VFE_CMD_ASYNC_T1_POLARITY_A_HIGH        0x0000
-#define        VFE_CMD_ASYNC_T1_POLARITY_A_LOW         0x0001
-#define        VFE_CMD_ASYNC_T1_POLARITY_B_HIGH        0x0000
-#define        VFE_CMD_ASYNC_T1_POLARITY_B_LOW         0x0002
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    async_t1a_cfg;
-       unsigned int    async_t1b_cfg;
-       unsigned int    async_t1_polarity;
-} __attribute__((packed)) vfe_cmd_async_timer1_start;
-
-
-/*
- * Command to configure and start asynchronous timer2
- */
-
-#define        VFE_CMD_ASYNC_TIMER2_START      0x001C
-#define        VFE_CMD_ASYNC_TIMER2_START_LEN  \
-       sizeof(vfe_cmd_async_timer2_start)
-
-#define        VFE_CMD_ASYNC_T2_POLARITY_A_HIGH        0x0000
-#define        VFE_CMD_ASYNC_T2_POLARITY_A_LOW         0x0001
-#define        VFE_CMD_ASYNC_T2_POLARITY_B_HIGH        0x0000
-#define        VFE_CMD_ASYNC_T2_POLARITY_B_LOW         0x0002
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    async_t2a_cfg;
-       unsigned int    async_t2b_cfg;
-       unsigned int    async_t2_polarity;
-} __attribute__((packed)) vfe_cmd_async_timer2_start;
-
-
-/*
- * Command to program partial configurations of auto focus(af)
- */
-
-#define        VFE_CMD_STATS_AF_UPDATE         0x001D
-#define        VFE_CMD_STATS_AF_UPDATE_LEN     \
-       sizeof(vfe_cmd_stats_af_update)
-
-#define        VFE_CMD_AF_UPDATE_PART1_WINDOW_ONE      0x00000000
-#define        VFE_CMD_AF_UPDATE_PART1_WINDOW_MULTI    0x80000000
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    af_update_part1;
-       unsigned int    af_update_part2;
-} __attribute__((packed)) vfe_cmd_stats_af_update;
-
-
-/*
- * Command to program partial cfg of wb and exp
- */
-
-#define        VFE_CMD_STATS_WB_EXP_UPDATE     0x001E
-#define        VFE_CMD_STATS_WB_EXP_UPDATE_LEN \
-       sizeof(vfe_cmd_stats_wb_exp_update)
-
-#define        VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_8_8         0x0000
-#define        VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_16_16       0x0001
-#define        VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_8_8        0x0000
-#define        VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_4_4        0x0002
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    wb_exp_update_part1;
-       unsigned int    wb_exp_update_part2;
-       unsigned int    wb_exp_update_part3;
-       unsigned int    wb_exp_update_part4;
-} __attribute__((packed)) vfe_cmd_stats_wb_exp_update;
-
-
-
-/*
- * Command to re program the CAMIF FRAME CONFIG settings
- */
-
-#define        VFE_CMD_UPDATE_CAMIF_FRAME_CFG          0x001F
-#define        VFE_CMD_UPDATE_CAMIF_FRAME_CFG_LEN      \
-       sizeof(vfe_cmd_update_camif_frame_cfg)
-
-typedef struct {
-       unsigned int    cmd_id;
-       unsigned int    camif_frame_cfg;
-} __attribute__((packed)) vfe_cmd_update_camif_frame_cfg;
-
-
-#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h
deleted file mode 100644 (file)
index 0053cfb..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-#ifndef QDSP5VFEMSGI_H
-#define QDSP5VFEMSGI_H
-
-/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
-
-    V F E   I N T E R N A L   M E S S A G E S
-
-GENERAL DESCRIPTION
-  This file contains defintions of format blocks of commands
-  that are sent by VFE Task
-
-REFERENCES
-  None
-
-EXTERNALIZED FUNCTIONS
-  None
-
-Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
-
-This software is licensed under the terms of the GNU General Public
-License version 2, as published by the Free Software Foundation, and
-may be copied, distributed, and modified under those terms.
-
-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.
-
-*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
-/*===========================================================================
-
-                      EDIT HISTORY FOR FILE
-
-This section contains comments describing changes made to this file.
-Notice that changes are listed in reverse chronological order.
-
-$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfemsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
-Revision History:
-
-when       who     what, where, why
---------   ---     ----------------------------------------------------------
-06/12/08   sv      initial version
-===========================================================================*/
-
-
-/*
- * Message to acknowledge CMD_VFE_REST command
- */
-
-#define        VFE_MSG_RESET_ACK       0x0000
-#define        VFE_MSG_RESET_ACK_LEN   sizeof(vfe_msg_reset_ack)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_reset_ack;
-
-
-/*
- * Message to acknowledge CMD_VFE_START command
- */
-
-#define        VFE_MSG_START_ACK       0x0001
-#define        VFE_MSG_START_ACK_LEN   sizeof(vfe_msg_start_ack)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_start_ack;
-
-/*
- * Message to acknowledge CMD_VFE_STOP command
- */
-
-#define        VFE_MSG_STOP_ACK        0x0002
-#define        VFE_MSG_STOP_ACK_LEN    sizeof(vfe_msg_stop_ack)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_stop_ack;
-
-
-/*
- * Message to acknowledge CMD_VFE_UPDATE command
- */
-
-#define        VFE_MSG_UPDATE_ACK      0x0003
-#define        VFE_MSG_UPDATE_ACK_LEN  sizeof(vfe_msg_update_ack)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_update_ack;
-
-
-/*
- * Message to notify the ARM that snapshot processing is complete
- * and that the VFE is now STATE_VFE_IDLE
- */
-
-#define        VFE_MSG_SNAPSHOT_DONE           0x0004
-#define        VFE_MSG_SNAPSHOT_DONE_LEN       \
-       sizeof(vfe_msg_snapshot_done)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_snapshot_done;
-
-
-
-/*
- * Message to notify ARM that illegal cmd was received and
- * system is in the IDLE state
- */
-
-#define        VFE_MSG_ILLEGAL_CMD     0x0005
-#define        VFE_MSG_ILLEGAL_CMD_LEN \
-       sizeof(vfe_msg_illegal_cmd)
-
-typedef struct {
-       unsigned int    status;
-} __attribute__((packed)) vfe_msg_illegal_cmd;
-
-
-/*
- * Message to notify ARM that op1 buf is full and ready
- */
-
-#define        VFE_MSG_OP1             0x0006
-#define        VFE_MSG_OP1_LEN         sizeof(vfe_msg_op1)
-
-typedef struct {
-       unsigned int    op1_buf_y_addr;
-       unsigned int    op1_buf_cbcr_addr;
-       unsigned int    black_level_even_col;
-       unsigned int    black_level_odd_col;
-       unsigned int    defect_pixels_detected;
-       unsigned int    asf_max_edge;
-} __attribute__((packed)) vfe_msg_op1;
-
-
-/*
- * Message to notify ARM that op2 buf is full and ready
- */
-
-#define        VFE_MSG_OP2             0x0007
-#define        VFE_MSG_OP2_LEN         sizeof(vfe_msg_op2)
-
-typedef struct {
-       unsigned int    op2_buf_y_addr;
-       unsigned int    op2_buf_cbcr_addr;
-       unsigned int    black_level_even_col;
-       unsigned int    black_level_odd_col;
-       unsigned int    defect_pixels_detected;
-       unsigned int    asf_max_edge;
-} __attribute__((packed)) vfe_msg_op2;
-
-
-/*
- * Message to notify ARM that autofocus(af) stats are ready
- */
-
-#define        VFE_MSG_STATS_AF        0x0008
-#define        VFE_MSG_STATS_AF_LEN    sizeof(vfe_msg_stats_af)
-
-typedef struct {
-       unsigned int    af_stats_op_buffer;
-} __attribute__((packed)) vfe_msg_stats_af;
-
-
-/*
- * Message to notify ARM that white balance(wb) and exposure (exp)
- * stats are ready
- */
-
-#define        VFE_MSG_STATS_WB_EXP            0x0009
-#define        VFE_MSG_STATS_WB_EXP_LEN        \
-       sizeof(vfe_msg_stats_wb_exp)
-
-typedef struct {
-       unsigned int    wb_exp_stats_op_buf;
-} __attribute__((packed)) vfe_msg_stats_wb_exp;
-
-
-/*
- * Message to notify the ARM that histogram(hg) stats are ready
- */
-
-#define        VFE_MSG_STATS_HG        0x000A
-#define        VFE_MSG_STATS_HG_LEN    sizeof(vfe_msg_stats_hg)
-
-typedef struct {
-       unsigned int    hg_stats_op_buf;
-} __attribute__((packed)) vfe_msg_stats_hg;
-
-
-/*
- * Message to notify the ARM that epoch1 event occurred in the CAMIF
- */
-
-#define        VFE_MSG_EPOCH1          0x000B
-#define        VFE_MSG_EPOCH1_LEN      sizeof(vfe_msg_epoch1)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_epoch1;
-
-
-/*
- * Message to notify the ARM that epoch2 event occurred in the CAMIF
- */
-
-#define        VFE_MSG_EPOCH2          0x000C
-#define        VFE_MSG_EPOCH2_LEN      sizeof(vfe_msg_epoch2)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_epoch2;
-
-
-/*
- * Message to notify the ARM that sync timer1 op is completed
- */
-
-#define        VFE_MSG_SYNC_T1_DONE            0x000D
-#define        VFE_MSG_SYNC_T1_DONE_LEN        sizeof(vfe_msg_sync_t1_done)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_sync_t1_done;
-
-
-/*
- * Message to notify the ARM that sync timer2 op is completed
- */
-
-#define        VFE_MSG_SYNC_T2_DONE            0x000E
-#define        VFE_MSG_SYNC_T2_DONE_LEN        sizeof(vfe_msg_sync_t2_done)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_sync_t2_done;
-
-
-/*
- * Message to notify the ARM that async t1 operation completed
- */
-
-#define        VFE_MSG_ASYNC_T1_DONE           0x000F
-#define        VFE_MSG_ASYNC_T1_DONE_LEN       sizeof(vfe_msg_async_t1_done)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_async_t1_done;
-
-
-
-/*
- * Message to notify the ARM that async t2 operation completed
- */
-
-#define        VFE_MSG_ASYNC_T2_DONE           0x0010
-#define        VFE_MSG_ASYNC_T2_DONE_LEN       sizeof(vfe_msg_async_t2_done)
-
-typedef struct {
-} __attribute__((packed)) vfe_msg_async_t2_done;
-
-
-
-/*
- * Message to notify the ARM that an error has occurred
- */
-
-#define        VFE_MSG_ERROR           0x0011
-#define        VFE_MSG_ERROR_LEN       sizeof(vfe_msg_error)
-
-#define        VFE_MSG_ERR_COND_NO_CAMIF_ERR           0x0000
-#define        VFE_MSG_ERR_COND_CAMIF_ERR              0x0001
-#define        VFE_MSG_ERR_COND_OP1_Y_NO_BUS_OF        0x0000
-#define        VFE_MSG_ERR_COND_OP1_Y_BUS_OF           0x0002
-#define        VFE_MSG_ERR_COND_OP1_CBCR_NO_BUS_OF     0x0000
-#define        VFE_MSG_ERR_COND_OP1_CBCR_BUS_OF        0x0004
-#define        VFE_MSG_ERR_COND_OP2_Y_NO_BUS_OF        0x0000
-#define        VFE_MSG_ERR_COND_OP2_Y_BUS_OF           0x0008
-#define        VFE_MSG_ERR_COND_OP2_CBCR_NO_BUS_OF     0x0000
-#define        VFE_MSG_ERR_COND_OP2_CBCR_BUS_OF        0x0010
-#define        VFE_MSG_ERR_COND_AF_NO_BUS_OF           0x0000
-#define        VFE_MSG_ERR_COND_AF_BUS_OF              0x0020
-#define        VFE_MSG_ERR_COND_WB_EXP_NO_BUS_OF       0x0000
-#define        VFE_MSG_ERR_COND_WB_EXP_BUS_OF          0x0040
-#define        VFE_MSG_ERR_COND_NO_AXI_ERR             0x0000
-#define        VFE_MSG_ERR_COND_AXI_ERR                0x0080
-
-#define        VFE_MSG_CAMIF_STS_IDLE                  0x0000
-#define        VFE_MSG_CAMIF_STS_CAPTURE_DATA          0x0001
-
-typedef struct {
-       unsigned int    err_cond;
-       unsigned int    camif_sts;
-} __attribute__((packed)) vfe_msg_error;
-
-
-#endif
diff --git a/drivers/staging/dream/include/media/msm_camera.h b/drivers/staging/dream/include/media/msm_camera.h
deleted file mode 100644 (file)
index 09812d6..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2008-2009 QUALCOMM Incorporated.
- */
-#ifndef __LINUX_MSM_CAMERA_H
-#define __LINUX_MSM_CAMERA_H
-
-#include <linux/types.h>
-#include <asm/sizes.h>
-#include <linux/ioctl.h>
-
-#define MSM_CAM_IOCTL_MAGIC 'm'
-
-#define MSM_CAM_IOCTL_GET_SENSOR_INFO \
-       _IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *)
-
-#define MSM_CAM_IOCTL_REGISTER_PMEM \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *)
-
-#define MSM_CAM_IOCTL_UNREGISTER_PMEM \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned)
-
-#define MSM_CAM_IOCTL_CTRL_COMMAND \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *)
-
-#define MSM_CAM_IOCTL_CONFIG_VFE  \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *)
-
-#define MSM_CAM_IOCTL_GET_STATS \
-       _IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *)
-
-#define MSM_CAM_IOCTL_GETFRAME \
-       _IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *)
-
-#define MSM_CAM_IOCTL_ENABLE_VFE \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *)
-
-#define MSM_CAM_IOCTL_CTRL_CMD_DONE \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *)
-
-#define MSM_CAM_IOCTL_CONFIG_CMD \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *)
-
-#define MSM_CAM_IOCTL_DISABLE_VFE \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *)
-
-#define MSM_CAM_IOCTL_PAD_REG_RESET2 \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *)
-
-#define MSM_CAM_IOCTL_VFE_APPS_RESET \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *)
-
-#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *)
-
-#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *)
-
-#define MSM_CAM_IOCTL_AXI_CONFIG \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *)
-
-#define MSM_CAM_IOCTL_GET_PICTURE \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_camera_ctrl_cmd *)
-
-#define MSM_CAM_IOCTL_SET_CROP \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *)
-
-#define MSM_CAM_IOCTL_PICT_PP \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *)
-
-#define MSM_CAM_IOCTL_PICT_PP_DONE \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *)
-
-#define MSM_CAM_IOCTL_SENSOR_IO_CFG \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *)
-
-#define MSM_CAMERA_LED_OFF  0
-#define MSM_CAMERA_LED_LOW  1
-#define MSM_CAMERA_LED_HIGH 2
-
-#define MSM_CAM_IOCTL_FLASH_LED_CFG \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *)
-
-#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \
-       _IO(MSM_CAM_IOCTL_MAGIC, 23)
-
-#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \
-       _IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *)
-
-#define MAX_SENSOR_NUM  3
-#define MAX_SENSOR_NAME 32
-
-#define MSM_CAM_CTRL_CMD_DONE  0
-#define MSM_CAM_SENSOR_VFE_CMD 1
-
-/*****************************************************
- *  structure
- *****************************************************/
-
-/* define five type of structures for userspace <==> kernel
- * space communication:
- * command 1 - 2 are from userspace ==> kernel
- * command 3 - 4 are from kernel ==> userspace
- *
- * 1. control command: control command(from control thread),
- *                     control status (from config thread);
- */
-struct msm_ctrl_cmd {
-       uint16_t type;
-       uint16_t length;
-       void *value;
-       uint16_t status;
-       uint32_t timeout_ms;
-       int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */
-};
-
-struct msm_vfe_evt_msg {
-       unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */
-       unsigned short msg_id;
-       unsigned int len; /* size in, number of bytes out */
-       void *data;
-};
-
-#define MSM_CAM_RESP_CTRL         0
-#define MSM_CAM_RESP_STAT_EVT_MSG 1
-#define MSM_CAM_RESP_V4L2         2
-#define MSM_CAM_RESP_MAX          3
-
-/* this one is used to send ctrl/status up to config thread */
-struct msm_stats_event_ctrl {
-       /* 0 - ctrl_cmd from control thread,
-        * 1 - stats/event kernel,
-        * 2 - V4L control or read request */
-       int resptype;
-       int timeout_ms;
-       struct msm_ctrl_cmd ctrl_cmd;
-       /* struct  vfe_event_t  stats_event; */
-       struct msm_vfe_evt_msg stats_event;
-};
-
-/* 2. config command: config command(from config thread); */
-struct msm_camera_cfg_cmd {
-       /* what to config:
-        * 1 - sensor config, 2 - vfe config */
-       uint16_t cfg_type;
-
-       /* sensor config type */
-       uint16_t cmd_type;
-       uint16_t queue;
-       uint16_t length;
-       void *value;
-};
-
-#define CMD_GENERAL                    0
-#define CMD_AXI_CFG_OUT1               1
-#define CMD_AXI_CFG_SNAP_O1_AND_O2     2
-#define CMD_AXI_CFG_OUT2               3
-#define CMD_PICT_T_AXI_CFG             4
-#define CMD_PICT_M_AXI_CFG             5
-#define CMD_RAW_PICT_AXI_CFG           6
-#define CMD_STATS_AXI_CFG              7
-#define CMD_STATS_AF_AXI_CFG           8
-#define CMD_FRAME_BUF_RELEASE          9
-#define CMD_PREV_BUF_CFG               10
-#define CMD_SNAP_BUF_RELEASE           11
-#define CMD_SNAP_BUF_CFG               12
-#define CMD_STATS_DISABLE              13
-#define CMD_STATS_ENABLE               14
-#define CMD_STATS_AF_ENABLE            15
-#define CMD_STATS_BUF_RELEASE          16
-#define CMD_STATS_AF_BUF_RELEASE       17
-#define UPDATE_STATS_INVALID           18
-
-/* vfe config command: config command(from config thread)*/
-struct msm_vfe_cfg_cmd {
-       int cmd_type;
-       uint16_t length;
-       void *value;
-};
-
-#define MAX_CAMERA_ENABLE_NAME_LEN 32
-struct camera_enable_cmd {
-       char name[MAX_CAMERA_ENABLE_NAME_LEN];
-};
-
-#define MSM_PMEM_OUTPUT1               0
-#define MSM_PMEM_OUTPUT2               1
-#define MSM_PMEM_OUTPUT1_OUTPUT2       2
-#define MSM_PMEM_THUMBAIL              3
-#define MSM_PMEM_MAINIMG               4
-#define MSM_PMEM_RAW_MAINIMG           5
-#define MSM_PMEM_AEC_AWB               6
-#define MSM_PMEM_AF                    7
-#define MSM_PMEM_MAX                   8
-
-#define FRAME_PREVIEW_OUTPUT1          0
-#define FRAME_PREVIEW_OUTPUT2          1
-#define FRAME_SNAPSHOT                 2
-#define FRAME_THUMBAIL                 3
-#define FRAME_RAW_SNAPSHOT             4
-#define FRAME_MAX                      5
-
-struct msm_pmem_info {
-       int type;
-       int fd;
-       void *vaddr;
-       uint32_t y_off;
-       uint32_t cbcr_off;
-       uint8_t active;
-};
-
-struct outputCfg {
-       uint32_t height;
-       uint32_t width;
-
-       uint32_t window_height_firstline;
-       uint32_t window_height_lastline;
-};
-
-#define OUTPUT_1       0
-#define OUTPUT_2       1
-#define OUTPUT_1_AND_2 2
-#define CAMIF_TO_AXI_VIA_OUTPUT_2              3
-#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 4
-#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 5
-#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
-
-#define MSM_FRAME_PREV_1       0
-#define MSM_FRAME_PREV_2       1
-#define MSM_FRAME_ENC          2
-
-struct msm_frame {
-       int path;
-       unsigned long buffer;
-       uint32_t y_off;
-       uint32_t cbcr_off;
-       int fd;
-
-       void *cropinfo;
-       int croplen;
-};
-
-#define STAT_AEAW      0
-#define STAT_AF                1
-#define STAT_MAX       2
-
-struct msm_stats_buf {
-       int type;
-       unsigned long buffer;
-       int fd;
-};
-
-#define MSM_V4L2_VID_CAP_TYPE  0
-#define MSM_V4L2_STREAM_ON     1
-#define MSM_V4L2_STREAM_OFF    2
-#define MSM_V4L2_SNAPSHOT      3
-#define MSM_V4L2_QUERY_CTRL    4
-#define MSM_V4L2_GET_CTRL      5
-#define MSM_V4L2_SET_CTRL      6
-#define MSM_V4L2_QUERY         7
-#define MSM_V4L2_MAX           8
-
-struct crop_info {
-       void *info;
-       int len;
-};
-
-struct msm_postproc {
-       int ftnum;
-       struct msm_frame fthumnail;
-       int fmnum;
-       struct msm_frame fmain;
-};
-
-struct msm_snapshot_pp_status {
-       void *status;
-};
-
-#define CFG_SET_MODE                   0
-#define CFG_SET_EFFECT                 1
-#define CFG_START                      2
-#define CFG_PWR_UP                     3
-#define CFG_PWR_DOWN                   4
-#define CFG_WRITE_EXPOSURE_GAIN                5
-#define CFG_SET_DEFAULT_FOCUS          6
-#define CFG_MOVE_FOCUS                 7
-#define CFG_REGISTER_TO_REAL_GAIN      8
-#define CFG_REAL_TO_REGISTER_GAIN      9
-#define CFG_SET_FPS                    10
-#define CFG_SET_PICT_FPS               11
-#define CFG_SET_BRIGHTNESS             12
-#define CFG_SET_CONTRAST               13
-#define CFG_SET_ZOOM                   14
-#define CFG_SET_EXPOSURE_MODE          15
-#define CFG_SET_WB                     16
-#define CFG_SET_ANTIBANDING            17
-#define CFG_SET_EXP_GAIN               18
-#define CFG_SET_PICT_EXP_GAIN          19
-#define CFG_SET_LENS_SHADING           20
-#define CFG_GET_PICT_FPS               21
-#define CFG_GET_PREV_L_PF              22
-#define CFG_GET_PREV_P_PL              23
-#define CFG_GET_PICT_L_PF              24
-#define CFG_GET_PICT_P_PL              25
-#define CFG_GET_AF_MAX_STEPS           26
-#define CFG_GET_PICT_MAX_EXP_LC                27
-#define CFG_MAX                                28
-
-#define MOVE_NEAR      0
-#define MOVE_FAR       1
-
-#define SENSOR_PREVIEW_MODE            0
-#define SENSOR_SNAPSHOT_MODE           1
-#define SENSOR_RAW_SNAPSHOT_MODE       2
-
-#define SENSOR_QTR_SIZE                        0
-#define SENSOR_FULL_SIZE               1
-#define SENSOR_INVALID_SIZE            2
-
-#define CAMERA_EFFECT_OFF              0
-#define CAMERA_EFFECT_MONO             1
-#define CAMERA_EFFECT_NEGATIVE         2
-#define CAMERA_EFFECT_SOLARIZE         3
-#define CAMERA_EFFECT_PASTEL           4
-#define CAMERA_EFFECT_MOSAIC           5
-#define CAMERA_EFFECT_RESIZE           6
-#define CAMERA_EFFECT_SEPIA            7
-#define CAMERA_EFFECT_POSTERIZE                8
-#define CAMERA_EFFECT_WHITEBOARD       9
-#define CAMERA_EFFECT_BLACKBOARD       10
-#define CAMERA_EFFECT_AQUA             11
-#define CAMERA_EFFECT_MAX              12
-
-struct sensor_pict_fps {
-       uint16_t prevfps;
-       uint16_t pictfps;
-};
-
-struct exp_gain_cfg {
-       uint16_t gain;
-       uint32_t line;
-};
-
-struct focus_cfg {
-       int32_t steps;
-       int dir;
-};
-
-struct fps_cfg {
-       uint16_t f_mult;
-       uint16_t fps_div;
-       uint32_t pict_fps_div;
-};
-
-struct sensor_cfg_data {
-       int cfgtype;
-       int mode;
-       int rs;
-       uint8_t max_steps;
-
-       union {
-               int8_t effect;
-               uint8_t lens_shading;
-               uint16_t prevl_pf;
-               uint16_t prevp_pl;
-               uint16_t pictl_pf;
-               uint16_t pictp_pl;
-               uint32_t pict_max_exp_lc;
-               uint16_t p_fps;
-               struct sensor_pict_fps gfps;
-               struct exp_gain_cfg exp_gain;
-               struct focus_cfg focus;
-               struct fps_cfg fps;
-       } cfg;
-};
-
-#define GET_NAME                       0
-#define GET_PREVIEW_LINE_PER_FRAME     1
-#define GET_PREVIEW_PIXELS_PER_LINE    2
-#define GET_SNAPSHOT_LINE_PER_FRAME    3
-#define GET_SNAPSHOT_PIXELS_PER_LINE   4
-#define GET_SNAPSHOT_FPS               5
-#define GET_SNAPSHOT_MAX_EP_LINE_CNT   6
-
-struct msm_camsensor_info {
-       char name[MAX_SENSOR_NAME];
-       uint8_t flash_enabled;
-};
-#endif /* __LINUX_MSM_CAMERA_H */
diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c
deleted file mode 100644 (file)
index 4d3d300..0000000
+++ /dev/null
@@ -1,1333 +0,0 @@
-/* drivers/android/pmem.c
- *
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/miscdevice.h>
-#include <linux/platform_device.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/mm.h>
-#include <linux/list.h>
-#include <linux/debugfs.h>
-#include <linux/android_pmem.h>
-#include <linux/mempolicy.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <asm/cacheflush.h>
-
-#define PMEM_MAX_DEVICES 10
-#define PMEM_MAX_ORDER 128
-#define PMEM_MIN_ALLOC PAGE_SIZE
-
-#define PMEM_DEBUG 1
-
-/* indicates that a refernce to this file has been taken via get_pmem_file,
- * the file should not be released until put_pmem_file is called */
-#define PMEM_FLAGS_BUSY 0x1
-/* indicates that this is a suballocation of a larger master range */
-#define PMEM_FLAGS_CONNECTED (0x1 << 1)
-/* indicates this is a master and not a sub allocation and that it is mmaped */
-#define PMEM_FLAGS_MASTERMAP (0x1 << 2)
-/* submap and unsubmap flags indicate:
- * 00: subregion has never been mmaped
- * 10: subregion has been mmaped, reference to the mm was taken
- * 11: subretion has ben released, refernece to the mm still held
- * 01: subretion has been released, reference to the mm has been released
- */
-#define PMEM_FLAGS_SUBMAP (0x1 << 3)
-#define PMEM_FLAGS_UNSUBMAP (0x1 << 4)
-
-
-struct pmem_data {
-       /* in alloc mode: an index into the bitmap
-        * in no_alloc mode: the size of the allocation */
-       int index;
-       /* see flags above for descriptions */
-       unsigned int flags;
-       /* protects this data field, if the mm_mmap sem will be held at the
-        * same time as this sem, the mm sem must be taken first (as this is
-        * the order for vma_open and vma_close ops */
-       struct rw_semaphore sem;
-       /* info about the mmaping process */
-       struct vm_area_struct *vma;
-       /* task struct of the mapping process */
-       struct task_struct *task;
-       /* process id of teh mapping process */
-       pid_t pid;
-       /* file descriptor of the master */
-       int master_fd;
-       /* file struct of the master */
-       struct file *master_file;
-       /* a list of currently available regions if this is a suballocation */
-       struct list_head region_list;
-       /* a linked list of data so we can access them for debugging */
-       struct list_head list;
-#if PMEM_DEBUG
-       int ref;
-#endif
-};
-
-struct pmem_bits {
-       unsigned allocated:1;           /* 1 if allocated, 0 if free */
-       unsigned order:7;               /* size of the region in pmem space */
-};
-
-struct pmem_region_node {
-       struct pmem_region region;
-       struct list_head list;
-};
-
-#define PMEM_DEBUG_MSGS 0
-#if PMEM_DEBUG_MSGS
-#define DLOG(fmt, args...) \
-       do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
-                   ##args); } \
-       while (0)
-#else
-#define DLOG(x...) do {} while (0)
-#endif
-
-struct pmem_info {
-       struct miscdevice dev;
-       /* physical start address of the remaped pmem space */
-       unsigned long base;
-       /* vitual start address of the remaped pmem space */
-       unsigned char __iomem *vbase;
-       /* total size of the pmem space */
-       unsigned long size;
-       /* number of entries in the pmem space */
-       unsigned long num_entries;
-       /* pfn of the garbage page in memory */
-       unsigned long garbage_pfn;
-       /* index of the garbage page in the pmem space */
-       int garbage_index;
-       /* the bitmap for the region indicating which entries are allocated
-        * and which are free */
-       struct pmem_bits *bitmap;
-       /* indicates the region should not be managed with an allocator */
-       unsigned no_allocator;
-       /* indicates maps of this region should be cached, if a mix of
-        * cached and uncached is desired, set this and open the device with
-        * O_SYNC to get an uncached region */
-       unsigned cached;
-       unsigned buffered;
-       /* in no_allocator mode the first mapper gets the whole space and sets
-        * this flag */
-       unsigned allocated;
-       /* for debugging, creates a list of pmem file structs, the
-        * data_list_sem should be taken before pmem_data->sem if both are
-        * needed */
-       struct semaphore data_list_sem;
-       struct list_head data_list;
-       /* pmem_sem protects the bitmap array
-        * a write lock should be held when modifying entries in bitmap
-        * a read lock should be held when reading data from bits or
-        * dereferencing a pointer into bitmap
-        *
-        * pmem_data->sem protects the pmem data of a particular file
-        * Many of the function that require the pmem_data->sem have a non-
-        * locking version for when the caller is already holding that sem.
-        *
-        * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER:
-        * down(pmem_data->sem) => down(bitmap_sem)
-        */
-       struct rw_semaphore bitmap_sem;
-
-       long (*ioctl)(struct file *, unsigned int, unsigned long);
-       int (*release)(struct inode *, struct file *);
-};
-
-static struct pmem_info pmem[PMEM_MAX_DEVICES];
-static int id_count;
-
-#define PMEM_IS_FREE(id, index) (!(pmem[id].bitmap[index].allocated))
-#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
-#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
-#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
-#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC)
-#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base)
-#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC)
-#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \
-       PMEM_LEN(id, index))
-#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase)
-#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \
-       PMEM_LEN(id, index))
-#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED)
-#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
-#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \
-       (!(data->flags & PMEM_FLAGS_UNSUBMAP)))
-
-static int pmem_release(struct inode *, struct file *);
-static int pmem_mmap(struct file *, struct vm_area_struct *);
-static int pmem_open(struct inode *, struct file *);
-static long pmem_ioctl(struct file *, unsigned int, unsigned long);
-
-const struct file_operations pmem_fops = {
-       .release = pmem_release,
-       .mmap = pmem_mmap,
-       .open = pmem_open,
-       .unlocked_ioctl = pmem_ioctl,
-       .llseek = noop_llseek,
-};
-
-static int get_id(struct file *file)
-{
-       return MINOR(file->f_dentry->d_inode->i_rdev);
-}
-
-static int is_pmem_file(struct file *file)
-{
-       int id;
-
-       if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode))
-               return 0;
-       id = get_id(file);
-       if (unlikely(id >= PMEM_MAX_DEVICES))
-               return 0;
-       if (unlikely(file->f_dentry->d_inode->i_rdev !=
-            MKDEV(MISC_MAJOR, pmem[id].dev.minor)))
-               return 0;
-       return 1;
-}
-
-static int has_allocation(struct file *file)
-{
-       struct pmem_data *data;
-       /* check is_pmem_file first if not accessed via pmem_file_ops */
-
-       if (unlikely(!file->private_data))
-               return 0;
-       data = file->private_data;
-       if (unlikely(data->index < 0))
-               return 0;
-       return 1;
-}
-
-static int is_master_owner(struct file *file)
-{
-       struct file *master_file;
-       struct pmem_data *data;
-       int put_needed, ret = 0;
-
-       if (!is_pmem_file(file) || !has_allocation(file))
-               return 0;
-       data = file->private_data;
-       if (PMEM_FLAGS_MASTERMAP & data->flags)
-               return 1;
-       master_file = fget_light(data->master_fd, &put_needed);
-       if (master_file && data->master_file == master_file)
-               ret = 1;
-       fput_light(master_file, put_needed);
-       return ret;
-}
-
-static int pmem_free(int id, int index)
-{
-       /* caller should hold the write lock on pmem_sem! */
-       int buddy, curr = index;
-       DLOG("index %d\n", index);
-
-       if (pmem[id].no_allocator) {
-               pmem[id].allocated = 0;
-               return 0;
-       }
-       /* clean up the bitmap, merging any buddies */
-       pmem[id].bitmap[curr].allocated = 0;
-       /* find a slots buddy Buddy# = Slot# ^ (1 << order)
-        * if the buddy is also free merge them
-        * repeat until the buddy is not free or end of the bitmap is reached
-        */
-       do {
-               buddy = PMEM_BUDDY_INDEX(id, curr);
-               if (PMEM_IS_FREE(id, buddy) &&
-                               PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) {
-                       PMEM_ORDER(id, buddy)++;
-                       PMEM_ORDER(id, curr)++;
-                       curr = min(buddy, curr);
-               } else {
-                       break;
-               }
-       } while (curr < pmem[id].num_entries);
-
-       return 0;
-}
-
-static void pmem_revoke(struct file *file, struct pmem_data *data);
-
-static int pmem_release(struct inode *inode, struct file *file)
-{
-       struct pmem_data *data = file->private_data;
-       struct pmem_region_node *region_node;
-       struct list_head *elt, *elt2;
-       int id = get_id(file), ret = 0;
-
-
-       down(&pmem[id].data_list_sem);
-       /* if this file is a master, revoke all the memory in the connected
-        *  files */
-       if (PMEM_FLAGS_MASTERMAP & data->flags) {
-               struct pmem_data *sub_data;
-               list_for_each(elt, &pmem[id].data_list) {
-                       sub_data = list_entry(elt, struct pmem_data, list);
-                       down_read(&sub_data->sem);
-                       if (PMEM_IS_SUBMAP(sub_data) &&
-                           file == sub_data->master_file) {
-                               up_read(&sub_data->sem);
-                               pmem_revoke(file, sub_data);
-                       }  else
-                               up_read(&sub_data->sem);
-               }
-       }
-       list_del(&data->list);
-       up(&pmem[id].data_list_sem);
-
-
-       down_write(&data->sem);
-
-       /* if its not a conencted file and it has an allocation, free it */
-       if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) {
-               down_write(&pmem[id].bitmap_sem);
-               ret = pmem_free(id, data->index);
-               up_write(&pmem[id].bitmap_sem);
-       }
-
-       /* if this file is a submap (mapped, connected file), downref the
-        * task struct */
-       if (PMEM_FLAGS_SUBMAP & data->flags)
-               if (data->task) {
-                       put_task_struct(data->task);
-                       data->task = NULL;
-               }
-
-       file->private_data = NULL;
-
-       list_for_each_safe(elt, elt2, &data->region_list) {
-               region_node = list_entry(elt, struct pmem_region_node, list);
-               list_del(elt);
-               kfree(region_node);
-       }
-       BUG_ON(!list_empty(&data->region_list));
-
-       up_write(&data->sem);
-       kfree(data);
-       if (pmem[id].release)
-               ret = pmem[id].release(inode, file);
-
-       return ret;
-}
-
-static int pmem_open(struct inode *inode, struct file *file)
-{
-       struct pmem_data *data;
-       int id = get_id(file);
-       int ret = 0;
-
-       DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file));
-       /* setup file->private_data to indicate its unmapped */
-       /*  you can only open a pmem device one time */
-       if (file->private_data != NULL)
-               return -1;
-       data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL);
-       if (!data) {
-               printk("pmem: unable to allocate memory for pmem metadata.");
-               return -1;
-       }
-       data->flags = 0;
-       data->index = -1;
-       data->task = NULL;
-       data->vma = NULL;
-       data->pid = 0;
-       data->master_file = NULL;
-#if PMEM_DEBUG
-       data->ref = 0;
-#endif
-       INIT_LIST_HEAD(&data->region_list);
-       init_rwsem(&data->sem);
-
-       file->private_data = data;
-       INIT_LIST_HEAD(&data->list);
-
-       down(&pmem[id].data_list_sem);
-       list_add(&data->list, &pmem[id].data_list);
-       up(&pmem[id].data_list_sem);
-       return ret;
-}
-
-static unsigned long pmem_order(unsigned long len)
-{
-       int i;
-
-       len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC;
-       len--;
-       for (i = 0; i < sizeof(len)*8; i++)
-               if (len >> i == 0)
-                       break;
-       return i;
-}
-
-static int pmem_allocate(int id, unsigned long len)
-{
-       /* caller should hold the write lock on pmem_sem! */
-       /* return the corresponding pdata[] entry */
-       int curr = 0;
-       int end = pmem[id].num_entries;
-       int best_fit = -1;
-       unsigned long order = pmem_order(len);
-
-       if (pmem[id].no_allocator) {
-               DLOG("no allocator");
-               if ((len > pmem[id].size) || pmem[id].allocated)
-                       return -1;
-               pmem[id].allocated = 1;
-               return len;
-       }
-
-       if (order > PMEM_MAX_ORDER)
-               return -1;
-       DLOG("order %lx\n", order);
-
-       /* look through the bitmap:
-        *      if you find a free slot of the correct order use it
-        *      otherwise, use the best fit (smallest with size > order) slot
-        */
-       while (curr < end) {
-               if (PMEM_IS_FREE(id, curr)) {
-                       if (PMEM_ORDER(id, curr) == (unsigned char)order) {
-                               /* set the not free bit and clear others */
-                               best_fit = curr;
-                               break;
-                       }
-                       if (PMEM_ORDER(id, curr) > (unsigned char)order &&
-                           (best_fit < 0 ||
-                            PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit)))
-                               best_fit = curr;
-               }
-               curr = PMEM_NEXT_INDEX(id, curr);
-       }
-
-       /* if best_fit < 0, there are no suitable slots,
-        * return an error
-        */
-       if (best_fit < 0) {
-               printk("pmem: no space left to allocate!\n");
-               return -1;
-       }
-
-       /* now partition the best fit:
-        *      split the slot into 2 buddies of order - 1
-        *      repeat until the slot is of the correct order
-        */
-       while (PMEM_ORDER(id, best_fit) > (unsigned char)order) {
-               int buddy;
-               PMEM_ORDER(id, best_fit) -= 1;
-               buddy = PMEM_BUDDY_INDEX(id, best_fit);
-               PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit);
-       }
-       pmem[id].bitmap[best_fit].allocated = 1;
-       return best_fit;
-}
-
-static pgprot_t phys_mem_access_prot(struct file *file, pgprot_t vma_prot)
-{
-       int id = get_id(file);
-#ifdef pgprot_noncached
-       if (pmem[id].cached == 0 || file->f_flags & O_SYNC)
-               return pgprot_noncached(vma_prot);
-#endif
-#ifdef pgprot_ext_buffered
-       else if (pmem[id].buffered)
-               return pgprot_ext_buffered(vma_prot);
-#endif
-       return vma_prot;
-}
-
-static unsigned long pmem_start_addr(int id, struct pmem_data *data)
-{
-       if (pmem[id].no_allocator)
-               return PMEM_START_ADDR(id, 0);
-       else
-               return PMEM_START_ADDR(id, data->index);
-
-}
-
-static void *pmem_start_vaddr(int id, struct pmem_data *data)
-{
-       return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase;
-}
-
-static unsigned long pmem_len(int id, struct pmem_data *data)
-{
-       if (pmem[id].no_allocator)
-               return data->index;
-       else
-               return PMEM_LEN(id, data->index);
-}
-
-static int pmem_map_garbage(int id, struct vm_area_struct *vma,
-                           struct pmem_data *data, unsigned long offset,
-                           unsigned long len)
-{
-       int i, garbage_pages = len >> PAGE_SHIFT;
-
-       vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE;
-       for (i = 0; i < garbage_pages; i++) {
-               if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE),
-                   pmem[id].garbage_pfn))
-                       return -EAGAIN;
-       }
-       return 0;
-}
-
-static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma,
-                               struct pmem_data *data, unsigned long offset,
-                               unsigned long len)
-{
-       int garbage_pages;
-       DLOG("unmap offset %lx len %lx\n", offset, len);
-
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
-
-       garbage_pages = len >> PAGE_SHIFT;
-       zap_page_range(vma, vma->vm_start + offset, len, NULL);
-       pmem_map_garbage(id, vma, data, offset, len);
-       return 0;
-}
-
-static int pmem_map_pfn_range(int id, struct vm_area_struct *vma,
-                             struct pmem_data *data, unsigned long offset,
-                             unsigned long len)
-{
-       DLOG("map offset %lx len %lx\n", offset, len);
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start));
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end));
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
-       BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset));
-
-       if (io_remap_pfn_range(vma, vma->vm_start + offset,
-               (pmem_start_addr(id, data) + offset) >> PAGE_SHIFT,
-               len, vma->vm_page_prot)) {
-               return -EAGAIN;
-       }
-       return 0;
-}
-
-static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma,
-                             struct pmem_data *data, unsigned long offset,
-                             unsigned long len)
-{
-       /* hold the mm semp for the vma you are modifying when you call this */
-       BUG_ON(!vma);
-       zap_page_range(vma, vma->vm_start + offset, len, NULL);
-       return pmem_map_pfn_range(id, vma, data, offset, len);
-}
-
-static void pmem_vma_open(struct vm_area_struct *vma)
-{
-       struct file *file = vma->vm_file;
-       struct pmem_data *data = file->private_data;
-       int id = get_id(file);
-       /* this should never be called as we don't support copying pmem
-        * ranges via fork */
-       BUG_ON(!has_allocation(file));
-       down_write(&data->sem);
-       /* remap the garbage pages, forkers don't get access to the data */
-       pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end);
-       up_write(&data->sem);
-}
-
-static void pmem_vma_close(struct vm_area_struct *vma)
-{
-       struct file *file = vma->vm_file;
-       struct pmem_data *data = file->private_data;
-
-       DLOG("current %u ppid %u file %p count %d\n", current->pid,
-            current->parent->pid, file, file_count(file));
-       if (unlikely(!is_pmem_file(file) || !has_allocation(file))) {
-               printk(KERN_WARNING "pmem: something is very wrong, you are "
-                      "closing a vm backing an allocation that doesn't "
-                      "exist!\n");
-               return;
-       }
-       down_write(&data->sem);
-       if (data->vma == vma) {
-               data->vma = NULL;
-               if ((data->flags & PMEM_FLAGS_CONNECTED) &&
-                   (data->flags & PMEM_FLAGS_SUBMAP))
-                       data->flags |= PMEM_FLAGS_UNSUBMAP;
-       }
-       /* the kernel is going to free this vma now anyway */
-       up_write(&data->sem);
-}
-
-static struct vm_operations_struct vm_ops = {
-       .open = pmem_vma_open,
-       .close = pmem_vma_close,
-};
-
-static int pmem_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct pmem_data *data;
-       int index;
-       unsigned long vma_size =  vma->vm_end - vma->vm_start;
-       int ret = 0, id = get_id(file);
-
-       if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) {
-#if PMEM_DEBUG
-               printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned"
-                               " and a multiple of pages_size.\n");
-#endif
-               return -EINVAL;
-       }
-
-       data = file->private_data;
-       down_write(&data->sem);
-       /* check this file isn't already mmaped, for submaps check this file
-        * has never been mmaped */
-       if ((data->flags & PMEM_FLAGS_MASTERMAP) ||
-           (data->flags & PMEM_FLAGS_SUBMAP) ||
-           (data->flags & PMEM_FLAGS_UNSUBMAP)) {
-#if PMEM_DEBUG
-               printk(KERN_ERR "pmem: you can only mmap a pmem file once, "
-                      "this file is already mmaped. %x\n", data->flags);
-#endif
-               ret = -EINVAL;
-               goto error;
-       }
-       /* if file->private_data == unalloced, alloc*/
-       if (data && data->index == -1) {
-               down_write(&pmem[id].bitmap_sem);
-               index = pmem_allocate(id, vma->vm_end - vma->vm_start);
-               up_write(&pmem[id].bitmap_sem);
-               data->index = index;
-       }
-       /* either no space was available or an error occured */
-       if (!has_allocation(file)) {
-               ret = -EINVAL;
-               printk("pmem: could not find allocation for map.\n");
-               goto error;
-       }
-
-       if (pmem_len(id, data) < vma_size) {
-#if PMEM_DEBUG
-               printk(KERN_WARNING "pmem: mmap size [%lu] does not match"
-                      "size of backing region [%lu].\n", vma_size,
-                      pmem_len(id, data));
-#endif
-               ret = -EINVAL;
-               goto error;
-       }
-
-       vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT;
-       vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_page_prot);
-
-       if (data->flags & PMEM_FLAGS_CONNECTED) {
-               struct pmem_region_node *region_node;
-               struct list_head *elt;
-               if (pmem_map_garbage(id, vma, data, 0, vma_size)) {
-                       printk("pmem: mmap failed in kernel!\n");
-                       ret = -EAGAIN;
-                       goto error;
-               }
-               list_for_each(elt, &data->region_list) {
-                       region_node = list_entry(elt, struct pmem_region_node,
-                                                list);
-                       DLOG("remapping file: %p %lx %lx\n", file,
-                               region_node->region.offset,
-                               region_node->region.len);
-                       if (pmem_remap_pfn_range(id, vma, data,
-                                                region_node->region.offset,
-                                                region_node->region.len)) {
-                               ret = -EAGAIN;
-                               goto error;
-                       }
-               }
-               data->flags |= PMEM_FLAGS_SUBMAP;
-               get_task_struct(current->group_leader);
-               data->task = current->group_leader;
-               data->vma = vma;
-#if PMEM_DEBUG
-               data->pid = current->pid;
-#endif
-               DLOG("submmapped file %p vma %p pid %u\n", file, vma,
-                    current->pid);
-       } else {
-               if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) {
-                       printk(KERN_INFO "pmem: mmap failed in kernel!\n");
-                       ret = -EAGAIN;
-                       goto error;
-               }
-               data->flags |= PMEM_FLAGS_MASTERMAP;
-               data->pid = current->pid;
-       }
-       vma->vm_ops = &vm_ops;
-error:
-       up_write(&data->sem);
-       return ret;
-}
-
-/* the following are the api for accessing pmem regions by other drivers
- * from inside the kernel */
-int get_pmem_user_addr(struct file *file, unsigned long *start,
-                  unsigned long *len)
-{
-       struct pmem_data *data;
-       if (!is_pmem_file(file) || !has_allocation(file)) {
-#if PMEM_DEBUG
-               printk(KERN_INFO "pmem: requested pmem data from invalid"
-                                 "file.\n");
-#endif
-               return -1;
-       }
-       data = file->private_data;
-       down_read(&data->sem);
-       if (data->vma) {
-               *start = data->vma->vm_start;
-               *len = data->vma->vm_end - data->vma->vm_start;
-       } else {
-               *start = 0;
-               *len = 0;
-       }
-       up_read(&data->sem);
-       return 0;
-}
-
-int get_pmem_addr(struct file *file, unsigned long *start,
-                 unsigned long *vstart, unsigned long *len)
-{
-       struct pmem_data *data;
-       int id;
-
-       if (!is_pmem_file(file) || !has_allocation(file))
-               return -1;
-
-       data = file->private_data;
-       if (data->index == -1) {
-#if PMEM_DEBUG
-               printk(KERN_INFO "pmem: requested pmem data from file with no "
-                      "allocation.\n");
-               return -1;
-#endif
-       }
-       id = get_id(file);
-
-       down_read(&data->sem);
-       *start = pmem_start_addr(id, data);
-       *len = pmem_len(id, data);
-       *vstart = (unsigned long)pmem_start_vaddr(id, data);
-       up_read(&data->sem);
-#if PMEM_DEBUG
-       down_write(&data->sem);
-       data->ref++;
-       up_write(&data->sem);
-#endif
-       return 0;
-}
-
-int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
-                 unsigned long *len, struct file **filp)
-{
-       struct file *file;
-
-       file = fget(fd);
-       if (unlikely(file == NULL)) {
-               printk(KERN_INFO "pmem: requested data from file descriptor "
-                      "that doesn't exist.");
-               return -1;
-       }
-
-       if (get_pmem_addr(file, start, vstart, len))
-               goto end;
-
-       if (filp)
-               *filp = file;
-       return 0;
-end:
-       fput(file);
-       return -1;
-}
-
-void put_pmem_file(struct file *file)
-{
-       struct pmem_data *data;
-       int id;
-
-       if (!is_pmem_file(file))
-               return;
-       id = get_id(file);
-       data = file->private_data;
-#if PMEM_DEBUG
-       down_write(&data->sem);
-       if (data->ref == 0) {
-               printk("pmem: pmem_put > pmem_get %s (pid %d)\n",
-                      pmem[id].dev.name, data->pid);
-               BUG();
-       }
-       data->ref--;
-       up_write(&data->sem);
-#endif
-       fput(file);
-}
-
-void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
-{
-       struct pmem_data *data;
-       int id;
-       void *vaddr;
-       struct pmem_region_node *region_node;
-       struct list_head *elt;
-       void *flush_start, *flush_end;
-
-       if (!is_pmem_file(file) || !has_allocation(file))
-               return;
-
-       id = get_id(file);
-       data = file->private_data;
-       if (!pmem[id].cached)
-               return;
-
-       down_read(&data->sem);
-       vaddr = pmem_start_vaddr(id, data);
-       /* if this isn't a submmapped file, flush the whole thing */
-       if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) {
-               dmac_flush_range(vaddr, vaddr + pmem_len(id, data));
-               goto end;
-       }
-       /* otherwise, flush the region of the file we are drawing */
-       list_for_each(elt, &data->region_list) {
-               region_node = list_entry(elt, struct pmem_region_node, list);
-               if ((offset >= region_node->region.offset) &&
-                   ((offset + len) <= (region_node->region.offset +
-                       region_node->region.len))) {
-                       flush_start = vaddr + region_node->region.offset;
-                       flush_end = flush_start + region_node->region.len;
-                       dmac_flush_range(flush_start, flush_end);
-                       break;
-               }
-       }
-end:
-       up_read(&data->sem);
-}
-
-static int pmem_connect(unsigned long connect, struct file *file)
-{
-       struct pmem_data *data = file->private_data;
-       struct pmem_data *src_data;
-       struct file *src_file;
-       int ret = 0, put_needed;
-
-       down_write(&data->sem);
-       /* retrieve the src file and check it is a pmem file with an alloc */
-       src_file = fget_light(connect, &put_needed);
-       DLOG("connect %p to %p\n", file, src_file);
-       if (!src_file) {
-               printk(KERN_INFO "pmem: src file not found!\n");
-               ret = -EINVAL;
-               goto err_no_file;
-       }
-       if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) {
-               printk(KERN_INFO "pmem: src file is not a pmem file or has no "
-                      "alloc!\n");
-               ret = -EINVAL;
-               goto err_bad_file;
-       }
-       src_data = src_file->private_data;
-
-       if (has_allocation(file) && (data->index != src_data->index)) {
-               printk(KERN_INFO "pmem: file is already mapped but doesn't "
-                       "match this src_file!\n");
-               ret = -EINVAL;
-               goto err_bad_file;
-       }
-       data->index = src_data->index;
-       data->flags |= PMEM_FLAGS_CONNECTED;
-       data->master_fd = connect;
-       data->master_file = src_file;
-
-err_bad_file:
-       fput_light(src_file, put_needed);
-err_no_file:
-       up_write(&data->sem);
-       return ret;
-}
-
-static void pmem_unlock_data_and_mm(struct pmem_data *data,
-                                   struct mm_struct *mm)
-{
-       up_write(&data->sem);
-       if (mm != NULL) {
-               up_write(&mm->mmap_sem);
-               mmput(mm);
-       }
-}
-
-static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data,
-                                struct mm_struct **locked_mm)
-{
-       int ret = 0;
-       struct mm_struct *mm = NULL;
-       *locked_mm = NULL;
-lock_mm:
-       down_read(&data->sem);
-       if (PMEM_IS_SUBMAP(data)) {
-               mm = get_task_mm(data->task);
-               if (!mm) {
-#if PMEM_DEBUG
-                       printk(KERN_DEBUG "pmem: can't remap task is gone!\n");
-#endif
-                       up_read(&data->sem);
-                       return -1;
-               }
-       }
-       up_read(&data->sem);
-
-       if (mm)
-               down_write(&mm->mmap_sem);
-
-       down_write(&data->sem);
-       /* check that the file didn't get mmaped before we could take the
-        * data sem, this should be safe b/c you can only submap each file
-        * once */
-       if (PMEM_IS_SUBMAP(data) && !mm) {
-               pmem_unlock_data_and_mm(data, mm);
-               up_write(&data->sem);
-               goto lock_mm;
-       }
-       /* now check that vma.mm is still there, it could have been
-        * deleted by vma_close before we could get the data->sem */
-       if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) {
-               /* might as well release this */
-               if (data->flags & PMEM_FLAGS_SUBMAP) {
-                       put_task_struct(data->task);
-                       data->task = NULL;
-                       /* lower the submap flag to show the mm is gone */
-                       data->flags &= ~(PMEM_FLAGS_SUBMAP);
-               }
-               pmem_unlock_data_and_mm(data, mm);
-               return -1;
-       }
-       *locked_mm = mm;
-       return ret;
-}
-
-int pmem_remap(struct pmem_region *region, struct file *file,
-                     unsigned operation)
-{
-       int ret;
-       struct pmem_region_node *region_node;
-       struct mm_struct *mm = NULL;
-       struct list_head *elt, *elt2;
-       int id = get_id(file);
-       struct pmem_data *data = file->private_data;
-
-       /* pmem region must be aligned on a page boundry */
-       if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
-                !PMEM_IS_PAGE_ALIGNED(region->len))) {
-#if PMEM_DEBUG
-               printk(KERN_DEBUG "pmem: request for unaligned pmem "
-                       "suballocation %lx %lx\n", region->offset, region->len);
-#endif
-               return -EINVAL;
-       }
-
-       /* if userspace requests a region of len 0, there's nothing to do */
-       if (region->len == 0)
-               return 0;
-
-       /* lock the mm and data */
-       ret = pmem_lock_data_and_mm(file, data, &mm);
-       if (ret)
-               return 0;
-
-       /* only the owner of the master file can remap the client fds
-        * that back in it */
-       if (!is_master_owner(file)) {
-#if PMEM_DEBUG
-               printk("pmem: remap requested from non-master process\n");
-#endif
-               ret = -EINVAL;
-               goto err;
-       }
-
-       /* check that the requested range is within the src allocation */
-       if (unlikely((region->offset > pmem_len(id, data)) ||
-                    (region->len > pmem_len(id, data)) ||
-                    (region->offset + region->len > pmem_len(id, data)))) {
-#if PMEM_DEBUG
-               printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n");
-#endif
-               ret = -EINVAL;
-               goto err;
-       }
-
-       if (operation == PMEM_MAP) {
-               region_node = kmalloc(sizeof(struct pmem_region_node),
-                             GFP_KERNEL);
-               if (!region_node) {
-                       ret = -ENOMEM;
-#if PMEM_DEBUG
-                       printk(KERN_INFO "No space to allocate metadata!");
-#endif
-                       goto err;
-               }
-               region_node->region = *region;
-               list_add(&region_node->list, &data->region_list);
-       } else if (operation == PMEM_UNMAP) {
-               int found = 0;
-               list_for_each_safe(elt, elt2, &data->region_list) {
-                       region_node = list_entry(elt, struct pmem_region_node,
-                                     list);
-                       if (region->len == 0 ||
-                           (region_node->region.offset == region->offset &&
-                           region_node->region.len == region->len)) {
-                               list_del(elt);
-                               kfree(region_node);
-                               found = 1;
-                       }
-               }
-               if (!found) {
-#if PMEM_DEBUG
-                       printk("pmem: Unmap region does not map any mapped "
-                               "region!");
-#endif
-                       ret = -EINVAL;
-                       goto err;
-               }
-       }
-
-       if (data->vma && PMEM_IS_SUBMAP(data)) {
-               if (operation == PMEM_MAP)
-                       ret = pmem_remap_pfn_range(id, data->vma, data,
-                                                  region->offset, region->len);
-               else if (operation == PMEM_UNMAP)
-                       ret = pmem_unmap_pfn_range(id, data->vma, data,
-                                                  region->offset, region->len);
-       }
-
-err:
-       pmem_unlock_data_and_mm(data, mm);
-       return ret;
-}
-
-static void pmem_revoke(struct file *file, struct pmem_data *data)
-{
-       struct pmem_region_node *region_node;
-       struct list_head *elt, *elt2;
-       struct mm_struct *mm = NULL;
-       int id = get_id(file);
-       int ret = 0;
-
-       data->master_file = NULL;
-       ret = pmem_lock_data_and_mm(file, data, &mm);
-       /* if lock_data_and_mm fails either the task that mapped the fd, or
-        * the vma that mapped it have already gone away, nothing more
-        * needs to be done */
-       if (ret)
-               return;
-       /* unmap everything */
-       /* delete the regions and region list nothing is mapped any more */
-       if (data->vma)
-               list_for_each_safe(elt, elt2, &data->region_list) {
-                       region_node = list_entry(elt, struct pmem_region_node,
-                                                list);
-                       pmem_unmap_pfn_range(id, data->vma, data,
-                                            region_node->region.offset,
-                                            region_node->region.len);
-                       list_del(elt);
-                       kfree(region_node);
-       }
-       /* delete the master file */
-       pmem_unlock_data_and_mm(data, mm);
-}
-
-static void pmem_get_size(struct pmem_region *region, struct file *file)
-{
-       struct pmem_data *data = file->private_data;
-       int id = get_id(file);
-
-       if (!has_allocation(file)) {
-               region->offset = 0;
-               region->len = 0;
-               return;
-       } else {
-               region->offset = pmem_start_addr(id, data);
-               region->len = pmem_len(id, data);
-       }
-       DLOG("offset %lx len %lx\n", region->offset, region->len);
-}
-
-
-static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct pmem_data *data;
-       int id = get_id(file);
-
-       switch (cmd) {
-       case PMEM_GET_PHYS:
-               {
-                       struct pmem_region region;
-                       DLOG("get_phys\n");
-                       if (!has_allocation(file)) {
-                               region.offset = 0;
-                               region.len = 0;
-                       } else {
-                               data = file->private_data;
-                               region.offset = pmem_start_addr(id, data);
-                               region.len = pmem_len(id, data);
-                       }
-                       printk(KERN_INFO "pmem: request for physical address "
-                            "of pmem region from process %d.\n", current->pid);
-                       if (copy_to_user((void __user *)arg, &region,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       break;
-               }
-       case PMEM_MAP:
-               {
-                       struct pmem_region region;
-                       if (copy_from_user(&region, (void __user *)arg,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       data = file->private_data;
-                       return pmem_remap(&region, file, PMEM_MAP);
-               }
-               break;
-       case PMEM_UNMAP:
-               {
-                       struct pmem_region region;
-                       if (copy_from_user(&region, (void __user *)arg,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       data = file->private_data;
-                       return pmem_remap(&region, file, PMEM_UNMAP);
-                       break;
-               }
-       case PMEM_GET_SIZE:
-               {
-                       struct pmem_region region;
-                       DLOG("get_size\n");
-                       pmem_get_size(&region, file);
-                       if (copy_to_user((void __user *)arg, &region,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       break;
-               }
-       case PMEM_GET_TOTAL_SIZE:
-               {
-                       struct pmem_region region;
-                       DLOG("get total size\n");
-                       region.offset = 0;
-                       get_id(file);
-                       region.len = pmem[id].size;
-                       if (copy_to_user((void __user *)arg, &region,
-                                               sizeof(struct pmem_region)))
-                               return -EFAULT;
-                       break;
-               }
-       case PMEM_ALLOCATE:
-               {
-                       if (has_allocation(file))
-                               return -EINVAL;
-                       data = file->private_data;
-                       data->index = pmem_allocate(id, arg);
-                       break;
-               }
-       case PMEM_CONNECT:
-               DLOG("connect\n");
-               return pmem_connect(arg, file);
-               break;
-       default:
-               if (pmem[id].ioctl)
-                       return pmem[id].ioctl(file, cmd, arg);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-#if PMEM_DEBUG
-static ssize_t debug_open(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
-                         loff_t *ppos)
-{
-       struct list_head *elt, *elt2;
-       struct pmem_data *data;
-       struct pmem_region_node *region_node;
-       int id = (int)file->private_data;
-       const int debug_bufmax = 4096;
-       static char buffer[4096];
-       int n = 0;
-
-       DLOG("debug open\n");
-       n = scnprintf(buffer, debug_bufmax,
-                     "pid #: mapped regions (offset, len) (offset,len)...\n");
-
-       down(&pmem[id].data_list_sem);
-       list_for_each(elt, &pmem[id].data_list) {
-               data = list_entry(elt, struct pmem_data, list);
-               down_read(&data->sem);
-               n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:",
-                               data->pid);
-               list_for_each(elt2, &data->region_list) {
-                       region_node = list_entry(elt2, struct pmem_region_node,
-                                     list);
-                       n += scnprintf(buffer + n, debug_bufmax - n,
-                                       "(%lx,%lx) ",
-                                       region_node->region.offset,
-                                       region_node->region.len);
-               }
-               n += scnprintf(buffer + n, debug_bufmax - n, "\n");
-               up_read(&data->sem);
-       }
-       up(&pmem[id].data_list_sem);
-
-       n++;
-       buffer[n] = 0;
-       return simple_read_from_buffer(buf, count, ppos, buffer, n);
-}
-
-static struct file_operations debug_fops = {
-       .read = debug_read,
-       .open = debug_open,
-       .llseek = default_llseek,
-};
-#endif
-
-#if 0
-static struct miscdevice pmem_dev = {
-       .name = "pmem",
-       .fops = &pmem_fops,
-};
-#endif
-
-int pmem_setup(struct android_pmem_platform_data *pdata,
-              long (*ioctl)(struct file *, unsigned int, unsigned long),
-              int (*release)(struct inode *, struct file *))
-{
-       int err = 0;
-       int i, index = 0;
-       int id = id_count;
-       id_count++;
-
-       pmem[id].no_allocator = pdata->no_allocator;
-       pmem[id].cached = pdata->cached;
-       pmem[id].buffered = pdata->buffered;
-       pmem[id].base = pdata->start;
-       pmem[id].size = pdata->size;
-       pmem[id].ioctl = ioctl;
-       pmem[id].release = release;
-       init_rwsem(&pmem[id].bitmap_sem);
-       sema_init(&pmem[id].data_list_sem, 1);
-       INIT_LIST_HEAD(&pmem[id].data_list);
-       pmem[id].dev.name = pdata->name;
-       pmem[id].dev.minor = id;
-       pmem[id].dev.fops = &pmem_fops;
-       printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached);
-
-       err = misc_register(&pmem[id].dev);
-       if (err) {
-               printk(KERN_ALERT "Unable to register pmem driver!\n");
-               goto err_cant_register_device;
-       }
-       pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC;
-
-       pmem[id].bitmap = kcalloc(pmem[id].num_entries,
-                                 sizeof(struct pmem_bits), GFP_KERNEL);
-       if (!pmem[id].bitmap)
-               goto err_no_mem_for_metadata;
-
-       for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) {
-               if ((pmem[id].num_entries) &  1<<i) {
-                       PMEM_ORDER(id, index) = i;
-                       index = PMEM_NEXT_INDEX(id, index);
-               }
-       }
-
-       if (pmem[id].cached)
-               pmem[id].vbase = ioremap_cached(pmem[id].base,
-                                               pmem[id].size);
-#ifdef ioremap_ext_buffered
-       else if (pmem[id].buffered)
-               pmem[id].vbase = ioremap_ext_buffered(pmem[id].base,
-                                                     pmem[id].size);
-#endif
-       else
-               pmem[id].vbase = ioremap(pmem[id].base, pmem[id].size);
-
-       if (pmem[id].vbase == 0)
-               goto error_cant_remap;
-
-       pmem[id].garbage_pfn = page_to_pfn(alloc_page(GFP_KERNEL));
-       if (pmem[id].no_allocator)
-               pmem[id].allocated = 0;
-
-#if PMEM_DEBUG
-       debugfs_create_file(pdata->name, S_IFREG | S_IRUGO, NULL, (void *)id,
-                           &debug_fops);
-#endif
-       return 0;
-error_cant_remap:
-       kfree(pmem[id].bitmap);
-err_no_mem_for_metadata:
-       misc_deregister(&pmem[id].dev);
-err_cant_register_device:
-       return -1;
-}
-
-static int pmem_probe(struct platform_device *pdev)
-{
-       struct android_pmem_platform_data *pdata;
-
-       if (!pdev || !pdev->dev.platform_data) {
-               printk(KERN_ALERT "Unable to probe pmem!\n");
-               return -1;
-       }
-       pdata = pdev->dev.platform_data;
-       return pmem_setup(pdata, NULL, NULL);
-}
-
-
-static int pmem_remove(struct platform_device *pdev)
-{
-       int id = pdev->id;
-       __free_page(pfn_to_page(pmem[id].garbage_pfn));
-       misc_deregister(&pmem[id].dev);
-       return 0;
-}
-
-static struct platform_driver pmem_driver = {
-       .probe = pmem_probe,
-       .remove = pmem_remove,
-       .driver = { .name = "android_pmem" }
-};
-
-
-static int __init pmem_init(void)
-{
-       return platform_driver_register(&pmem_driver);
-}
-
-static void __exit pmem_exit(void)
-{
-       platform_driver_unregister(&pmem_driver);
-}
-
-module_init(pmem_init);
-module_exit(pmem_exit);
-
diff --git a/drivers/staging/dream/qdsp5/Makefile b/drivers/staging/dream/qdsp5/Makefile
deleted file mode 100644 (file)
index 44ae6b4..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-ccflags-y:=-Idrivers/staging/dream/include
-obj-y += adsp.o
-ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y)
-obj-y += adsp_info.o
-obj-y += audio_evrc.o audio_qcelp.o audio_amrnb.o audio_aac.o
-else
-obj-y += adsp_6225.o
-endif
-
-obj-y += adsp_driver.o
-obj-y += adsp_video_verify_cmd.o
-obj-y += adsp_videoenc_verify_cmd.o
-obj-y += adsp_jpeg_verify_cmd.o adsp_jpeg_patch_event.o
-obj-y += adsp_vfe_verify_cmd.o adsp_vfe_patch_event.o
-obj-y += adsp_lpm_verify_cmd.o
-obj-y += audio_out.o audio_in.o audio_mp3.o audmgr.o audpp.o
-obj-y += snd.o
-
diff --git a/drivers/staging/dream/qdsp5/adsp.c b/drivers/staging/dream/qdsp5/adsp.c
deleted file mode 100644 (file)
index f1e9d81..0000000
+++ /dev/null
@@ -1,1159 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp.c
- *
- * Register/Interrupt access for userspace aDSP library.
- *
- * Copyright (c) 2008 QUALCOMM Incorporated
- * Copyright (C) 2008 Google, Inc.
- * Author: Iliyan Malchev <ibm@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-/* TODO:
- * - move shareable rpc code outside of adsp.c
- * - general solution for virt->phys patchup
- * - queue IDs should be relative to modules
- * - disallow access to non-associated queues
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/kthread.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/wait.h>
-
-static inline void prevent_suspend(void)
-{
-}
-static inline void allow_suspend(void)
-{
-}
-
-#include <linux/io.h>
-#include <mach/msm_iomap.h>
-#include "adsp.h"
-
-#define INT_ADSP INT_ADSP_A9_A11
-
-static struct adsp_info adsp_info;
-static struct msm_rpc_endpoint *rpc_cb_server_client;
-static struct msm_adsp_module *adsp_modules;
-static int adsp_open_count;
-static DEFINE_MUTEX(adsp_open_lock);
-
-/* protect interactions with the ADSP command/message queue */
-static spinlock_t adsp_cmd_lock;
-
-static uint32_t current_image = -1;
-
-void adsp_set_image(struct adsp_info *info, uint32_t image)
-{
-       current_image = image;
-}
-
-/*
- * Checks whether the module_id is available in the
- * module_entries table.If module_id is available returns `0`.
- * If module_id is not available returns `-ENXIO`.
- */
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-static int32_t adsp_validate_module(uint32_t module_id)
-{
-       uint32_t        *ptr;
-       uint32_t        module_index;
-       uint32_t        num_mod_entries;
-
-       ptr = adsp_info.init_info_ptr->module_entries;
-       num_mod_entries = adsp_info.init_info_ptr->module_table_size;
-
-       for (module_index = 0; module_index < num_mod_entries; module_index++)
-               if (module_id == ptr[module_index])
-                       return 0;
-
-       return -ENXIO;
-}
-#else
-static inline int32_t adsp_validate_module(uint32_t module_id) { return 0; }
-#endif
-
-uint32_t adsp_get_module(struct adsp_info *info, uint32_t task)
-{
-       BUG_ON(current_image == -1UL);
-       return info->task_to_module[current_image][task];
-}
-
-uint32_t adsp_get_queue_offset(struct adsp_info *info, uint32_t queue_id)
-{
-       BUG_ON(current_image == -1UL);
-       return info->queue_offset[current_image][queue_id];
-}
-
-static int rpc_adsp_rtos_app_to_modem(uint32_t cmd, uint32_t module,
-                                     struct msm_adsp_module *adsp_module)
-{
-       int rc;
-       struct rpc_adsp_rtos_app_to_modem_args_t rpc_req;
-       struct rpc_reply_hdr *rpc_rsp;
-
-       msm_rpc_setup_req(&rpc_req.hdr,
-                         RPC_ADSP_RTOS_ATOM_PROG,
-                         msm_rpc_get_vers(adsp_module->rpc_client),
-                         RPC_ADSP_RTOS_APP_TO_MODEM_PROC);
-
-       rpc_req.gotit = cpu_to_be32(1);
-       rpc_req.cmd = cpu_to_be32(cmd);
-       rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS);
-       rpc_req.module = cpu_to_be32(module);
-       rc = msm_rpc_write(adsp_module->rpc_client, &rpc_req, sizeof(rpc_req));
-       if (rc < 0) {
-               pr_err("adsp: could not send RPC request: %d\n", rc);
-               return rc;
-       }
-
-       rc = msm_rpc_read(adsp_module->rpc_client,
-                         (void **)&rpc_rsp, -1, (5*HZ));
-       if (rc < 0) {
-               pr_err("adsp: error receiving RPC reply: %d (%d)\n",
-                      rc, -ERESTARTSYS);
-               return rc;
-       }
-
-       if (be32_to_cpu(rpc_rsp->reply_stat) != RPCMSG_REPLYSTAT_ACCEPTED) {
-               pr_err("adsp: RPC call was denied!\n");
-               kfree(rpc_rsp);
-               return -EPERM;
-       }
-
-       if (be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat) !=
-           RPC_ACCEPTSTAT_SUCCESS) {
-               pr_err("adsp error: RPC call was not successful (%d)\n",
-                      be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat));
-               kfree(rpc_rsp);
-               return -EINVAL;
-       }
-
-       kfree(rpc_rsp);
-       return 0;
-}
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-static int get_module_index(uint32_t id)
-{
-       int mod_idx;
-       for (mod_idx = 0; mod_idx < adsp_info.module_count; mod_idx++)
-               if (adsp_info.module[mod_idx].id == id)
-                       return mod_idx;
-
-       return -ENXIO;
-}
-#endif
-
-static struct msm_adsp_module *find_adsp_module_by_id(
-       struct adsp_info *info, uint32_t id)
-{
-       if (id > info->max_module_id) {
-               return NULL;
-       } else {
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-               id = get_module_index(id);
-               if (id < 0)
-                       return NULL;
-#endif
-               return info->id_to_module[id];
-       }
-}
-
-static struct msm_adsp_module *find_adsp_module_by_name(
-       struct adsp_info *info, const char *name)
-{
-       unsigned n;
-       for (n = 0; n < info->module_count; n++)
-               if (!strcmp(name, adsp_modules[n].name))
-                       return adsp_modules + n;
-       return NULL;
-}
-
-static int adsp_rpc_init(struct msm_adsp_module *adsp_module)
-{
-       /* remove the original connect once compatible support is complete */
-       adsp_module->rpc_client = msm_rpc_connect(
-                       RPC_ADSP_RTOS_ATOM_PROG,
-                       RPC_ADSP_RTOS_ATOM_VERS,
-                       MSM_RPC_UNINTERRUPTIBLE);
-
-       if (IS_ERR(adsp_module->rpc_client)) {
-               int rc = PTR_ERR(adsp_module->rpc_client);
-               adsp_module->rpc_client = 0;
-               pr_err("adsp: could not open rpc client: %d\n", rc);
-               return rc;
-       }
-
-       return 0;
-}
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-/*
- * Send RPC_ADSP_RTOS_CMD_GET_INIT_INFO cmd to ARM9 and get
- * queue offsets and module entries (init info) as part of the event.
- */
-static void  msm_get_init_info(void)
-{
-       int rc;
-       struct rpc_adsp_rtos_app_to_modem_args_t rpc_req;
-
-       adsp_info.init_info_rpc_client = msm_rpc_connect(
-                       RPC_ADSP_RTOS_ATOM_PROG,
-                       RPC_ADSP_RTOS_ATOM_VERS,
-                       MSM_RPC_UNINTERRUPTIBLE);
-       if (IS_ERR(adsp_info.init_info_rpc_client)) {
-               rc = PTR_ERR(adsp_info.init_info_rpc_client);
-               adsp_info.init_info_rpc_client = 0;
-               pr_err("adsp: could not open rpc client: %d\n", rc);
-               return;
-       }
-
-       msm_rpc_setup_req(&rpc_req.hdr,
-                       RPC_ADSP_RTOS_ATOM_PROG,
-                       msm_rpc_get_vers(adsp_info.init_info_rpc_client),
-                       RPC_ADSP_RTOS_APP_TO_MODEM_PROC);
-
-       rpc_req.gotit = cpu_to_be32(1);
-       rpc_req.cmd = cpu_to_be32(RPC_ADSP_RTOS_CMD_GET_INIT_INFO);
-       rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS);
-       rpc_req.module = 0;
-
-       rc = msm_rpc_write(adsp_info.init_info_rpc_client,
-                               &rpc_req, sizeof(rpc_req));
-       if (rc < 0)
-               pr_err("adsp: could not send RPC request: %d\n", rc);
-}
-#endif
-
-int msm_adsp_get(const char *name, struct msm_adsp_module **out,
-                struct msm_adsp_ops *ops, void *driver_data)
-{
-       struct msm_adsp_module *module;
-       int rc = 0;
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-       static uint32_t init_info_cmd_sent;
-       if (!init_info_cmd_sent) {
-               msm_get_init_info();
-               init_waitqueue_head(&adsp_info.init_info_wait);
-               rc = wait_event_timeout(adsp_info.init_info_wait,
-                       adsp_info.init_info_state == ADSP_STATE_INIT_INFO,
-                       5 * HZ);
-               if (!rc) {
-                       pr_info("adsp: INIT_INFO failed\n");
-                       return -ETIMEDOUT;
-               }
-               init_info_cmd_sent++;
-       }
-#endif
-
-       module = find_adsp_module_by_name(&adsp_info, name);
-       if (!module)
-               return -ENODEV;
-
-       mutex_lock(&module->lock);
-       pr_info("adsp: opening module %s\n", module->name);
-       if (module->open_count++ == 0 && module->clk)
-               clk_enable(module->clk);
-
-       mutex_lock(&adsp_open_lock);
-       if (adsp_open_count++ == 0) {
-               enable_irq(INT_ADSP);
-               prevent_suspend();
-       }
-       mutex_unlock(&adsp_open_lock);
-
-       if (module->ops) {
-               rc = -EBUSY;
-               goto done;
-       }
-
-       rc = adsp_rpc_init(module);
-       if (rc)
-               goto done;
-
-       module->ops = ops;
-       module->driver_data = driver_data;
-       *out = module;
-       rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_REGISTER_APP,
-                                       module->id, module);
-       if (rc) {
-               module->ops = NULL;
-               module->driver_data = NULL;
-               *out = NULL;
-               pr_err("adsp: REGISTER_APP failed\n");
-               goto done;
-       }
-
-       pr_info("adsp: module %s has been registered\n", module->name);
-
-done:
-       mutex_lock(&adsp_open_lock);
-       if (rc && --adsp_open_count == 0) {
-               disable_irq(INT_ADSP);
-               allow_suspend();
-       }
-       if (rc && --module->open_count == 0 && module->clk)
-               clk_disable(module->clk);
-       mutex_unlock(&adsp_open_lock);
-       mutex_unlock(&module->lock);
-       return rc;
-}
-EXPORT_SYMBOL(msm_adsp_get);
-
-static int msm_adsp_disable_locked(struct msm_adsp_module *module);
-
-void msm_adsp_put(struct msm_adsp_module *module)
-{
-       unsigned long flags;
-
-       mutex_lock(&module->lock);
-       if (--module->open_count == 0 && module->clk)
-               clk_disable(module->clk);
-       if (module->ops) {
-               pr_info("adsp: closing module %s\n", module->name);
-
-               /* lock to ensure a dsp event cannot be delivered
-                * during or after removal of the ops and driver_data
-                */
-               spin_lock_irqsave(&adsp_cmd_lock, flags);
-               module->ops = NULL;
-               module->driver_data = NULL;
-               spin_unlock_irqrestore(&adsp_cmd_lock, flags);
-
-               if (module->state != ADSP_STATE_DISABLED) {
-                       pr_info("adsp: disabling module %s\n", module->name);
-                       msm_adsp_disable_locked(module);
-               }
-
-               msm_rpc_close(module->rpc_client);
-               module->rpc_client = 0;
-               if (--adsp_open_count == 0) {
-                       disable_irq(INT_ADSP);
-                       allow_suspend();
-                       pr_info("adsp: disable interrupt\n");
-               }
-       } else {
-               pr_info("adsp: module %s is already closed\n", module->name);
-       }
-       mutex_unlock(&module->lock);
-}
-EXPORT_SYMBOL(msm_adsp_put);
-
-/* this should be common code with rpc_servers.c */
-static int rpc_send_accepted_void_reply(struct msm_rpc_endpoint *client,
-                                       uint32_t xid, uint32_t accept_status)
-{
-       int rc = 0;
-       uint8_t reply_buf[sizeof(struct rpc_reply_hdr)];
-       struct rpc_reply_hdr *reply = (struct rpc_reply_hdr *)reply_buf;
-
-       reply->xid = cpu_to_be32(xid);
-       reply->type = cpu_to_be32(1); /* reply */
-       reply->reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
-
-       reply->data.acc_hdr.accept_stat = cpu_to_be32(accept_status);
-       reply->data.acc_hdr.verf_flavor = 0;
-       reply->data.acc_hdr.verf_length = 0;
-
-       rc = msm_rpc_write(rpc_cb_server_client, reply_buf, sizeof(reply_buf));
-       if (rc < 0)
-               pr_err("adsp: could not write RPC response: %d\n", rc);
-       return rc;
-}
-
-int __msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr,
-                  void *cmd_buf, size_t cmd_size)
-{
-       uint32_t ctrl_word;
-       uint32_t dsp_q_addr;
-       uint32_t dsp_addr;
-       uint32_t cmd_id = 0;
-       int cnt = 0;
-       int ret_status = 0;
-       unsigned long flags;
-       struct adsp_info *info = module->info;
-
-       spin_lock_irqsave(&adsp_cmd_lock, flags);
-
-       if (module->state != ADSP_STATE_ENABLED) {
-               spin_unlock_irqrestore(&adsp_cmd_lock, flags);
-               pr_err("adsp: module %s not enabled before write\n",
-                      module->name);
-               return -ENODEV;
-       }
-       if (adsp_validate_module(module->id)) {
-               spin_unlock_irqrestore(&adsp_cmd_lock, flags);
-               pr_info("adsp: module id validation failed %s  %d\n",
-                       module->name, module->id);
-               return -ENXIO;
-       }
-       dsp_q_addr = adsp_get_queue_offset(info, dsp_queue_addr);
-       dsp_q_addr &= ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M;
-
-       /* Poll until the ADSP is ready to accept a command.
-        * Wait for 100us, return error if it's not responding.
-        * If this returns an error, we need to disable ALL modules and
-        * then retry.
-        */
-       while (((ctrl_word = readl(info->write_ctrl)) &
-               ADSP_RTOS_WRITE_CTRL_WORD_READY_M) !=
-               ADSP_RTOS_WRITE_CTRL_WORD_READY_V) {
-               if (cnt > 100) {
-                       pr_err("adsp: timeout waiting for DSP write ready\n");
-                       ret_status = -EIO;
-                       goto fail;
-               }
-               pr_warning("adsp: waiting for DSP write ready\n");
-               udelay(1);
-               cnt++;
-       }
-
-       /* Set the mutex bits */
-       ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M);
-       ctrl_word |=  ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V;
-
-       /* Clear the command bits */
-       ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M);
-
-       /* Set the queue address bits */
-       ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M);
-       ctrl_word |= dsp_q_addr;
-
-       writel(ctrl_word, info->write_ctrl);
-
-       /* Generate an interrupt to the DSP.  This notifies the DSP that
-        * we are about to send a command on this particular queue.  The
-        * DSP will in response change its state.
-        */
-       writel(1, info->send_irq);
-
-       /* Poll until the adsp responds to the interrupt; this does not
-        * generate an interrupt from the adsp.  This should happen within
-        * 5ms.
-        */
-       cnt = 0;
-       while ((readl(info->write_ctrl) &
-               ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M) ==
-               ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V) {
-               if (cnt > 5000) {
-                       pr_err("adsp: timeout waiting for adsp ack\n");
-                       ret_status = -EIO;
-                       goto fail;
-               }
-               udelay(1);
-               cnt++;
-       }
-
-       /* Read the ctrl word */
-       ctrl_word = readl(info->write_ctrl);
-
-       if ((ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M) !=
-                        ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V) {
-               ret_status = -EAGAIN;
-               goto fail;
-       }
-
-       /* Ctrl word status bits were 00, no error in the ctrl word */
-
-       /* Get the DSP buffer address */
-       dsp_addr = (ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M) +
-                  (uint32_t)MSM_AD5_BASE;
-
-       if (dsp_addr < (uint32_t)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) {
-               uint16_t *buf_ptr = (uint16_t *) cmd_buf;
-               uint16_t *dsp_addr16 = (uint16_t *)dsp_addr;
-               cmd_size /= sizeof(uint16_t);
-
-               /* Save the command ID */
-               cmd_id = (uint32_t) buf_ptr[0];
-
-               /* Copy the command to DSP memory */
-               cmd_size++;
-               while (--cmd_size)
-                       *dsp_addr16++ = *buf_ptr++;
-       } else {
-               uint32_t *buf_ptr = (uint32_t *) cmd_buf;
-               uint32_t *dsp_addr32 = (uint32_t *)dsp_addr;
-               cmd_size /= sizeof(uint32_t);
-
-               /* Save the command ID */
-               cmd_id = buf_ptr[0];
-
-               cmd_size++;
-               while (--cmd_size)
-                       *dsp_addr32++ = *buf_ptr++;
-       }
-
-       /* Set the mutex bits */
-       ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M);
-       ctrl_word |=  ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V;
-
-       /* Set the command bits to write done */
-       ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M);
-       ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V;
-
-       /* Set the queue address bits */
-       ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M);
-       ctrl_word |= dsp_q_addr;
-
-       writel(ctrl_word, info->write_ctrl);
-
-       /* Generate an interrupt to the DSP.  It does not respond with
-        * an interrupt, and we do not need to wait for it to
-        * acknowledge, because it will hold the mutex lock until it's
-        * ready to receive more commands again.
-        */
-       writel(1, info->send_irq);
-
-       module->num_commands++;
-
-fail:
-       spin_unlock_irqrestore(&adsp_cmd_lock, flags);
-       return ret_status;
-}
-EXPORT_SYMBOL(msm_adsp_write);
-
-int msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr,
-                  void *cmd_buf, size_t cmd_size)
-{
-       int rc, retries = 0;
-       do {
-               rc = __msm_adsp_write(module, dsp_queue_addr, cmd_buf, cmd_size);
-               if (rc == -EAGAIN)
-                       udelay(10);
-       } while(rc == -EAGAIN && retries++ < 100);
-       if (retries > 50)
-               pr_warning("adsp: %s command took %d attempts: rc %d\n",
-                               module->name, retries, rc);
-       return rc;
-}
-
-#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
-static void *modem_event_addr;
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-static void read_modem_event(void *buf, size_t len)
-{
-       uint32_t *dptr = buf;
-       struct rpc_adsp_rtos_modem_to_app_args_t *sptr;
-       struct adsp_rtos_mp_mtoa_type *pkt_ptr;
-
-       sptr = modem_event_addr;
-       pkt_ptr = &sptr->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet;
-
-       dptr[0] = be32_to_cpu(sptr->mtoa_pkt.mp_mtoa_header.event);
-       dptr[1] = be32_to_cpu(pkt_ptr->module);
-       dptr[2] = be32_to_cpu(pkt_ptr->image);
-}
-#else
-static void read_modem_event(void *buf, size_t len)
-{
-       uint32_t *dptr = buf;
-       struct rpc_adsp_rtos_modem_to_app_args_t *sptr =
-               modem_event_addr;
-       dptr[0] = be32_to_cpu(sptr->event);
-       dptr[1] = be32_to_cpu(sptr->module);
-       dptr[2] = be32_to_cpu(sptr->image);
-}
-#endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */
-#endif /* CONFIG_MSM_ADSP_REPORT_EVENTS */
-
-static void handle_adsp_rtos_mtoa_app(struct rpc_request_hdr *req)
-{
-       struct rpc_adsp_rtos_modem_to_app_args_t *args =
-               (struct rpc_adsp_rtos_modem_to_app_args_t *)req;
-       uint32_t event;
-       uint32_t proc_id;
-       uint32_t module_id;
-       uint32_t image;
-       struct msm_adsp_module *module;
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-       struct adsp_rtos_mp_mtoa_type *pkt_ptr =
-               &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet;
-
-       event = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.event);
-       proc_id = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.proc_id);
-       module_id = be32_to_cpu(pkt_ptr->module);
-       image = be32_to_cpu(pkt_ptr->image);
-
-       if (be32_to_cpu(args->mtoa_pkt.desc_field) == RPC_ADSP_RTOS_INIT_INFO) {
-               struct queue_to_offset_type *qptr;
-               struct queue_to_offset_type *qtbl;
-               uint32_t *mptr;
-               uint32_t *mtbl;
-               uint32_t q_idx;
-               uint32_t num_entries;
-               uint32_t entries_per_image;
-               struct adsp_rtos_mp_mtoa_init_info_type *iptr;
-               struct adsp_rtos_mp_mtoa_init_info_type *sptr;
-               int32_t i_no, e_idx;
-
-               pr_info("adsp:INIT_INFO Event\n");
-               sptr = &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.
-                               mp_mtoa_init_packet;
-
-               iptr = adsp_info.init_info_ptr;
-               iptr->image_count = be32_to_cpu(sptr->image_count);
-               iptr->num_queue_offsets = be32_to_cpu(sptr->num_queue_offsets);
-               num_entries = iptr->num_queue_offsets;
-               qptr = &sptr->queue_offsets_tbl[0][0];
-               for (i_no = 0; i_no < iptr->image_count; i_no++) {
-                       qtbl = &iptr->queue_offsets_tbl[i_no][0];
-                       for (e_idx = 0; e_idx < num_entries; e_idx++) {
-                               qtbl[e_idx].offset = be32_to_cpu(qptr->offset);
-                               qtbl[e_idx].queue = be32_to_cpu(qptr->queue);
-                               q_idx = be32_to_cpu(qptr->queue);
-                               iptr->queue_offsets[i_no][q_idx] =
-                                               qtbl[e_idx].offset;
-                               qptr++;
-                       }
-               }
-
-               num_entries = be32_to_cpu(sptr->num_task_module_entries);
-               iptr->num_task_module_entries = num_entries;
-               entries_per_image = num_entries / iptr->image_count;
-               mptr = &sptr->task_to_module_tbl[0][0];
-               for (i_no = 0; i_no < iptr->image_count; i_no++) {
-                       mtbl = &iptr->task_to_module_tbl[i_no][0];
-                       for (e_idx = 0; e_idx < entries_per_image; e_idx++) {
-                               mtbl[e_idx] = be32_to_cpu(*mptr);
-                               mptr++;
-                       }
-               }
-
-               iptr->module_table_size = be32_to_cpu(sptr->module_table_size);
-               mptr = &sptr->module_entries[0];
-               for (i_no = 0; i_no < iptr->module_table_size; i_no++)
-                       iptr->module_entries[i_no] = be32_to_cpu(mptr[i_no]);
-               adsp_info.init_info_state = ADSP_STATE_INIT_INFO;
-               rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
-                                               RPC_ACCEPTSTAT_SUCCESS);
-               wake_up(&adsp_info.init_info_wait);
-
-               return;
-       }
-#else
-       event = be32_to_cpu(args->event);
-       proc_id = be32_to_cpu(args->proc_id);
-       module_id = be32_to_cpu(args->module);
-       image = be32_to_cpu(args->image);
-#endif
-
-       pr_info("adsp: rpc event=%d, proc_id=%d, module=%d, image=%d\n",
-               event, proc_id, module_id, image);
-
-       module = find_adsp_module_by_id(&adsp_info, module_id);
-       if (!module) {
-               pr_err("adsp: module %d is not supported!\n", module_id);
-               rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
-                               RPC_ACCEPTSTAT_GARBAGE_ARGS);
-               return;
-       }
-
-       mutex_lock(&module->lock);
-       switch (event) {
-       case RPC_ADSP_RTOS_MOD_READY:
-               pr_info("adsp: module %s: READY\n", module->name);
-               module->state = ADSP_STATE_ENABLED;
-               wake_up(&module->state_wait);
-               adsp_set_image(module->info, image);
-               break;
-       case RPC_ADSP_RTOS_MOD_DISABLE:
-               pr_info("adsp: module %s: DISABLED\n", module->name);
-               module->state = ADSP_STATE_DISABLED;
-               wake_up(&module->state_wait);
-               break;
-       case RPC_ADSP_RTOS_SERVICE_RESET:
-               pr_info("adsp: module %s: SERVICE_RESET\n", module->name);
-               module->state = ADSP_STATE_DISABLED;
-               wake_up(&module->state_wait);
-               break;
-       case RPC_ADSP_RTOS_CMD_SUCCESS:
-               pr_info("adsp: module %s: CMD_SUCCESS\n", module->name);
-               break;
-       case RPC_ADSP_RTOS_CMD_FAIL:
-               pr_info("adsp: module %s: CMD_FAIL\n", module->name);
-               break;
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-       case RPC_ADSP_RTOS_DISABLE_FAIL:
-               pr_info("adsp: module %s: DISABLE_FAIL\n", module->name);
-               break;
-#endif
-       default:
-               pr_info("adsp: unknown event %d\n", event);
-               rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
-                                            RPC_ACCEPTSTAT_GARBAGE_ARGS);
-               mutex_unlock(&module->lock);
-               return;
-       }
-       rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
-                                    RPC_ACCEPTSTAT_SUCCESS);
-       mutex_unlock(&module->lock);
-#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
-       modem_event_addr = (uint32_t *)req;
-       module->ops->event(module->driver_data, EVENT_MSG_ID,
-                               EVENT_LEN, read_modem_event);
-#endif
-}
-
-static int handle_adsp_rtos_mtoa(struct rpc_request_hdr *req)
-{
-       switch (req->procedure) {
-       case RPC_ADSP_RTOS_MTOA_NULL_PROC:
-               rpc_send_accepted_void_reply(rpc_cb_server_client,
-                                            req->xid,
-                                            RPC_ACCEPTSTAT_SUCCESS);
-               break;
-       case RPC_ADSP_RTOS_MODEM_TO_APP_PROC:
-               handle_adsp_rtos_mtoa_app(req);
-               break;
-       default:
-               pr_err("adsp: unknowned proc %d\n", req->procedure);
-               rpc_send_accepted_void_reply(
-                       rpc_cb_server_client, req->xid,
-                       RPC_ACCEPTSTAT_PROC_UNAVAIL);
-               break;
-       }
-       return 0;
-}
-
-/* this should be common code with rpc_servers.c */
-static int adsp_rpc_thread(void *data)
-{
-       void *buffer;
-       struct rpc_request_hdr *req;
-       int rc;
-
-       do {
-               rc = msm_rpc_read(rpc_cb_server_client, &buffer, -1, -1);
-               if (rc < 0) {
-                       pr_err("adsp: could not read rpc: %d\n", rc);
-                       break;
-               }
-               req = (struct rpc_request_hdr *)buffer;
-
-               req->type = be32_to_cpu(req->type);
-               req->xid = be32_to_cpu(req->xid);
-               req->rpc_vers = be32_to_cpu(req->rpc_vers);
-               req->prog = be32_to_cpu(req->prog);
-               req->vers = be32_to_cpu(req->vers);
-               req->procedure = be32_to_cpu(req->procedure);
-
-               if (req->type != 0)
-                       goto bad_rpc;
-               if (req->rpc_vers != 2)
-                       goto bad_rpc;
-               if (req->prog != RPC_ADSP_RTOS_MTOA_PROG)
-                       goto bad_rpc;
-               if (req->vers != RPC_ADSP_RTOS_MTOA_VERS)
-                       goto bad_rpc;
-
-               handle_adsp_rtos_mtoa(req);
-               kfree(buffer);
-               continue;
-
-bad_rpc:
-               pr_err("adsp: bogus rpc from modem\n");
-               kfree(buffer);
-       } while (1);
-
-       do_exit(0);
-}
-
-static size_t read_event_size;
-static void *read_event_addr;
-
-static void read_event_16(void *buf, size_t len)
-{
-       uint16_t *dst = buf;
-       uint16_t *src = read_event_addr;
-       len /= 2;
-       if (len > read_event_size)
-               len = read_event_size;
-       while (len--)
-               *dst++ = *src++;
-}
-
-static void read_event_32(void *buf, size_t len)
-{
-       uint32_t *dst = buf;
-       uint32_t *src = read_event_addr;
-       len /= 2;
-       if (len > read_event_size)
-               len = read_event_size;
-       while (len--)
-               *dst++ = *src++;
-}
-
-static int adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(
-       struct adsp_info *info, void *dsp_addr)
-{
-       struct msm_adsp_module *module;
-       unsigned rtos_task_id;
-       unsigned msg_id;
-       unsigned msg_length;
-       void (*func)(void *, size_t);
-
-       if (dsp_addr >= (void *)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) {
-               uint32_t *dsp_addr32 = dsp_addr;
-               uint32_t tmp = *dsp_addr32++;
-               rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8;
-               msg_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M);
-               read_event_size = tmp >> 16;
-               read_event_addr = dsp_addr32;
-               msg_length = read_event_size * sizeof(uint32_t);
-               func = read_event_32;
-       } else {
-               uint16_t *dsp_addr16 = dsp_addr;
-               uint16_t tmp = *dsp_addr16++;
-               rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8;
-               msg_id = tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M;
-               read_event_size = *dsp_addr16++;
-               read_event_addr = dsp_addr16;
-               msg_length = read_event_size * sizeof(uint16_t);
-               func = read_event_16;
-       }
-
-       if (rtos_task_id > info->max_task_id) {
-               pr_err("adsp: bogus task id %d\n", rtos_task_id);
-               return 0;
-       }
-       module = find_adsp_module_by_id(info,
-                                       adsp_get_module(info, rtos_task_id));
-
-       if (!module) {
-               pr_err("adsp: no module for task id %d\n", rtos_task_id);
-               return 0;
-       }
-
-       module->num_events++;
-
-       if (!module->ops) {
-               pr_err("adsp: module %s is not open\n", module->name);
-               return 0;
-       }
-
-       module->ops->event(module->driver_data, msg_id, msg_length, func);
-       return 0;
-}
-
-static int adsp_get_event(struct adsp_info *info)
-{
-       uint32_t ctrl_word;
-       uint32_t ready;
-       void *dsp_addr;
-       uint32_t cmd_type;
-       int cnt;
-       unsigned long flags;
-       int rc = 0;
-
-       spin_lock_irqsave(&adsp_cmd_lock, flags);
-
-       /* Whenever the DSP has a message, it updates this control word
-        * and generates an interrupt.  When we receive the interrupt, we
-        * read this register to find out what ADSP task the command is
-        * comming from.
-        *
-        * The ADSP should *always* be ready on the first call, but the
-        * irq handler calls us in a loop (to handle back-to-back command
-        * processing), so we give the DSP some time to return to the
-        * ready state.  The DSP will not issue another IRQ for events
-        * pending between the first IRQ and the event queue being drained,
-        * unfortunately.
-        */
-
-       for (cnt = 0; cnt < 10; cnt++) {
-               ctrl_word = readl(info->read_ctrl);
-
-               if ((ctrl_word & ADSP_RTOS_READ_CTRL_WORD_FLAG_M) ==
-                   ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V)
-                       goto ready;
-
-               udelay(10);
-       }
-       pr_warning("adsp: not ready after 100uS\n");
-       rc = -EBUSY;
-       goto done;
-
-ready:
-       /* Here we check to see if there are pending messages. If there are
-        * none, we siply return -EAGAIN to indicate that there are no more
-        * messages pending.
-        */
-       ready = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_READY_M;
-       if ((ready != ADSP_RTOS_READ_CTRL_WORD_READY_V) &&
-           (ready != ADSP_RTOS_READ_CTRL_WORD_CONT_V)) {
-               rc = -EAGAIN;
-               goto done;
-       }
-
-       /* DSP says that there are messages waiting for the host to read */
-
-       /* Get the Command Type */
-       cmd_type = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M;
-
-       /* Get the DSP buffer address */
-       dsp_addr = (void *)((ctrl_word &
-                            ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M) +
-                           (uint32_t)MSM_AD5_BASE);
-
-       /* We can only handle Task-to-Host messages */
-       if (cmd_type != ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V) {
-               pr_err("adsp: unknown dsp cmd_type %d\n", cmd_type);
-               rc = -EIO;
-               goto done;
-       }
-
-       adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(info, dsp_addr);
-
-       ctrl_word = readl(info->read_ctrl);
-       ctrl_word &= ~ADSP_RTOS_READ_CTRL_WORD_READY_M;
-
-       /* Write ctrl word to the DSP */
-       writel(ctrl_word, info->read_ctrl);
-
-       /* Generate an interrupt to the DSP */
-       writel(1, info->send_irq);
-
-done:
-       spin_unlock_irqrestore(&adsp_cmd_lock, flags);
-       return rc;
-}
-
-static irqreturn_t adsp_irq_handler(int irq, void *data)
-{
-       struct adsp_info *info = &adsp_info;
-       int cnt = 0;
-       for (cnt = 0; cnt < 10; cnt++)
-               if (adsp_get_event(info) < 0)
-                       break;
-       if (cnt > info->event_backlog_max)
-               info->event_backlog_max = cnt;
-       info->events_received += cnt;
-       if (cnt == 10)
-               pr_err("adsp: too many (%d) events for single irq!\n", cnt);
-       return IRQ_HANDLED;
-}
-
-int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate)
-{
-       if (module->clk && clk_rate)
-               return clk_set_rate(module->clk, clk_rate);
-
-       return -EINVAL;
-}
-
-int msm_adsp_enable(struct msm_adsp_module *module)
-{
-       int rc = 0;
-
-       pr_info("msm_adsp_enable() '%s'state[%d] id[%d]\n",
-               module->name, module->state, module->id);
-
-       mutex_lock(&module->lock);
-       switch (module->state) {
-       case ADSP_STATE_DISABLED:
-               rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_ENABLE,
-                                               module->id, module);
-               if (rc)
-                       break;
-               module->state = ADSP_STATE_ENABLING;
-               mutex_unlock(&module->lock);
-               rc = wait_event_timeout(module->state_wait,
-                                       module->state != ADSP_STATE_ENABLING,
-                                       1 * HZ);
-               mutex_lock(&module->lock);
-               if (module->state == ADSP_STATE_ENABLED) {
-                       rc = 0;
-               } else {
-                       pr_err("adsp: module '%s' enable timed out\n",
-                              module->name);
-                       rc = -ETIMEDOUT;
-               }
-               break;
-       case ADSP_STATE_ENABLING:
-               pr_warning("adsp: module '%s' enable in progress\n",
-                          module->name);
-               break;
-       case ADSP_STATE_ENABLED:
-               pr_warning("adsp: module '%s' already enabled\n",
-                          module->name);
-               break;
-       case ADSP_STATE_DISABLING:
-               pr_err("adsp: module '%s' disable in progress\n",
-                      module->name);
-               rc = -EBUSY;
-               break;
-       }
-       mutex_unlock(&module->lock);
-       return rc;
-}
-EXPORT_SYMBOL(msm_adsp_enable);
-
-static int msm_adsp_disable_locked(struct msm_adsp_module *module)
-{
-       int rc = 0;
-
-       switch (module->state) {
-       case ADSP_STATE_DISABLED:
-               pr_warning("adsp: module '%s' already disabled\n",
-                          module->name);
-               break;
-       case ADSP_STATE_ENABLING:
-       case ADSP_STATE_ENABLED:
-               rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_DISABLE,
-                                               module->id, module);
-               module->state = ADSP_STATE_DISABLED;
-       }
-       return rc;
-}
-
-int msm_adsp_disable(struct msm_adsp_module *module)
-{
-       int rc;
-       pr_info("msm_adsp_disable() '%s'\n", module->name);
-       mutex_lock(&module->lock);
-       rc = msm_adsp_disable_locked(module);
-       mutex_unlock(&module->lock);
-       return rc;
-}
-EXPORT_SYMBOL(msm_adsp_disable);
-
-static int msm_adsp_probe(struct platform_device *pdev)
-{
-       unsigned count;
-       int rc, i;
-       int max_module_id;
-
-       pr_info("adsp: probe\n");
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-       adsp_info.init_info_ptr = kzalloc(
-               (sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL);
-       if (!adsp_info.init_info_ptr)
-               return -ENOMEM;
-#endif
-
-       rc = adsp_init_info(&adsp_info);
-       if (rc)
-               return rc;
-       adsp_info.send_irq += (uint32_t) MSM_AD5_BASE;
-       adsp_info.read_ctrl += (uint32_t) MSM_AD5_BASE;
-       adsp_info.write_ctrl += (uint32_t) MSM_AD5_BASE;
-       count = adsp_info.module_count;
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-       max_module_id = count;
-#else
-       max_module_id = adsp_info.max_module_id + 1;
-#endif
-
-       adsp_modules = kzalloc(
-               sizeof(struct msm_adsp_module) * count +
-               sizeof(void *) * max_module_id, GFP_KERNEL);
-       if (!adsp_modules)
-               return -ENOMEM;
-
-       adsp_info.id_to_module = (void *) (adsp_modules + count);
-
-       spin_lock_init(&adsp_cmd_lock);
-
-       rc = request_irq(INT_ADSP, adsp_irq_handler, IRQF_TRIGGER_RISING,
-                        "adsp", 0);
-       if (rc < 0)
-               goto fail_request_irq;
-       disable_irq(INT_ADSP);
-
-       rpc_cb_server_client = msm_rpc_open();
-       if (IS_ERR(rpc_cb_server_client)) {
-               rpc_cb_server_client = NULL;
-               rc = PTR_ERR(rpc_cb_server_client);
-               pr_err("adsp: could not create rpc server (%d)\n", rc);
-               goto fail_rpc_open;
-       }
-
-       rc = msm_rpc_register_server(rpc_cb_server_client,
-                                    RPC_ADSP_RTOS_MTOA_PROG,
-                                    RPC_ADSP_RTOS_MTOA_VERS);
-       if (rc) {
-               pr_err("adsp: could not register callback server (%d)\n", rc);
-               goto fail_rpc_register;
-       }
-
-       /* start the kernel thread to process the callbacks */
-       kthread_run(adsp_rpc_thread, NULL, "kadspd");
-
-       for (i = 0; i < count; i++) {
-               struct msm_adsp_module *mod = adsp_modules + i;
-               mutex_init(&mod->lock);
-               init_waitqueue_head(&mod->state_wait);
-               mod->info = &adsp_info;
-               mod->name = adsp_info.module[i].name;
-               mod->id = adsp_info.module[i].id;
-               if (adsp_info.module[i].clk_name)
-                       mod->clk = clk_get(NULL, adsp_info.module[i].clk_name);
-               else
-                       mod->clk = NULL;
-               if (mod->clk && adsp_info.module[i].clk_rate)
-                       clk_set_rate(mod->clk, adsp_info.module[i].clk_rate);
-               mod->verify_cmd = adsp_info.module[i].verify_cmd;
-               mod->patch_event = adsp_info.module[i].patch_event;
-               INIT_HLIST_HEAD(&mod->pmem_regions);
-               mod->pdev.name = adsp_info.module[i].pdev_name;
-               mod->pdev.id = -1;
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-               adsp_info.id_to_module[i] = mod;
-#else
-               adsp_info.id_to_module[mod->id] = mod;
-#endif
-               platform_device_register(&mod->pdev);
-       }
-
-       msm_adsp_publish_cdevs(adsp_modules, count);
-
-       return 0;
-
-fail_rpc_register:
-       msm_rpc_close(rpc_cb_server_client);
-       rpc_cb_server_client = NULL;
-fail_rpc_open:
-       enable_irq(INT_ADSP);
-       free_irq(INT_ADSP, 0);
-fail_request_irq:
-       kfree(adsp_modules);
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-       kfree(adsp_info.init_info_ptr);
-#endif
-       return rc;
-}
-
-static struct platform_driver msm_adsp_driver = {
-       .probe = msm_adsp_probe,
-       .driver = {
-               .name = MSM_ADSP_DRIVER_NAME,
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init adsp_init(void)
-{
-       return platform_driver_register(&msm_adsp_driver);
-}
-
-device_initcall(adsp_init);
diff --git a/drivers/staging/dream/qdsp5/adsp.h b/drivers/staging/dream/qdsp5/adsp.h
deleted file mode 100644 (file)
index 0e5c9ab..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp.h
- *
- * Copyright (c) 2008 QUALCOMM Incorporated
- * Copyright (C) 2008 Google, Inc.
- * Author: Iliyan Malchev <ibm@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _ARCH_ARM_MACH_MSM_ADSP_H
-#define _ARCH_ARM_MACH_MSM_ADSP_H
-
-#include <linux/types.h>
-#include <linux/msm_adsp.h>
-#include <mach/msm_rpcrouter.h>
-#include <mach/msm_adsp.h>
-
-int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr,
-                   unsigned long len);
-int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr,
-                          unsigned long *kvaddr, unsigned long len);
-int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr);
-
-int adsp_vfe_verify_cmd(struct msm_adsp_module *module,
-                       unsigned int queue_id, void *cmd_data,
-                       size_t cmd_size);
-int adsp_jpeg_verify_cmd(struct msm_adsp_module *module,
-                        unsigned int queue_id, void *cmd_data,
-                        size_t cmd_size);
-int adsp_lpm_verify_cmd(struct msm_adsp_module *module,
-                       unsigned int queue_id, void *cmd_data,
-                       size_t cmd_size);
-int adsp_video_verify_cmd(struct msm_adsp_module *module,
-                         unsigned int queue_id, void *cmd_data,
-                         size_t cmd_size);
-int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
-                         unsigned int queue_id, void *cmd_data,
-                         size_t cmd_size);
-
-
-struct adsp_event;
-
-int adsp_vfe_patch_event(struct msm_adsp_module *module,
-                       struct adsp_event *event);
-
-int adsp_jpeg_patch_event(struct msm_adsp_module *module,
-                       struct adsp_event *event);
-
-
-struct adsp_module_info {
-       const char *name;
-       const char *pdev_name;
-       uint32_t id;
-       const char *clk_name;
-       unsigned long clk_rate;
-       int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *,
-                          size_t);
-       int (*patch_event) (struct msm_adsp_module*, struct adsp_event *);
-};
-
-#define ADSP_EVENT_MAX_SIZE 496
-#define EVENT_LEN      12
-#define EVENT_MSG_ID   ((uint16_t)~0)
-
-struct adsp_event {
-       struct list_head list;
-       uint32_t size; /* always in bytes */
-       uint16_t msg_id;
-       uint16_t type; /* 0 for msgs (from aDSP), -1 for events (from ARM9) */
-       int is16; /* always 0 (msg is 32-bit) when the event type is 1(ARM9) */
-       union {
-               uint16_t msg16[ADSP_EVENT_MAX_SIZE / 2];
-               uint32_t msg32[ADSP_EVENT_MAX_SIZE / 4];
-       } data;
-};
-
-struct adsp_info {
-       uint32_t send_irq;
-       uint32_t read_ctrl;
-       uint32_t write_ctrl;
-
-       uint32_t max_msg16_size;
-       uint32_t max_msg32_size;
-
-       uint32_t max_task_id;
-       uint32_t max_module_id;
-       uint32_t max_queue_id;
-       uint32_t max_image_id;
-
-       /* for each image id, a map of queue id to offset */
-       uint32_t **queue_offset;
-
-       /* for each image id, a map of task id to module id */
-       uint32_t **task_to_module;
-
-       /* for each module id, map of module id to module */
-       struct msm_adsp_module **id_to_module;
-
-       uint32_t module_count;
-       struct adsp_module_info *module;
-
-       /* stats */
-       uint32_t events_received;
-       uint32_t event_backlog_max;
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-       /* rpc_client for init_info */
-       struct msm_rpc_endpoint *init_info_rpc_client;
-       struct adsp_rtos_mp_mtoa_init_info_type *init_info_ptr;
-       wait_queue_head_t init_info_wait;
-       unsigned init_info_state;
-#endif
-};
-
-#define RPC_ADSP_RTOS_ATOM_PROG 0x3000000a
-#define RPC_ADSP_RTOS_MTOA_PROG 0x3000000b
-#define RPC_ADSP_RTOS_ATOM_NULL_PROC 0
-#define RPC_ADSP_RTOS_MTOA_NULL_PROC 0
-#define RPC_ADSP_RTOS_APP_TO_MODEM_PROC 2
-#define RPC_ADSP_RTOS_MODEM_TO_APP_PROC 2
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(1,0)
-#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(2,1) /* must be actual vers */
-#define MSM_ADSP_DRIVER_NAME "rs3000000a:00010000"
-#elif (CONFIG_MSM_AMSS_VERSION == 6220) || (CONFIG_MSM_AMSS_VERSION == 6225)
-#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x71d1094b, 0)
-#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0xee3a9966, 0)
-#define MSM_ADSP_DRIVER_NAME "rs3000000a:71d1094b"
-#elif CONFIG_MSM_AMSS_VERSION == 6210
-#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x20f17fd3, 0)
-#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0x75babbd6, 0)
-#define MSM_ADSP_DRIVER_NAME "rs3000000a:20f17fd3"
-#else
-#error "Unknown AMSS version"
-#endif
-
-enum rpc_adsp_rtos_proc_type {
-       RPC_ADSP_RTOS_PROC_NONE = 0,
-       RPC_ADSP_RTOS_PROC_MODEM = 1,
-       RPC_ADSP_RTOS_PROC_APPS = 2,
-};
-
-enum {
-       RPC_ADSP_RTOS_CMD_REGISTER_APP,
-       RPC_ADSP_RTOS_CMD_ENABLE,
-       RPC_ADSP_RTOS_CMD_DISABLE,
-       RPC_ADSP_RTOS_CMD_KERNEL_COMMAND,
-       RPC_ADSP_RTOS_CMD_16_COMMAND,
-       RPC_ADSP_RTOS_CMD_32_COMMAND,
-       RPC_ADSP_RTOS_CMD_DISABLE_EVENT_RSP,
-       RPC_ADSP_RTOS_CMD_REMOTE_EVENT,
-       RPC_ADSP_RTOS_CMD_SET_STATE,
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-       RPC_ADSP_RTOS_CMD_REMOTE_INIT_INFO_EVENT,
-       RPC_ADSP_RTOS_CMD_GET_INIT_INFO,
-#endif
-};
-
-enum rpc_adsp_rtos_mod_status_type {
-       RPC_ADSP_RTOS_MOD_READY,
-       RPC_ADSP_RTOS_MOD_DISABLE,
-       RPC_ADSP_RTOS_SERVICE_RESET,
-       RPC_ADSP_RTOS_CMD_FAIL,
-       RPC_ADSP_RTOS_CMD_SUCCESS,
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-       RPC_ADSP_RTOS_INIT_INFO,
-       RPC_ADSP_RTOS_DISABLE_FAIL,
-#endif
-};
-
-struct rpc_adsp_rtos_app_to_modem_args_t {
-       struct rpc_request_hdr hdr;
-       uint32_t gotit; /* if 1, the next elements are present */
-       uint32_t cmd; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */
-       uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */
-       uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */
-};
-
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-enum qdsp_image_type {
-       QDSP_IMAGE_COMBO,
-       QDSP_IMAGE_GAUDIO,
-       QDSP_IMAGE_QTV_LP,
-       QDSP_IMAGE_MAX,
-       /* DO NOT USE: Force this enum to be a 32bit type to improve speed */
-       QDSP_IMAGE_32BIT_DUMMY = 0x10000
-};
-
-struct adsp_rtos_mp_mtoa_header_type {
-       enum rpc_adsp_rtos_mod_status_type  event;
-       enum rpc_adsp_rtos_proc_type        proc_id;
-};
-
-/* ADSP RTOS MP Communications - Modem to APP's  Event Info*/
-struct adsp_rtos_mp_mtoa_type {
-       uint32_t        module;
-       uint32_t        image;
-       uint32_t        apps_okts;
-};
-
-/* ADSP RTOS MP Communications - Modem to APP's Init Info  */
-#define IMG_MAX         8
-#define ENTRIES_MAX     64
-
-struct queue_to_offset_type {
-       uint32_t        queue;
-       uint32_t        offset;
-};
-
-struct adsp_rtos_mp_mtoa_init_info_type {
-       uint32_t        image_count;
-       uint32_t        num_queue_offsets;
-       struct queue_to_offset_type     queue_offsets_tbl[IMG_MAX][ENTRIES_MAX];
-       uint32_t        num_task_module_entries;
-       uint32_t        task_to_module_tbl[IMG_MAX][ENTRIES_MAX];
-
-       uint32_t        module_table_size;
-       uint32_t        module_entries[ENTRIES_MAX];
-       /*
-        * queue_offsets[] is to store only queue_offsets
-        */
-       uint32_t        queue_offsets[IMG_MAX][ENTRIES_MAX];
-};
-
-struct adsp_rtos_mp_mtoa_s_type {
-       struct adsp_rtos_mp_mtoa_header_type mp_mtoa_header;
-
-       uint32_t desc_field;
-       union {
-               struct adsp_rtos_mp_mtoa_init_info_type mp_mtoa_init_packet;
-               struct adsp_rtos_mp_mtoa_type mp_mtoa_packet;
-       } adsp_rtos_mp_mtoa_data;
-};
-
-struct rpc_adsp_rtos_modem_to_app_args_t {
-       struct rpc_request_hdr hdr;
-       uint32_t gotit; /* if 1, the next elements are present */
-       struct adsp_rtos_mp_mtoa_s_type mtoa_pkt;
-};
-#else
-struct rpc_adsp_rtos_modem_to_app_args_t {
-       struct rpc_request_hdr hdr;
-       uint32_t gotit; /* if 1, the next elements are present */
-       uint32_t event; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */
-       uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */
-       uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */
-       uint32_t image; /* RPC_QDSP_IMAGE_GAUDIO */
-};
-#endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */
-
-#define ADSP_STATE_DISABLED   0
-#define ADSP_STATE_ENABLING   1
-#define ADSP_STATE_ENABLED    2
-#define ADSP_STATE_DISABLING  3
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-#define ADSP_STATE_INIT_INFO  4
-#endif
-
-struct msm_adsp_module {
-       struct mutex lock;
-       const char *name;
-       unsigned id;
-       struct adsp_info *info;
-
-       struct msm_rpc_endpoint *rpc_client;
-       struct msm_adsp_ops *ops;
-       void *driver_data;
-
-       /* statistics */
-       unsigned num_commands;
-       unsigned num_events;
-
-       wait_queue_head_t state_wait;
-       unsigned state;
-
-       struct platform_device pdev;
-       struct clk *clk;
-       int open_count;
-
-       struct mutex pmem_regions_lock;
-       struct hlist_head pmem_regions;
-       int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *,
-                          size_t);
-       int (*patch_event) (struct msm_adsp_module*, struct adsp_event *);
-};
-
-extern void msm_adsp_publish_cdevs(struct msm_adsp_module *, unsigned);
-extern int adsp_init_info(struct adsp_info *info);
-
-/* Value to indicate that a queue is not defined for a particular image */
-#if CONFIG_MSM_AMSS_VERSION >= 6350
-#define QDSP_RTOS_NO_QUEUE  0xfffffffe
-#else
-#define QDSP_RTOS_NO_QUEUE  0xffffffff
-#endif
-
-/*
- * Constants used to communicate with the ADSP RTOS
- */
-#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M            0x80000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V     0x80000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_AVAIL_V      0x00000000U
-
-#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_M              0x70000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_REQ_V    0x00000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V   0x10000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_NO_CMD_V       0x70000000U
-
-#define ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M           0x0E000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V           0x00000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_NO_FREE_BUF_V      0x02000000U
-
-#define ADSP_RTOS_WRITE_CTRL_WORD_KERNEL_FLG_M       0x01000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_MSG_WRITE_V   0x00000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_V         0x01000000U
-
-#define ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M         0x00FFFFFFU
-#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_ID_M      0x00FFFFFFU
-
-/* Combination of MUTEX and CMD bits to check if the DSP is busy */
-#define ADSP_RTOS_WRITE_CTRL_WORD_READY_M            0xF0000000U
-#define ADSP_RTOS_WRITE_CTRL_WORD_READY_V            0x70000000U
-
-/* RTOS to Host processor command mask values */
-#define ADSP_RTOS_READ_CTRL_WORD_FLAG_M              0x80000000U
-#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_WAIT_V      0x00000000U
-#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V      0x80000000U
-
-#define ADSP_RTOS_READ_CTRL_WORD_CMD_M               0x60000000U
-#define ADSP_RTOS_READ_CTRL_WORD_READ_DONE_V         0x00000000U
-#define ADSP_RTOS_READ_CTRL_WORD_READ_REQ_V          0x20000000U
-#define ADSP_RTOS_READ_CTRL_WORD_NO_CMD_V            0x60000000U
-
-/* Combination of FLAG and COMMAND bits to check if MSG ready */
-#define ADSP_RTOS_READ_CTRL_WORD_READY_M             0xE0000000U
-#define ADSP_RTOS_READ_CTRL_WORD_READY_V             0xA0000000U
-#define ADSP_RTOS_READ_CTRL_WORD_CONT_V              0xC0000000U
-#define ADSP_RTOS_READ_CTRL_WORD_DONE_V              0xE0000000U
-
-#define ADSP_RTOS_READ_CTRL_WORD_STATUS_M            0x18000000U
-#define ADSP_RTOS_READ_CTRL_WORD_NO_ERR_V            0x00000000U
-
-#define ADSP_RTOS_READ_CTRL_WORD_IN_PROG_M           0x04000000U
-#define ADSP_RTOS_READ_CTRL_WORD_NO_READ_IN_PROG_V   0x00000000U
-#define ADSP_RTOS_READ_CTRL_WORD_READ_IN_PROG_V      0x04000000U
-
-#define ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M          0x03000000U
-#define ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V     0x00000000U
-#define ADSP_RTOS_READ_CTRL_WORD_CMD_KRNL_TO_H_V     0x01000000U
-#define ADSP_RTOS_READ_CTRL_WORD_CMD_H_TO_KRNL_CFM_V 0x02000000U
-
-#define ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M          0x00FFFFFFU
-
-#define ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M            0x000000FFU
-#define ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M           0x0000FF00U
-
-/* Base address of DSP and DSP hardware registers */
-#define QDSP_RAMC_OFFSET  0x400000
-
-#endif /* _ARCH_ARM_MACH_MSM_ADSP_H */
diff --git a/drivers/staging/dream/qdsp5/adsp_6210.c b/drivers/staging/dream/qdsp5/adsp_6210.c
deleted file mode 100644 (file)
index 3cf4e99..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_6210.h
- *
- * Copyright (c) 2008 QUALCOMM Incorporated.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include "adsp.h"
-
-/* Firmware modules */
-typedef enum {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_AUDPLAY1TASK,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_VIDEOTASK,
-       QDSP_MODULE_VIDEO_AAC_VOC,
-       QDSP_MODULE_PCM_DEC,
-       QDSP_MODULE_AUDIO_DEC_MP3,
-       QDSP_MODULE_AUDIO_DEC_AAC,
-       QDSP_MODULE_AUDIO_DEC_WMA,
-       QDSP_MODULE_HOSTPCM,
-       QDSP_MODULE_DTMF,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_SBC_ENC,
-       QDSP_MODULE_VOC,
-       QDSP_MODULE_VOC_PCM,
-       QDSP_MODULE_VOCENCTASK,
-       QDSP_MODULE_VOCDECTASK,
-       QDSP_MODULE_VOICEPROCTASK,
-       QDSP_MODULE_VIDEOENCTASK,
-       QDSP_MODULE_VFETASK,
-       QDSP_MODULE_WAV_ENC,
-       QDSP_MODULE_AACLC_ENC,
-       QDSP_MODULE_VIDEO_AMR,
-       QDSP_MODULE_VOC_AMR,
-       QDSP_MODULE_VOC_EVRC,
-       QDSP_MODULE_VOC_13K,
-       QDSP_MODULE_VOC_FGV,
-       QDSP_MODULE_DIAGTASK,
-       QDSP_MODULE_JPEGTASK,
-       QDSP_MODULE_LPMTASK,
-       QDSP_MODULE_QCAMTASK,
-       QDSP_MODULE_MODMATHTASK,
-       QDSP_MODULE_AUDPLAY2TASK,
-       QDSP_MODULE_AUDPLAY3TASK,
-       QDSP_MODULE_AUDPLAY4TASK,
-       QDSP_MODULE_GRAPHICSTASK,
-       QDSP_MODULE_MIDI,
-       QDSP_MODULE_GAUDIO,
-       QDSP_MODULE_VDEC_LP_MODE,
-       QDSP_MODULE_MAX,
-} qdsp_module_type;
-
-#define QDSP_RTOS_MAX_TASK_ID  19U
-
-/* Table of modules indexed by task ID for the GAUDIO image */
-static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_AUDPLAY1TASK,
-       QDSP_MODULE_AUDPLAY2TASK,
-       QDSP_MODULE_AUDPLAY3TASK,
-       QDSP_MODULE_AUDPLAY4TASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_GRAPHICSTASK,
-       QDSP_MODULE_MAX
-};
-
-/* Queue offset table indexed by queue ID for the GAUDIO image */
-static uint32_t qdsp_gaudio_queue_offset_table[] = {
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
-       0x3be,               /* QDSP_mpuAfeQueue                  */
-       0x3ee,               /* QDSP_mpuGraphicsCmdQueue          */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecCmdQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecPktQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
-       0x3c2,               /* QDSP_uPAudPPCmd1Queue             */
-       0x3c6,               /* QDSP_uPAudPPCmd2Queue             */
-       0x3ca,               /* QDSP_uPAudPPCmd3Queue             */
-       0x3da,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
-       0x3de,               /* QDSP_uPAudPlay1BitStreamCtrlQueue */
-       0x3e2,               /* QDSP_uPAudPlay2BitStreamCtrlQueue */
-       0x3e6,               /* QDSP_uPAudPlay3BitStreamCtrlQueue */
-       0x3ea,               /* QDSP_uPAudPlay4BitStreamCtrlQueue */
-       0x3ce,               /* QDSP_uPAudPreProcCmdQueue         */
-       0x3d6,               /* QDSP_uPAudRecBitStreamQueue       */
-       0x3d2,               /* QDSP_uPAudRecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
-       QDSP_RTOS_NO_QUEUE   /* QDSP_vfeCommandTableQueue         */
-};
-
-/* Table of modules indexed by task ID for the COMBO image */
-static qdsp_module_type qdsp_combo_task_to_module_table[] = {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_VOCDECTASK,
-       QDSP_MODULE_VOCENCTASK,
-       QDSP_MODULE_VIDEOTASK,
-       QDSP_MODULE_VIDEOENCTASK,
-       QDSP_MODULE_VOICEPROCTASK,
-       QDSP_MODULE_VFETASK,
-       QDSP_MODULE_JPEGTASK,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_AUDPLAY1TASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_LPMTASK,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_MODMATHTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX
-};
-
-/* Queue offset table indexed by queue ID for the COMBO image */
-static uint32_t qdsp_combo_queue_offset_table[] = {
-       0x585,               /* QDSP_lpmCommandQueue              */
-       0x52d,               /* QDSP_mpuAfeQueue                  */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
-       0x541,               /* QDSP_mpuModmathCmdQueue           */
-       0x555,               /* QDSP_mpuVDecCmdQueue              */
-       0x559,               /* QDSP_mpuVDecPktQueue              */
-       0x551,               /* QDSP_mpuVEncCmdQueue              */
-       0x535,               /* QDSP_rxMpuDecCmdQueue             */
-       0x539,               /* QDSP_rxMpuDecPktQueue             */
-       0x53d,               /* QDSP_txMpuEncQueue                */
-       0x55d,               /* QDSP_uPAudPPCmd1Queue             */
-       0x561,               /* QDSP_uPAudPPCmd2Queue             */
-       0x565,               /* QDSP_uPAudPPCmd3Queue             */
-       0x575,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
-       0x579,               /* QDSP_uPAudPlay1BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
-       0x569,               /* QDSP_uPAudPreProcCmdQueue         */
-       0x571,               /* QDSP_uPAudRecBitStreamQueue       */
-       0x56d,               /* QDSP_uPAudRecCmdQueue             */
-       0x581,               /* QDSP_uPJpegActionCmdQueue         */
-       0x57d,               /* QDSP_uPJpegCfgCmdQueue            */
-       0x531,               /* QDSP_uPVocProcQueue               */
-       0x545,               /* QDSP_vfeCommandQueue              */
-       0x54d,               /* QDSP_vfeCommandScaleQueue         */
-       0x549                /* QDSP_vfeCommandTableQueue         */
-};
-
-/* Table of modules indexed by task ID for the QTV_LP image */
-static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_VIDEOTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX
-};
-
-/* Queue offset table indexed by queue ID for the QTV_LP image */
-static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
-       0x40c,               /* QDSP_mpuAfeQueue                  */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
-       0x410,               /* QDSP_mpuVDecCmdQueue              */
-       0x414,               /* QDSP_mpuVDecPktQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
-       0x41c,               /* QDSP_uPAudPPCmd1Queue             */
-       0x420,               /* QDSP_uPAudPPCmd2Queue             */
-       0x424,               /* QDSP_uPAudPPCmd3Queue             */
-       0x430,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
-       0x418,               /* QDSP_uPAudPreProcCmdQueue         */
-       0x42c,               /* QDSP_uPAudRecBitStreamQueue       */
-       0x428,               /* QDSP_uPAudRecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
-       QDSP_RTOS_NO_QUEUE   /* QDSP_vfeCommandTableQueue         */
-};
-
-/* Tables to convert tasks to modules */
-static uint32_t *qdsp_task_to_module[] = {
-       qdsp_combo_task_to_module_table,
-       qdsp_gaudio_task_to_module_table,
-       qdsp_qtv_lp_task_to_module_table,
-};
-
-/* Tables to retrieve queue offsets */
-static uint32_t *qdsp_queue_offset_table[] = {
-       qdsp_combo_queue_offset_table,
-       qdsp_gaudio_queue_offset_table,
-       qdsp_qtv_lp_queue_offset_table,
-};
-
-#define QDSP_MODULE(n) \
-       { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n }
-
-static struct adsp_module_info module_info[] = {
-       QDSP_MODULE(AUDPPTASK),
-       QDSP_MODULE(AUDRECTASK),
-       QDSP_MODULE(AUDPREPROCTASK),
-       QDSP_MODULE(VFETASK),
-       QDSP_MODULE(QCAMTASK),
-       QDSP_MODULE(LPMTASK),
-       QDSP_MODULE(JPEGTASK),
-       QDSP_MODULE(VIDEOTASK),
-       QDSP_MODULE(VDEC_LP_MODE),
-};
-
-int adsp_init_info(struct adsp_info *info)
-{
-       info->send_irq =   0x00c00200;
-       info->read_ctrl =  0x00400038;
-       info->write_ctrl = 0x00400034;
-
-       info->max_msg16_size = 193;
-       info->max_msg32_size = 8;
-
-       info->max_task_id = 16;
-       info->max_module_id = QDSP_MODULE_MAX - 1;
-       info->max_queue_id = QDSP_QUEUE_MAX;
-       info->max_image_id = 2;
-       info->queue_offset = qdsp_queue_offset_table;
-       info->task_to_module = qdsp_task_to_module;
-
-       info->module_count = ARRAY_SIZE(module_info);
-       info->module = module_info;
-       return 0;
-}
diff --git a/drivers/staging/dream/qdsp5/adsp_6220.c b/drivers/staging/dream/qdsp5/adsp_6220.c
deleted file mode 100644 (file)
index 02225cd..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_6220.h
- *
- * Copyright (c) 2008 QUALCOMM Incorporated.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include "adsp.h"
-
-/* Firmware modules */
-typedef enum {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_AUDPLAY1TASK,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_VIDEOTASK,
-       QDSP_MODULE_VIDEO_AAC_VOC,
-       QDSP_MODULE_PCM_DEC,
-       QDSP_MODULE_AUDIO_DEC_MP3,
-       QDSP_MODULE_AUDIO_DEC_AAC,
-       QDSP_MODULE_AUDIO_DEC_WMA,
-       QDSP_MODULE_HOSTPCM,
-       QDSP_MODULE_DTMF,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_SBC_ENC,
-       QDSP_MODULE_VOC,
-       QDSP_MODULE_VOC_PCM,
-       QDSP_MODULE_VOCENCTASK,
-       QDSP_MODULE_VOCDECTASK,
-       QDSP_MODULE_VOICEPROCTASK,
-       QDSP_MODULE_VIDEOENCTASK,
-       QDSP_MODULE_VFETASK,
-       QDSP_MODULE_WAV_ENC,
-       QDSP_MODULE_AACLC_ENC,
-       QDSP_MODULE_VIDEO_AMR,
-       QDSP_MODULE_VOC_AMR,
-       QDSP_MODULE_VOC_EVRC,
-       QDSP_MODULE_VOC_13K,
-       QDSP_MODULE_VOC_FGV,
-       QDSP_MODULE_DIAGTASK,
-       QDSP_MODULE_JPEGTASK,
-       QDSP_MODULE_LPMTASK,
-       QDSP_MODULE_QCAMTASK,
-       QDSP_MODULE_MODMATHTASK,
-       QDSP_MODULE_AUDPLAY2TASK,
-       QDSP_MODULE_AUDPLAY3TASK,
-       QDSP_MODULE_AUDPLAY4TASK,
-       QDSP_MODULE_GRAPHICSTASK,
-       QDSP_MODULE_MIDI,
-       QDSP_MODULE_GAUDIO,
-       QDSP_MODULE_VDEC_LP_MODE,
-       QDSP_MODULE_MAX,
-} qdsp_module_type;
-
-#define QDSP_RTOS_MAX_TASK_ID  19U
-
-/* Table of modules indexed by task ID for the GAUDIO image */
-static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_AUDPLAY1TASK,
-       QDSP_MODULE_AUDPLAY2TASK,
-       QDSP_MODULE_AUDPLAY3TASK,
-       QDSP_MODULE_AUDPLAY4TASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_GRAPHICSTASK,
-       QDSP_MODULE_MAX
-};
-
-/* Queue offset table indexed by queue ID for the GAUDIO image */
-static uint32_t qdsp_gaudio_queue_offset_table[] = {
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
-       0x3f0,               /* QDSP_mpuAfeQueue                  */
-       0x420,               /* QDSP_mpuGraphicsCmdQueue          */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecCmdQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecPktQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
-       0x3f4,               /* QDSP_uPAudPPCmd1Queue             */
-       0x3f8,               /* QDSP_uPAudPPCmd2Queue             */
-       0x3fc,               /* QDSP_uPAudPPCmd3Queue             */
-       0x40c,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
-       0x410,               /* QDSP_uPAudPlay1BitStreamCtrlQueue */
-       0x414,               /* QDSP_uPAudPlay2BitStreamCtrlQueue */
-       0x418,               /* QDSP_uPAudPlay3BitStreamCtrlQueue */
-       0x41c,               /* QDSP_uPAudPlay4BitStreamCtrlQueue */
-       0x400,               /* QDSP_uPAudPreProcCmdQueue         */
-       0x408,               /* QDSP_uPAudRecBitStreamQueue       */
-       0x404,               /* QDSP_uPAudRecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
-       QDSP_RTOS_NO_QUEUE   /* QDSP_vfeCommandTableQueue         */
-};
-
-/* Table of modules indexed by task ID for the COMBO image */
-static qdsp_module_type qdsp_combo_task_to_module_table[] = {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_VOCDECTASK,
-       QDSP_MODULE_VOCENCTASK,
-       QDSP_MODULE_VIDEOTASK,
-       QDSP_MODULE_VIDEOENCTASK,
-       QDSP_MODULE_VOICEPROCTASK,
-       QDSP_MODULE_VFETASK,
-       QDSP_MODULE_JPEGTASK,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_AUDPLAY1TASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_LPMTASK,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_MODMATHTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX
-};
-
-/* Queue offset table indexed by queue ID for the COMBO image */
-static uint32_t qdsp_combo_queue_offset_table[] = {
-       0x6f2,               /* QDSP_lpmCommandQueue              */
-       0x69e,               /* QDSP_mpuAfeQueue                  */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
-       0x6b2,               /* QDSP_mpuModmathCmdQueue           */
-       0x6c6,               /* QDSP_mpuVDecCmdQueue              */
-       0x6ca,               /* QDSP_mpuVDecPktQueue              */
-       0x6c2,               /* QDSP_mpuVEncCmdQueue              */
-       0x6a6,               /* QDSP_rxMpuDecCmdQueue             */
-       0x6aa,               /* QDSP_rxMpuDecPktQueue             */
-       0x6ae,               /* QDSP_txMpuEncQueue                */
-       0x6ce,               /* QDSP_uPAudPPCmd1Queue             */
-       0x6d2,               /* QDSP_uPAudPPCmd2Queue             */
-       0x6d6,               /* QDSP_uPAudPPCmd3Queue             */
-       0x6e6,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
-       0x6da,               /* QDSP_uPAudPreProcCmdQueue         */
-       0x6e2,               /* QDSP_uPAudRecBitStreamQueue       */
-       0x6de,               /* QDSP_uPAudRecCmdQueue             */
-       0x6ee,               /* QDSP_uPJpegActionCmdQueue         */
-       0x6ea,               /* QDSP_uPJpegCfgCmdQueue            */
-       0x6a2,               /* QDSP_uPVocProcQueue               */
-       0x6b6,               /* QDSP_vfeCommandQueue              */
-       0x6be,               /* QDSP_vfeCommandScaleQueue         */
-       0x6ba                /* QDSP_vfeCommandTableQueue         */
-};
-
-/* Table of modules indexed by task ID for the QTV_LP image */
-static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_VIDEOTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX
-};
-
-/* Queue offset table indexed by queue ID for the QTV_LP image */
-static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
-       0x430,               /* QDSP_mpuAfeQueue                  */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
-       0x434,               /* QDSP_mpuVDecCmdQueue              */
-       0x438,               /* QDSP_mpuVDecPktQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
-       0x440,               /* QDSP_uPAudPPCmd1Queue             */
-       0x444,               /* QDSP_uPAudPPCmd2Queue             */
-       0x448,               /* QDSP_uPAudPPCmd3Queue             */
-       0x454,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
-       0x43c,               /* QDSP_uPAudPreProcCmdQueue         */
-       0x450,               /* QDSP_uPAudRecBitStreamQueue       */
-       0x44c,               /* QDSP_uPAudRecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
-       QDSP_RTOS_NO_QUEUE   /* QDSP_vfeCommandTableQueue         */
-};
-
-/* Tables to convert tasks to modules */
-static qdsp_module_type *qdsp_task_to_module[] = {
-       qdsp_combo_task_to_module_table,
-       qdsp_gaudio_task_to_module_table,
-       qdsp_qtv_lp_task_to_module_table,
-};
-
-/* Tables to retrieve queue offsets */
-static uint32_t *qdsp_queue_offset_table[] = {
-       qdsp_combo_queue_offset_table,
-       qdsp_gaudio_queue_offset_table,
-       qdsp_qtv_lp_queue_offset_table,
-};
-
-#define QDSP_MODULE(n) \
-       { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n }
-
-static struct adsp_module_info module_info[] = {
-       QDSP_MODULE(AUDPLAY0TASK),
-       QDSP_MODULE(AUDPPTASK),
-       QDSP_MODULE(AUDPREPROCTASK),
-       QDSP_MODULE(AUDRECTASK),
-       QDSP_MODULE(VFETASK),
-       QDSP_MODULE(QCAMTASK),
-       QDSP_MODULE(LPMTASK),
-       QDSP_MODULE(JPEGTASK),
-       QDSP_MODULE(VIDEOTASK),
-       QDSP_MODULE(VDEC_LP_MODE),
-};
-
-int adsp_init_info(struct adsp_info *info)
-{
-       info->send_irq =   0x00c00200;
-       info->read_ctrl =  0x00400038;
-       info->write_ctrl = 0x00400034;
-
-       info->max_msg16_size = 193;
-       info->max_msg32_size = 8;
-
-       info->max_task_id = 16;
-       info->max_module_id = QDSP_MODULE_MAX - 1;
-       info->max_queue_id = QDSP_QUEUE_MAX;
-       info->max_image_id = 2;
-       info->queue_offset = qdsp_queue_offset_table;
-       info->task_to_module = qdsp_task_to_module;
-
-       info->module_count = ARRAY_SIZE(module_info);
-       info->module = module_info;
-       return 0;
-}
diff --git a/drivers/staging/dream/qdsp5/adsp_6225.c b/drivers/staging/dream/qdsp5/adsp_6225.c
deleted file mode 100644 (file)
index 5078afb..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_6225.h
- *
- * Copyright (c) 2008 QUALCOMM Incorporated.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include "adsp.h"
-
-/* Firmware modules */
-typedef enum {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_AUDPLAY1TASK,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_VIDEOTASK,
-       QDSP_MODULE_VIDEO_AAC_VOC,
-       QDSP_MODULE_PCM_DEC,
-       QDSP_MODULE_AUDIO_DEC_MP3,
-       QDSP_MODULE_AUDIO_DEC_AAC,
-       QDSP_MODULE_AUDIO_DEC_WMA,
-       QDSP_MODULE_HOSTPCM,
-       QDSP_MODULE_DTMF,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_SBC_ENC,
-       QDSP_MODULE_VOC_UMTS,
-       QDSP_MODULE_VOC_CDMA,
-       QDSP_MODULE_VOC_PCM,
-       QDSP_MODULE_VOCENCTASK,
-       QDSP_MODULE_VOCDECTASK,
-       QDSP_MODULE_VOICEPROCTASK,
-       QDSP_MODULE_VIDEOENCTASK,
-       QDSP_MODULE_VFETASK,
-       QDSP_MODULE_WAV_ENC,
-       QDSP_MODULE_AACLC_ENC,
-       QDSP_MODULE_VIDEO_AMR,
-       QDSP_MODULE_VOC_AMR,
-       QDSP_MODULE_VOC_EVRC,
-       QDSP_MODULE_VOC_13K,
-       QDSP_MODULE_VOC_FGV,
-       QDSP_MODULE_DIAGTASK,
-       QDSP_MODULE_JPEGTASK,
-       QDSP_MODULE_LPMTASK,
-       QDSP_MODULE_QCAMTASK,
-       QDSP_MODULE_MODMATHTASK,
-       QDSP_MODULE_AUDPLAY2TASK,
-       QDSP_MODULE_AUDPLAY3TASK,
-       QDSP_MODULE_AUDPLAY4TASK,
-       QDSP_MODULE_GRAPHICSTASK,
-       QDSP_MODULE_MIDI,
-       QDSP_MODULE_GAUDIO,
-       QDSP_MODULE_VDEC_LP_MODE,
-       QDSP_MODULE_MAX,
-} qdsp_module_type;
-
-#define QDSP_RTOS_MAX_TASK_ID  30U
-
-/* Table of modules indexed by task ID for the GAUDIO image */
-static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_AUDPLAY1TASK,
-       QDSP_MODULE_AUDPLAY2TASK,
-       QDSP_MODULE_AUDPLAY3TASK,
-       QDSP_MODULE_AUDPLAY4TASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_GRAPHICSTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-};
-
-/* Queue offset table indexed by queue ID for the GAUDIO image */
-static uint32_t qdsp_gaudio_queue_offset_table[] = {
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
-       0x3f0,               /* QDSP_mpuAfeQueue                  */
-       0x420,               /* QDSP_mpuGraphicsCmdQueue          */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecCmdQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecPktQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
-       0x3f4,               /* QDSP_uPAudPPCmd1Queue             */
-       0x3f8,               /* QDSP_uPAudPPCmd2Queue             */
-       0x3fc,               /* QDSP_uPAudPPCmd3Queue             */
-       0x40c,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
-       0x410,               /* QDSP_uPAudPlay1BitStreamCtrlQueue */
-       0x414,               /* QDSP_uPAudPlay2BitStreamCtrlQueue */
-       0x418,               /* QDSP_uPAudPlay3BitStreamCtrlQueue */
-       0x41c,               /* QDSP_uPAudPlay4BitStreamCtrlQueue */
-       0x400,               /* QDSP_uPAudPreProcCmdQueue         */
-       0x408,               /* QDSP_uPAudRecBitStreamQueue       */
-       0x404,               /* QDSP_uPAudRecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandTableQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPDiagQueue                  */
-};
-
-/* Table of modules indexed by task ID for the COMBO image */
-static qdsp_module_type qdsp_combo_task_to_module_table[] = {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_VOCDECTASK,
-       QDSP_MODULE_VOCENCTASK,
-       QDSP_MODULE_VIDEOTASK,
-       QDSP_MODULE_VIDEOENCTASK,
-       QDSP_MODULE_VOICEPROCTASK,
-       QDSP_MODULE_VFETASK,
-       QDSP_MODULE_JPEGTASK,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_AUDPLAY1TASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_LPMTASK,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_MODMATHTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_DIAGTASK,
-       QDSP_MODULE_MAX,
-};
-
-/* Queue offset table indexed by queue ID for the COMBO image */
-static uint32_t qdsp_combo_queue_offset_table[] = {
-       0x714,               /* QDSP_lpmCommandQueue              */
-       0x6bc,               /* QDSP_mpuAfeQueue                  */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
-       0x6d0,               /* QDSP_mpuModmathCmdQueue           */
-       0x6e8,               /* QDSP_mpuVDecCmdQueue              */
-       0x6ec,               /* QDSP_mpuVDecPktQueue              */
-       0x6e4,               /* QDSP_mpuVEncCmdQueue              */
-       0x6c4,               /* QDSP_rxMpuDecCmdQueue             */
-       0x6c8,               /* QDSP_rxMpuDecPktQueue             */
-       0x6cc,               /* QDSP_txMpuEncQueue                */
-       0x6f0,               /* QDSP_uPAudPPCmd1Queue             */
-       0x6f4,               /* QDSP_uPAudPPCmd2Queue             */
-       0x6f8,               /* QDSP_uPAudPPCmd3Queue             */
-       0x708,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
-       0x6fc,               /* QDSP_uPAudPreProcCmdQueue         */
-       0x704,               /* QDSP_uPAudRecBitStreamQueue       */
-       0x700,               /* QDSP_uPAudRecCmdQueue             */
-       0x710,               /* QDSP_uPJpegActionCmdQueue         */
-       0x70c,               /* QDSP_uPJpegCfgCmdQueue            */
-       0x6c0,               /* QDSP_uPVocProcQueue               */
-       0x6d8,               /* QDSP_vfeCommandQueue              */
-       0x6e0,               /* QDSP_vfeCommandScaleQueue         */
-       0x6dc,               /* QDSP_vfeCommandTableQueue         */
-       0x6d4,               /* QDSP_uPDiagQueue                  */
-};
-
-/* Table of modules indexed by task ID for the QTV_LP image */
-static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
-       QDSP_MODULE_KERNEL,
-       QDSP_MODULE_AFETASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_VIDEOTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDPPTASK,
-       QDSP_MODULE_AUDPLAY0TASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_AUDRECTASK,
-       QDSP_MODULE_AUDPREPROCTASK,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-       QDSP_MODULE_MAX,
-};
-
-/* Queue offset table indexed by queue ID for the QTV_LP image */
-static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
-       0x3fe,               /* QDSP_mpuAfeQueue                  */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
-       0x402,               /* QDSP_mpuVDecCmdQueue              */
-       0x406,               /* QDSP_mpuVDecPktQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
-       0x40e,               /* QDSP_uPAudPPCmd1Queue             */
-       0x412,               /* QDSP_uPAudPPCmd2Queue             */
-       0x416,               /* QDSP_uPAudPPCmd3Queue             */
-       0x422,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
-       0x40a,               /* QDSP_uPAudPreProcCmdQueue         */
-       0x41e,               /* QDSP_uPAudRecBitStreamQueue       */
-       0x41a,               /* QDSP_uPAudRecCmdQueue             */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandTableQueue         */
-       QDSP_RTOS_NO_QUEUE,  /* QDSP_uPDiagQueue                  */
-};
-
-/* Tables to convert tasks to modules */
-static qdsp_module_type *qdsp_task_to_module[] = {
-       qdsp_combo_task_to_module_table,
-       qdsp_gaudio_task_to_module_table,
-       qdsp_qtv_lp_task_to_module_table,
-};
-
-/* Tables to retrieve queue offsets */
-static uint32_t *qdsp_queue_offset_table[] = {
-       qdsp_combo_queue_offset_table,
-       qdsp_gaudio_queue_offset_table,
-       qdsp_qtv_lp_queue_offset_table,
-};
-
-#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \
-       { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \
-         .clk_name = clkname, .clk_rate = clkrate, \
-         .verify_cmd = verify_cmd_func, .patch_event = patch_event_func }
-
-static struct adsp_module_info module_info[] = {
-       QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd,
-               adsp_vfe_patch_event),
-       QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL),
-       QDSP_MODULE(JPEGTASK, "vdc_clk", 0, adsp_jpeg_verify_cmd,
-               adsp_jpeg_patch_event),
-       QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000,
-               adsp_video_verify_cmd, NULL),
-       QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL),
-       QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000,
-               adsp_videoenc_verify_cmd, NULL),
-};
-
-int adsp_init_info(struct adsp_info *info)
-{
-       info->send_irq =   0x00c00200;
-       info->read_ctrl =  0x00400038;
-       info->write_ctrl = 0x00400034;
-
-       info->max_msg16_size = 193;
-       info->max_msg32_size = 8;
-
-       info->max_task_id = 16;
-       info->max_module_id = QDSP_MODULE_MAX - 1;
-       info->max_queue_id = QDSP_QUEUE_MAX;
-       info->max_image_id = 2;
-       info->queue_offset = qdsp_queue_offset_table;
-       info->task_to_module = qdsp_task_to_module;
-
-       info->module_count = ARRAY_SIZE(module_info);
-       info->module = module_info;
-       return 0;
-}
diff --git a/drivers/staging/dream/qdsp5/adsp_driver.c b/drivers/staging/dream/qdsp5/adsp_driver.c
deleted file mode 100644 (file)
index 28a6f8d..0000000
+++ /dev/null
@@ -1,643 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_driver.c
- *
- * Copyright (C) 2008 Google, Inc.
- * Author: Iliyan Malchev <ibm@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/cdev.h>
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include "adsp.h"
-
-#include <linux/msm_adsp.h>
-#include <linux/android_pmem.h>
-
-struct adsp_pmem_region {
-       struct hlist_node list;
-       void *vaddr;
-       unsigned long paddr;
-       unsigned long kvaddr;
-       unsigned long len;
-       struct file *file;
-};
-
-struct adsp_device {
-       struct msm_adsp_module *module;
-
-       spinlock_t event_queue_lock;
-       wait_queue_head_t event_wait;
-       struct list_head event_queue;
-       int abort;
-
-       const char *name;
-       struct device *device;
-       struct cdev cdev;
-};
-
-static struct adsp_device *inode_to_device(struct inode *inode);
-
-#define __CONTAINS(r, v, l) ({                                 \
-       typeof(r) __r = r;                                      \
-       typeof(v) __v = v;                                      \
-       typeof(v) __e = __v + l;                                \
-       int res = __v >= __r->vaddr &&                          \
-               __e <= __r->vaddr + __r->len;                   \
-       res;                                                    \
-})
-
-#define CONTAINS(r1, r2) ({                                    \
-       typeof(r2) __r2 = r2;                                   \
-       __CONTAINS(r1, __r2->vaddr, __r2->len);                 \
-})
-
-#define IN_RANGE(r, v) ({                                      \
-       typeof(r) __r = r;                                      \
-       typeof(v) __vv = v;                                     \
-       int res = ((__vv >= __r->vaddr) &&                      \
-               (__vv < (__r->vaddr + __r->len)));              \
-       res;                                                    \
-})
-
-#define OVERLAPS(r1, r2) ({                                    \
-       typeof(r1) __r1 = r1;                                   \
-       typeof(r2) __r2 = r2;                                   \
-       typeof(__r2->vaddr) __v = __r2->vaddr;                  \
-       typeof(__v) __e = __v + __r2->len - 1;                  \
-       int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \
-       res;                                                    \
-})
-
-static int adsp_pmem_check(struct msm_adsp_module *module,
-               void *vaddr, unsigned long len)
-{
-       struct adsp_pmem_region *region_elt;
-       struct hlist_node *node;
-       struct adsp_pmem_region t = { .vaddr = vaddr, .len = len };
-
-       hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
-               if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
-                   OVERLAPS(region_elt, &t)) {
-                       printk(KERN_ERR "adsp: module %s:"
-                               " region (vaddr %p len %ld)"
-                               " clashes with registered region"
-                               " (vaddr %p paddr %p len %ld)\n",
-                               module->name,
-                               vaddr, len,
-                               region_elt->vaddr,
-                               (void *)region_elt->paddr,
-                               region_elt->len);
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-
-static int adsp_pmem_add(struct msm_adsp_module *module,
-                        struct adsp_pmem_info *info)
-{
-       unsigned long paddr, kvaddr, len;
-       struct file *file;
-       struct adsp_pmem_region *region;
-       int rc = -EINVAL;
-
-       mutex_lock(&module->pmem_regions_lock);
-       region = kmalloc(sizeof(*region), GFP_KERNEL);
-       if (!region) {
-               rc = -ENOMEM;
-               goto end;
-       }
-       INIT_HLIST_NODE(&region->list);
-       if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
-               kfree(region);
-               goto end;
-       }
-
-       rc = adsp_pmem_check(module, info->vaddr, len);
-       if (rc < 0) {
-               put_pmem_file(file);
-               kfree(region);
-               goto end;
-       }
-
-       region->vaddr = info->vaddr;
-       region->paddr = paddr;
-       region->kvaddr = kvaddr;
-       region->len = len;
-       region->file = file;
-
-       hlist_add_head(&region->list, &module->pmem_regions);
-end:
-       mutex_unlock(&module->pmem_regions_lock);
-       return rc;
-}
-
-static int adsp_pmem_lookup_vaddr(struct msm_adsp_module *module, void **addr,
-                    unsigned long len, struct adsp_pmem_region **region)
-{
-       struct hlist_node *node;
-       void *vaddr = *addr;
-       struct adsp_pmem_region *region_elt;
-
-       int match_count = 0;
-
-       *region = NULL;
-
-       /* returns physical address or zero */
-       hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
-               if (vaddr >= region_elt->vaddr &&
-                   vaddr < region_elt->vaddr + region_elt->len &&
-                   vaddr + len <= region_elt->vaddr + region_elt->len) {
-                       /* offset since we could pass vaddr inside a registerd
-                        * pmem buffer
-                        */
-
-                       match_count++;
-                       if (!*region)
-                               *region = region_elt;
-               }
-       }
-
-       if (match_count > 1) {
-               printk(KERN_ERR "adsp: module %s: "
-                       "multiple hits for vaddr %p, len %ld\n",
-                       module->name, vaddr, len);
-               hlist_for_each_entry(region_elt, node,
-                               &module->pmem_regions, list) {
-                       if (vaddr >= region_elt->vaddr &&
-                           vaddr < region_elt->vaddr + region_elt->len &&
-                           vaddr + len <= region_elt->vaddr + region_elt->len)
-                               printk(KERN_ERR "\t%p, %ld --> %p\n",
-                                       region_elt->vaddr,
-                                       region_elt->len,
-                                       (void *)region_elt->paddr);
-               }
-       }
-
-       return *region ? 0 : -1;
-}
-
-int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr,
-                          unsigned long *kvaddr, unsigned long len)
-{
-       struct adsp_pmem_region *region;
-       void *vaddr = *addr;
-       unsigned long *paddr = (unsigned long *)addr;
-       int ret;
-
-       ret = adsp_pmem_lookup_vaddr(module, addr, len, &region);
-       if (ret) {
-               printk(KERN_ERR "adsp: not patching %s (paddr & kvaddr),"
-                       " lookup (%p, %ld) failed\n",
-                       module->name, vaddr, len);
-               return ret;
-       }
-       *paddr = region->paddr + (vaddr - region->vaddr);
-       *kvaddr = region->kvaddr + (vaddr - region->vaddr);
-       return 0;
-}
-
-int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr,
-                   unsigned long len)
-{
-       struct adsp_pmem_region *region;
-       void *vaddr = *addr;
-       unsigned long *paddr = (unsigned long *)addr;
-       int ret;
-
-       ret = adsp_pmem_lookup_vaddr(module, addr, len, &region);
-       if (ret) {
-               printk(KERN_ERR "adsp: not patching %s, lookup (%p, %ld) failed\n",
-                       module->name, vaddr, len);
-               return ret;
-       }
-
-       *paddr = region->paddr + (vaddr - region->vaddr);
-       return 0;
-}
-
-static int adsp_verify_cmd(struct msm_adsp_module *module,
-                          unsigned int queue_id, void *cmd_data,
-                          size_t cmd_size)
-{
-       /* call the per module verifier */
-       if (module->verify_cmd)
-               return module->verify_cmd(module, queue_id, cmd_data,
-                                            cmd_size);
-       else
-               printk(KERN_INFO "adsp: no packet verifying function "
-                                "for task %s\n", module->name);
-       return 0;
-}
-
-static long adsp_write_cmd(struct adsp_device *adev, void __user *arg)
-{
-       struct adsp_command_t cmd;
-       unsigned char buf[256];
-       void *cmd_data;
-       long rc;
-
-       if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)))
-               return -EFAULT;
-
-       if (cmd.len > 256) {
-               cmd_data = kmalloc(cmd.len, GFP_USER);
-               if (!cmd_data)
-                       return -ENOMEM;
-       } else {
-               cmd_data = buf;
-       }
-
-       if (copy_from_user(cmd_data, (void __user *)(cmd.data), cmd.len)) {
-               rc = -EFAULT;
-               goto end;
-       }
-
-       mutex_lock(&adev->module->pmem_regions_lock);
-       if (adsp_verify_cmd(adev->module, cmd.queue, cmd_data, cmd.len)) {
-               printk(KERN_ERR "module %s: verify failed.\n",
-                       adev->module->name);
-               rc = -EINVAL;
-               goto end;
-       }
-       rc = msm_adsp_write(adev->module, cmd.queue, cmd_data, cmd.len);
-end:
-       mutex_unlock(&adev->module->pmem_regions_lock);
-
-       if (cmd.len > 256)
-               kfree(cmd_data);
-
-       return rc;
-}
-
-static int adsp_events_pending(struct adsp_device *adev)
-{
-       unsigned long flags;
-       int yes;
-       spin_lock_irqsave(&adev->event_queue_lock, flags);
-       yes = !list_empty(&adev->event_queue);
-       spin_unlock_irqrestore(&adev->event_queue_lock, flags);
-       return yes || adev->abort;
-}
-
-static int adsp_pmem_lookup_paddr(struct msm_adsp_module *module, void **addr,
-                    struct adsp_pmem_region **region)
-{
-       struct hlist_node *node;
-       unsigned long paddr = (unsigned long)(*addr);
-       struct adsp_pmem_region *region_elt;
-
-       hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
-               if (paddr >= region_elt->paddr &&
-                   paddr < region_elt->paddr + region_elt->len) {
-                       *region = region_elt;
-                       return 0;
-               }
-       }
-       return -1;
-}
-
-int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr)
-{
-       struct adsp_pmem_region *region;
-       unsigned long paddr = (unsigned long)(*addr);
-       unsigned long *vaddr = (unsigned long *)addr;
-       int ret;
-
-       ret = adsp_pmem_lookup_paddr(module, addr, &region);
-       if (ret) {
-               printk(KERN_ERR "adsp: not patching %s, paddr %p lookup failed\n",
-                       module->name, vaddr);
-               return ret;
-       }
-
-       *vaddr = (unsigned long)region->vaddr + (paddr - region->paddr);
-       return 0;
-}
-
-static int adsp_patch_event(struct msm_adsp_module *module,
-                               struct adsp_event *event)
-{
-       /* call the per-module msg verifier */
-       if (module->patch_event)
-               return module->patch_event(module, event);
-       return 0;
-}
-
-static long adsp_get_event(struct adsp_device *adev, void __user *arg)
-{
-       unsigned long flags;
-       struct adsp_event *data = NULL;
-       struct adsp_event_t evt;
-       int timeout;
-       long rc = 0;
-
-       if (copy_from_user(&evt, arg, sizeof(struct adsp_event_t)))
-               return -EFAULT;
-
-       timeout = (int)evt.timeout_ms;
-
-       if (timeout > 0) {
-               rc = wait_event_interruptible_timeout(
-                       adev->event_wait, adsp_events_pending(adev),
-                       msecs_to_jiffies(timeout));
-               if (rc == 0)
-                       return -ETIMEDOUT;
-       } else {
-               rc = wait_event_interruptible(
-                       adev->event_wait, adsp_events_pending(adev));
-       }
-       if (rc < 0)
-               return rc;
-
-       if (adev->abort)
-               return -ENODEV;
-
-       spin_lock_irqsave(&adev->event_queue_lock, flags);
-       if (!list_empty(&adev->event_queue)) {
-               data = list_first_entry(&adev->event_queue,
-                                       struct adsp_event, list);
-               list_del(&data->list);
-       }
-       spin_unlock_irqrestore(&adev->event_queue_lock, flags);
-
-       if (!data)
-               return -EAGAIN;
-
-       /* DSP messages are type 0; they may contain physical addresses */
-       if (data->type == 0)
-               adsp_patch_event(adev->module, data);
-
-       /* map adsp_event --> adsp_event_t */
-       if (evt.len < data->size) {
-               rc = -ETOOSMALL;
-               goto end;
-       }
-       if (data->msg_id != EVENT_MSG_ID) {
-               if (copy_to_user((void *)(evt.data), data->data.msg16,
-                                       data->size)) {
-                       rc = -EFAULT;
-                       goto end;
-       }
-       } else {
-               if (copy_to_user((void *)(evt.data), data->data.msg32,
-                                       data->size)) {
-                       rc = -EFAULT;
-                       goto end;
-               }
-       }
-
-       evt.type = data->type; /* 0 --> from aDSP, 1 --> from ARM9 */
-       evt.msg_id = data->msg_id;
-       evt.flags = data->is16;
-       evt.len = data->size;
-       if (copy_to_user(arg, &evt, sizeof(evt)))
-               rc = -EFAULT;
-end:
-       kfree(data);
-       return rc;
-}
-
-static long adsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-       struct adsp_device *adev = filp->private_data;
-
-       switch (cmd) {
-       case ADSP_IOCTL_ENABLE:
-               return msm_adsp_enable(adev->module);
-
-       case ADSP_IOCTL_DISABLE:
-               return msm_adsp_disable(adev->module);
-
-       case ADSP_IOCTL_DISABLE_EVENT_RSP:
-               return 0;
-
-       case ADSP_IOCTL_DISABLE_ACK:
-               pr_err("adsp: ADSP_IOCTL_DISABLE_ACK is not implemented.\n");
-               break;
-
-       case ADSP_IOCTL_WRITE_COMMAND:
-               return adsp_write_cmd(adev, (void __user *) arg);
-
-       case ADSP_IOCTL_GET_EVENT:
-               return adsp_get_event(adev, (void __user *) arg);
-
-       case ADSP_IOCTL_SET_CLKRATE: {
-#if CONFIG_MSM_AMSS_VERSION==6350
-               unsigned long clk_rate;
-               if (copy_from_user(&clk_rate, (void *) arg, sizeof(clk_rate)))
-                       return -EFAULT;
-               return adsp_set_clkrate(adev->module, clk_rate);
-#endif
-       }
-
-       case ADSP_IOCTL_REGISTER_PMEM: {
-               struct adsp_pmem_info info;
-               if (copy_from_user(&info, (void *) arg, sizeof(info)))
-                       return -EFAULT;
-               return adsp_pmem_add(adev->module, &info);
-       }
-
-       case ADSP_IOCTL_ABORT_EVENT_READ:
-               adev->abort = 1;
-               wake_up(&adev->event_wait);
-               break;
-
-       default:
-               break;
-       }
-       return -EINVAL;
-}
-
-static int adsp_release(struct inode *inode, struct file *filp)
-{
-       struct adsp_device *adev = filp->private_data;
-       struct msm_adsp_module *module = adev->module;
-       struct hlist_node *node, *tmp;
-       struct adsp_pmem_region *region;
-
-       pr_info("adsp_release() '%s'\n", adev->name);
-
-       /* clear module before putting it to avoid race with open() */
-       adev->module = NULL;
-
-       mutex_lock(&module->pmem_regions_lock);
-       hlist_for_each_safe(node, tmp, &module->pmem_regions) {
-               region = hlist_entry(node, struct adsp_pmem_region, list);
-               hlist_del(node);
-               put_pmem_file(region->file);
-               kfree(region);
-       }
-       mutex_unlock(&module->pmem_regions_lock);
-       BUG_ON(!hlist_empty(&module->pmem_regions));
-
-       msm_adsp_put(module);
-       return 0;
-}
-
-static void adsp_event(void *driver_data, unsigned id, size_t len,
-                      void (*getevent)(void *ptr, size_t len))
-{
-       struct adsp_device *adev = driver_data;
-       struct adsp_event *event;
-       unsigned long flags;
-
-       if (len > ADSP_EVENT_MAX_SIZE) {
-               pr_err("adsp_event: event too large (%d bytes)\n", len);
-               return;
-       }
-
-       event = kmalloc(sizeof(*event), GFP_ATOMIC);
-       if (!event) {
-               pr_err("adsp_event: cannot allocate buffer\n");
-               return;
-       }
-
-       if (id != EVENT_MSG_ID) {
-               event->type = 0;
-               event->is16 = 0;
-               event->msg_id = id;
-               event->size = len;
-
-               getevent(event->data.msg16, len);
-       } else {
-               event->type = 1;
-               event->is16 = 1;
-               event->msg_id = id;
-               event->size = len;
-               getevent(event->data.msg32, len);
-       }
-
-       spin_lock_irqsave(&adev->event_queue_lock, flags);
-       list_add_tail(&event->list, &adev->event_queue);
-       spin_unlock_irqrestore(&adev->event_queue_lock, flags);
-       wake_up(&adev->event_wait);
-}
-
-static struct msm_adsp_ops adsp_ops = {
-       .event = adsp_event,
-};
-
-static int adsp_open(struct inode *inode, struct file *filp)
-{
-       struct adsp_device *adev;
-       int rc;
-
-       rc = nonseekable_open(inode, filp);
-       if (rc < 0)
-               return rc;
-
-       adev = inode_to_device(inode);
-       if (!adev)
-               return -ENODEV;
-
-       pr_info("adsp_open() name = '%s'\n", adev->name);
-
-       rc = msm_adsp_get(adev->name, &adev->module, &adsp_ops, adev);
-       if (rc)
-               return rc;
-
-       pr_info("adsp_open() module '%s' adev %p\n", adev->name, adev);
-       filp->private_data = adev;
-       adev->abort = 0;
-       INIT_HLIST_HEAD(&adev->module->pmem_regions);
-       mutex_init(&adev->module->pmem_regions_lock);
-
-       return 0;
-}
-
-static unsigned adsp_device_count;
-static struct adsp_device *adsp_devices;
-
-static struct adsp_device *inode_to_device(struct inode *inode)
-{
-       unsigned n = MINOR(inode->i_rdev);
-       if (n < adsp_device_count) {
-               if (adsp_devices[n].device)
-                       return adsp_devices + n;
-       }
-       return NULL;
-}
-
-static dev_t adsp_devno;
-static struct class *adsp_class;
-
-static struct file_operations adsp_fops = {
-       .owner = THIS_MODULE,
-       .open = adsp_open,
-       .unlocked_ioctl = adsp_ioctl,
-       .release = adsp_release,
-       .llseek = no_llseek,
-};
-
-static void adsp_create(struct adsp_device *adev, const char *name,
-                       struct device *parent, dev_t devt)
-{
-       struct device *dev;
-       int rc;
-
-       dev = device_create(adsp_class, parent, devt, "%s", name);
-       if (IS_ERR(dev))
-               return;
-
-       init_waitqueue_head(&adev->event_wait);
-       INIT_LIST_HEAD(&adev->event_queue);
-       spin_lock_init(&adev->event_queue_lock);
-
-       cdev_init(&adev->cdev, &adsp_fops);
-       adev->cdev.owner = THIS_MODULE;
-
-       rc = cdev_add(&adev->cdev, devt, 1);
-       if (rc < 0) {
-               device_destroy(adsp_class, devt);
-       } else {
-               adev->device = dev;
-               adev->name = name;
-       }
-}
-
-void msm_adsp_publish_cdevs(struct msm_adsp_module *modules, unsigned n)
-{
-       int rc;
-
-       adsp_devices = kzalloc(sizeof(struct adsp_device) * n, GFP_KERNEL);
-       if (!adsp_devices)
-               return;
-
-       adsp_class = class_create(THIS_MODULE, "adsp");
-       if (IS_ERR(adsp_class))
-               goto fail_create_class;
-
-       rc = alloc_chrdev_region(&adsp_devno, 0, n, "adsp");
-       if (rc < 0)
-               goto fail_alloc_region;
-
-       adsp_device_count = n;
-       for (n = 0; n < adsp_device_count; n++) {
-               adsp_create(adsp_devices + n,
-                           modules[n].name, &modules[n].pdev.dev,
-                           MKDEV(MAJOR(adsp_devno), n));
-       }
-
-       return;
-
-fail_alloc_region:
-       class_unregister(adsp_class);
-fail_create_class:
-       kfree(adsp_devices);
-}
diff --git a/drivers/staging/dream/qdsp5/adsp_info.c b/drivers/staging/dream/qdsp5/adsp_info.c
deleted file mode 100644 (file)
index b9c77d2..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/* arch/arm/mach-msm/adsp_info.c
- *
- * Copyright (c) 2008 QUALCOMM Incorporated.
- * Copyright (c) 2008 QUALCOMM USA, INC.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include "adsp.h"
-
-/* Firmware modules */
-#define QDSP_MODULE_KERNEL                  0x0106dd4e
-#define QDSP_MODULE_AFETASK                 0x0106dd6f
-#define QDSP_MODULE_AUDPLAY0TASK            0x0106dd70
-#define QDSP_MODULE_AUDPLAY1TASK            0x0106dd71
-#define QDSP_MODULE_AUDPPTASK               0x0106dd72
-#define QDSP_MODULE_VIDEOTASK               0x0106dd73
-#define QDSP_MODULE_VIDEO_AAC_VOC           0x0106dd74
-#define QDSP_MODULE_PCM_DEC                 0x0106dd75
-#define QDSP_MODULE_AUDIO_DEC_MP3           0x0106dd76
-#define QDSP_MODULE_AUDIO_DEC_AAC           0x0106dd77
-#define QDSP_MODULE_AUDIO_DEC_WMA           0x0106dd78
-#define QDSP_MODULE_HOSTPCM                 0x0106dd79
-#define QDSP_MODULE_DTMF                    0x0106dd7a
-#define QDSP_MODULE_AUDRECTASK              0x0106dd7b
-#define QDSP_MODULE_AUDPREPROCTASK          0x0106dd7c
-#define QDSP_MODULE_SBC_ENC                 0x0106dd7d
-#define QDSP_MODULE_VOC_UMTS                0x0106dd9a
-#define QDSP_MODULE_VOC_CDMA                0x0106dd98
-#define QDSP_MODULE_VOC_PCM                 0x0106dd7f
-#define QDSP_MODULE_VOCENCTASK              0x0106dd80
-#define QDSP_MODULE_VOCDECTASK              0x0106dd81
-#define QDSP_MODULE_VOICEPROCTASK           0x0106dd82
-#define QDSP_MODULE_VIDEOENCTASK            0x0106dd83
-#define QDSP_MODULE_VFETASK                 0x0106dd84
-#define QDSP_MODULE_WAV_ENC                 0x0106dd85
-#define QDSP_MODULE_AACLC_ENC               0x0106dd86
-#define QDSP_MODULE_VIDEO_AMR               0x0106dd87
-#define QDSP_MODULE_VOC_AMR                 0x0106dd88
-#define QDSP_MODULE_VOC_EVRC                0x0106dd89
-#define QDSP_MODULE_VOC_13K                 0x0106dd8a
-#define QDSP_MODULE_VOC_FGV                 0x0106dd8b
-#define QDSP_MODULE_DIAGTASK                0x0106dd8c
-#define QDSP_MODULE_JPEGTASK                0x0106dd8d
-#define QDSP_MODULE_LPMTASK                 0x0106dd8e
-#define QDSP_MODULE_QCAMTASK                0x0106dd8f
-#define QDSP_MODULE_MODMATHTASK             0x0106dd90
-#define QDSP_MODULE_AUDPLAY2TASK            0x0106dd91
-#define QDSP_MODULE_AUDPLAY3TASK            0x0106dd92
-#define QDSP_MODULE_AUDPLAY4TASK            0x0106dd93
-#define QDSP_MODULE_GRAPHICSTASK            0x0106dd94
-#define QDSP_MODULE_MIDI                    0x0106dd95
-#define QDSP_MODULE_GAUDIO                  0x0106dd96
-#define QDSP_MODULE_VDEC_LP_MODE            0x0106dd97
-#define QDSP_MODULE_MAX                     0x7fffffff
-
-   /* DO NOT USE: Force this enum to be a 32bit type to improve speed */
-#define QDSP_MODULE_32BIT_DUMMY 0x10000
-
-static uint32_t *qdsp_task_to_module[IMG_MAX];
-static uint32_t        *qdsp_queue_offset_table[IMG_MAX];
-
-#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \
-       { .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \
-         .clk_name = clkname, .clk_rate = clkrate, \
-         .verify_cmd = verify_cmd_func, .patch_event = patch_event_func }
-
-static struct adsp_module_info module_info[] = {
-       QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd,
-               adsp_vfe_patch_event),
-       QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL),
-       QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL),
-       QDSP_MODULE(JPEGTASK, "vdc_clk", 96000000, adsp_jpeg_verify_cmd,
-               adsp_jpeg_patch_event),
-       QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000,
-               adsp_video_verify_cmd, NULL),
-       QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL),
-       QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000,
-               adsp_videoenc_verify_cmd, NULL),
-};
-
-int adsp_init_info(struct adsp_info *info)
-{
-       uint32_t img_num;
-
-       info->send_irq =   0x00c00200;
-       info->read_ctrl =  0x00400038;
-       info->write_ctrl = 0x00400034;
-
-       info->max_msg16_size = 193;
-       info->max_msg32_size = 8;
-       for (img_num = 0; img_num < IMG_MAX; img_num++)
-               qdsp_queue_offset_table[img_num] =
-               &info->init_info_ptr->queue_offsets[img_num][0];
-
-       for (img_num = 0; img_num < IMG_MAX; img_num++)
-               qdsp_task_to_module[img_num] =
-               &info->init_info_ptr->task_to_module_tbl[img_num][0];
-       info->max_task_id = 30;
-       info->max_module_id = QDSP_MODULE_MAX - 1;
-       info->max_queue_id = QDSP_MAX_NUM_QUEUES;
-       info->max_image_id = 2;
-       info->queue_offset = qdsp_queue_offset_table;
-       info->task_to_module = qdsp_task_to_module;
-
-       info->module_count = ARRAY_SIZE(module_info);
-       info->module = module_info;
-       return 0;
-}
diff --git a/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c b/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c
deleted file mode 100644 (file)
index 4f493ed..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
- *
- * Verification code for aDSP JPEG events.
- *
- * Copyright (c) 2008 QUALCOMM Incorporated
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <mach/qdsp5/qdsp5jpegmsg.h>
-#include "adsp.h"
-
-int adsp_jpeg_patch_event(struct msm_adsp_module *module,
-                       struct adsp_event *event)
-{
-       if (event->msg_id == JPEG_MSG_ENC_OP_PRODUCED) {
-               jpeg_msg_enc_op_produced *op = (jpeg_msg_enc_op_produced *)event->data.msg16;
-               return adsp_pmem_paddr_fixup(module, (void **)&op->op_buf_addr);
-       }
-
-       return 0;
-}
diff --git a/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c
deleted file mode 100644 (file)
index b33eba2..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
- *
- * Verification code for aDSP JPEG packets from userspace.
- *
- * Copyright (c) 2008 QUALCOMM Incorporated
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <mach/qdsp5/qdsp5jpegcmdi.h>
-#include "adsp.h"
-
-static uint32_t dec_fmt;
-
-static inline void get_sizes(jpeg_cmd_enc_cfg *cmd, uint32_t *luma_size,
-                            uint32_t *chroma_size)
-{
-       uint32_t fmt, luma_width, luma_height;
-
-       fmt = cmd->process_cfg & JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M;
-       luma_width = (cmd->ip_size_cfg & JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M)
-                     >> 16;
-       luma_height = cmd->frag_cfg & JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M;
-       *luma_size = luma_width * luma_height;
-       if (fmt == JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2)
-               *chroma_size = *luma_size/2;
-       else
-               *chroma_size = *luma_size;
-}
-
-static inline int verify_jpeg_cmd_enc_cfg(struct msm_adsp_module *module,
-                                         void *cmd_data, size_t cmd_size)
-{
-       jpeg_cmd_enc_cfg *cmd = (jpeg_cmd_enc_cfg *)cmd_data;
-       uint32_t luma_size, chroma_size;
-       int i, num_frags;
-
-       if (cmd_size != sizeof(jpeg_cmd_enc_cfg)) {
-               printk(KERN_ERR "adsp: module %s: JPEG ENC CFG invalid cmd_size %d\n",
-                       module->name, cmd_size);
-               return -1;
-       }
-
-       get_sizes(cmd, &luma_size, &chroma_size);
-       num_frags = (cmd->process_cfg >> 10) & 0xf;
-       num_frags = ((num_frags == 1) ? num_frags : num_frags * 2);
-       for (i = 0; i < num_frags; i += 2) {
-               if (adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i]), luma_size) ||
-                   adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i+1]), chroma_size))
-                       return -1;
-       }
-
-       if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_0_cfg_part1,
-                           cmd->op_buf_0_cfg_part2) ||
-           adsp_pmem_fixup(module, (void **)&cmd->op_buf_1_cfg_part1,
-                           cmd->op_buf_1_cfg_part2))
-               return -1;
-       return 0;
-}
-
-static inline int verify_jpeg_cmd_dec_cfg(struct msm_adsp_module *module,
-                                         void *cmd_data, size_t cmd_size)
-{
-       jpeg_cmd_dec_cfg *cmd = (jpeg_cmd_dec_cfg *)cmd_data;
-       uint32_t div;
-
-       if (cmd_size != sizeof(jpeg_cmd_dec_cfg)) {
-               printk(KERN_ERR "adsp: module %s: JPEG DEC CFG invalid cmd_size %d\n",
-                       module->name, cmd_size);
-               return -1;
-       }
-
-       if (adsp_pmem_fixup(module, (void **)&cmd->ip_stream_buf_cfg_part1,
-                           cmd->ip_stream_buf_cfg_part2) ||
-           adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part1,
-                           cmd->op_stream_buf_0_cfg_part2) ||
-           adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part1,
-                           cmd->op_stream_buf_1_cfg_part2))
-               return -1;
-       dec_fmt = cmd->op_data_format &
-               JPEG_CMD_DEC_OP_DATA_FORMAT_M;
-       div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1;
-       if (adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part3,
-                           cmd->op_stream_buf_0_cfg_part2 / div) ||
-           adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part3,
-                           cmd->op_stream_buf_1_cfg_part2 / div))
-               return -1;
-       return 0;
-}
-
-static int verify_jpeg_cfg_cmd(struct msm_adsp_module *module,
-                              void *cmd_data, size_t cmd_size)
-{
-       uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
-       switch(cmd_id) {
-       case JPEG_CMD_ENC_CFG:
-               return verify_jpeg_cmd_enc_cfg(module, cmd_data, cmd_size);
-       case JPEG_CMD_DEC_CFG:
-               return verify_jpeg_cmd_dec_cfg(module, cmd_data, cmd_size);
-       default:
-               if (cmd_id > 1) {
-                       printk(KERN_ERR "adsp: module %s: invalid JPEG CFG cmd_id %d\n", module->name, cmd_id);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static int verify_jpeg_action_cmd(struct msm_adsp_module *module,
-                                 void *cmd_data, size_t cmd_size)
-{
-       uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
-       switch (cmd_id) {
-       case JPEG_CMD_ENC_OP_CONSUMED:
-       {
-               jpeg_cmd_enc_op_consumed *cmd =
-                       (jpeg_cmd_enc_op_consumed *)cmd_data;
-
-               if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) {
-                       printk(KERN_ERR "adsp: module %s: JPEG_CMD_ENC_OP_CONSUMED invalid size %d\n",
-                               module->name, cmd_size);
-                       return -1;
-               }
-
-               if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_addr,
-                                   cmd->op_buf_size))
-                       return -1;
-       }
-       break;
-       case JPEG_CMD_DEC_OP_CONSUMED:
-       {
-               uint32_t div;
-               jpeg_cmd_dec_op_consumed *cmd =
-                       (jpeg_cmd_dec_op_consumed *)cmd_data;
-
-               if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) {
-                       printk(KERN_ERR "adsp: module %s: JPEG_CMD_DEC_OP_CONSUMED invalid size %d\n",
-                               module->name, cmd_size);
-                       return -1;
-               }
-
-               div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ?  2 : 1;
-               if (adsp_pmem_fixup(module, (void **)&cmd->luma_op_buf_addr,
-                                   cmd->luma_op_buf_size) ||
-                   adsp_pmem_fixup(module, (void **)&cmd->chroma_op_buf_addr,
-                                   cmd->luma_op_buf_size / div))
-                       return -1;
-       }
-       break;
-       default:
-               if (cmd_id > 7) {
-                       printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n",
-                               module->name, cmd_id);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-int adsp_jpeg_verify_cmd(struct msm_adsp_module *module,
-                        unsigned int queue_id, void *cmd_data,
-                        size_t cmd_size)
-{
-       switch(queue_id) {
-       case QDSP_uPJpegCfgCmdQueue:
-               return verify_jpeg_cfg_cmd(module, cmd_data, cmd_size);
-       case QDSP_uPJpegActionCmdQueue:
-               return verify_jpeg_action_cmd(module, cmd_data, cmd_size);
-       default:
-               return -1;
-       }
-}
-
diff --git a/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c
deleted file mode 100644 (file)
index 1e23ef3..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
- *
- * Verificion code for aDSP LPM packets from userspace.
- *
- * Copyright (c) 2008 QUALCOMM Incorporated
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <mach/qdsp5/qdsp5lpmcmdi.h>
-#include "adsp.h"
-
-int adsp_lpm_verify_cmd(struct msm_adsp_module *module,
-                        unsigned int queue_id, void *cmd_data,
-                        size_t cmd_size)
-{
-       uint32_t cmd_id, col_height, input_row_incr, output_row_incr,
-               input_size, output_size;
-       uint32_t size_mask = 0x0fff;
-       lpm_cmd_start *cmd;
-
-       if (queue_id != QDSP_lpmCommandQueue) {
-               printk(KERN_ERR "adsp: module %s: wrong queue id %d\n",
-                       module->name, queue_id);
-               return -1;
-       }
-
-       cmd = (lpm_cmd_start *)cmd_data;
-       cmd_id = cmd->cmd_id;
-
-       if (cmd_id == LPM_CMD_START) {
-               if (cmd_size != sizeof(lpm_cmd_start)) {
-                       printk(KERN_ERR "adsp: module %s: wrong size %d, expect %d\n",
-                               module->name, cmd_size, sizeof(lpm_cmd_start));
-                       return -1;
-               }
-               col_height = cmd->ip_data_cfg_part1 & size_mask;
-               input_row_incr = cmd->ip_data_cfg_part2 & size_mask;
-               output_row_incr = cmd->op_data_cfg_part1 & size_mask;
-               input_size = col_height * input_row_incr;
-               output_size = col_height * output_row_incr;
-               if ((cmd->ip_data_cfg_part4 && adsp_pmem_fixup(module,
-                                   (void **)(&cmd->ip_data_cfg_part4),
-                                   input_size)) ||
-                  (cmd->op_data_cfg_part3 && adsp_pmem_fixup(module,
-                                   (void **)(&cmd->op_data_cfg_part3),
-                                   output_size)))
-                       return -1;
-       } else if (cmd_id > 1) {
-               printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n",
-                       module->name, cmd_id);
-               return -1;
-       }
-       return 0;
-}
-
diff --git a/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c b/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c
deleted file mode 100644 (file)
index a56392b..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
- *
- * Verification code for aDSP VFE packets from userspace.
- *
- * Copyright (c) 2008 QUALCOMM Incorporated
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <mach/qdsp5/qdsp5vfemsg.h>
-#include "adsp.h"
-
-static int patch_op_event(struct msm_adsp_module *module,
-                               struct adsp_event *event)
-{
-       vfe_msg_op1 *op = (vfe_msg_op1 *)event->data.msg16;
-       if (adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_y_addr) ||
-           adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_cbcr_addr))
-               return -1;
-       return 0;
-}
-
-static int patch_af_wb_event(struct msm_adsp_module *module,
-                               struct adsp_event *event)
-{
-       vfe_msg_stats_wb_exp *af = (vfe_msg_stats_wb_exp *)event->data.msg16;
-       return adsp_pmem_paddr_fixup(module, (void **)&af->wb_exp_stats_op_buf);
-}
-
-int adsp_vfe_patch_event(struct msm_adsp_module *module,
-                       struct adsp_event *event)
-{
-       switch(event->msg_id) {
-       case VFE_MSG_OP1:
-       case VFE_MSG_OP2:
-               return patch_op_event(module, event);
-       case VFE_MSG_STATS_AF:
-       case VFE_MSG_STATS_WB_EXP:
-               return patch_af_wb_event(module, event);
-       default:
-               break;
-       }
-
-       return 0;
-}
diff --git a/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c
deleted file mode 100644 (file)
index 927d50a..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
- *
- * Verification code for aDSP VFE packets from userspace.
- *
- * Copyright (c) 2008 QUALCOMM Incorporated
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <mach/qdsp5/qdsp5vfecmdi.h>
-#include "adsp.h"
-
-static uint32_t size1_y, size2_y, size1_cbcr, size2_cbcr;
-static uint32_t af_size = 4228;
-static uint32_t awb_size = 8196;
-
-static inline int verify_cmd_op_ack(struct msm_adsp_module *module,
-                                   void *cmd_data, size_t cmd_size)
-{
-       vfe_cmd_op1_ack *cmd = (vfe_cmd_op1_ack *)cmd_data;
-       void **addr_y = (void **)&cmd->op1_buf_y_addr;
-       void **addr_cbcr = (void **)(&cmd->op1_buf_cbcr_addr);
-
-       if (cmd_size != sizeof(vfe_cmd_op1_ack))
-               return -1;
-       if ((*addr_y && adsp_pmem_fixup(module, addr_y, size1_y)) ||
-           (*addr_cbcr && adsp_pmem_fixup(module, addr_cbcr, size1_cbcr)))
-               return -1;
-       return 0;
-}
-
-static inline int verify_cmd_stats_autofocus_cfg(struct msm_adsp_module *module,
-                                                void *cmd_data, size_t cmd_size)
-{
-       int i;
-       vfe_cmd_stats_autofocus_cfg *cmd =
-               (vfe_cmd_stats_autofocus_cfg *)cmd_data;
-
-       if (cmd_size != sizeof(vfe_cmd_stats_autofocus_cfg))
-               return -1;
-
-       for (i = 0; i < 3; i++) {
-               void **addr = (void **)(&cmd->af_stats_op_buf[i]);
-               if (*addr && adsp_pmem_fixup(module, addr, af_size))
-                       return -1;
-       }
-       return 0;
-}
-
-static inline int verify_cmd_stats_wb_exp_cfg(struct msm_adsp_module *module,
-                                             void *cmd_data, size_t cmd_size)
-{
-       vfe_cmd_stats_wb_exp_cfg *cmd =
-               (vfe_cmd_stats_wb_exp_cfg *)cmd_data;
-       int i;
-
-       if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_cfg))
-               return -1;
-
-       for (i = 0; i < 3; i++) {
-               void **addr = (void **)(&cmd->wb_exp_stats_op_buf[i]);
-               if (*addr && adsp_pmem_fixup(module, addr, awb_size))
-                       return -1;
-       }
-       return 0;
-}
-
-static inline int verify_cmd_stats_af_ack(struct msm_adsp_module *module,
-                                         void *cmd_data, size_t cmd_size)
-{
-       vfe_cmd_stats_af_ack *cmd = (vfe_cmd_stats_af_ack *)cmd_data;
-       void **addr = (void **)&cmd->af_stats_op_buf;
-
-       if (cmd_size != sizeof(vfe_cmd_stats_af_ack))
-               return -1;
-
-       if (*addr && adsp_pmem_fixup(module, addr, af_size))
-               return -1;
-       return 0;
-}
-
-static inline int verify_cmd_stats_wb_exp_ack(struct msm_adsp_module *module,
-                                             void *cmd_data, size_t cmd_size)
-{
-       vfe_cmd_stats_wb_exp_ack *cmd =
-               (vfe_cmd_stats_wb_exp_ack *)cmd_data;
-       void **addr = (void **)&cmd->wb_exp_stats_op_buf;
-
-       if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_ack))
-               return -1;
-
-       if (*addr && adsp_pmem_fixup(module, addr, awb_size))
-               return -1;
-       return 0;
-}
-
-static int verify_vfe_command(struct msm_adsp_module *module,
-                             void *cmd_data, size_t cmd_size)
-{
-       uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
-       switch (cmd_id) {
-       case VFE_CMD_OP1_ACK:
-               return verify_cmd_op_ack(module, cmd_data, cmd_size);
-       case VFE_CMD_OP2_ACK:
-               return verify_cmd_op_ack(module, cmd_data, cmd_size);
-       case VFE_CMD_STATS_AUTOFOCUS_CFG:
-               return verify_cmd_stats_autofocus_cfg(module, cmd_data,
-                                                     cmd_size);
-       case VFE_CMD_STATS_WB_EXP_CFG:
-               return verify_cmd_stats_wb_exp_cfg(module, cmd_data, cmd_size);
-       case VFE_CMD_STATS_AF_ACK:
-               return verify_cmd_stats_af_ack(module, cmd_data, cmd_size);
-       case VFE_CMD_STATS_WB_EXP_ACK:
-               return verify_cmd_stats_wb_exp_ack(module, cmd_data, cmd_size);
-       default:
-               if (cmd_id > 29) {
-                       printk(KERN_ERR "adsp: module %s: invalid VFE command id %d\n", module->name, cmd_id);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static int verify_vfe_command_scale(struct msm_adsp_module *module,
-                                   void *cmd_data, size_t cmd_size)
-{
-       uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
-       // FIXME: check the size
-       if (cmd_id > 1) {
-               printk(KERN_ERR "adsp: module %s: invalid VFE SCALE command id %d\n", module->name, cmd_id);
-               return -1;
-       }
-       return 0;
-}
-
-
-static uint32_t get_size(uint32_t hw)
-{
-       uint32_t height, width;
-       uint32_t height_mask = 0x3ffc;
-       uint32_t width_mask = 0x3ffc000;
-
-       height = (hw & height_mask) >> 2;
-       width = (hw & width_mask) >> 14 ;
-       return height * width;
-}
-
-static int verify_vfe_command_table(struct msm_adsp_module *module,
-                                   void *cmd_data, size_t cmd_size)
-{
-       uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
-       int i;
-
-       switch (cmd_id) {
-       case VFE_CMD_AXI_IP_CFG:
-       {
-               vfe_cmd_axi_ip_cfg *cmd = (vfe_cmd_axi_ip_cfg *)cmd_data;
-               uint32_t size;
-               if (cmd_size != sizeof(vfe_cmd_axi_ip_cfg)) {
-                       printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_IP_CFG) command size %d\n",
-                               module->name, cmd_size);
-                       return -1;
-               }
-               size = get_size(cmd->ip_cfg_part2);
-
-               for (i = 0; i < 8; i++) {
-                       void **addr = (void **)
-                               &cmd->ip_buf_addr[i];
-                       if (*addr && adsp_pmem_fixup(module, addr, size))
-                               return -1;
-               }
-       }
-       case VFE_CMD_AXI_OP_CFG:
-       {
-               vfe_cmd_axi_op_cfg *cmd = (vfe_cmd_axi_op_cfg *)cmd_data;
-               void **addr1_y, **addr2_y, **addr1_cbcr, **addr2_cbcr;
-
-               if (cmd_size != sizeof(vfe_cmd_axi_op_cfg)) {
-                       printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_OP_CFG) command size %d\n",
-                               module->name, cmd_size);
-                       return -1;
-               }
-               size1_y = get_size(cmd->op1_y_cfg_part2);
-               size1_cbcr = get_size(cmd->op1_cbcr_cfg_part2);
-               size2_y = get_size(cmd->op2_y_cfg_part2);
-               size2_cbcr = get_size(cmd->op2_cbcr_cfg_part2);
-               for (i = 0; i < 8; i++) {
-                       addr1_y = (void **)(&cmd->op1_buf1_addr[2*i]);
-                       addr1_cbcr = (void **)(&cmd->op1_buf1_addr[2*i+1]);
-                       addr2_y = (void **)(&cmd->op2_buf1_addr[2*i]);
-                       addr2_cbcr = (void **)(&cmd->op2_buf1_addr[2*i+1]);
-/*
-                       printk("module %s: [%d] %p %p %p %p\n",
-                               module->name, i,
-                               *addr1_y, *addr1_cbcr, *addr2_y, *addr2_cbcr);
-*/
-                       if ((*addr1_y && adsp_pmem_fixup(module, addr1_y, size1_y)) ||
-                           (*addr1_cbcr && adsp_pmem_fixup(module, addr1_cbcr, size1_cbcr)) ||
-                           (*addr2_y && adsp_pmem_fixup(module, addr2_y, size2_y)) ||
-                           (*addr2_cbcr && adsp_pmem_fixup(module, addr2_cbcr, size2_cbcr)))
-                               return -1;
-               }
-       }
-       default:
-               if (cmd_id > 4) {
-                       printk(KERN_ERR "adsp: module %s: invalid VFE TABLE command id %d\n",
-                               module->name, cmd_id);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-int adsp_vfe_verify_cmd(struct msm_adsp_module *module,
-                       unsigned int queue_id, void *cmd_data,
-                       size_t cmd_size)
-{
-       switch (queue_id) {
-       case QDSP_vfeCommandQueue:
-               return verify_vfe_command(module, cmd_data, cmd_size);
-       case QDSP_vfeCommandScaleQueue:
-               return verify_vfe_command_scale(module, cmd_data, cmd_size);
-       case QDSP_vfeCommandTableQueue:
-               return verify_vfe_command_table(module, cmd_data, cmd_size);
-       default:
-               printk(KERN_ERR "adsp: module %s: unknown queue id %d\n",
-                       module->name, queue_id);
-               return -1;
-       }
-}
diff --git a/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c
deleted file mode 100644 (file)
index 53aff77..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
- *
- * Verificion code for aDSP VDEC packets from userspace.
- *
- * Copyright (c) 2008 QUALCOMM Incorporated
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-#include <linux/io.h>
-
-#define ADSP_DEBUG_MSGS 0
-#if ADSP_DEBUG_MSGS
-#define DLOG(fmt,args...) \
-       do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
-            ##args); } \
-       while (0)
-#else
-#define DLOG(x...) do {} while (0)
-#endif
-
-
-#include <mach/qdsp5/qdsp5vdeccmdi.h>
-#include "adsp.h"
-
-static inline void *high_low_short_to_ptr(unsigned short high,
-                                         unsigned short low)
-{
-       return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
-}
-
-static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
-                                        unsigned short *low)
-{
-       *high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
-       *low = (unsigned short)((unsigned long)ptr & 0xffff);
-}
-
-static int pmem_fixup_high_low(unsigned short *high,
-                               unsigned short *low,
-                               unsigned short size_high,
-                               unsigned short size_low,
-                               struct msm_adsp_module *module,
-                               unsigned long *addr, unsigned long *size)
-{
-       void *phys_addr;
-       unsigned long phys_size;
-       unsigned long kvaddr;
-
-       phys_addr = high_low_short_to_ptr(*high, *low);
-       phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
-       DLOG("virt %x %x\n", phys_addr, phys_size);
-       if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
-               DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
-                       *high, *low, size_high, size_low, phys_addr, phys_size);
-               return -1;
-       }
-       ptr_to_high_low_short(phys_addr, high, low);
-       DLOG("phys %x %x\n", phys_addr, phys_size);
-       if (addr)
-               *addr = kvaddr;
-       if (size)
-               *size = phys_size;
-       return 0;
-}
-
-static int verify_vdec_pkt_cmd(struct msm_adsp_module *module,
-                              void *cmd_data, size_t cmd_size)
-{
-       unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
-       viddec_cmd_subframe_pkt *pkt;
-       unsigned long subframe_pkt_addr;
-       unsigned long subframe_pkt_size;
-       viddec_cmd_frame_header_packet *frame_header_pkt;
-       int i, num_addr, skip;
-       unsigned short *frame_buffer_high, *frame_buffer_low;
-       unsigned long frame_buffer_size;
-       unsigned short frame_buffer_size_high, frame_buffer_size_low;
-
-       DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
-       if (cmd_id != VIDDEC_CMD_SUBFRAME_PKT) {
-               printk(KERN_INFO "adsp_video: unknown video packet %u\n",
-                       cmd_id);
-               return 0;
-       }
-       if (cmd_size < sizeof(viddec_cmd_subframe_pkt))
-               return -1;
-
-       pkt = (viddec_cmd_subframe_pkt *)cmd_data;
-
-       if (pmem_fixup_high_low(&(pkt->subframe_packet_high),
-                               &(pkt->subframe_packet_low),
-                               pkt->subframe_packet_size_high,
-                               pkt->subframe_packet_size_low,
-                               module,
-                               &subframe_pkt_addr,
-                               &subframe_pkt_size))
-               return -1;
-
-       /* deref those ptrs and check if they are a frame header packet */
-       frame_header_pkt = (viddec_cmd_frame_header_packet *)subframe_pkt_addr;
-
-       switch (frame_header_pkt->packet_id) {
-       case 0xB201: /* h.264 */
-               num_addr = skip = 8;
-               break;
-       case 0x4D01: /* mpeg-4 and h.263 */
-               num_addr = 3;
-               skip = 0;
-               break;
-       default:
-               return 0;
-       }
-
-       frame_buffer_high = &frame_header_pkt->frame_buffer_0_high;
-       frame_buffer_low = &frame_header_pkt->frame_buffer_0_low;
-       frame_buffer_size = (frame_header_pkt->x_dimension *
-                            frame_header_pkt->y_dimension * 3) / 2;
-       ptr_to_high_low_short((void *)frame_buffer_size,
-                             &frame_buffer_size_high,
-                             &frame_buffer_size_low);
-       for (i = 0; i < num_addr; i++) {
-               if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low,
-                                       frame_buffer_size_high,
-                                       frame_buffer_size_low,
-                                       module,
-                                       NULL, NULL))
-                       return -1;
-               frame_buffer_high += 2;
-               frame_buffer_low += 2;
-       }
-       /* Patch the output buffer. */
-       frame_buffer_high += 2*skip;
-       frame_buffer_low += 2*skip;
-       if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low,
-                               frame_buffer_size_high,
-                               frame_buffer_size_low, module, NULL, NULL))
-               return -1;
-       return 0;
-}
-
-int adsp_video_verify_cmd(struct msm_adsp_module *module,
-                        unsigned int queue_id, void *cmd_data,
-                        size_t cmd_size)
-{
-       switch (queue_id) {
-       case QDSP_mpuVDecPktQueue:
-               DLOG("\n");
-               return verify_vdec_pkt_cmd(module, cmd_data, cmd_size);
-       default:
-               printk(KERN_INFO "unknown video queue %u\n", queue_id);
-               return 0;
-       }
-}
-
diff --git a/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c
deleted file mode 100644 (file)
index ee37449..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
- *
- * Verificion code for aDSP VENC packets from userspace.
- *
- * Copyright (c) 2008 QUALCOMM Incorporated
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-#include <linux/io.h>
-
-#define ADSP_DEBUG_MSGS 0
-#if ADSP_DEBUG_MSGS
-#define DLOG(fmt,args...) \
-       do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
-            ##args); } \
-       while (0)
-#else
-#define DLOG(x...) do {} while (0)
-#endif
-
-#include <mach/qdsp5/qdsp5venccmdi.h>
-#include "adsp.h"
-
-
-static unsigned short x_dimension, y_dimension;
-
-static inline void *high_low_short_to_ptr(unsigned short high,
-                                         unsigned short low)
-{
-       return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
-}
-
-static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
-                                        unsigned short *low)
-{
-       *high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
-       *low = (unsigned short)((unsigned long)ptr & 0xffff);
-}
-
-static int pmem_fixup_high_low(unsigned short *high,
-                               unsigned short *low,
-                               unsigned short size_high,
-                               unsigned short size_low,
-                               struct msm_adsp_module *module,
-                               unsigned long *addr, unsigned long *size)
-{
-       void *phys_addr;
-       unsigned long phys_size;
-       unsigned long kvaddr;
-
-       phys_addr = high_low_short_to_ptr(*high, *low);
-       phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
-       DLOG("virt %x %x\n", phys_addr, phys_size);
-       if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
-               DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
-                       *high, *low, size_high, size_low, phys_addr, phys_size);
-               return -1;
-       }
-       ptr_to_high_low_short(phys_addr, high, low);
-       DLOG("phys %x %x\n", phys_addr, phys_size);
-       if (addr)
-               *addr = kvaddr;
-       if (size)
-               *size = phys_size;
-       return 0;
-}
-
-static int verify_venc_cmd(struct msm_adsp_module *module,
-                              void *cmd_data, size_t cmd_size)
-{
-       unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
-       unsigned long frame_buf_size, luma_buf_size, chroma_buf_size;
-       unsigned short frame_buf_size_high, frame_buf_size_low;
-       unsigned short luma_buf_size_high, luma_buf_size_low;
-       unsigned short chroma_buf_size_high, chroma_buf_size_low;
-       videnc_cmd_cfg *config_cmd;
-       videnc_cmd_frame_start *frame_cmd;
-       videnc_cmd_dis *dis_cmd;
-
-       DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
-       switch (cmd_id) {
-       case VIDENC_CMD_ACTIVE:
-               if (cmd_size < sizeof(videnc_cmd_active))
-                       return -1;
-               break;
-       case VIDENC_CMD_IDLE:
-               if (cmd_size < sizeof(videnc_cmd_idle))
-                       return -1;
-               x_dimension = y_dimension = 0;
-               break;
-       case VIDENC_CMD_STATUS_QUERY:
-               if (cmd_size < sizeof(videnc_cmd_status_query))
-                       return -1;
-               break;
-       case VIDENC_CMD_RC_CFG:
-               if (cmd_size < sizeof(videnc_cmd_rc_cfg))
-                       return -1;
-               break;
-       case VIDENC_CMD_INTRA_REFRESH:
-               if (cmd_size < sizeof(videnc_cmd_intra_refresh))
-                       return -1;
-               break;
-       case VIDENC_CMD_DIGITAL_ZOOM:
-               if (cmd_size < sizeof(videnc_cmd_digital_zoom))
-                       return -1;
-               break;
-       case VIDENC_CMD_DIS_CFG:
-               if (cmd_size < sizeof(videnc_cmd_dis_cfg))
-                       return -1;
-               break;
-       case VIDENC_CMD_CFG:
-               if (cmd_size < sizeof(videnc_cmd_cfg))
-                       return -1;
-               config_cmd = (videnc_cmd_cfg *)cmd_data;
-               x_dimension = ((config_cmd->venc_frame_dim) & 0xFF00)>>8;
-               x_dimension = x_dimension*16;
-               y_dimension = (config_cmd->venc_frame_dim) & 0xFF;
-               y_dimension = y_dimension * 16;
-               break;
-       case VIDENC_CMD_FRAME_START:
-               if (cmd_size < sizeof(videnc_cmd_frame_start))
-                       return -1;
-               frame_cmd = (videnc_cmd_frame_start *)cmd_data;
-               luma_buf_size = x_dimension * y_dimension;
-               chroma_buf_size = luma_buf_size>>1;
-               frame_buf_size = luma_buf_size + chroma_buf_size;
-               ptr_to_high_low_short((void *)luma_buf_size,
-                             &luma_buf_size_high,
-                             &luma_buf_size_low);
-               ptr_to_high_low_short((void *)chroma_buf_size,
-                             &chroma_buf_size_high,
-                             &chroma_buf_size_low);
-               ptr_to_high_low_short((void *)frame_buf_size,
-                             &frame_buf_size_high,
-                             &frame_buf_size_low);
-               /* Address of raw Y data. */
-               if (pmem_fixup_high_low(&frame_cmd->input_luma_addr_high,
-                                       &frame_cmd->input_luma_addr_low,
-                                       luma_buf_size_high,
-                                       luma_buf_size_low,
-                                       module,
-                                       NULL, NULL))
-                       return -1;
-               /* Address of raw CbCr data */
-               if (pmem_fixup_high_low(&frame_cmd->input_chroma_addr_high,
-                                       &frame_cmd->input_chroma_addr_low,
-                                       chroma_buf_size_high,
-                                       chroma_buf_size_low,
-                                       module,
-                                       NULL, NULL))
-                       return -1;
-               /* Reference VOP */
-               if (pmem_fixup_high_low(&frame_cmd->ref_vop_buf_ptr_high,
-                                       &frame_cmd->ref_vop_buf_ptr_low,
-                                       frame_buf_size_high,
-                                       frame_buf_size_low,
-                                       module,
-                                       NULL, NULL))
-                       return -1;
-               /* Encoded Packet Address */
-               if (pmem_fixup_high_low(&frame_cmd->enc_pkt_buf_ptr_high,
-                                       &frame_cmd->enc_pkt_buf_ptr_low,
-                                       frame_cmd->enc_pkt_buf_size_high,
-                                       frame_cmd->enc_pkt_buf_size_low,
-                                       module,
-                                       NULL, NULL))
-                       return -1;
-               /* Unfiltered VOP Buffer Address */
-               if (pmem_fixup_high_low(
-                               &frame_cmd->unfilt_recon_vop_buf_ptr_high,
-                               &frame_cmd->unfilt_recon_vop_buf_ptr_low,
-                               frame_buf_size_high,
-                               frame_buf_size_low,
-                               module,
-                               NULL, NULL))
-                       return -1;
-               /* Filtered VOP Buffer Address */
-               if (pmem_fixup_high_low(&frame_cmd->filt_recon_vop_buf_ptr_high,
-                                       &frame_cmd->filt_recon_vop_buf_ptr_low,
-                                       frame_buf_size_high,
-                                       frame_buf_size_low,
-                                       module,
-                                       NULL, NULL))
-                       return -1;
-               break;
-       case VIDENC_CMD_DIS:
-               if (cmd_size < sizeof(videnc_cmd_dis))
-                       return -1;
-               dis_cmd = (videnc_cmd_dis *)cmd_data;
-               luma_buf_size = x_dimension * y_dimension;
-               ptr_to_high_low_short((void *)luma_buf_size,
-                             &luma_buf_size_high,
-                             &luma_buf_size_low);
-               /* Prev VFE Luma Output Address */
-               if (pmem_fixup_high_low(&dis_cmd->vfe_out_prev_luma_addr_high,
-                                       &dis_cmd->vfe_out_prev_luma_addr_low,
-                                       luma_buf_size_high,
-                                       luma_buf_size_low,
-                                       module,
-                                       NULL, NULL))
-                       return -1;
-               break;
-       default:
-               printk(KERN_INFO "adsp_video:unknown encoder video command %u\n",
-                       cmd_id);
-               return 0;
-       }
-
-       return 0;
-}
-
-
-int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
-                        unsigned int queue_id, void *cmd_data,
-                        size_t cmd_size)
-{
-       switch (queue_id) {
-       case QDSP_mpuVEncCmdQueue:
-               DLOG("\n");
-               return verify_venc_cmd(module, cmd_data, cmd_size);
-       default:
-               printk(KERN_INFO "unknown video queue %u\n", queue_id);
-               return 0;
-       }
-}
-
diff --git a/drivers/staging/dream/qdsp5/audio_aac.c b/drivers/staging/dream/qdsp5/audio_aac.c
deleted file mode 100644 (file)
index 45f4c78..0000000
+++ /dev/null
@@ -1,1054 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/audio_aac.c
- *
- * aac audio decoder device
- *
- * Copyright (C) 2008 Google, Inc.
- * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2008-2009 QUALCOMM USA, INC.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/kthread.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <linux/delay.h>
-
-#include <asm/atomic.h>
-#include <asm/ioctls.h>
-#include "audmgr.h"
-
-#include <mach/msm_adsp.h>
-#include <mach/msm_audio_aac.h>
-#include <mach/qdsp5/qdsp5audppcmdi.h>
-#include <mach/qdsp5/qdsp5audppmsg.h>
-#include <mach/qdsp5/qdsp5audplaycmdi.h>
-#include <mach/qdsp5/qdsp5audplaymsg.h>
-
-/* for queue ids - should be relative to module number*/
-#include "adsp.h"
-
-#ifdef DEBUG
-#define dprintk(format, arg...) \
-printk(KERN_DEBUG format, ## arg)
-#else
-#define dprintk(format, arg...) do {} while (0)
-#endif
-
-#define BUFSZ 32768
-#define DMASZ (BUFSZ * 2)
-
-#define AUDPLAY_INVALID_READ_PTR_OFFSET        0xFFFF
-#define AUDDEC_DEC_AAC 5
-
-#define PCM_BUFSZ_MIN 9600     /* Hold one stereo AAC frame */
-#define PCM_BUF_MAX_COUNT 5    /* DSP only accepts 5 buffers at most
-                                  but support 2 buffers currently */
-#define ROUTING_MODE_FTRT 1
-#define ROUTING_MODE_RT 2
-/* Decoder status received from AUDPPTASK */
-#define  AUDPP_DEC_STATUS_SLEEP        0
-#define         AUDPP_DEC_STATUS_INIT  1
-#define  AUDPP_DEC_STATUS_CFG   2
-#define  AUDPP_DEC_STATUS_PLAY  3
-
-struct buffer {
-       void *data;
-       unsigned size;
-       unsigned used;          /* Input usage actual DSP produced PCM size  */
-       unsigned addr;
-};
-
-struct audio {
-       struct buffer out[2];
-
-       spinlock_t dsp_lock;
-
-       uint8_t out_head;
-       uint8_t out_tail;
-       uint8_t out_needed;     /* number of buffers the dsp is waiting for */
-
-       atomic_t out_bytes;
-
-       struct mutex lock;
-       struct mutex write_lock;
-       wait_queue_head_t write_wait;
-
-       /* Host PCM section */
-       struct buffer in[PCM_BUF_MAX_COUNT];
-       struct mutex read_lock;
-       wait_queue_head_t read_wait;    /* Wait queue for read */
-       char *read_data;        /* pointer to reader buffer */
-       dma_addr_t read_phys;   /* physical address of reader buffer */
-       uint8_t read_next;      /* index to input buffers to be read next */
-       uint8_t fill_next;      /* index to buffer that DSP should be filling */
-       uint8_t pcm_buf_count;  /* number of pcm buffer allocated */
-       /* ---- End of Host PCM section */
-
-       struct msm_adsp_module *audplay;
-
-       /* configuration to use on next enable */
-       uint32_t out_sample_rate;
-       uint32_t out_channel_mode;
-       struct msm_audio_aac_config aac_config;
-       struct audmgr audmgr;
-
-       /* data allocated for various buffers */
-       char *data;
-       dma_addr_t phys;
-
-       int rflush; /* Read  flush */
-       int wflush; /* Write flush */
-       int opened;
-       int enabled;
-       int running;
-       int stopped;    /* set when stopped, cleared on flush */
-       int pcm_feedback;
-       int buf_refresh;
-
-       int reserved; /* A byte is being reserved */
-       char rsv_byte; /* Handle odd length user data */
-
-       unsigned volume;
-
-       uint16_t dec_id;
-       uint32_t read_ptr_offset;
-};
-
-static int auddec_dsp_config(struct audio *audio, int enable);
-static void audpp_cmd_cfg_adec_params(struct audio *audio);
-static void audpp_cmd_cfg_routing_mode(struct audio *audio);
-static void audplay_send_data(struct audio *audio, unsigned needed);
-static void audplay_config_hostpcm(struct audio *audio);
-static void audplay_buffer_refresh(struct audio *audio);
-static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
-
-/* must be called with audio->lock held */
-static int audio_enable(struct audio *audio)
-{
-       struct audmgr_config cfg;
-       int rc;
-
-       dprintk("audio_enable()\n");
-
-       if (audio->enabled)
-               return 0;
-
-       audio->out_tail = 0;
-       audio->out_needed = 0;
-
-       cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
-       cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
-       cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
-       cfg.codec = RPC_AUD_DEF_CODEC_AAC;
-       cfg.snd_method = RPC_SND_METHOD_MIDI;
-
-       rc = audmgr_enable(&audio->audmgr, &cfg);
-       if (rc < 0)
-               return rc;
-
-       if (msm_adsp_enable(audio->audplay)) {
-               pr_err("audio: msm_adsp_enable(audplay) failed\n");
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-
-       if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
-               pr_err("audio: audpp_enable() failed\n");
-    msm_adsp_disable(audio->audplay);
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-       audio->enabled = 1;
-       return 0;
-}
-
-/* must be called with audio->lock held */
-static int audio_disable(struct audio *audio)
-{
-       dprintk("audio_disable()\n");
-       if (audio->enabled) {
-               audio->enabled = 0;
-               auddec_dsp_config(audio, 0);
-               wake_up(&audio->write_wait);
-               wake_up(&audio->read_wait);
-               msm_adsp_disable(audio->audplay);
-               audpp_disable(audio->dec_id, audio);
-               audmgr_disable(&audio->audmgr);
-               audio->out_needed = 0;
-       }
-       return 0;
-}
-
-/* ------------------- dsp --------------------- */
-static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload)
-{
-       uint8_t index;
-       unsigned long flags;
-
-       if (audio->rflush)
-               return;
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       for (index = 0; index < payload[1]; index++) {
-               if (audio->in[audio->fill_next].addr ==
-                   payload[2 + index * 2]) {
-                       dprintk("audio_update_pcm_buf_entry: in[%d] ready\n",
-                               audio->fill_next);
-                       audio->in[audio->fill_next].used =
-                               payload[3 + index * 2];
-                       if ((++audio->fill_next) == audio->pcm_buf_count)
-                               audio->fill_next = 0;
-
-               } else {
-                       pr_err
-                           ("audio_update_pcm_buf_entry: expected=%x ret=%x\n"
-                            , audio->in[audio->fill_next].addr,
-                            payload[1 + index * 2]);
-                       break;
-               }
-       }
-       if (audio->in[audio->fill_next].used == 0) {
-               audplay_buffer_refresh(audio);
-       } else {
-               dprintk("audio_update_pcm_buf_entry: read cannot keep up\n");
-               audio->buf_refresh = 1;
-       }
-       wake_up(&audio->read_wait);
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-
-}
-
-static void audplay_dsp_event(void *data, unsigned id, size_t len,
-                             void (*getevent) (void *ptr, size_t len))
-{
-       struct audio *audio = data;
-       uint32_t msg[28];
-       getevent(msg, sizeof(msg));
-
-       dprintk("audplay_dsp_event: msg_id=%x\n", id);
-
-       switch (id) {
-       case AUDPLAY_MSG_DEC_NEEDS_DATA:
-               audplay_send_data(audio, 1);
-               break;
-
-       case AUDPLAY_MSG_BUFFER_UPDATE:
-               audio_update_pcm_buf_entry(audio, msg);
-               break;
-
-       default:
-               pr_err("unexpected message from decoder \n");
-       }
-}
-
-static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
-{
-       struct audio *audio = private;
-
-       switch (id) {
-       case AUDPP_MSG_STATUS_MSG:{
-                       unsigned status = msg[1];
-
-                       switch (status) {
-                       case AUDPP_DEC_STATUS_SLEEP:
-                               dprintk("decoder status: sleep \n");
-                               break;
-
-                       case AUDPP_DEC_STATUS_INIT:
-                               dprintk("decoder status: init \n");
-                               audpp_cmd_cfg_routing_mode(audio);
-                               break;
-
-                       case AUDPP_DEC_STATUS_CFG:
-                               dprintk("decoder status: cfg \n");
-                               break;
-                       case AUDPP_DEC_STATUS_PLAY:
-                               dprintk("decoder status: play \n");
-                               if (audio->pcm_feedback) {
-                                       audplay_config_hostpcm(audio);
-                                       audplay_buffer_refresh(audio);
-                               }
-                               break;
-                       default:
-                               pr_err("unknown decoder status \n");
-                       }
-                       break;
-               }
-       case AUDPP_MSG_CFG_MSG:
-               if (msg[0] == AUDPP_MSG_ENA_ENA) {
-                       dprintk("audio_dsp_event: CFG_MSG ENABLE\n");
-                       auddec_dsp_config(audio, 1);
-                       audio->out_needed = 0;
-                       audio->running = 1;
-                       audpp_set_volume_and_pan(audio->dec_id, audio->volume,
-                                                0);
-                       audpp_avsync(audio->dec_id, 22050);
-               } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
-                       dprintk("audio_dsp_event: CFG_MSG DISABLE\n");
-                       audpp_avsync(audio->dec_id, 0);
-                       audio->running = 0;
-               } else {
-                       pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
-               }
-               break;
-       case AUDPP_MSG_ROUTING_ACK:
-               dprintk("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
-               audpp_cmd_cfg_adec_params(audio);
-               break;
-
-       case AUDPP_MSG_FLUSH_ACK:
-               dprintk("%s: FLUSH_ACK\n", __func__);
-               audio->wflush = 0;
-               audio->rflush = 0;
-               if (audio->pcm_feedback)
-                       audplay_buffer_refresh(audio);
-               break;
-
-       default:
-               pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
-       }
-
-}
-
-struct msm_adsp_ops audplay_adsp_ops_aac = {
-       .event = audplay_dsp_event,
-};
-
-#define audplay_send_queue0(audio, cmd, len) \
-       msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
-                      cmd, len)
-
-static int auddec_dsp_config(struct audio *audio, int enable)
-{
-       audpp_cmd_cfg_dec_type cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
-       if (enable)
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
-                   AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AAC;
-       else
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
-
-       return audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_adec_params(struct audio *audio)
-{
-       audpp_cmd_cfg_adec_params_aac cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
-       cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN;
-       cmd.common.dec_id = audio->dec_id;
-       cmd.common.input_sampling_frequency = audio->out_sample_rate;
-       cmd.format = audio->aac_config.format;
-       cmd.audio_object = audio->aac_config.audio_object;
-       cmd.ep_config = audio->aac_config.ep_config;
-       cmd.aac_section_data_resilience_flag =
-               audio->aac_config.aac_section_data_resilience_flag;
-       cmd.aac_scalefactor_data_resilience_flag =
-               audio->aac_config.aac_scalefactor_data_resilience_flag;
-       cmd.aac_spectral_data_resilience_flag =
-               audio->aac_config.aac_spectral_data_resilience_flag;
-       cmd.sbr_on_flag = audio->aac_config.sbr_on_flag;
-       cmd.sbr_ps_on_flag = audio->aac_config.sbr_ps_on_flag;
-       cmd.channel_configuration = audio->aac_config.channel_configuration;
-
-       audpp_send_queue2(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_routing_mode(struct audio *audio)
-{
-       struct audpp_cmd_routing_mode cmd;
-       dprintk("audpp_cmd_cfg_routing_mode()\n");
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
-       cmd.object_number = audio->dec_id;
-       if (audio->pcm_feedback)
-               cmd.routing_mode = ROUTING_MODE_FTRT;
-       else
-               cmd.routing_mode = ROUTING_MODE_RT;
-
-       audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static int audplay_dsp_send_data_avail(struct audio *audio,
-                                      unsigned idx, unsigned len)
-{
-       audplay_cmd_bitstream_data_avail cmd;
-
-       cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
-       cmd.decoder_id = audio->dec_id;
-       cmd.buf_ptr = audio->out[idx].addr;
-       cmd.buf_size = len / 2;
-       cmd.partition_number = 0;
-       return audplay_send_queue0(audio, &cmd, sizeof(cmd));
-}
-
-static void audplay_buffer_refresh(struct audio *audio)
-{
-       struct audplay_cmd_buffer_refresh refresh_cmd;
-
-       refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
-       refresh_cmd.num_buffers = 1;
-       refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
-       refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
-               (audio->in[audio->fill_next].size % 1024); /* AAC frame size */
-       refresh_cmd.buf_read_count = 0;
-       dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
-               refresh_cmd.buf0_address, refresh_cmd.buf0_length);
-       (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
-}
-
-static void audplay_config_hostpcm(struct audio *audio)
-{
-       struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
-
-       dprintk("audplay_config_hostpcm()\n");
-       cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
-       cfg_cmd.max_buffers = audio->pcm_buf_count;
-       cfg_cmd.byte_swap = 0;
-       cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
-       cfg_cmd.feedback_frequency = 1;
-       cfg_cmd.partition_number = 0;
-       (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
-
-}
-
-static void audplay_send_data(struct audio *audio, unsigned needed)
-{
-       struct buffer *frame;
-       unsigned long flags;
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       if (!audio->running)
-               goto done;
-
-       if (needed && !audio->wflush) {
-               /* We were called from the callback because the DSP
-                * requested more data.  Note that the DSP does want
-                * more data, and if a buffer was in-flight, mark it
-                * as available (since the DSP must now be done with
-                * it).
-                */
-               audio->out_needed = 1;
-               frame = audio->out + audio->out_tail;
-               if (frame->used == 0xffffffff) {
-                       dprintk("frame %d free\n", audio->out_tail);
-                       frame->used = 0;
-                       audio->out_tail ^= 1;
-                       wake_up(&audio->write_wait);
-               }
-       }
-
-       if (audio->out_needed) {
-               /* If the DSP currently wants data and we have a
-                * buffer available, we will send it and reset
-                * the needed flag.  We'll mark the buffer as in-flight
-                * so that it won't be recycled until the next buffer
-                * is requested
-                */
-
-               frame = audio->out + audio->out_tail;
-               if (frame->used) {
-                       BUG_ON(frame->used == 0xffffffff);
-/*                      printk("frame %d busy\n", audio->out_tail); */
-                       audplay_dsp_send_data_avail(audio, audio->out_tail,
-                                                   frame->used);
-                       frame->used = 0xffffffff;
-                       audio->out_needed = 0;
-               }
-       }
- done:
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-}
-
-/* ------------------- device --------------------- */
-
-static void audio_flush(struct audio *audio)
-{
-       audio->out[0].used = 0;
-       audio->out[1].used = 0;
-       audio->out_head = 0;
-       audio->out_tail = 0;
-       audio->reserved = 0;
-       audio->out_needed = 0;
-       atomic_set(&audio->out_bytes, 0);
-}
-
-static void audio_flush_pcm_buf(struct audio *audio)
-{
-       uint8_t index;
-
-       for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
-               audio->in[index].used = 0;
-       audio->buf_refresh = 0;
-       audio->read_next = 0;
-       audio->fill_next = 0;
-}
-
-static int audaac_validate_usr_config(struct msm_audio_aac_config *config)
-{
-       int ret_val = -1;
-
-       if (config->format != AUDIO_AAC_FORMAT_ADTS &&
-               config->format != AUDIO_AAC_FORMAT_RAW &&
-               config->format != AUDIO_AAC_FORMAT_PSUEDO_RAW &&
-               config->format != AUDIO_AAC_FORMAT_LOAS)
-               goto done;
-
-       if (config->audio_object != AUDIO_AAC_OBJECT_LC &&
-               config->audio_object != AUDIO_AAC_OBJECT_LTP &&
-               config->audio_object != AUDIO_AAC_OBJECT_ERLC)
-               goto done;
-
-       if (config->audio_object == AUDIO_AAC_OBJECT_ERLC) {
-               if (config->ep_config > 3)
-                       goto done;
-               if (config->aac_scalefactor_data_resilience_flag !=
-                       AUDIO_AAC_SCA_DATA_RES_OFF &&
-                       config->aac_scalefactor_data_resilience_flag !=
-                       AUDIO_AAC_SCA_DATA_RES_ON)
-                       goto done;
-               if (config->aac_section_data_resilience_flag !=
-                       AUDIO_AAC_SEC_DATA_RES_OFF &&
-                       config->aac_section_data_resilience_flag !=
-                       AUDIO_AAC_SEC_DATA_RES_ON)
-                       goto done;
-               if (config->aac_spectral_data_resilience_flag !=
-                       AUDIO_AAC_SPEC_DATA_RES_OFF &&
-                       config->aac_spectral_data_resilience_flag !=
-                       AUDIO_AAC_SPEC_DATA_RES_ON)
-                       goto done;
-       } else {
-               config->aac_section_data_resilience_flag =
-                       AUDIO_AAC_SEC_DATA_RES_OFF;
-               config->aac_scalefactor_data_resilience_flag =
-                       AUDIO_AAC_SCA_DATA_RES_OFF;
-               config->aac_spectral_data_resilience_flag =
-                       AUDIO_AAC_SPEC_DATA_RES_OFF;
-       }
-
-       if (config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_OFF &&
-               config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_ON)
-               goto done;
-
-       if (config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_OFF &&
-               config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_ON)
-               goto done;
-
-       if (config->dual_mono_mode > AUDIO_AAC_DUAL_MONO_PL_SR)
-               goto done;
-
-       if (config->channel_configuration > 2)
-               goto done;
-
-       ret_val = 0;
- done:
-       return ret_val;
-}
-
-static void audio_ioport_reset(struct audio *audio)
-{
-       /* Make sure read/write thread are free from
-        * sleep and knowing that system is not able
-        * to process io request at the moment
-        */
-       wake_up(&audio->write_wait);
-       mutex_lock(&audio->write_lock);
-       audio_flush(audio);
-       mutex_unlock(&audio->write_lock);
-       wake_up(&audio->read_wait);
-       mutex_lock(&audio->read_lock);
-       audio_flush_pcm_buf(audio);
-       mutex_unlock(&audio->read_lock);
-}
-
-static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct audio *audio = file->private_data;
-       int rc = 0;
-
-       dprintk("audio_ioctl() cmd = %d\n", cmd);
-
-       if (cmd == AUDIO_GET_STATS) {
-               struct msm_audio_stats stats;
-               stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
-               stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
-               if (copy_to_user((void *)arg, &stats, sizeof(stats)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == AUDIO_SET_VOLUME) {
-               unsigned long flags;
-               spin_lock_irqsave(&audio->dsp_lock, flags);
-               audio->volume = arg;
-               if (audio->running)
-                       audpp_set_volume_and_pan(audio->dec_id, arg, 0);
-               spin_unlock_irqrestore(&audio->dsp_lock, flags);
-               return 0;
-       }
-       mutex_lock(&audio->lock);
-       switch (cmd) {
-       case AUDIO_START:
-               rc = audio_enable(audio);
-               break;
-       case AUDIO_STOP:
-               rc = audio_disable(audio);
-               audio->stopped = 1;
-               audio_ioport_reset(audio);
-               audio->stopped = 0;
-               break;
-       case AUDIO_FLUSH:
-               dprintk("%s: AUDIO_FLUSH\n", __func__);
-               audio->rflush = 1;
-               audio->wflush = 1;
-               audio_ioport_reset(audio);
-               if (audio->running)
-                       audpp_flush(audio->dec_id);
-               else {
-                       audio->rflush = 0;
-                       audio->wflush = 0;
-               }
-               break;
-
-       case AUDIO_SET_CONFIG:{
-                       struct msm_audio_config config;
-
-                       if (copy_from_user
-                           (&config, (void *)arg, sizeof(config))) {
-                               rc = -EFAULT;
-                               break;
-                       }
-
-                       if (config.channel_count == 1) {
-                               config.channel_count =
-                                   AUDPP_CMD_PCM_INTF_MONO_V;
-                       } else if (config.channel_count == 2) {
-                               config.channel_count =
-                                   AUDPP_CMD_PCM_INTF_STEREO_V;
-                       } else {
-                               rc = -EINVAL;
-                               break;
-                       }
-
-                       audio->out_sample_rate = config.sample_rate;
-                       audio->out_channel_mode = config.channel_count;
-                       rc = 0;
-                       break;
-               }
-       case AUDIO_GET_CONFIG:{
-                       struct msm_audio_config config;
-                       config.buffer_size = BUFSZ;
-                       config.buffer_count = 2;
-                       config.sample_rate = audio->out_sample_rate;
-                       if (audio->out_channel_mode ==
-                           AUDPP_CMD_PCM_INTF_MONO_V) {
-                               config.channel_count = 1;
-                       } else {
-                               config.channel_count = 2;
-                       }
-                       config.unused[0] = 0;
-                       config.unused[1] = 0;
-                       config.unused[2] = 0;
-                       config.unused[3] = 0;
-                       if (copy_to_user((void *)arg, &config,
-                                        sizeof(config)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-
-                       break;
-               }
-       case AUDIO_GET_AAC_CONFIG:{
-                       if (copy_to_user((void *)arg, &audio->aac_config,
-                               sizeof(audio->aac_config)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-                       break;
-               }
-       case AUDIO_SET_AAC_CONFIG:{
-                       struct msm_audio_aac_config usr_config;
-
-                       if (copy_from_user
-                               (&usr_config, (void *)arg,
-                                       sizeof(usr_config))) {
-                               rc = -EFAULT;
-                               break;
-                       }
-
-                       if (audaac_validate_usr_config(&usr_config) == 0) {
-                               audio->aac_config = usr_config;
-                               rc = 0;
-                       } else
-                               rc = -EINVAL;
-
-                       break;
-               }
-       case AUDIO_GET_PCM_CONFIG:{
-                       struct msm_audio_pcm_config config;
-                       config.pcm_feedback = 0;
-                       config.buffer_count = PCM_BUF_MAX_COUNT;
-                       config.buffer_size = PCM_BUFSZ_MIN;
-                       if (copy_to_user((void *)arg, &config,
-                                        sizeof(config)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-                       break;
-               }
-       case AUDIO_SET_PCM_CONFIG:{
-                       struct msm_audio_pcm_config config;
-                       if (copy_from_user
-                           (&config, (void *)arg, sizeof(config))) {
-                               rc = -EFAULT;
-                               break;
-                       }
-                       if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
-                           (config.buffer_count == 1))
-                               config.buffer_count = PCM_BUF_MAX_COUNT;
-
-                       if (config.buffer_size < PCM_BUFSZ_MIN)
-                               config.buffer_size = PCM_BUFSZ_MIN;
-
-                       /* Check if pcm feedback is required */
-                       if ((config.pcm_feedback) && (!audio->read_data)) {
-                               dprintk("ioctl: allocate PCM buffer %d\n",
-                                       config.buffer_count *
-                                       config.buffer_size);
-                               audio->read_data =
-                                   dma_alloc_coherent(NULL,
-                                                      config.buffer_size *
-                                                      config.buffer_count,
-                                                      &audio->read_phys,
-                                                      GFP_KERNEL);
-                               if (!audio->read_data) {
-                                       pr_err("audio_aac: buf alloc fail\n");
-                                       rc = -1;
-                               } else {
-                                       uint8_t index;
-                                       uint32_t offset = 0;
-                                       audio->pcm_feedback = 1;
-                                       audio->buf_refresh = 0;
-                                       audio->pcm_buf_count =
-                                           config.buffer_count;
-                                       audio->read_next = 0;
-                                       audio->fill_next = 0;
-
-                                       for (index = 0;
-                                            index < config.buffer_count;
-                                            index++) {
-                                               audio->in[index].data =
-                                                   audio->read_data + offset;
-                                               audio->in[index].addr =
-                                                   audio->read_phys + offset;
-                                               audio->in[index].size =
-                                                   config.buffer_size;
-                                               audio->in[index].used = 0;
-                                               offset += config.buffer_size;
-                                       }
-                                       rc = 0;
-                               }
-                       } else {
-                               rc = 0;
-                       }
-                       break;
-               }
-       case AUDIO_PAUSE:
-               dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
-               rc = audpp_pause(audio->dec_id, (int) arg);
-               break;
-       default:
-               rc = -EINVAL;
-       }
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
-                         loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       int rc = 0;
-
-       if (!audio->pcm_feedback)
-               return 0; /* PCM feedback is not enabled. Nothing to read */
-
-       mutex_lock(&audio->read_lock);
-       dprintk("audio_read() %d \n", count);
-       while (count > 0) {
-               rc = wait_event_interruptible(audio->read_wait,
-                                             (audio->in[audio->read_next].
-                                               used > 0) || (audio->stopped)
-                                               || (audio->rflush));
-
-               if (rc < 0)
-                       break;
-
-               if (audio->stopped || audio->rflush) {
-                       rc = -EBUSY;
-                       break;
-               }
-
-               if (count < audio->in[audio->read_next].used) {
-                       /* Read must happen in frame boundary. Since driver
-                          does not know frame size, read count must be greater
-                          or equal to size of PCM samples */
-                       dprintk("audio_read: no partial frame done reading\n");
-                       break;
-               } else {
-                       dprintk("audio_read: read from in[%d]\n",
-                               audio->read_next);
-                       if (copy_to_user
-                           (buf, audio->in[audio->read_next].data,
-                            audio->in[audio->read_next].used)) {
-                               pr_err("audio_read: invalid addr %x \n",
-                                      (unsigned int)buf);
-                               rc = -EFAULT;
-                               break;
-                       }
-                       count -= audio->in[audio->read_next].used;
-                       buf += audio->in[audio->read_next].used;
-                       audio->in[audio->read_next].used = 0;
-                       if ((++audio->read_next) == audio->pcm_buf_count)
-                               audio->read_next = 0;
-                       if (audio->in[audio->read_next].used == 0)
-                               break; /* No data ready at this moment
-                                       * Exit while loop to prevent
-                                       * output thread sleep too long
-                                       */
-               }
-       }
-
-       /* don't feed output buffer to HW decoder during flushing
-        * buffer refresh command will be sent once flush completes
-        * send buf refresh command here can confuse HW decoder
-        */
-       if (audio->buf_refresh && !audio->rflush) {
-               audio->buf_refresh = 0;
-               dprintk("audio_read: kick start pcm feedback again\n");
-               audplay_buffer_refresh(audio);
-       }
-
-       mutex_unlock(&audio->read_lock);
-
-       if (buf > start)
-               rc = buf - start;
-
-       dprintk("audio_read: read %d bytes\n", rc);
-       return rc;
-}
-
-static ssize_t audio_write(struct file *file, const char __user *buf,
-                          size_t count, loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       struct buffer *frame;
-       size_t xfer;
-       char *cpy_ptr;
-       int rc = 0;
-       unsigned dsize;
-
-       mutex_lock(&audio->write_lock);
-       while (count > 0) {
-               frame = audio->out + audio->out_head;
-               cpy_ptr = frame->data;
-               dsize = 0;
-               rc = wait_event_interruptible(audio->write_wait,
-                                             (frame->used == 0)
-                                               || (audio->stopped)
-                                               || (audio->wflush));
-               if (rc < 0)
-                       break;
-               if (audio->stopped || audio->wflush) {
-                       rc = -EBUSY;
-                       break;
-               }
-
-               if (audio->reserved) {
-                       dprintk("%s: append reserved byte %x\n",
-                               __func__, audio->rsv_byte);
-                       *cpy_ptr = audio->rsv_byte;
-                       xfer = (count > (frame->size - 1)) ?
-                               frame->size - 1 : count;
-                       cpy_ptr++;
-                       dsize = 1;
-                       audio->reserved = 0;
-               } else
-                       xfer = (count > frame->size) ? frame->size : count;
-
-               if (copy_from_user(cpy_ptr, buf, xfer)) {
-                       rc = -EFAULT;
-                       break;
-               }
-
-               dsize += xfer;
-               if (dsize & 1) {
-                       audio->rsv_byte = ((char *) frame->data)[dsize - 1];
-                       dprintk("%s: odd length buf reserve last byte %x\n",
-                               __func__, audio->rsv_byte);
-                       audio->reserved = 1;
-                       dsize--;
-               }
-               count -= xfer;
-               buf += xfer;
-
-               if (dsize > 0) {
-                       audio->out_head ^= 1;
-                       frame->used = dsize;
-                       audplay_send_data(audio, 0);
-               }
-       }
-       mutex_unlock(&audio->write_lock);
-       if (buf > start)
-               return buf - start;
-       return rc;
-}
-
-static int audio_release(struct inode *inode, struct file *file)
-{
-       struct audio *audio = file->private_data;
-
-       dprintk("audio_release()\n");
-
-       mutex_lock(&audio->lock);
-       audio_disable(audio);
-       audio_flush(audio);
-       audio_flush_pcm_buf(audio);
-       msm_adsp_put(audio->audplay);
-       audio->audplay = NULL;
-       audio->opened = 0;
-       audio->reserved = 0;
-       dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
-       audio->data = NULL;
-       if (audio->read_data != NULL) {
-               dma_free_coherent(NULL,
-                                 audio->in[0].size * audio->pcm_buf_count,
-                                 audio->read_data, audio->read_phys);
-               audio->read_data = NULL;
-       }
-       audio->pcm_feedback = 0;
-       mutex_unlock(&audio->lock);
-       return 0;
-}
-
-static struct audio the_aac_audio;
-
-static int audio_open(struct inode *inode, struct file *file)
-{
-       struct audio *audio = &the_aac_audio;
-       int rc;
-
-       mutex_lock(&audio->lock);
-
-       if (audio->opened) {
-               pr_err("audio: busy\n");
-               rc = -EBUSY;
-               goto done;
-       }
-
-       if (!audio->data) {
-               audio->data = dma_alloc_coherent(NULL, DMASZ,
-                                                &audio->phys, GFP_KERNEL);
-               if (!audio->data) {
-                       pr_err("audio: could not allocate DMA buffers\n");
-                       rc = -ENOMEM;
-                       goto done;
-               }
-       }
-
-       rc = audmgr_open(&audio->audmgr);
-       if (rc)
-               goto done;
-
-       rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
-                         &audplay_adsp_ops_aac, audio);
-       if (rc) {
-               pr_err("audio: failed to get audplay0 dsp module\n");
-               goto done;
-       }
-       audio->out_sample_rate = 44100;
-       audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
-       audio->aac_config.format = AUDIO_AAC_FORMAT_ADTS;
-       audio->aac_config.audio_object = AUDIO_AAC_OBJECT_LC;
-       audio->aac_config.ep_config = 0;
-       audio->aac_config.aac_section_data_resilience_flag =
-               AUDIO_AAC_SEC_DATA_RES_OFF;
-       audio->aac_config.aac_scalefactor_data_resilience_flag =
-               AUDIO_AAC_SCA_DATA_RES_OFF;
-       audio->aac_config.aac_spectral_data_resilience_flag =
-               AUDIO_AAC_SPEC_DATA_RES_OFF;
-       audio->aac_config.sbr_on_flag = AUDIO_AAC_SBR_ON_FLAG_ON;
-       audio->aac_config.sbr_ps_on_flag = AUDIO_AAC_SBR_PS_ON_FLAG_ON;
-       audio->aac_config.dual_mono_mode = AUDIO_AAC_DUAL_MONO_PL_SR;
-       audio->aac_config.channel_configuration = 2;
-       audio->dec_id = 0;
-
-       audio->out[0].data = audio->data + 0;
-       audio->out[0].addr = audio->phys + 0;
-       audio->out[0].size = BUFSZ;
-
-       audio->out[1].data = audio->data + BUFSZ;
-       audio->out[1].addr = audio->phys + BUFSZ;
-       audio->out[1].size = BUFSZ;
-
-       audio->volume = 0x2000; /* Q13 1.0 */
-
-       audio_flush(audio);
-
-       file->private_data = audio;
-       audio->opened = 1;
-       rc = 0;
-done:
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static struct file_operations audio_aac_fops = {
-       .owner = THIS_MODULE,
-       .open = audio_open,
-       .release = audio_release,
-       .read = audio_read,
-       .write = audio_write,
-       .unlocked_ioctl = audio_ioctl,
-       .llseek = noop_llseek,
-};
-
-struct miscdevice audio_aac_misc = {
-       .minor = MISC_DYNAMIC_MINOR,
-       .name = "msm_aac",
-       .fops = &audio_aac_fops,
-};
-
-static int __init audio_init(void)
-{
-       mutex_init(&the_aac_audio.lock);
-       mutex_init(&the_aac_audio.write_lock);
-       mutex_init(&the_aac_audio.read_lock);
-       spin_lock_init(&the_aac_audio.dsp_lock);
-       init_waitqueue_head(&the_aac_audio.write_wait);
-       init_waitqueue_head(&the_aac_audio.read_wait);
-       the_aac_audio.read_data = NULL;
-       return misc_register(&audio_aac_misc);
-}
-
-device_initcall(audio_init);
diff --git a/drivers/staging/dream/qdsp5/audio_amrnb.c b/drivers/staging/dream/qdsp5/audio_amrnb.c
deleted file mode 100644 (file)
index 402bbc1..0000000
+++ /dev/null
@@ -1,875 +0,0 @@
-/* linux/arch/arm/mach-msm/qdsp5/audio_amrnb.c
- *
- * amrnb audio decoder device
- *
- * Copyright (c) 2008 QUALCOMM USA, INC.
- *
- * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
- *
- * Copyright (C) 2008 Google, Inc.
- * Copyright (C) 2008 HTC Corporation
- *
- * All source code in this file is licensed under the following license except
- * where indicated.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * See the GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, you can find it at http://www.fsf.org
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/kthread.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <linux/delay.h>
-
-#include <asm/atomic.h>
-#include <asm/ioctls.h>
-#include <mach/msm_adsp.h>
-#include <linux/msm_audio.h>
-#include "audmgr.h"
-
-#include <mach/qdsp5/qdsp5audppcmdi.h>
-#include <mach/qdsp5/qdsp5audppmsg.h>
-#include <mach/qdsp5/qdsp5audplaycmdi.h>
-#include <mach/qdsp5/qdsp5audplaymsg.h>
-
-/* for queue ids - should be relative to module number*/
-#include "adsp.h"
-
-#define DEBUG
-#ifdef DEBUG
-#define dprintk(format, arg...) \
-printk(KERN_DEBUG format, ## arg)
-#else
-#define dprintk(format, arg...) do {} while (0)
-#endif
-
-#define BUFSZ 1024 /* Hold minimum 700ms voice data */
-#define DMASZ (BUFSZ * 2)
-
-#define AUDPLAY_INVALID_READ_PTR_OFFSET        0xFFFF
-#define AUDDEC_DEC_AMRNB 10
-
-#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
-#define AMRNB_DECODED_FRSZ 320 /* AMR-NB 20ms 8KHz mono PCM size */
-#define PCM_BUF_MAX_COUNT 5    /* DSP only accepts 5 buffers at most
-                                  but support 2 buffers currently */
-#define ROUTING_MODE_FTRT 1
-#define ROUTING_MODE_RT 2
-/* Decoder status received from AUDPPTASK */
-#define  AUDPP_DEC_STATUS_SLEEP        0
-#define         AUDPP_DEC_STATUS_INIT  1
-#define  AUDPP_DEC_STATUS_CFG   2
-#define  AUDPP_DEC_STATUS_PLAY  3
-
-struct buffer {
-       void *data;
-       unsigned size;
-       unsigned used;          /* Input usage actual DSP produced PCM size  */
-       unsigned addr;
-};
-
-struct audio {
-       struct buffer out[2];
-
-       spinlock_t dsp_lock;
-
-       uint8_t out_head;
-       uint8_t out_tail;
-       uint8_t out_needed;     /* number of buffers the dsp is waiting for */
-
-       atomic_t out_bytes;
-
-       struct mutex lock;
-       struct mutex write_lock;
-       wait_queue_head_t write_wait;
-
-       /* Host PCM section */
-       struct buffer in[PCM_BUF_MAX_COUNT];
-       struct mutex read_lock;
-       wait_queue_head_t read_wait;    /* Wait queue for read */
-       char *read_data;        /* pointer to reader buffer */
-       dma_addr_t read_phys;   /* physical address of reader buffer */
-       uint8_t read_next;      /* index to input buffers to be read next */
-       uint8_t fill_next;      /* index to buffer that DSP should be filling */
-       uint8_t pcm_buf_count;  /* number of pcm buffer allocated */
-       /* ---- End of Host PCM section */
-
-       struct msm_adsp_module *audplay;
-
-       struct audmgr audmgr;
-
-       /* data allocated for various buffers */
-       char *data;
-       dma_addr_t phys;
-
-       uint8_t opened:1;
-       uint8_t enabled:1;
-       uint8_t running:1;
-       uint8_t stopped:1;      /* set when stopped, cleared on flush */
-       uint8_t pcm_feedback:1;
-       uint8_t buf_refresh:1;
-
-       unsigned volume;
-
-       uint16_t dec_id;
-       uint32_t read_ptr_offset;
-};
-
-struct audpp_cmd_cfg_adec_params_amrnb {
-   audpp_cmd_cfg_adec_params_common     common;
-   unsigned short                       stereo_cfg;
-} __attribute__((packed)) ;
-
-static int auddec_dsp_config(struct audio *audio, int enable);
-static void audpp_cmd_cfg_adec_params(struct audio *audio);
-static void audpp_cmd_cfg_routing_mode(struct audio *audio);
-static void audamrnb_send_data(struct audio *audio, unsigned needed);
-static void audamrnb_config_hostpcm(struct audio *audio);
-static void audamrnb_buffer_refresh(struct audio *audio);
-static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg);
-
-/* must be called with audio->lock held */
-static int audamrnb_enable(struct audio *audio)
-{
-       struct audmgr_config cfg;
-       int rc;
-
-       dprintk("audamrnb_enable()\n");
-
-       if (audio->enabled)
-               return 0;
-
-       audio->out_tail = 0;
-       audio->out_needed = 0;
-
-       cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
-       cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
-       cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
-       cfg.codec = RPC_AUD_DEF_CODEC_AMR_NB;
-       cfg.snd_method = RPC_SND_METHOD_MIDI;
-
-       rc = audmgr_enable(&audio->audmgr, &cfg);
-       if (rc < 0)
-               return rc;
-
-       if (msm_adsp_enable(audio->audplay)) {
-               pr_err("audio: msm_adsp_enable(audplay) failed\n");
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-
-       if (audpp_enable(audio->dec_id, audamrnb_dsp_event, audio)) {
-               pr_err("audio: audpp_enable() failed\n");
-               msm_adsp_disable(audio->audplay);
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-       audio->enabled = 1;
-       return 0;
-}
-
-/* must be called with audio->lock held */
-static int audamrnb_disable(struct audio *audio)
-{
-       dprintk("audamrnb_disable()\n");
-       if (audio->enabled) {
-               audio->enabled = 0;
-               auddec_dsp_config(audio, 0);
-               wake_up(&audio->write_wait);
-               wake_up(&audio->read_wait);
-               msm_adsp_disable(audio->audplay);
-               audpp_disable(audio->dec_id, audio);
-               audmgr_disable(&audio->audmgr);
-               audio->out_needed = 0;
-       }
-       return 0;
-}
-
-/* ------------------- dsp --------------------- */
-static void audamrnb_update_pcm_buf_entry(struct audio *audio,
-               uint32_t *payload)
-{
-       uint8_t index;
-       unsigned long flags;
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       for (index = 0; index < payload[1]; index++) {
-               if (audio->in[audio->fill_next].addr ==
-                   payload[2 + index * 2]) {
-                       dprintk("audamrnb_update_pcm_buf_entry: in[%d] ready\n",
-                               audio->fill_next);
-                       audio->in[audio->fill_next].used =
-                           payload[3 + index * 2];
-                       if ((++audio->fill_next) == audio->pcm_buf_count)
-                               audio->fill_next = 0;
-
-               } else {
-                       pr_err
-                         ("audamrnb_update_pcm_buf_entry: expected=%x ret=%x\n"
-                          , audio->in[audio->fill_next].addr,
-                          payload[1 + index * 2]);
-                       break;
-               }
-       }
-       if (audio->in[audio->fill_next].used == 0) {
-               audamrnb_buffer_refresh(audio);
-       } else {
-               dprintk("audamrnb_update_pcm_buf_entry: read cannot keep up\n");
-               audio->buf_refresh = 1;
-       }
-
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-       wake_up(&audio->read_wait);
-}
-
-static void audplay_dsp_event(void *data, unsigned id, size_t len,
-                             void (*getevent) (void *ptr, size_t len))
-{
-       struct audio *audio = data;
-       uint32_t msg[28];
-       getevent(msg, sizeof(msg));
-
-       dprintk("audplay_dsp_event: msg_id=%x\n", id);
-
-       switch (id) {
-       case AUDPLAY_MSG_DEC_NEEDS_DATA:
-               audamrnb_send_data(audio, 1);
-               break;
-
-       case AUDPLAY_MSG_BUFFER_UPDATE:
-               audamrnb_update_pcm_buf_entry(audio, msg);
-               break;
-
-       default:
-               pr_err("unexpected message from decoder \n");
-       }
-}
-
-static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg)
-{
-       struct audio *audio = private;
-
-       switch (id) {
-       case AUDPP_MSG_STATUS_MSG:{
-                       unsigned status = msg[1];
-
-                       switch (status) {
-                       case AUDPP_DEC_STATUS_SLEEP:
-                               dprintk("decoder status: sleep \n");
-                               break;
-
-                       case AUDPP_DEC_STATUS_INIT:
-                               dprintk("decoder status: init \n");
-                               audpp_cmd_cfg_routing_mode(audio);
-                               break;
-
-                       case AUDPP_DEC_STATUS_CFG:
-                               dprintk("decoder status: cfg \n");
-                               break;
-                       case AUDPP_DEC_STATUS_PLAY:
-                               dprintk("decoder status: play \n");
-                               if (audio->pcm_feedback) {
-                                       audamrnb_config_hostpcm(audio);
-                                       audamrnb_buffer_refresh(audio);
-                               }
-                               break;
-                       default:
-                               pr_err("unknown decoder status \n");
-                               break;
-                       }
-                       break;
-               }
-       case AUDPP_MSG_CFG_MSG:
-               if (msg[0] == AUDPP_MSG_ENA_ENA) {
-                       dprintk("audamrnb_dsp_event: CFG_MSG ENABLE\n");
-                       auddec_dsp_config(audio, 1);
-                       audio->out_needed = 0;
-                       audio->running = 1;
-                       audpp_set_volume_and_pan(audio->dec_id, audio->volume,
-                                                0);
-                       audpp_avsync(audio->dec_id, 22050);
-               } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
-                       dprintk("audamrnb_dsp_event: CFG_MSG DISABLE\n");
-                       audpp_avsync(audio->dec_id, 0);
-                       audio->running = 0;
-               } else {
-                       pr_err("audamrnb_dsp_event: CFG_MSG %d?\n", msg[0]);
-               }
-               break;
-       case AUDPP_MSG_ROUTING_ACK:
-               dprintk("audamrnb_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
-               audpp_cmd_cfg_adec_params(audio);
-               break;
-
-       default:
-               pr_err("audamrnb_dsp_event: UNKNOWN (%d)\n", id);
-       }
-
-}
-
-struct msm_adsp_ops audplay_adsp_ops_amrnb = {
-       .event = audplay_dsp_event,
-};
-
-#define audplay_send_queue0(audio, cmd, len) \
-       msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
-                      cmd, len)
-
-static int auddec_dsp_config(struct audio *audio, int enable)
-{
-       audpp_cmd_cfg_dec_type cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
-       if (enable)
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
-                   AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRNB;
-       else
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
-
-       return audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_adec_params(struct audio *audio)
-{
-       struct audpp_cmd_cfg_adec_params_amrnb cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
-       cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN;
-       cmd.common.dec_id = audio->dec_id;
-       cmd.common.input_sampling_frequency = 8000;
-       cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
-
-       audpp_send_queue2(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_routing_mode(struct audio *audio)
-{
-       struct audpp_cmd_routing_mode cmd;
-       dprintk("audpp_cmd_cfg_routing_mode()\n");
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
-       cmd.object_number = audio->dec_id;
-       if (audio->pcm_feedback)
-               cmd.routing_mode = ROUTING_MODE_FTRT;
-       else
-               cmd.routing_mode = ROUTING_MODE_RT;
-
-       audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static int audplay_dsp_send_data_avail(struct audio *audio,
-                                      unsigned idx, unsigned len)
-{
-       audplay_cmd_bitstream_data_avail cmd;
-
-       cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
-       cmd.decoder_id = audio->dec_id;
-       cmd.buf_ptr = audio->out[idx].addr;
-       cmd.buf_size = len / 2;
-       cmd.partition_number = 0;
-       return audplay_send_queue0(audio, &cmd, sizeof(cmd));
-}
-
-static void audamrnb_buffer_refresh(struct audio *audio)
-{
-       struct audplay_cmd_buffer_refresh refresh_cmd;
-
-       refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
-       refresh_cmd.num_buffers = 1;
-       refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
-       refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
-         (audio->in[audio->fill_next].size % AMRNB_DECODED_FRSZ);
-       refresh_cmd.buf_read_count = 0;
-       dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
-               refresh_cmd.buf0_address, refresh_cmd.buf0_length);
-       (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
-}
-
-static void audamrnb_config_hostpcm(struct audio *audio)
-{
-       struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
-
-       dprintk("audamrnb_config_hostpcm()\n");
-       cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
-       cfg_cmd.max_buffers = audio->pcm_buf_count;
-       cfg_cmd.byte_swap = 0;
-       cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
-       cfg_cmd.feedback_frequency = 1;
-       cfg_cmd.partition_number = 0;
-       (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
-
-}
-
-static void audamrnb_send_data(struct audio *audio, unsigned needed)
-{
-       struct buffer *frame;
-       unsigned long flags;
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       if (!audio->running)
-               goto done;
-
-       if (needed) {
-               /* We were called from the callback because the DSP
-                * requested more data.  Note that the DSP does want
-                * more data, and if a buffer was in-flight, mark it
-                * as available (since the DSP must now be done with
-                * it).
-                */
-               audio->out_needed = 1;
-               frame = audio->out + audio->out_tail;
-               if (frame->used == 0xffffffff) {
-                       frame->used = 0;
-                       audio->out_tail ^= 1;
-                       wake_up(&audio->write_wait);
-               }
-       }
-
-       if (audio->out_needed) {
-               /* If the DSP currently wants data and we have a
-                * buffer available, we will send it and reset
-                * the needed flag.  We'll mark the buffer as in-flight
-                * so that it won't be recycled until the next buffer
-                * is requested
-                */
-
-               frame = audio->out + audio->out_tail;
-               if (frame->used) {
-                       BUG_ON(frame->used == 0xffffffff);
-/*                      printk("frame %d busy\n", audio->out_tail); */
-                       audplay_dsp_send_data_avail(audio, audio->out_tail,
-                                                   frame->used);
-                       frame->used = 0xffffffff;
-                       audio->out_needed = 0;
-               }
-       }
- done:
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-}
-
-/* ------------------- device --------------------- */
-
-static void audamrnb_flush(struct audio *audio)
-{
-       audio->out[0].used = 0;
-       audio->out[1].used = 0;
-       audio->out_head = 0;
-       audio->out_tail = 0;
-       audio->stopped = 0;
-       atomic_set(&audio->out_bytes, 0);
-}
-
-static void audamrnb_flush_pcm_buf(struct audio *audio)
-{
-       uint8_t index;
-
-       for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
-               audio->in[index].used = 0;
-
-       audio->read_next = 0;
-       audio->fill_next = 0;
-}
-
-static long audamrnb_ioctl(struct file *file, unsigned int cmd,
-               unsigned long arg)
-{
-       struct audio *audio = file->private_data;
-       int rc = 0;
-
-       dprintk("audamrnb_ioctl() cmd = %d\n", cmd);
-
-       if (cmd == AUDIO_GET_STATS) {
-               struct msm_audio_stats stats;
-               stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
-               stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
-               if (copy_to_user((void *)arg, &stats, sizeof(stats)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == AUDIO_SET_VOLUME) {
-               unsigned long flags;
-               spin_lock_irqsave(&audio->dsp_lock, flags);
-               audio->volume = arg;
-               if (audio->running)
-                       audpp_set_volume_and_pan(audio->dec_id, arg, 0);
-               spin_unlock_irqrestore(&audio->dsp_lock, flags);
-    return 0;
-       }
-       mutex_lock(&audio->lock);
-       switch (cmd) {
-       case AUDIO_START:
-               rc = audamrnb_enable(audio);
-               break;
-       case AUDIO_STOP:
-               rc = audamrnb_disable(audio);
-               audio->stopped = 1;
-               break;
-       case AUDIO_FLUSH:
-               if (audio->stopped) {
-                       /* Make sure we're stopped and we wake any threads
-                        * that might be blocked holding the write_lock.
-                        * While audio->stopped write threads will always
-                        * exit immediately.
-                        */
-                       wake_up(&audio->write_wait);
-                       mutex_lock(&audio->write_lock);
-                       audamrnb_flush(audio);
-                       mutex_unlock(&audio->write_lock);
-                       wake_up(&audio->read_wait);
-                       mutex_lock(&audio->read_lock);
-                       audamrnb_flush_pcm_buf(audio);
-                       mutex_unlock(&audio->read_lock);
-                       break;
-               }
-
-  case AUDIO_SET_CONFIG:{
-      dprintk("AUDIO_SET_CONFIG not applicable \n");
-                       break;
-               }
-       case AUDIO_GET_CONFIG:{
-                       struct msm_audio_config config;
-                       config.buffer_size = BUFSZ;
-                       config.buffer_count = 2;
-                       config.sample_rate = 8000;
-                       config.channel_count = 1;
-                       config.unused[0] = 0;
-                       config.unused[1] = 0;
-                       config.unused[2] = 0;
-                       config.unused[3] = 0;
-                       if (copy_to_user((void *)arg, &config,
-                                        sizeof(config)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-
-                       break;
-               }
-       case AUDIO_GET_PCM_CONFIG:{
-                       struct msm_audio_pcm_config config;
-                       config.pcm_feedback = 0;
-                       config.buffer_count = PCM_BUF_MAX_COUNT;
-                       config.buffer_size = PCM_BUFSZ_MIN;
-                       if (copy_to_user((void *)arg, &config,
-                                        sizeof(config)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-                       break;
-               }
-       case AUDIO_SET_PCM_CONFIG:{
-               struct msm_audio_pcm_config config;
-               if (copy_from_user
-                   (&config, (void *)arg, sizeof(config))) {
-                       rc = -EFAULT;
-                       break;
-               }
-               if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
-                   (config.buffer_count == 1))
-                       config.buffer_count = PCM_BUF_MAX_COUNT;
-
-               if (config.buffer_size < PCM_BUFSZ_MIN)
-                       config.buffer_size = PCM_BUFSZ_MIN;
-
-                       /* Check if pcm feedback is required */
-               if ((config.pcm_feedback) && (!audio->read_data)) {
-                       dprintk("audamrnb_ioctl: allocate PCM buf %d\n",
-                                       config.buffer_count *
-                                       config.buffer_size);
-                       audio->read_data =
-                               dma_alloc_coherent(NULL,
-                                                      config.buffer_size *
-                                                      config.buffer_count,
-                                                      &audio->read_phys,
-                                                      GFP_KERNEL);
-                       if (!audio->read_data) {
-                               pr_err("audamrnb_ioctl: no mem for pcm buf\n");
-                               rc = -1;
-                       } else {
-                               uint8_t index;
-                               uint32_t offset = 0;
-                               audio->pcm_feedback = 1;
-                               audio->buf_refresh = 0;
-                               audio->pcm_buf_count =
-                                       config.buffer_count;
-                               audio->read_next = 0;
-                               audio->fill_next = 0;
-
-                               for (index = 0;
-                               index < config.buffer_count; index++) {
-                                       audio->in[index].data =
-                                               audio->read_data + offset;
-                                       audio->in[index].addr =
-                                           audio->read_phys + offset;
-                                       audio->in[index].size =
-                                           config.buffer_size;
-                                       audio->in[index].used = 0;
-                                       offset += config.buffer_size;
-                               }
-                               rc = 0;
-                       }
-               } else {
-                       rc = 0;
-               }
-               break;
-       }
-       default:
-               rc = -EINVAL;
-       }
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static ssize_t audamrnb_read(struct file *file, char __user *buf, size_t count,
-                         loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       int rc = 0;
-
-       if (!audio->pcm_feedback)
-               return 0; /* PCM feedback is not enabled. Nothing to read */
-
-       mutex_lock(&audio->read_lock);
-       dprintk("audamrnb_read() %d \n", count);
-       while (count > 0) {
-               rc = wait_event_interruptible(audio->read_wait,
-                                             (audio->in[audio->read_next].
-                                              used > 0) || (audio->stopped));
-
-               if (rc < 0)
-                       break;
-
-               if (audio->stopped) {
-                       rc = -EBUSY;
-                       break;
-               }
-
-               if (count < audio->in[audio->read_next].used) {
-                       /* Read must happen in frame boundary. Since driver does
-                        * not know frame size, read count must be greater or
-                        * equal to size of PCM samples
-                        */
-                       dprintk("audamrnb_read:read stop - partial frame\n");
-                       break;
-               } else {
-                       dprintk("audamrnb_read: read from in[%d]\n",
-                               audio->read_next);
-                       if (copy_to_user
-                           (buf, audio->in[audio->read_next].data,
-                            audio->in[audio->read_next].used)) {
-                               pr_err("audamrnb_read: invalid addr %x \n",
-                                      (unsigned int)buf);
-                               rc = -EFAULT;
-                               break;
-                       }
-                       count -= audio->in[audio->read_next].used;
-                       buf += audio->in[audio->read_next].used;
-                       audio->in[audio->read_next].used = 0;
-                       if ((++audio->read_next) == audio->pcm_buf_count)
-                               audio->read_next = 0;
-               }
-       }
-
-       if (audio->buf_refresh) {
-               audio->buf_refresh = 0;
-               dprintk("audamrnb_read: kick start pcm feedback again\n");
-               audamrnb_buffer_refresh(audio);
-       }
-
-       mutex_unlock(&audio->read_lock);
-
-       if (buf > start)
-               rc = buf - start;
-
-       dprintk("audamrnb_read: read %d bytes\n", rc);
-       return rc;
-}
-
-static ssize_t audamrnb_write(struct file *file, const char __user *buf,
-                          size_t count, loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       struct buffer *frame;
-       size_t xfer;
-       int rc = 0;
-
-       if (count & 1)
-               return -EINVAL;
-       dprintk("audamrnb_write() \n");
-       mutex_lock(&audio->write_lock);
-       while (count > 0) {
-               frame = audio->out + audio->out_head;
-               rc = wait_event_interruptible(audio->write_wait,
-                                             (frame->used == 0)
-                                             || (audio->stopped));
-               dprintk("audamrnb_write() buffer available\n");
-               if (rc < 0)
-                       break;
-               if (audio->stopped) {
-                       rc = -EBUSY;
-                       break;
-               }
-               xfer = (count > frame->size) ? frame->size : count;
-               if (copy_from_user(frame->data, buf, xfer)) {
-                       rc = -EFAULT;
-                       break;
-               }
-
-               frame->used = xfer;
-               audio->out_head ^= 1;
-               count -= xfer;
-               buf += xfer;
-
-               audamrnb_send_data(audio, 0);
-
-       }
-       mutex_unlock(&audio->write_lock);
-       if (buf > start)
-               return buf - start;
-       return rc;
-}
-
-static int audamrnb_release(struct inode *inode, struct file *file)
-{
-       struct audio *audio = file->private_data;
-
-       dprintk("audamrnb_release()\n");
-
-       mutex_lock(&audio->lock);
-       audamrnb_disable(audio);
-       audamrnb_flush(audio);
-       audamrnb_flush_pcm_buf(audio);
-       msm_adsp_put(audio->audplay);
-       audio->audplay = NULL;
-       audio->opened = 0;
-       dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
-       audio->data = NULL;
-       if (audio->read_data != NULL) {
-               dma_free_coherent(NULL,
-                                 audio->in[0].size * audio->pcm_buf_count,
-                                 audio->read_data, audio->read_phys);
-               audio->read_data = NULL;
-       }
-       audio->pcm_feedback = 0;
-       mutex_unlock(&audio->lock);
-       return 0;
-}
-
-static struct audio the_amrnb_audio;
-
-static int audamrnb_open(struct inode *inode, struct file *file)
-{
-       struct audio *audio = &the_amrnb_audio;
-       int rc;
-
-       mutex_lock(&audio->lock);
-
-       if (audio->opened) {
-               pr_err("audio: busy\n");
-               rc = -EBUSY;
-               goto done;
-       }
-
-       if (!audio->data) {
-               audio->data = dma_alloc_coherent(NULL, DMASZ,
-                                                &audio->phys, GFP_KERNEL);
-               if (!audio->data) {
-                       pr_err("audio: could not allocate DMA buffers\n");
-                       rc = -ENOMEM;
-                       goto done;
-               }
-       }
-
-       rc = audmgr_open(&audio->audmgr);
-       if (rc)
-               goto done;
-
-       rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
-               &audplay_adsp_ops_amrnb, audio);
-       if (rc) {
-               pr_err("audio: failed to get audplay0 dsp module\n");
-               audmgr_disable(&audio->audmgr);
-               dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
-               audio->data = NULL;
-               goto done;
-       }
-
-       audio->dec_id = 0;
-
-       audio->out[0].data = audio->data + 0;
-       audio->out[0].addr = audio->phys + 0;
-       audio->out[0].size = BUFSZ;
-
-       audio->out[1].data = audio->data + BUFSZ;
-       audio->out[1].addr = audio->phys + BUFSZ;
-       audio->out[1].size = BUFSZ;
-
-       audio->volume = 0x2000; /* Q13 1.0 */
-
-       audamrnb_flush(audio);
-
-       file->private_data = audio;
-       audio->opened = 1;
-       rc = 0;
-done:
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static struct file_operations audio_amrnb_fops = {
-       .owner = THIS_MODULE,
-       .open = audamrnb_open,
-       .release = audamrnb_release,
-       .read = audamrnb_read,
-       .write = audamrnb_write,
-       .unlocked_ioctl = audamrnb_ioctl,
-       .llseek = noop_llseek,
-};
-
-struct miscdevice audio_amrnb_misc = {
-       .minor = MISC_DYNAMIC_MINOR,
-       .name = "msm_amrnb",
-       .fops = &audio_amrnb_fops,
-};
-
-static int __init audamrnb_init(void)
-{
-       mutex_init(&the_amrnb_audio.lock);
-       mutex_init(&the_amrnb_audio.write_lock);
-       mutex_init(&the_amrnb_audio.read_lock);
-       spin_lock_init(&the_amrnb_audio.dsp_lock);
-       init_waitqueue_head(&the_amrnb_audio.write_wait);
-       init_waitqueue_head(&the_amrnb_audio.read_wait);
-       the_amrnb_audio.read_data = NULL;
-       return misc_register(&audio_amrnb_misc);
-}
-
-static void __exit audamrnb_exit(void)
-{
-       misc_deregister(&audio_amrnb_misc);
-}
-
-module_init(audamrnb_init);
-module_exit(audamrnb_exit);
-
-MODULE_DESCRIPTION("MSM AMR-NB driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("QUALCOMM Inc");
diff --git a/drivers/staging/dream/qdsp5/audio_evrc.c b/drivers/staging/dream/qdsp5/audio_evrc.c
deleted file mode 100644 (file)
index 24a8926..0000000
+++ /dev/null
@@ -1,847 +0,0 @@
-/* arch/arm/mach-msm/audio_evrc.c
- *
- * Copyright (c) 2008 QUALCOMM USA, INC.
- *
- * This code also borrows from audio_aac.c, which is
- * Copyright (C) 2008 Google, Inc.
- * Copyright (C) 2008 HTC Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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, you can find it at http://www.fsf.org.
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/kthread.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/gfp.h>
-
-#include <asm/atomic.h>
-#include <asm/ioctls.h>
-#include <mach/msm_adsp.h>
-#include <linux/msm_audio.h>
-#include "audmgr.h"
-
-#include <mach/qdsp5/qdsp5audppcmdi.h>
-#include <mach/qdsp5/qdsp5audppmsg.h>
-#include <mach/qdsp5/qdsp5audplaycmdi.h>
-#include <mach/qdsp5/qdsp5audplaymsg.h>
-
-#include "adsp.h"
-
-#ifdef DEBUG
-#define dprintk(format, arg...) \
-       printk(KERN_DEBUG format, ## arg)
-#else
-#define dprintk(format, arg...) do {} while (0)
-#endif
-
-/* Hold 30 packets of 24 bytes each*/
-#define BUFSZ                  720
-#define DMASZ                  (BUFSZ * 2)
-
-#define AUDDEC_DEC_EVRC        12
-
-#define PCM_BUFSZ_MIN          1600    /* 100ms worth of data */
-#define PCM_BUF_MAX_COUNT      5
-/* DSP only accepts 5 buffers at most
- * but support 2 buffers currently
- */
-#define EVRC_DECODED_FRSZ      320     /* EVRC 20ms 8KHz mono PCM size */
-
-#define ROUTING_MODE_FTRT      1
-#define ROUTING_MODE_RT        2
-/* Decoder status received from AUDPPTASK */
-#define  AUDPP_DEC_STATUS_SLEEP        0
-#define         AUDPP_DEC_STATUS_INIT  1
-#define  AUDPP_DEC_STATUS_CFG   2
-#define  AUDPP_DEC_STATUS_PLAY  3
-
-struct buffer {
-       void *data;
-       unsigned size;
-       unsigned used;          /* Input usage actual DSP produced PCM size  */
-       unsigned addr;
-};
-
-struct audio {
-       struct buffer out[2];
-
-       spinlock_t dsp_lock;
-
-       uint8_t out_head;
-       uint8_t out_tail;
-       uint8_t out_needed;     /* number of buffers the dsp is waiting for */
-
-       atomic_t out_bytes;
-
-       struct mutex lock;
-       struct mutex write_lock;
-       wait_queue_head_t write_wait;
-
-       /* Host PCM section */
-       struct buffer in[PCM_BUF_MAX_COUNT];
-       struct mutex read_lock;
-       wait_queue_head_t read_wait;    /* Wait queue for read */
-       char *read_data;        /* pointer to reader buffer */
-       dma_addr_t read_phys;   /* physical address of reader buffer */
-       uint8_t read_next;      /* index to input buffers to be read next */
-       uint8_t fill_next;      /* index to buffer that DSP should be filling */
-       uint8_t pcm_buf_count;  /* number of pcm buffer allocated */
-       /* ---- End of Host PCM section */
-
-       struct msm_adsp_module *audplay;
-       struct audmgr audmgr;
-
-       /* data allocated for various buffers */
-       char *data;
-       dma_addr_t phys;
-
-       uint8_t opened:1;
-       uint8_t enabled:1;
-       uint8_t running:1;
-       uint8_t stopped:1;      /* set when stopped, cleared on flush */
-       uint8_t pcm_feedback:1;
-       uint8_t buf_refresh:1;
-
-       unsigned volume;
-       uint16_t dec_id;
-       uint32_t read_ptr_offset;
-};
-static struct audio the_evrc_audio;
-
-static int auddec_dsp_config(struct audio *audio, int enable);
-static void audpp_cmd_cfg_adec_params(struct audio *audio);
-static void audpp_cmd_cfg_routing_mode(struct audio *audio);
-static void audevrc_send_data(struct audio *audio, unsigned needed);
-static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg);
-static void audevrc_config_hostpcm(struct audio *audio);
-static void audevrc_buffer_refresh(struct audio *audio);
-
-/* must be called with audio->lock held */
-static int audevrc_enable(struct audio *audio)
-{
-       struct audmgr_config cfg;
-       int rc;
-
-       if (audio->enabled)
-               return 0;
-
-       audio->out_tail = 0;
-       audio->out_needed = 0;
-
-       cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
-       cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
-       cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
-       cfg.codec = RPC_AUD_DEF_CODEC_EVRC;
-       cfg.snd_method = RPC_SND_METHOD_MIDI;
-
-       rc = audmgr_enable(&audio->audmgr, &cfg);
-       if (rc < 0)
-               return rc;
-
-       if (msm_adsp_enable(audio->audplay)) {
-               pr_err("audio: msm_adsp_enable(audplay) failed\n");
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-
-       if (audpp_enable(audio->dec_id, audevrc_dsp_event, audio)) {
-               pr_err("audio: audpp_enable() failed\n");
-               msm_adsp_disable(audio->audplay);
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-       audio->enabled = 1;
-       return 0;
-}
-
-/* must be called with audio->lock held */
-static int audevrc_disable(struct audio *audio)
-{
-       if (audio->enabled) {
-               audio->enabled = 0;
-               auddec_dsp_config(audio, 0);
-               wake_up(&audio->write_wait);
-               wake_up(&audio->read_wait);
-               msm_adsp_disable(audio->audplay);
-               audpp_disable(audio->dec_id, audio);
-               audmgr_disable(&audio->audmgr);
-               audio->out_needed = 0;
-       }
-       return 0;
-}
-
-/* ------------------- dsp --------------------- */
-
-static void audevrc_update_pcm_buf_entry(struct audio *audio,
-                                        uint32_t *payload)
-{
-       uint8_t index;
-       unsigned long flags;
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       for (index = 0; index < payload[1]; index++) {
-               if (audio->in[audio->fill_next].addr
-                               == payload[2 + index * 2]) {
-                       dprintk("audevrc_update_pcm_buf_entry: in[%d] ready\n",
-                               audio->fill_next);
-                       audio->in[audio->fill_next].used =
-                               payload[3 + index * 2];
-                       if ((++audio->fill_next) == audio->pcm_buf_count)
-                               audio->fill_next = 0;
-
-               } else {
-                       pr_err
-                       ("audevrc_update_pcm_buf_entry: expected=%x ret=%x\n",
-                               audio->in[audio->fill_next].addr,
-                               payload[1 + index * 2]);
-                       break;
-               }
-       }
-       if (audio->in[audio->fill_next].used == 0) {
-               audevrc_buffer_refresh(audio);
-       } else {
-               dprintk("audevrc_update_pcm_buf_entry: read cannot keep up\n");
-               audio->buf_refresh = 1;
-       }
-
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-       wake_up(&audio->read_wait);
-}
-
-static void audplay_dsp_event(void *data, unsigned id, size_t len,
-                             void (*getevent) (void *ptr, size_t len))
-{
-       struct audio *audio = data;
-       uint32_t msg[28];
-       getevent(msg, sizeof(msg));
-
-       dprintk("audplay_dsp_event: msg_id=%x\n", id);
-       switch (id) {
-       case AUDPLAY_MSG_DEC_NEEDS_DATA:
-               audevrc_send_data(audio, 1);
-               break;
-       case AUDPLAY_MSG_BUFFER_UPDATE:
-               dprintk("audevrc_update_pcm_buf_entry:======> \n");
-               audevrc_update_pcm_buf_entry(audio, msg);
-               break;
-       default:
-               pr_err("unexpected message from decoder \n");
-       }
-}
-
-static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg)
-{
-       struct audio *audio = private;
-
-       switch (id) {
-       case AUDPP_MSG_STATUS_MSG:{
-                       unsigned status = msg[1];
-
-                       switch (status) {
-                       case AUDPP_DEC_STATUS_SLEEP:
-                               dprintk("decoder status: sleep \n");
-                               break;
-
-                       case AUDPP_DEC_STATUS_INIT:
-                               dprintk("decoder status: init \n");
-                               audpp_cmd_cfg_routing_mode(audio);
-                               break;
-
-                       case AUDPP_DEC_STATUS_CFG:
-                               dprintk("decoder status: cfg \n");
-                               break;
-                       case AUDPP_DEC_STATUS_PLAY:
-                               dprintk("decoder status: play \n");
-                               if (audio->pcm_feedback) {
-                                       audevrc_config_hostpcm(audio);
-                                       audevrc_buffer_refresh(audio);
-                               }
-                               break;
-                       default:
-                               pr_err("unknown decoder status \n");
-                       }
-                       break;
-               }
-       case AUDPP_MSG_CFG_MSG:
-               if (msg[0] == AUDPP_MSG_ENA_ENA) {
-                       dprintk("audevrc_dsp_event: CFG_MSG ENABLE\n");
-                       auddec_dsp_config(audio, 1);
-                       audio->out_needed = 0;
-                       audio->running = 1;
-                       audpp_set_volume_and_pan(audio->dec_id, audio->volume,
-                                                0);
-                       audpp_avsync(audio->dec_id, 22050);
-               } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
-                       dprintk("audevrc_dsp_event: CFG_MSG DISABLE\n");
-                       audpp_avsync(audio->dec_id, 0);
-                       audio->running = 0;
-               } else {
-                       pr_err("audevrc_dsp_event: CFG_MSG %d?\n", msg[0]);
-               }
-               break;
-       case AUDPP_MSG_ROUTING_ACK:
-               dprintk("audevrc_dsp_event: ROUTING_ACK\n");
-               audpp_cmd_cfg_adec_params(audio);
-               break;
-
-       default:
-               pr_err("audevrc_dsp_event: UNKNOWN (%d)\n", id);
-       }
-
-}
-
-struct msm_adsp_ops audplay_adsp_ops_evrc = {
-       .event = audplay_dsp_event,
-};
-
-#define audplay_send_queue0(audio, cmd, len) \
-       msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
-                      cmd, len)
-
-static int auddec_dsp_config(struct audio *audio, int enable)
-{
-       audpp_cmd_cfg_dec_type cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
-       if (enable)
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
-                   AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_EVRC;
-       else
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
-
-       return audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_adec_params(struct audio *audio)
-{
-       struct audpp_cmd_cfg_adec_params_evrc cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
-       cmd.common.length = sizeof(cmd);
-       cmd.common.dec_id = audio->dec_id;
-       cmd.common.input_sampling_frequency = 8000;
-       cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
-
-       audpp_send_queue2(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_routing_mode(struct audio *audio)
-{
-       struct audpp_cmd_routing_mode cmd;
-       dprintk("audpp_cmd_cfg_routing_mode()\n");
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
-       cmd.object_number = audio->dec_id;
-       if (audio->pcm_feedback)
-               cmd.routing_mode = ROUTING_MODE_FTRT;
-       else
-               cmd.routing_mode = ROUTING_MODE_RT;
-
-       audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static int audplay_dsp_send_data_avail(struct audio *audio,
-                                      unsigned idx, unsigned len)
-{
-       audplay_cmd_bitstream_data_avail cmd;
-
-       cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
-       cmd.decoder_id = audio->dec_id;
-       cmd.buf_ptr = audio->out[idx].addr;
-       cmd.buf_size = len / 2;
-       cmd.partition_number = 0;
-       return audplay_send_queue0(audio, &cmd, sizeof(cmd));
-}
-
-static void audevrc_buffer_refresh(struct audio *audio)
-{
-       struct audplay_cmd_buffer_refresh refresh_cmd;
-
-       refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
-       refresh_cmd.num_buffers = 1;
-       refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
-       refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
-
-       refresh_cmd.buf_read_count = 0;
-       dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
-               refresh_cmd.buf0_address, refresh_cmd.buf0_length);
-       audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
-}
-
-static void audevrc_config_hostpcm(struct audio *audio)
-{
-       struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
-
-       dprintk("audevrc_config_hostpcm()\n");
-       cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
-       cfg_cmd.max_buffers = 1;
-       cfg_cmd.byte_swap = 0;
-       cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
-       cfg_cmd.feedback_frequency = 1;
-       cfg_cmd.partition_number = 0;
-       audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
-
-}
-
-static void audevrc_send_data(struct audio *audio, unsigned needed)
-{
-       struct buffer *frame;
-       unsigned long flags;
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       if (!audio->running)
-               goto done;
-
-       if (needed) {
-               /* We were called from the callback because the DSP
-                * requested more data.  Note that the DSP does want
-                * more data, and if a buffer was in-flight, mark it
-                * as available (since the DSP must now be done with
-                * it).
-                */
-               audio->out_needed = 1;
-               frame = audio->out + audio->out_tail;
-               if (frame->used == 0xffffffff) {
-                       dprintk("frame %d free\n", audio->out_tail);
-                       frame->used = 0;
-                       audio->out_tail ^= 1;
-                       wake_up(&audio->write_wait);
-               }
-       }
-
-       if (audio->out_needed) {
-               /* If the DSP currently wants data and we have a
-                * buffer available, we will send it and reset
-                * the needed flag.  We'll mark the buffer as in-flight
-                * so that it won't be recycled until the next buffer
-                * is requested
-                */
-
-               frame = audio->out + audio->out_tail;
-               if (frame->used) {
-                       BUG_ON(frame->used == 0xffffffff);
-                       dprintk("frame %d busy\n", audio->out_tail);
-                       audplay_dsp_send_data_avail(audio, audio->out_tail,
-                                                   frame->used);
-                       frame->used = 0xffffffff;
-                       audio->out_needed = 0;
-               }
-       }
-done:
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-}
-
-/* ------------------- device --------------------- */
-
-static void audevrc_flush(struct audio *audio)
-{
-       audio->out[0].used = 0;
-       audio->out[1].used = 0;
-       audio->out_head = 0;
-       audio->out_tail = 0;
-       audio->stopped = 0;
-       atomic_set(&audio->out_bytes, 0);
-}
-
-static void audevrc_flush_pcm_buf(struct audio *audio)
-{
-       uint8_t index;
-
-       for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
-               audio->in[index].used = 0;
-
-       audio->read_next = 0;
-       audio->fill_next = 0;
-}
-
-static long audevrc_ioctl(struct file *file, unsigned int cmd,
-                         unsigned long arg)
-{
-       struct audio *audio = file->private_data;
-       int rc = 0;
-
-       dprintk("audevrc_ioctl() cmd = %d\n", cmd);
-
-       if (cmd == AUDIO_GET_STATS) {
-               struct msm_audio_stats stats;
-               stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
-               stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
-               if (copy_to_user((void *)arg, &stats, sizeof(stats)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == AUDIO_SET_VOLUME) {
-               unsigned long flags;
-               spin_lock_irqsave(&audio->dsp_lock, flags);
-               audio->volume = arg;
-               if (audio->running)
-                       audpp_set_volume_and_pan(audio->dec_id, arg, 0);
-               spin_unlock_irqrestore(&audio->dsp_lock, flags);
-               return 0;
-       }
-       mutex_lock(&audio->lock);
-       switch (cmd) {
-       case AUDIO_START:
-               rc = audevrc_enable(audio);
-               break;
-       case AUDIO_STOP:
-               rc = audevrc_disable(audio);
-               audio->stopped = 1;
-               break;
-       case AUDIO_SET_CONFIG:{
-                       dprintk("AUDIO_SET_CONFIG not applicable \n");
-                       break;
-               }
-       case AUDIO_GET_CONFIG:{
-                       struct msm_audio_config config;
-                       config.buffer_size = BUFSZ;
-                       config.buffer_count = 2;
-                       config.sample_rate = 8000;
-                       config.channel_count = 1;
-                       config.unused[0] = 0;
-                       config.unused[1] = 0;
-                       config.unused[2] = 0;
-                       config.unused[3] = 0;
-                       if (copy_to_user((void *)arg, &config, sizeof(config)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-                       break;
-               }
-       case AUDIO_GET_PCM_CONFIG:{
-                       struct msm_audio_pcm_config config;
-                       config.pcm_feedback = 0;
-                       config.buffer_count = PCM_BUF_MAX_COUNT;
-                       config.buffer_size = PCM_BUFSZ_MIN;
-                       if (copy_to_user((void *)arg, &config, sizeof(config)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-                       break;
-               }
-       case AUDIO_SET_PCM_CONFIG:{
-                       struct msm_audio_pcm_config config;
-                       if (copy_from_user
-                           (&config, (void *)arg, sizeof(config))) {
-                               rc = -EFAULT;
-                               break;
-                       }
-                       if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
-                           (config.buffer_count == 1))
-                               config.buffer_count = PCM_BUF_MAX_COUNT;
-
-                       if (config.buffer_size < PCM_BUFSZ_MIN)
-                               config.buffer_size = PCM_BUFSZ_MIN;
-
-                       /* Check if pcm feedback is required */
-                       if ((config.pcm_feedback) && (!audio->read_data)) {
-                               dprintk("audevrc_ioctl: allocate PCM buf %d\n",
-                                       config.buffer_count *
-                                       config.buffer_size);
-                               audio->read_data =
-                                   dma_alloc_coherent(NULL,
-                                                      config.buffer_size *
-                                                      config.buffer_count,
-                                                      &audio->read_phys,
-                                                      GFP_KERNEL);
-                               if (!audio->read_data) {
-                                       pr_err
-                                       ("audevrc_ioctl: no mem for pcm buf\n");
-                                       rc = -1;
-                               } else {
-                                       uint8_t index;
-                                       uint32_t offset = 0;
-                                       audio->pcm_feedback = 1;
-                                       audio->buf_refresh = 0;
-                                       audio->pcm_buf_count =
-                                           config.buffer_count;
-                                       audio->read_next = 0;
-                                       audio->fill_next = 0;
-
-                                       for (index = 0;
-                                            index < config.buffer_count;
-                                            index++) {
-                                               audio->in[index].data =
-                                                   audio->read_data + offset;
-                                               audio->in[index].addr =
-                                                   audio->read_phys + offset;
-                                               audio->in[index].size =
-                                                   config.buffer_size;
-                                               audio->in[index].used = 0;
-                                               offset += config.buffer_size;
-                                       }
-                                       rc = 0;
-                               }
-                       } else {
-                               rc = 0;
-                       }
-                       break;
-               }
-       case AUDIO_PAUSE:
-               dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
-               rc = audpp_pause(audio->dec_id, (int) arg);
-               break;
-       default:
-               rc = -EINVAL;
-       }
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static ssize_t audevrc_read(struct file *file, char __user *buf, size_t count,
-                           loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       int rc = 0;
-       if (!audio->pcm_feedback) {
-               return 0;
-               /* PCM feedback is not enabled. Nothing to read */
-       }
-       mutex_lock(&audio->read_lock);
-       dprintk("audevrc_read() \n");
-       while (count > 0) {
-               rc = wait_event_interruptible(audio->read_wait,
-                                             (audio->in[audio->read_next].
-                                              used > 0) || (audio->stopped));
-               dprintk("audevrc_read() wait terminated \n");
-               if (rc < 0)
-                       break;
-               if (audio->stopped) {
-                       rc = -EBUSY;
-                       break;
-               }
-               if (count < audio->in[audio->read_next].used) {
-                       /* Read must happen in frame boundary. Since driver does
-                        * not know frame size, read count must be greater or
-                        * equal to size of PCM samples
-                        */
-                       dprintk("audevrc_read:read stop - partial frame\n");
-                       break;
-               } else {
-                       dprintk("audevrc_read: read from in[%d]\n",
-                               audio->read_next);
-                       if (copy_to_user
-                           (buf, audio->in[audio->read_next].data,
-                            audio->in[audio->read_next].used)) {
-                               pr_err("audevrc_read: invalid addr %x \n",
-                                      (unsigned int)buf);
-                               rc = -EFAULT;
-                               break;
-                       }
-                       count -= audio->in[audio->read_next].used;
-                       buf += audio->in[audio->read_next].used;
-                       audio->in[audio->read_next].used = 0;
-                       if ((++audio->read_next) == audio->pcm_buf_count)
-                               audio->read_next = 0;
-                       if (audio->in[audio->read_next].used == 0)
-                               break;  /* No data ready at this moment
-                                        * Exit while loop to prevent
-                                        * output thread sleep too long
-                                        */
-
-               }
-       }
-       if (audio->buf_refresh) {
-               audio->buf_refresh = 0;
-               dprintk("audevrc_read: kick start pcm feedback again\n");
-               audevrc_buffer_refresh(audio);
-       }
-       mutex_unlock(&audio->read_lock);
-       if (buf > start)
-               rc = buf - start;
-       dprintk("audevrc_read: read %d bytes\n", rc);
-       return rc;
-}
-
-static ssize_t audevrc_write(struct file *file, const char __user *buf,
-                            size_t count, loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       struct buffer *frame;
-       size_t xfer;
-       int rc = 0;
-
-       if (count & 1)
-               return -EINVAL;
-       mutex_lock(&audio->write_lock);
-       dprintk("audevrc_write() \n");
-       while (count > 0) {
-               frame = audio->out + audio->out_head;
-               rc = wait_event_interruptible(audio->write_wait,
-                                             (frame->used == 0)
-                                             || (audio->stopped));
-               if (rc < 0)
-                       break;
-               if (audio->stopped) {
-                       rc = -EBUSY;
-                       break;
-               }
-               xfer = (count > frame->size) ? frame->size : count;
-               if (copy_from_user(frame->data, buf, xfer)) {
-                       rc = -EFAULT;
-                       break;
-               }
-
-               frame->used = xfer;
-               audio->out_head ^= 1;
-               count -= xfer;
-               buf += xfer;
-
-               audevrc_send_data(audio, 0);
-
-       }
-       mutex_unlock(&audio->write_lock);
-       if (buf > start)
-               return buf - start;
-       return rc;
-}
-
-static int audevrc_release(struct inode *inode, struct file *file)
-{
-       struct audio *audio = file->private_data;
-
-       dprintk("audevrc_release()\n");
-
-       mutex_lock(&audio->lock);
-       audevrc_disable(audio);
-       audevrc_flush(audio);
-       audevrc_flush_pcm_buf(audio);
-       msm_adsp_put(audio->audplay);
-       audio->audplay = NULL;
-       audio->opened = 0;
-       dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
-       audio->data = NULL;
-       if (audio->read_data != NULL) {
-               dma_free_coherent(NULL,
-                                 audio->in[0].size * audio->pcm_buf_count,
-                                 audio->read_data, audio->read_phys);
-               audio->read_data = NULL;
-       }
-       audio->pcm_feedback = 0;
-       mutex_unlock(&audio->lock);
-       return 0;
-}
-
-static struct audio the_evrc_audio;
-
-static int audevrc_open(struct inode *inode, struct file *file)
-{
-       struct audio *audio = &the_evrc_audio;
-       int rc;
-
-       if (audio->opened) {
-               pr_err("audio: busy\n");
-               return -EBUSY;
-       }
-
-       /* Acquire Lock */
-       mutex_lock(&audio->lock);
-
-       if (!audio->data) {
-               audio->data = dma_alloc_coherent(NULL, DMASZ,
-                                                &audio->phys, GFP_KERNEL);
-               if (!audio->data) {
-                       pr_err("audio: could not allocate DMA buffers\n");
-                       rc = -ENOMEM;
-                       goto dma_fail;
-               }
-       }
-
-       rc = audmgr_open(&audio->audmgr);
-       if (rc)
-               goto audmgr_fail;
-
-       rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
-                         &audplay_adsp_ops_evrc, audio);
-       if (rc) {
-               pr_err("audio: failed to get audplay0 dsp module\n");
-               goto adsp_fail;
-       }
-
-       audio->dec_id = 0;
-
-       audio->out[0].data = audio->data + 0;
-       audio->out[0].addr = audio->phys + 0;
-       audio->out[0].size = BUFSZ;
-
-       audio->out[1].data = audio->data + BUFSZ;
-       audio->out[1].addr = audio->phys + BUFSZ;
-       audio->out[1].size = BUFSZ;
-
-       audio->volume = 0x3FFF;
-
-       audevrc_flush(audio);
-
-       audio->opened = 1;
-       file->private_data = audio;
-
-       mutex_unlock(&audio->lock);
-       return rc;
-
-adsp_fail:
-       audmgr_close(&audio->audmgr);
-audmgr_fail:
-       dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
-dma_fail:
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static struct file_operations audio_evrc_fops = {
-       .owner = THIS_MODULE,
-       .open = audevrc_open,
-       .release = audevrc_release,
-       .read = audevrc_read,
-       .write = audevrc_write,
-       .unlocked_ioctl = audevrc_ioctl,
-       .llseek = noop_llseek,
-};
-
-struct miscdevice audio_evrc_misc = {
-       .minor = MISC_DYNAMIC_MINOR,
-       .name = "msm_evrc",
-       .fops = &audio_evrc_fops,
-};
-
-static int __init audevrc_init(void)
-{
-       mutex_init(&the_evrc_audio.lock);
-       mutex_init(&the_evrc_audio.write_lock);
-       mutex_init(&the_evrc_audio.read_lock);
-       spin_lock_init(&the_evrc_audio.dsp_lock);
-       init_waitqueue_head(&the_evrc_audio.write_wait);
-       init_waitqueue_head(&the_evrc_audio.read_wait);
-       the_evrc_audio.read_data = NULL;
-       return misc_register(&audio_evrc_misc);
-}
-
-static void __exit audevrc_exit(void)
-{
-       misc_deregister(&audio_evrc_misc);
-}
-
-module_init(audevrc_init);
-module_exit(audevrc_exit);
-
-MODULE_DESCRIPTION("MSM EVRC driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("QUALCOMM Inc");
diff --git a/drivers/staging/dream/qdsp5/audio_in.c b/drivers/staging/dream/qdsp5/audio_in.c
deleted file mode 100644 (file)
index b51fa09..0000000
+++ /dev/null
@@ -1,970 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/audio_in.c
- *
- * pcm audio input device
- *
- * Copyright (C) 2008 Google, Inc.
- * Copyright (C) 2008 HTC Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/kthread.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <linux/delay.h>
-
-#include <linux/msm_audio.h>
-
-#include <asm/atomic.h>
-#include <asm/ioctls.h>
-#include <mach/msm_adsp.h>
-#include <mach/msm_rpcrouter.h>
-
-#include "audmgr.h"
-
-#include <mach/qdsp5/qdsp5audpreproccmdi.h>
-#include <mach/qdsp5/qdsp5audpreprocmsg.h>
-#include <mach/qdsp5/qdsp5audreccmdi.h>
-#include <mach/qdsp5/qdsp5audrecmsg.h>
-
-/* for queue ids - should be relative to module number*/
-#include "adsp.h"
-
-/* FRAME_NUM must be a power of two */
-#define FRAME_NUM              (8)
-#define FRAME_SIZE             (2052 * 2)
-#define MONO_DATA_SIZE         (2048)
-#define STEREO_DATA_SIZE       (MONO_DATA_SIZE * 2)
-#define DMASZ                  (FRAME_SIZE * FRAME_NUM)
-
-#define AGC_PARAM_SIZE         (20)
-#define NS_PARAM_SIZE          (6)
-#define IIR_PARAM_SIZE         (48)
-#define DEBUG                  (0)
-
-#define AGC_ENABLE   0x0001
-#define NS_ENABLE    0x0002
-#define IIR_ENABLE   0x0004
-
-struct tx_agc_config {
-       uint16_t agc_params[AGC_PARAM_SIZE];
-};
-
-struct ns_config {
-       uint16_t ns_params[NS_PARAM_SIZE];
-};
-
-struct tx_iir_filter {
-       uint16_t num_bands;
-       uint16_t iir_params[IIR_PARAM_SIZE];
-};
-
-struct audpre_cmd_iir_config_type {
-       uint16_t cmd_id;
-       uint16_t active_flag;
-       uint16_t num_bands;
-       uint16_t iir_params[IIR_PARAM_SIZE];
-};
-
-struct buffer {
-       void *data;
-       uint32_t size;
-       uint32_t read;
-       uint32_t addr;
-};
-
-struct audio_in {
-       struct buffer in[FRAME_NUM];
-
-       spinlock_t dsp_lock;
-
-       atomic_t in_bytes;
-
-       struct mutex lock;
-       struct mutex read_lock;
-       wait_queue_head_t wait;
-
-       struct msm_adsp_module *audpre;
-       struct msm_adsp_module *audrec;
-
-       /* configuration to use on next enable */
-       uint32_t samp_rate;
-       uint32_t channel_mode;
-       uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */
-       uint32_t type; /* 0 for PCM ,1 for AAC */
-       uint32_t dsp_cnt;
-       uint32_t in_head; /* next buffer dsp will write */
-       uint32_t in_tail; /* next buffer read() will read */
-       uint32_t in_count; /* number of buffers available to read() */
-
-       unsigned short samp_rate_index;
-
-       struct audmgr audmgr;
-
-       /* data allocated for various buffers */
-       char *data;
-       dma_addr_t phys;
-
-       int opened;
-       int enabled;
-       int running;
-       int stopped; /* set when stopped, cleared on flush */
-
-       /* audpre settings */
-       int agc_enable;
-       struct tx_agc_config agc;
-
-       int ns_enable;
-       struct ns_config ns;
-
-       int iir_enable;
-       struct tx_iir_filter iir;
-};
-
-static int audio_in_dsp_enable(struct audio_in *audio, int enable);
-static int audio_in_encoder_config(struct audio_in *audio);
-static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt);
-static void audio_flush(struct audio_in *audio);
-static int audio_dsp_set_agc(struct audio_in *audio);
-static int audio_dsp_set_ns(struct audio_in *audio);
-static int audio_dsp_set_tx_iir(struct audio_in *audio);
-
-static unsigned convert_dsp_samp_index(unsigned index)
-{
-       switch (index) {
-       case 48000:     return AUDREC_CMD_SAMP_RATE_INDX_48000;
-       case 44100:     return AUDREC_CMD_SAMP_RATE_INDX_44100;
-       case 32000:     return AUDREC_CMD_SAMP_RATE_INDX_32000;
-       case 24000:     return AUDREC_CMD_SAMP_RATE_INDX_24000;
-       case 22050:     return AUDREC_CMD_SAMP_RATE_INDX_22050;
-       case 16000:     return AUDREC_CMD_SAMP_RATE_INDX_16000;
-       case 12000:     return AUDREC_CMD_SAMP_RATE_INDX_12000;
-       case 11025:     return AUDREC_CMD_SAMP_RATE_INDX_11025;
-       case 8000:      return AUDREC_CMD_SAMP_RATE_INDX_8000;
-       default:        return AUDREC_CMD_SAMP_RATE_INDX_11025;
-       }
-}
-
-static unsigned convert_samp_rate(unsigned hz)
-{
-       switch (hz) {
-       case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000;
-       case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100;
-       case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000;
-       case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000;
-       case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050;
-       case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000;
-       case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000;
-       case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025;
-       case 8000:  return RPC_AUD_DEF_SAMPLE_RATE_8000;
-       default:    return RPC_AUD_DEF_SAMPLE_RATE_11025;
-       }
-}
-
-static unsigned convert_samp_index(unsigned index)
-{
-       switch (index) {
-       case RPC_AUD_DEF_SAMPLE_RATE_48000:     return 48000;
-       case RPC_AUD_DEF_SAMPLE_RATE_44100:     return 44100;
-       case RPC_AUD_DEF_SAMPLE_RATE_32000:     return 32000;
-       case RPC_AUD_DEF_SAMPLE_RATE_24000:     return 24000;
-       case RPC_AUD_DEF_SAMPLE_RATE_22050:     return 22050;
-       case RPC_AUD_DEF_SAMPLE_RATE_16000:     return 16000;
-       case RPC_AUD_DEF_SAMPLE_RATE_12000:     return 12000;
-       case RPC_AUD_DEF_SAMPLE_RATE_11025:     return 11025;
-       case RPC_AUD_DEF_SAMPLE_RATE_8000:      return 8000;
-       default:                                return 11025;
-       }
-}
-
-/* must be called with audio->lock held */
-static int audio_in_enable(struct audio_in *audio)
-{
-       struct audmgr_config cfg;
-       int rc;
-
-       if (audio->enabled)
-               return 0;
-
-       cfg.tx_rate = audio->samp_rate;
-       cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
-       cfg.def_method = RPC_AUD_DEF_METHOD_RECORD;
-       if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
-               cfg.codec = RPC_AUD_DEF_CODEC_PCM;
-       else
-               cfg.codec = RPC_AUD_DEF_CODEC_AAC;
-       cfg.snd_method = RPC_SND_METHOD_MIDI;
-
-       rc = audmgr_enable(&audio->audmgr, &cfg);
-       if (rc < 0)
-               return rc;
-
-       if (msm_adsp_enable(audio->audpre)) {
-               pr_err("audrec: msm_adsp_enable(audpre) failed\n");
-               return -ENODEV;
-       }
-       if (msm_adsp_enable(audio->audrec)) {
-               pr_err("audrec: msm_adsp_enable(audrec) failed\n");
-               return -ENODEV;
-       }
-
-       audio->enabled = 1;
-       audio_in_dsp_enable(audio, 1);
-
-       return 0;
-}
-
-/* must be called with audio->lock held */
-static int audio_in_disable(struct audio_in *audio)
-{
-       if (audio->enabled) {
-               audio->enabled = 0;
-
-               audio_in_dsp_enable(audio, 0);
-
-               wake_up(&audio->wait);
-
-               msm_adsp_disable(audio->audrec);
-               msm_adsp_disable(audio->audpre);
-               audmgr_disable(&audio->audmgr);
-       }
-       return 0;
-}
-
-/* ------------------- dsp --------------------- */
-static void audpre_dsp_event(void *data, unsigned id, size_t len,
-                           void (*getevent)(void *ptr, size_t len))
-{
-       uint16_t msg[2];
-       getevent(msg, sizeof(msg));
-
-       switch (id) {
-       case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
-               pr_info("audpre: type %d, status_flag %d\n", msg[0], msg[1]);
-               break;
-       case AUDPREPROC_MSG_ERROR_MSG_ID:
-               pr_info("audpre: err_index %d\n", msg[0]);
-               break;
-       default:
-               pr_err("audpre: unknown event %d\n", id);
-       }
-}
-
-struct audio_frame {
-       uint16_t count_low;
-       uint16_t count_high;
-       uint16_t bytes;
-       uint16_t unknown;
-       unsigned char samples[];
-} __attribute__((packed));
-
-static void audio_in_get_dsp_frames(struct audio_in *audio)
-{
-       struct audio_frame *frame;
-       uint32_t index;
-       unsigned long flags;
-
-       index = audio->in_head;
-
-       /* XXX check for bogus frame size? */
-
-       frame = (void *) (((char *)audio->in[index].data) - sizeof(*frame));
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       audio->in[index].size = frame->bytes;
-
-       audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1);
-
-       /* If overflow, move the tail index foward. */
-       if (audio->in_head == audio->in_tail)
-               audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
-       else
-               audio->in_count++;
-
-       audio_dsp_read_buffer(audio, audio->dsp_cnt++);
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-
-       wake_up(&audio->wait);
-}
-
-static void audrec_dsp_event(void *data, unsigned id, size_t len,
-                           void (*getevent)(void *ptr, size_t len))
-{
-       struct audio_in *audio = data;
-       uint16_t msg[3];
-       getevent(msg, sizeof(msg));
-
-       switch (id) {
-       case AUDREC_MSG_CMD_CFG_DONE_MSG:
-               if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE) {
-                       if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_ENA) {
-                               pr_info("audpre: CFG ENABLED\n");
-                               audio_dsp_set_agc(audio);
-                               audio_dsp_set_ns(audio);
-                               audio_dsp_set_tx_iir(audio);
-                               audio_in_encoder_config(audio);
-                       } else {
-                               pr_info("audrec: CFG SLEEP\n");
-                               audio->running = 0;
-                       }
-               } else {
-                       pr_info("audrec: CMD_CFG_DONE %x\n", msg[0]);
-               }
-               break;
-       case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: {
-               pr_info("audrec: PARAM CFG DONE\n");
-               audio->running = 1;
-               break;
-       }
-       case AUDREC_MSG_FATAL_ERR_MSG:
-               pr_err("audrec: ERROR %x\n", msg[0]);
-               break;
-       case AUDREC_MSG_PACKET_READY_MSG:
-/* REC_DBG("type %x, count %d", msg[0], (msg[1] | (msg[2] << 16))); */
-               audio_in_get_dsp_frames(audio);
-               break;
-       default:
-               pr_err("audrec: unknown event %d\n", id);
-       }
-}
-
-struct msm_adsp_ops audpre_adsp_ops = {
-       .event = audpre_dsp_event,
-};
-
-struct msm_adsp_ops audrec_adsp_ops = {
-       .event = audrec_dsp_event,
-};
-
-
-#define audio_send_queue_pre(audio, cmd, len) \
-       msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len)
-#define audio_send_queue_recbs(audio, cmd, len) \
-       msm_adsp_write(audio->audrec, QDSP_uPAudRecBitStreamQueue, cmd, len)
-#define audio_send_queue_rec(audio, cmd, len) \
-       msm_adsp_write(audio->audrec, \
-       QDSP_uPAudRecCmdQueue, cmd, len)
-
-static int audio_dsp_set_agc(struct audio_in *audio)
-{
-       audpreproc_cmd_cfg_agc_params cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS;
-
-       if (audio->agc_enable) {
-               /* cmd.tx_agc_param_mask = 0xFE00 from sample code */
-               cmd.tx_agc_param_mask =
-               (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE) |
-               (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH) |
-               (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE) |
-               (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH) |
-               (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG) |
-               (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN) |
-               (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG);
-               cmd.tx_agc_enable_flag =
-                       AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA;
-               memcpy(&cmd.static_gain, &audio->agc.agc_params[0],
-                       sizeof(uint16_t) * 6);
-               /* cmd.param_mask = 0xFFF0 from sample code */
-               cmd.param_mask =
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_RMS_TAY) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_RELEASEK) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_DELAY) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_ATTACKK) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MIN) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MAX) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_UP) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN) |
-                       (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK);
-               memcpy(&cmd.aig_attackk, &audio->agc.agc_params[6],
-                       sizeof(uint16_t) * 14);
-
-       } else {
-               cmd.tx_agc_param_mask =
-                       (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG);
-               cmd.tx_agc_enable_flag =
-                       AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS;
-       }
-#if DEBUG
-       pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
-       pr_info("tx_agc_param_mask = 0x%04x\n", cmd.tx_agc_param_mask);
-       pr_info("tx_agc_enable_flag = 0x%04x\n", cmd.tx_agc_enable_flag);
-       pr_info("static_gain = 0x%04x\n", cmd.static_gain);
-       pr_info("adaptive_gain_flag = 0x%04x\n", cmd.adaptive_gain_flag);
-       pr_info("expander_th = 0x%04x\n", cmd.expander_th);
-       pr_info("expander_slope = 0x%04x\n", cmd.expander_slope);
-       pr_info("compressor_th = 0x%04x\n", cmd.compressor_th);
-       pr_info("compressor_slope = 0x%04x\n", cmd.compressor_slope);
-       pr_info("param_mask = 0x%04x\n", cmd.param_mask);
-       pr_info("aig_attackk = 0x%04x\n", cmd.aig_attackk);
-       pr_info("aig_leak_down = 0x%04x\n", cmd.aig_leak_down);
-       pr_info("aig_leak_up = 0x%04x\n", cmd.aig_leak_up);
-       pr_info("aig_max = 0x%04x\n", cmd.aig_max);
-       pr_info("aig_min = 0x%04x\n", cmd.aig_min);
-       pr_info("aig_releasek = 0x%04x\n", cmd.aig_releasek);
-       pr_info("aig_leakrate_fast = 0x%04x\n", cmd.aig_leakrate_fast);
-       pr_info("aig_leakrate_slow = 0x%04x\n", cmd.aig_leakrate_slow);
-       pr_info("attackk_msw = 0x%04x\n", cmd.attackk_msw);
-       pr_info("attackk_lsw = 0x%04x\n", cmd.attackk_lsw);
-       pr_info("delay = 0x%04x\n", cmd.delay);
-       pr_info("releasek_msw = 0x%04x\n", cmd.releasek_msw);
-       pr_info("releasek_lsw = 0x%04x\n", cmd.releasek_lsw);
-       pr_info("rms_tav = 0x%04x\n", cmd.rms_tav);
-#endif
-       return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
-}
-
-static int audio_dsp_set_ns(struct audio_in *audio)
-{
-       audpreproc_cmd_cfg_ns_params cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS;
-
-       if (audio->ns_enable) {
-               /* cmd.ec_mode_new is fixed as 0x0064 when enable from sample code */
-               cmd.ec_mode_new =
-                       AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA |
-                       AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA |
-                       AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA;
-               memcpy(&cmd.dens_gamma_n, &audio->ns.ns_params,
-                       sizeof(audio->ns.ns_params));
-       } else {
-               cmd.ec_mode_new =
-                       AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS |
-                       AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS;
-       }
-#if DEBUG
-       pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
-       pr_info("ec_mode_new = 0x%04x\n", cmd.ec_mode_new);
-       pr_info("dens_gamma_n = 0x%04x\n", cmd.dens_gamma_n);
-       pr_info("dens_nfe_block_size = 0x%04x\n", cmd.dens_nfe_block_size);
-       pr_info("dens_limit_ns = 0x%04x\n", cmd.dens_limit_ns);
-       pr_info("dens_limit_ns_d = 0x%04x\n", cmd.dens_limit_ns_d);
-       pr_info("wb_gamma_e = 0x%04x\n", cmd.wb_gamma_e);
-       pr_info("wb_gamma_n = 0x%04x\n", cmd.wb_gamma_n);
-#endif
-       return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
-}
-
-static int audio_dsp_set_tx_iir(struct audio_in *audio)
-{
-       struct audpre_cmd_iir_config_type cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
-
-       if (audio->iir_enable) {
-               cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA;
-               cmd.num_bands = audio->iir.num_bands;
-               memcpy(&cmd.iir_params, &audio->iir.iir_params,
-                       sizeof(audio->iir.iir_params));
-       } else {
-               cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS;
-       }
-#if DEBUG
-       pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
-       pr_info("active_flag = 0x%04x\n", cmd.active_flag);
-#endif
-       return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
-}
-
-static int audio_in_dsp_enable(struct audio_in *audio, int enable)
-{
-       audrec_cmd_cfg cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDREC_CMD_CFG;
-       cmd.type_0 = enable ? AUDREC_CMD_TYPE_0_ENA : AUDREC_CMD_TYPE_0_DIS;
-       cmd.type_0 |= (AUDREC_CMD_TYPE_0_UPDATE | audio->type);
-       cmd.type_1 = 0;
-
-       return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
-}
-
-static int audio_in_encoder_config(struct audio_in *audio)
-{
-       audrec_cmd_arec0param_cfg cmd;
-       uint16_t *data = (void *) audio->data;
-       unsigned n;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDREC_CMD_AREC0PARAM_CFG;
-       cmd.ptr_to_extpkt_buffer_msw = audio->phys >> 16;
-       cmd.ptr_to_extpkt_buffer_lsw = audio->phys;
-       cmd.buf_len = FRAME_NUM; /* Both WAV and AAC use 8 frames */
-       cmd.samp_rate_index = audio->samp_rate_index;
-       cmd.stereo_mode = audio->channel_mode; /* 0 for mono, 1 for stereo */
-
-       /* FIXME have no idea why cmd.rec_quality is fixed
-        * as 0x1C00 from sample code
-        */
-       cmd.rec_quality = 0x1C00;
-
-       /* prepare buffer pointers:
-        * Mono: 1024 samples + 4 halfword header
-        * Stereo: 2048 samples + 4 halfword header
-        * AAC
-        * Mono/Stere: 768 + 4 halfword header
-        */
-       for (n = 0; n < FRAME_NUM; n++) {
-               audio->in[n].data = data + 4;
-               if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
-                       data += (4 + (audio->channel_mode ? 2048 : 1024));
-               else if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
-                       data += (4 + 768);
-       }
-
-       return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
-}
-
-static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt)
-{
-       audrec_cmd_packet_ext_ptr cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR;
-       /* Both WAV and AAC use AUDREC_CMD_TYPE_0 */
-       cmd.type = AUDREC_CMD_TYPE_0;
-       cmd.curr_rec_count_msw = read_cnt >> 16;
-       cmd.curr_rec_count_lsw = read_cnt;
-
-       return audio_send_queue_recbs(audio, &cmd, sizeof(cmd));
-}
-
-/* ------------------- device --------------------- */
-
-static void audio_enable_agc(struct audio_in *audio, int enable)
-{
-       if (audio->agc_enable != enable) {
-               audio->agc_enable = enable;
-               if (audio->running)
-                       audio_dsp_set_agc(audio);
-       }
-}
-
-static void audio_enable_ns(struct audio_in *audio, int enable)
-{
-       if (audio->ns_enable != enable) {
-               audio->ns_enable = enable;
-               if (audio->running)
-                       audio_dsp_set_ns(audio);
-       }
-}
-
-static void audio_enable_tx_iir(struct audio_in *audio, int enable)
-{
-       if (audio->iir_enable != enable) {
-               audio->iir_enable = enable;
-               if (audio->running)
-                       audio_dsp_set_tx_iir(audio);
-       }
-}
-
-static void audio_flush(struct audio_in *audio)
-{
-       int i;
-
-       audio->dsp_cnt = 0;
-       audio->in_head = 0;
-       audio->in_tail = 0;
-       audio->in_count = 0;
-       for (i = 0; i < FRAME_NUM; i++) {
-               audio->in[i].size = 0;
-               audio->in[i].read = 0;
-       }
-}
-
-static long audio_in_ioctl(struct file *file,
-                               unsigned int cmd, unsigned long arg)
-{
-       struct audio_in *audio = file->private_data;
-       int rc;
-
-       if (cmd == AUDIO_GET_STATS) {
-               struct msm_audio_stats stats;
-               stats.byte_count = atomic_read(&audio->in_bytes);
-               if (copy_to_user((void *) arg, &stats, sizeof(stats)))
-                       return -EFAULT;
-               return 0;
-       }
-
-       mutex_lock(&audio->lock);
-       switch (cmd) {
-       case AUDIO_START:
-               rc = audio_in_enable(audio);
-               break;
-       case AUDIO_STOP:
-               rc = audio_in_disable(audio);
-               audio->stopped = 1;
-               break;
-       case AUDIO_FLUSH:
-               if (audio->stopped) {
-                       /* Make sure we're stopped and we wake any threads
-                        * that might be blocked holding the read_lock.
-                        * While audio->stopped read threads will always
-                        * exit immediately.
-                        */
-                       wake_up(&audio->wait);
-                       mutex_lock(&audio->read_lock);
-                       audio_flush(audio);
-                       mutex_unlock(&audio->read_lock);
-               }
-       case AUDIO_SET_CONFIG: {
-               struct msm_audio_config cfg;
-               if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
-                       rc = -EFAULT;
-                       break;
-               }
-               if (cfg.channel_count == 1) {
-                       cfg.channel_count = AUDREC_CMD_STEREO_MODE_MONO;
-               } else if (cfg.channel_count == 2) {
-                       cfg.channel_count = AUDREC_CMD_STEREO_MODE_STEREO;
-               } else {
-                       rc = -EINVAL;
-                       break;
-               }
-
-               if (cfg.type == 0) {
-                       cfg.type = AUDREC_CMD_TYPE_0_INDEX_WAV;
-               } else if (cfg.type == 1) {
-                       cfg.type = AUDREC_CMD_TYPE_0_INDEX_AAC;
-               } else {
-                       rc = -EINVAL;
-                       break;
-               }
-               audio->samp_rate = convert_samp_rate(cfg.sample_rate);
-               audio->samp_rate_index =
-                 convert_dsp_samp_index(cfg.sample_rate);
-               audio->channel_mode = cfg.channel_count;
-               audio->buffer_size =
-                               audio->channel_mode ? STEREO_DATA_SIZE
-                                                       : MONO_DATA_SIZE;
-               audio->type = cfg.type;
-               rc = 0;
-               break;
-       }
-       case AUDIO_GET_CONFIG: {
-               struct msm_audio_config cfg;
-               cfg.buffer_size = audio->buffer_size;
-               cfg.buffer_count = FRAME_NUM;
-               cfg.sample_rate = convert_samp_index(audio->samp_rate);
-               if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO)
-                       cfg.channel_count = 1;
-               else
-                       cfg.channel_count = 2;
-               if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
-                       cfg.type = 0;
-               else
-                       cfg.type = 1;
-               cfg.unused[0] = 0;
-               cfg.unused[1] = 0;
-               cfg.unused[2] = 0;
-               if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
-                       rc = -EFAULT;
-               else
-                       rc = 0;
-               break;
-       }
-       default:
-               rc = -EINVAL;
-       }
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static ssize_t audio_in_read(struct file *file,
-                               char __user *buf,
-                               size_t count, loff_t *pos)
-{
-       struct audio_in *audio = file->private_data;
-       unsigned long flags;
-       const char __user *start = buf;
-       void *data;
-       uint32_t index;
-       uint32_t size;
-       int rc = 0;
-
-       mutex_lock(&audio->read_lock);
-       while (count > 0) {
-               rc = wait_event_interruptible(
-                       audio->wait, (audio->in_count > 0) || audio->stopped);
-               if (rc < 0)
-                       break;
-
-               if (audio->stopped) {
-                       rc = -EBUSY;
-                       break;
-               }
-
-               index = audio->in_tail;
-               data = (uint8_t *) audio->in[index].data;
-               size = audio->in[index].size;
-               if (count >= size) {
-                       if (copy_to_user(buf, data, size)) {
-                               rc = -EFAULT;
-                               break;
-                       }
-                       spin_lock_irqsave(&audio->dsp_lock, flags);
-                       if (index != audio->in_tail) {
-                       /* overrun -- data is invalid and we need to retry */
-                               spin_unlock_irqrestore(&audio->dsp_lock, flags);
-                               continue;
-                       }
-                       audio->in[index].size = 0;
-                       audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
-                       audio->in_count--;
-                       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-                       count -= size;
-                       buf += size;
-                       if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
-                               break;
-               } else {
-                       pr_err("audio_in: short read\n");
-                       break;
-               }
-               if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
-                       break; /* AAC only read one frame */
-       }
-       mutex_unlock(&audio->read_lock);
-
-       if (buf > start)
-               return buf - start;
-
-       return rc;
-}
-
-static ssize_t audio_in_write(struct file *file,
-                               const char __user *buf,
-                               size_t count, loff_t *pos)
-{
-       return -EINVAL;
-}
-
-static int audio_in_release(struct inode *inode, struct file *file)
-{
-       struct audio_in *audio = file->private_data;
-
-       mutex_lock(&audio->lock);
-       audio_in_disable(audio);
-       audio_flush(audio);
-       msm_adsp_put(audio->audrec);
-       msm_adsp_put(audio->audpre);
-       audio->audrec = NULL;
-       audio->audpre = NULL;
-       audio->opened = 0;
-       mutex_unlock(&audio->lock);
-       return 0;
-}
-
-static struct audio_in the_audio_in;
-
-static int audio_in_open(struct inode *inode, struct file *file)
-{
-       struct audio_in *audio = &the_audio_in;
-       int rc;
-
-       mutex_lock(&audio->lock);
-       if (audio->opened) {
-               rc = -EBUSY;
-               goto done;
-       }
-
-       /* Settings will be re-config at AUDIO_SET_CONFIG,
-        * but at least we need to have initial config
-        */
-       audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025;
-       audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025;
-       audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
-       audio->buffer_size = MONO_DATA_SIZE;
-       audio->type = AUDREC_CMD_TYPE_0_INDEX_WAV;
-
-       rc = audmgr_open(&audio->audmgr);
-       if (rc)
-               goto done;
-       rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
-                               &audpre_adsp_ops, audio);
-       if (rc)
-               goto done;
-       rc = msm_adsp_get("AUDRECTASK", &audio->audrec,
-                          &audrec_adsp_ops, audio);
-       if (rc)
-               goto done;
-
-       audio->dsp_cnt = 0;
-       audio->stopped = 0;
-
-       audio_flush(audio);
-
-       file->private_data = audio;
-       audio->opened = 1;
-       rc = 0;
-done:
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static long audpre_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct audio_in *audio = file->private_data;
-       int rc = 0, enable;
-       uint16_t enable_mask;
-#if DEBUG
-       int i;
-#endif
-
-       mutex_lock(&audio->lock);
-       switch (cmd) {
-       case AUDIO_ENABLE_AUDPRE: {
-               if (copy_from_user(&enable_mask, (void *) arg,
-                               sizeof(enable_mask)))
-                       goto out_fault;
-
-               enable = (enable_mask & AGC_ENABLE) ? 1 : 0;
-               audio_enable_agc(audio, enable);
-               enable = (enable_mask & NS_ENABLE) ? 1 : 0;
-               audio_enable_ns(audio, enable);
-               enable = (enable_mask & IIR_ENABLE) ? 1 : 0;
-               audio_enable_tx_iir(audio, enable);
-               break;
-       }
-       case AUDIO_SET_AGC: {
-               if (copy_from_user(&audio->agc, (void *) arg,
-                               sizeof(audio->agc)))
-                       goto out_fault;
-#if DEBUG
-               pr_info("set agc\n");
-               for (i = 0; i < AGC_PARAM_SIZE; i++) \
-                       pr_info("agc_params[%d] = 0x%04x\n", i,
-                               audio->agc.agc_params[i]);
-#endif
-               break;
-       }
-       case AUDIO_SET_NS: {
-               if (copy_from_user(&audio->ns, (void *) arg,
-                               sizeof(audio->ns)))
-                       goto out_fault;
-#if DEBUG
-               pr_info("set ns\n");
-               for (i = 0; i < NS_PARAM_SIZE; i++) \
-                       pr_info("ns_params[%d] = 0x%04x\n",
-                               i, audio->ns.ns_params[i]);
-#endif
-               break;
-       }
-       case AUDIO_SET_TX_IIR: {
-               if (copy_from_user(&audio->iir, (void *) arg,
-                               sizeof(audio->iir)))
-                       goto out_fault;
-#if DEBUG
-               pr_info("set iir\n");
-               pr_info("iir.num_bands = 0x%04x\n", audio->iir.num_bands);
-               for (i = 0; i < IIR_PARAM_SIZE; i++) \
-                       pr_info("iir_params[%d] = 0x%04x\n",
-                               i, audio->iir.iir_params[i]);
-#endif
-               break;
-       }
-       default:
-               rc = -EINVAL;
-       }
-
-       goto out;
-
-out_fault:
-       rc = -EFAULT;
-out:
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static int audpre_open(struct inode *inode, struct file *file)
-{
-       struct audio_in *audio = &the_audio_in;
-       file->private_data = audio;
-       return 0;
-}
-
-static struct file_operations audio_fops = {
-       .owner          = THIS_MODULE,
-       .open           = audio_in_open,
-       .release        = audio_in_release,
-       .read           = audio_in_read,
-       .write          = audio_in_write,
-       .unlocked_ioctl = audio_in_ioctl,
-       .llseek         = noop_llseek,
-};
-
-static struct file_operations audpre_fops = {
-       .owner          = THIS_MODULE,
-       .open           = audpre_open,
-       .unlocked_ioctl = audpre_ioctl,
-       .llseek         = noop_llseek,
-};
-
-struct miscdevice audio_in_misc = {
-       .minor  = MISC_DYNAMIC_MINOR,
-       .name   = "msm_pcm_in",
-       .fops   = &audio_fops,
-};
-
-struct miscdevice audpre_misc = {
-       .minor  = MISC_DYNAMIC_MINOR,
-       .name   = "msm_audpre",
-       .fops   = &audpre_fops,
-};
-
-static int __init audio_in_init(void)
-{
-       int rc;
-       the_audio_in.data = dma_alloc_coherent(NULL, DMASZ,
-                                              &the_audio_in.phys, GFP_KERNEL);
-       if (!the_audio_in.data) {
-               printk(KERN_ERR "%s: Unable to allocate DMA buffer\n",
-                      __func__);
-               return -ENOMEM;
-       }
-
-       mutex_init(&the_audio_in.lock);
-       mutex_init(&the_audio_in.read_lock);
-       spin_lock_init(&the_audio_in.dsp_lock);
-       init_waitqueue_head(&the_audio_in.wait);
-       rc = misc_register(&audio_in_misc);
-       if (!rc) {
-               rc = misc_register(&audpre_misc);
-               if (rc < 0)
-                       misc_deregister(&audio_in_misc);
-       }
-       return rc;
-}
-
-device_initcall(audio_in_init);
diff --git a/drivers/staging/dream/qdsp5/audio_mp3.c b/drivers/staging/dream/qdsp5/audio_mp3.c
deleted file mode 100644 (file)
index 409a19c..0000000
+++ /dev/null
@@ -1,972 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/audio_mp3.c
- *
- * mp3 audio output device
- *
- * Copyright (C) 2008 Google, Inc.
- * Copyright (C) 2008 HTC Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/kthread.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <linux/delay.h>
-
-#include <asm/atomic.h>
-#include <asm/ioctls.h>
-#include <mach/msm_adsp.h>
-
-#include <linux/msm_audio.h>
-
-#include "audmgr.h"
-
-#include <mach/qdsp5/qdsp5audppcmdi.h>
-#include <mach/qdsp5/qdsp5audppmsg.h>
-#include <mach/qdsp5/qdsp5audplaycmdi.h>
-#include <mach/qdsp5/qdsp5audplaymsg.h>
-
-/* for queue ids - should be relative to module number*/
-#include "adsp.h"
-
-#ifdef DEBUG
-#define dprintk(format, arg...) \
-printk(KERN_DEBUG format, ## arg)
-#else
-#define dprintk(format, arg...) do {} while (0)
-#endif
-
-/* Size must be power of 2 */
-#define BUFSZ_MAX 32768
-#define BUFSZ_MIN 4096
-#define DMASZ_MAX (BUFSZ_MAX * 2)
-#define DMASZ_MIN (BUFSZ_MIN * 2)
-
-#define AUDPLAY_INVALID_READ_PTR_OFFSET        0xFFFF
-#define AUDDEC_DEC_MP3 2
-
-#define PCM_BUFSZ_MIN 4800     /* Hold one stereo MP3 frame */
-#define PCM_BUF_MAX_COUNT 5    /* DSP only accepts 5 buffers at most
-                                  but support 2 buffers currently */
-#define ROUTING_MODE_FTRT 1
-#define ROUTING_MODE_RT 2
-/* Decoder status received from AUDPPTASK */
-#define  AUDPP_DEC_STATUS_SLEEP        0
-#define         AUDPP_DEC_STATUS_INIT  1
-#define  AUDPP_DEC_STATUS_CFG   2
-#define  AUDPP_DEC_STATUS_PLAY  3
-
-struct buffer {
-       void *data;
-       unsigned size;
-       unsigned used;          /* Input usage actual DSP produced PCM size  */
-       unsigned addr;
-};
-
-struct audio {
-       struct buffer out[2];
-
-       spinlock_t dsp_lock;
-
-       uint8_t out_head;
-       uint8_t out_tail;
-       uint8_t out_needed; /* number of buffers the dsp is waiting for */
-       unsigned out_dma_sz;
-
-       atomic_t out_bytes;
-
-       struct mutex lock;
-       struct mutex write_lock;
-       wait_queue_head_t write_wait;
-
-       /* Host PCM section */
-       struct buffer in[PCM_BUF_MAX_COUNT];
-       struct mutex read_lock;
-       wait_queue_head_t read_wait;    /* Wait queue for read */
-       char *read_data;        /* pointer to reader buffer */
-       dma_addr_t read_phys;   /* physical address of reader buffer */
-       uint8_t read_next;      /* index to input buffers to be read next */
-       uint8_t fill_next;      /* index to buffer that DSP should be filling */
-       uint8_t pcm_buf_count;  /* number of pcm buffer allocated */
-       /* ---- End of Host PCM section */
-
-       struct msm_adsp_module *audplay;
-
-       /* configuration to use on next enable */
-       uint32_t out_sample_rate;
-       uint32_t out_channel_mode;
-
-       struct audmgr audmgr;
-
-       /* data allocated for various buffers */
-       char *data;
-       dma_addr_t phys;
-
-       int rflush; /* Read  flush */
-       int wflush; /* Write flush */
-       int opened;
-       int enabled;
-       int running;
-       int stopped; /* set when stopped, cleared on flush */
-       int pcm_feedback;
-       int buf_refresh;
-
-       int reserved; /* A byte is being reserved */
-       char rsv_byte; /* Handle odd length user data */
-
-       unsigned volume;
-
-       uint16_t dec_id;
-       uint32_t read_ptr_offset;
-};
-
-static int auddec_dsp_config(struct audio *audio, int enable);
-static void audpp_cmd_cfg_adec_params(struct audio *audio);
-static void audpp_cmd_cfg_routing_mode(struct audio *audio);
-static void audplay_send_data(struct audio *audio, unsigned needed);
-static void audplay_config_hostpcm(struct audio *audio);
-static void audplay_buffer_refresh(struct audio *audio);
-static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
-
-/* must be called with audio->lock held */
-static int audio_enable(struct audio *audio)
-{
-       struct audmgr_config cfg;
-       int rc;
-
-       pr_info("audio_enable()\n");
-
-       if (audio->enabled)
-               return 0;
-
-       audio->out_tail = 0;
-       audio->out_needed = 0;
-
-       cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
-       cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
-       cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
-       cfg.codec = RPC_AUD_DEF_CODEC_MP3;
-       cfg.snd_method = RPC_SND_METHOD_MIDI;
-
-       rc = audmgr_enable(&audio->audmgr, &cfg);
-       if (rc < 0)
-               return rc;
-
-       if (msm_adsp_enable(audio->audplay)) {
-               pr_err("audio: msm_adsp_enable(audplay) failed\n");
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-
-       if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
-               pr_err("audio: audpp_enable() failed\n");
-               msm_adsp_disable(audio->audplay);
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-
-       audio->enabled = 1;
-       return 0;
-}
-
-/* must be called with audio->lock held */
-static int audio_disable(struct audio *audio)
-{
-       pr_info("audio_disable()\n");
-       if (audio->enabled) {
-               audio->enabled = 0;
-               auddec_dsp_config(audio, 0);
-               wake_up(&audio->write_wait);
-               wake_up(&audio->read_wait);
-               msm_adsp_disable(audio->audplay);
-               audpp_disable(audio->dec_id, audio);
-               audmgr_disable(&audio->audmgr);
-               audio->out_needed = 0;
-       }
-       return 0;
-}
-
-/* ------------------- dsp --------------------- */
-static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload)
-{
-       uint8_t index;
-       unsigned long flags;
-
-       if (audio->rflush) {
-               audio->buf_refresh = 1;
-               return;
-       }
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       for (index = 0; index < payload[1]; index++) {
-               if (audio->in[audio->fill_next].addr ==
-                   payload[2 + index * 2]) {
-                       pr_info("audio_update_pcm_buf_entry: in[%d] ready\n",
-                               audio->fill_next);
-                       audio->in[audio->fill_next].used =
-                         payload[3 + index * 2];
-                       if ((++audio->fill_next) == audio->pcm_buf_count)
-                               audio->fill_next = 0;
-
-               } else {
-                       pr_err
-                           ("audio_update_pcm_buf_entry: expected=%x ret=%x\n"
-                            , audio->in[audio->fill_next].addr,
-                            payload[1 + index * 2]);
-                       break;
-               }
-       }
-       if (audio->in[audio->fill_next].used == 0) {
-               audplay_buffer_refresh(audio);
-       } else {
-               pr_info("audio_update_pcm_buf_entry: read cannot keep up\n");
-               audio->buf_refresh = 1;
-       }
-       wake_up(&audio->read_wait);
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-
-}
-
-static void audplay_dsp_event(void *data, unsigned id, size_t len,
-                             void (*getevent) (void *ptr, size_t len))
-{
-       struct audio *audio = data;
-       uint32_t msg[28];
-       getevent(msg, sizeof(msg));
-
-       dprintk("audplay_dsp_event: msg_id=%x\n", id);
-
-       switch (id) {
-       case AUDPLAY_MSG_DEC_NEEDS_DATA:
-               audplay_send_data(audio, 1);
-               break;
-
-       case AUDPLAY_MSG_BUFFER_UPDATE:
-               audio_update_pcm_buf_entry(audio, msg);
-               break;
-
-       default:
-               pr_err("unexpected message from decoder \n");
-               break;
-       }
-}
-
-static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
-{
-       struct audio *audio = private;
-
-       switch (id) {
-       case AUDPP_MSG_STATUS_MSG:{
-                       unsigned status = msg[1];
-
-                       switch (status) {
-                       case AUDPP_DEC_STATUS_SLEEP:
-                               pr_info("decoder status: sleep \n");
-                               break;
-
-                       case AUDPP_DEC_STATUS_INIT:
-                               pr_info("decoder status: init \n");
-                               audpp_cmd_cfg_routing_mode(audio);
-                               break;
-
-                       case AUDPP_DEC_STATUS_CFG:
-                               pr_info("decoder status: cfg \n");
-                               break;
-                       case AUDPP_DEC_STATUS_PLAY:
-                               pr_info("decoder status: play \n");
-                               if (audio->pcm_feedback) {
-                                       audplay_config_hostpcm(audio);
-                                       audplay_buffer_refresh(audio);
-                               }
-                               break;
-                       default:
-                               pr_err("unknown decoder status \n");
-                               break;
-                       }
-      break;
-               }
-       case AUDPP_MSG_CFG_MSG:
-               if (msg[0] == AUDPP_MSG_ENA_ENA) {
-                       pr_info("audio_dsp_event: CFG_MSG ENABLE\n");
-                       auddec_dsp_config(audio, 1);
-                       audio->out_needed = 0;
-                       audio->running = 1;
-                       audpp_set_volume_and_pan(audio->dec_id, audio->volume,
-                                                0);
-                       audpp_avsync(audio->dec_id, 22050);
-               } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
-                       pr_info("audio_dsp_event: CFG_MSG DISABLE\n");
-                       audpp_avsync(audio->dec_id, 0);
-                       audio->running = 0;
-               } else {
-                       pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
-               }
-               break;
-       case AUDPP_MSG_ROUTING_ACK:
-               pr_info("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
-               audpp_cmd_cfg_adec_params(audio);
-               break;
-
-       case AUDPP_MSG_FLUSH_ACK:
-               dprintk("%s: FLUSH_ACK\n", __func__);
-               audio->wflush = 0;
-               audio->rflush = 0;
-               if (audio->pcm_feedback)
-                       audplay_buffer_refresh(audio);
-               break;
-
-       default:
-               pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
-       }
-
-}
-
-
-struct msm_adsp_ops audplay_adsp_ops = {
-       .event = audplay_dsp_event,
-};
-
-
-#define audplay_send_queue0(audio, cmd, len) \
-       msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
-                      cmd, len)
-
-static int auddec_dsp_config(struct audio *audio, int enable)
-{
-       audpp_cmd_cfg_dec_type cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
-       if (enable)
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
-                              AUDPP_CMD_ENA_DEC_V |
-                              AUDDEC_DEC_MP3;
-       else
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
-                              AUDPP_CMD_DIS_DEC_V;
-
-       return audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_adec_params(struct audio *audio)
-{
-       audpp_cmd_cfg_adec_params_mp3 cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
-       cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN;
-       cmd.common.dec_id = audio->dec_id;
-       cmd.common.input_sampling_frequency = audio->out_sample_rate;
-
-       audpp_send_queue2(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_routing_mode(struct audio *audio)
-{
-       struct audpp_cmd_routing_mode cmd;
-       pr_info("audpp_cmd_cfg_routing_mode()\n");
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
-       cmd.object_number = audio->dec_id;
-       if (audio->pcm_feedback)
-               cmd.routing_mode = ROUTING_MODE_FTRT;
-       else
-               cmd.routing_mode = ROUTING_MODE_RT;
-
-       audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static int audplay_dsp_send_data_avail(struct audio *audio,
-                                       unsigned idx, unsigned len)
-{
-       audplay_cmd_bitstream_data_avail cmd;
-
-       cmd.cmd_id              = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
-       cmd.decoder_id          = audio->dec_id;
-       cmd.buf_ptr             = audio->out[idx].addr;
-       cmd.buf_size            = len/2;
-       cmd.partition_number    = 0;
-       return audplay_send_queue0(audio, &cmd, sizeof(cmd));
-}
-
-static void audplay_buffer_refresh(struct audio *audio)
-{
-       struct audplay_cmd_buffer_refresh refresh_cmd;
-
-       refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
-       refresh_cmd.num_buffers = 1;
-       refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
-       refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
-         (audio->in[audio->fill_next].size % 576);     /* Mp3 frame size */
-       refresh_cmd.buf_read_count = 0;
-       pr_info("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
-               refresh_cmd.buf0_address, refresh_cmd.buf0_length);
-       (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
-}
-
-static void audplay_config_hostpcm(struct audio *audio)
-{
-       struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
-
-       pr_info("audplay_config_hostpcm()\n");
-       cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
-       cfg_cmd.max_buffers = 1;
-       cfg_cmd.byte_swap = 0;
-       cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
-       cfg_cmd.feedback_frequency = 1;
-       cfg_cmd.partition_number = 0;
-       (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
-
-}
-
-static void audplay_send_data(struct audio *audio, unsigned needed)
-{
-       struct buffer *frame;
-       unsigned long flags;
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       if (!audio->running)
-               goto done;
-
-       if (audio->wflush) {
-               audio->out_needed = 1;
-               goto done;
-       }
-
-       if (needed && !audio->wflush) {
-               /* We were called from the callback because the DSP
-                * requested more data.  Note that the DSP does want
-                * more data, and if a buffer was in-flight, mark it
-                * as available (since the DSP must now be done with
-                * it).
-                */
-               audio->out_needed = 1;
-               frame = audio->out + audio->out_tail;
-               if (frame->used == 0xffffffff) {
-                 dprintk("frame %d free\n", audio->out_tail);
-                 frame->used = 0;
-                 audio->out_tail ^= 1;
-                 wake_up(&audio->write_wait);
-               }
-       }
-
-       if (audio->out_needed) {
-               /* If the DSP currently wants data and we have a
-                * buffer available, we will send it and reset
-                * the needed flag.  We'll mark the buffer as in-flight
-                * so that it won't be recycled until the next buffer
-                * is requested
-                */
-
-               frame = audio->out + audio->out_tail;
-               if (frame->used) {
-                 BUG_ON(frame->used == 0xffffffff);
-                 dprintk("frame %d busy\n", audio->out_tail);
-                 audplay_dsp_send_data_avail(audio, audio->out_tail,
-                                             frame->used);
-                 frame->used = 0xffffffff;
-                 audio->out_needed = 0;
-               }
-       }
-done:
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-}
-
-/* ------------------- device --------------------- */
-
-static void audio_flush(struct audio *audio)
-{
-       audio->out[0].used = 0;
-       audio->out[1].used = 0;
-       audio->out_head = 0;
-       audio->out_tail = 0;
-       audio->reserved = 0;
-       atomic_set(&audio->out_bytes, 0);
-}
-
-static void audio_flush_pcm_buf(struct audio *audio)
-{
-       uint8_t index;
-
-       for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
-               audio->in[index].used = 0;
-
-       audio->read_next = 0;
-       audio->fill_next = 0;
-}
-
-static void audio_ioport_reset(struct audio *audio)
-{
-       /* Make sure read/write thread are free from
-        * sleep and knowing that system is not able
-        * to process io request at the moment
-        */
-       wake_up(&audio->write_wait);
-       mutex_lock(&audio->write_lock);
-       audio_flush(audio);
-       mutex_unlock(&audio->write_lock);
-       wake_up(&audio->read_wait);
-       mutex_lock(&audio->read_lock);
-       audio_flush_pcm_buf(audio);
-       mutex_unlock(&audio->read_lock);
-}
-
-static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct audio *audio = file->private_data;
-       int rc = 0;
-
-       pr_info("audio_ioctl() cmd = %d\n", cmd);
-
-       if (cmd == AUDIO_GET_STATS) {
-               struct msm_audio_stats stats;
-               stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
-               stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
-               if (copy_to_user((void *) arg, &stats, sizeof(stats)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == AUDIO_SET_VOLUME) {
-               unsigned long flags;
-               spin_lock_irqsave(&audio->dsp_lock, flags);
-               audio->volume = arg;
-               if (audio->running)
-                       audpp_set_volume_and_pan(audio->dec_id, arg, 0);
-               spin_unlock_irqrestore(&audio->dsp_lock, flags);
-               return 0;
-       }
-       mutex_lock(&audio->lock);
-       switch (cmd) {
-       case AUDIO_START:
-               rc = audio_enable(audio);
-               break;
-       case AUDIO_STOP:
-               rc = audio_disable(audio);
-               audio->stopped = 1;
-               audio_ioport_reset(audio);
-               audio->stopped = 0;
-               break;
-       case AUDIO_FLUSH:
-               dprintk("%s: AUDIO_FLUSH\n", __func__);
-               audio->rflush = 1;
-               audio->wflush = 1;
-               audio_ioport_reset(audio);
-               audio->rflush = 0;
-               audio->wflush = 0;
-
-               if (audio->buf_refresh) {
-                       audio->buf_refresh = 0;
-                       audplay_buffer_refresh(audio);
-               }
-               break;
-
-       case AUDIO_SET_CONFIG: {
-               struct msm_audio_config config;
-               if (copy_from_user(&config, (void *) arg, sizeof(config))) {
-                       rc = -EFAULT;
-                       break;
-               }
-               if (config.channel_count == 1) {
-                       config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
-               } else if (config.channel_count == 2) {
-                       config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V;
-               } else {
-                       rc = -EINVAL;
-                       break;
-               }
-               audio->out_sample_rate = config.sample_rate;
-               audio->out_channel_mode = config.channel_count;
-               rc = 0;
-               break;
-       }
-       case AUDIO_GET_CONFIG: {
-               struct msm_audio_config config;
-               config.buffer_size = (audio->out_dma_sz >> 1);
-               config.buffer_count = 2;
-               config.sample_rate = audio->out_sample_rate;
-               if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) {
-                       config.channel_count = 1;
-               } else {
-                       config.channel_count = 2;
-               }
-               config.unused[0] = 0;
-               config.unused[1] = 0;
-               config.unused[2] = 0;
-               config.unused[3] = 0;
-               if (copy_to_user((void *) arg, &config, sizeof(config))) {
-                       rc = -EFAULT;
-               } else {
-                       rc = 0;
-               }
-               break;
-       }
-       case AUDIO_GET_PCM_CONFIG:{
-               struct msm_audio_pcm_config config;
-               config.pcm_feedback = 0;
-               config.buffer_count = PCM_BUF_MAX_COUNT;
-               config.buffer_size = PCM_BUFSZ_MIN;
-               if (copy_to_user((void *)arg, &config,
-                        sizeof(config)))
-                       rc = -EFAULT;
-               else
-                       rc = 0;
-               break;
-       }
-       case AUDIO_SET_PCM_CONFIG:{
-                       struct msm_audio_pcm_config config;
-                       if (copy_from_user
-                           (&config, (void *)arg, sizeof(config))) {
-                               rc = -EFAULT;
-                               break;
-                       }
-                       if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
-                           (config.buffer_count == 1))
-                               config.buffer_count = PCM_BUF_MAX_COUNT;
-
-                       if (config.buffer_size < PCM_BUFSZ_MIN)
-                               config.buffer_size = PCM_BUFSZ_MIN;
-
-                       /* Check if pcm feedback is required */
-                       if ((config.pcm_feedback) && (!audio->read_data)) {
-                               pr_info("ioctl: allocate PCM buffer %d\n",
-                                       config.buffer_count *
-                                       config.buffer_size);
-                               audio->read_data =
-                                   dma_alloc_coherent(NULL,
-                                                      config.buffer_size *
-                                                      config.buffer_count,
-                                                      &audio->read_phys,
-                                                      GFP_KERNEL);
-                               if (!audio->read_data) {
-                                       pr_err("audio_mp3: malloc pcm buf failed\n");
-                                       rc = -1;
-                               } else {
-                                       uint8_t index;
-                                       uint32_t offset = 0;
-                                       audio->pcm_feedback = 1;
-                                       audio->buf_refresh = 0;
-                                       audio->pcm_buf_count =
-                                           config.buffer_count;
-                                       audio->read_next = 0;
-                                       audio->fill_next = 0;
-
-                                       for (index = 0;
-                                            index < config.buffer_count;
-                                            index++) {
-                                               audio->in[index].data =
-                                                   audio->read_data + offset;
-                                               audio->in[index].addr =
-                                                   audio->read_phys + offset;
-                                               audio->in[index].size =
-                                                   config.buffer_size;
-                                               audio->in[index].used = 0;
-                                               offset += config.buffer_size;
-                                       }
-                                       rc = 0;
-                               }
-                       } else {
-                               rc = 0;
-                       }
-                       break;
-               }
-       case AUDIO_PAUSE:
-               dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
-               rc = audpp_pause(audio->dec_id, (int) arg);
-               break;
-       default:
-               rc = -EINVAL;
-       }
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
-                         loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       int rc = 0;
-
-       if (!audio->pcm_feedback)
-               return 0; /* PCM feedback disabled. Nothing to read */
-
-       mutex_lock(&audio->read_lock);
-       pr_info("audio_read() %d \n", count);
-       while (count > 0) {
-               rc = wait_event_interruptible(audio->read_wait,
-                                             (audio->in[audio->read_next].
-                                              used > 0) || (audio->stopped)
-                                                  || (audio->rflush));
-
-               if (rc < 0)
-                       break;
-
-               if (audio->stopped || audio->rflush) {
-                       rc = -EBUSY;
-                       break;
-               }
-
-               if (count < audio->in[audio->read_next].used) {
-                       /* Read must happen in frame boundary. Since
-                        * driver does not know frame size, read count
-                        * must be greater or equal
-                        * to size of PCM samples
-                        */
-                       pr_info("audio_read: no partial frame done reading\n");
-                       break;
-               } else {
-                       pr_info("audio_read: read from in[%d]\n",
-                               audio->read_next);
-                       if (copy_to_user
-                           (buf, audio->in[audio->read_next].data,
-                            audio->in[audio->read_next].used)) {
-                               pr_err("audio_read: invalid addr %x \n",
-                                      (unsigned int)buf);
-                               rc = -EFAULT;
-                               break;
-                       }
-                       count -= audio->in[audio->read_next].used;
-                       buf += audio->in[audio->read_next].used;
-                       audio->in[audio->read_next].used = 0;
-                       if ((++audio->read_next) == audio->pcm_buf_count)
-                               audio->read_next = 0;
-                       if (audio->in[audio->read_next].used == 0)
-                               break; /* No data ready at this moment
-                                       * Exit while loop to prevent
-                                       * output thread sleep too long
-                                       */
-               }
-       }
-
-       /* don't feed output buffer to HW decoder during flushing
-        * buffer refresh command will be sent once flush completes
-        * send buf refresh command here can confuse HW decoder
-        */
-       if (audio->buf_refresh && !audio->rflush) {
-               audio->buf_refresh = 0;
-               pr_info("audio_read: kick start pcm feedback again\n");
-               audplay_buffer_refresh(audio);
-       }
-
-       mutex_unlock(&audio->read_lock);
-
-       if (buf > start)
-               rc = buf - start;
-
-       pr_info("audio_read: read %d bytes\n", rc);
-       return rc;
-}
-
-static ssize_t audio_write(struct file *file, const char __user *buf,
-                          size_t count, loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       struct buffer *frame;
-       size_t xfer;
-       char *cpy_ptr;
-       int rc = 0;
-       unsigned dsize;
-
-       mutex_lock(&audio->write_lock);
-       while (count > 0) {
-               frame = audio->out + audio->out_head;
-               cpy_ptr = frame->data;
-               dsize = 0;
-               rc = wait_event_interruptible(audio->write_wait,
-                                             (frame->used == 0)
-                                             || (audio->stopped)
-                                                 || (audio->wflush));
-               if (rc < 0)
-                       break;
-               if (audio->stopped || audio->wflush) {
-                       rc = -EBUSY;
-                       break;
-               }
-
-               if (audio->reserved) {
-                       dprintk("%s: append reserved byte %x\n",
-                               __func__, audio->rsv_byte);
-                       *cpy_ptr = audio->rsv_byte;
-                       xfer = (count > (frame->size - 1)) ?
-                               frame->size - 1 : count;
-                       cpy_ptr++;
-                       dsize = 1;
-                       audio->reserved = 0;
-               } else
-                       xfer = (count > frame->size) ? frame->size : count;
-
-               if (copy_from_user(cpy_ptr, buf, xfer)) {
-                       rc = -EFAULT;
-                       break;
-               }
-
-               dsize += xfer;
-               if (dsize & 1) {
-                       audio->rsv_byte = ((char *) frame->data)[dsize - 1];
-                       dprintk("%s: odd length buf reserve last byte %x\n",
-                               __func__, audio->rsv_byte);
-                       audio->reserved = 1;
-                       dsize--;
-               }
-               count -= xfer;
-               buf += xfer;
-
-               if (dsize > 0) {
-                       audio->out_head ^= 1;
-                       frame->used = dsize;
-                       audplay_send_data(audio, 0);
-               }
-       }
-       mutex_unlock(&audio->write_lock);
-       if (buf > start)
-               return buf - start;
-       return rc;
-}
-
-static int audio_release(struct inode *inode, struct file *file)
-{
-       struct audio *audio = file->private_data;
-
-       dprintk("audio_release()\n");
-
-       mutex_lock(&audio->lock);
-       audio_disable(audio);
-       audio_flush(audio);
-       audio_flush_pcm_buf(audio);
-       msm_adsp_put(audio->audplay);
-       audio->audplay = NULL;
-       audio->opened = 0;
-       audio->reserved = 0;
-       dma_free_coherent(NULL, audio->out_dma_sz, audio->data, audio->phys);
-       audio->data = NULL;
-       if (audio->read_data != NULL) {
-               dma_free_coherent(NULL,
-                                 audio->in[0].size * audio->pcm_buf_count,
-                                 audio->read_data, audio->read_phys);
-               audio->read_data = NULL;
-       }
-       audio->pcm_feedback = 0;
-       mutex_unlock(&audio->lock);
-       return 0;
-}
-
-static struct audio the_mp3_audio;
-
-static int audio_open(struct inode *inode, struct file *file)
-{
-       struct audio *audio = &the_mp3_audio;
-       int rc;
-       unsigned pmem_sz;
-
-       mutex_lock(&audio->lock);
-
-       if (audio->opened) {
-               pr_err("audio: busy\n");
-               rc = -EBUSY;
-               goto done;
-       }
-
-       pmem_sz = DMASZ_MAX;
-
-       while (pmem_sz >= DMASZ_MIN) {
-               audio->data = dma_alloc_coherent(NULL, pmem_sz,
-                                                &audio->phys, GFP_KERNEL);
-               if (audio->data)
-                       break;
-               else if (pmem_sz == DMASZ_MIN) {
-                       pr_err("audio: could not allocate DMA buffers\n");
-                       rc = -ENOMEM;
-                       goto done;
-               } else
-                       pmem_sz >>= 1;
-       }
-
-       dprintk("%s: allocated %d bytes DMA buffer\n", __func__, pmem_sz);
-
-       rc = audmgr_open(&audio->audmgr);
-       if (rc) {
-               dma_free_coherent(NULL, pmem_sz,
-               audio->data, audio->phys);
-               goto done;
-       }
-
-       rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, &audplay_adsp_ops,
-                         audio);
-       if (rc) {
-               pr_err("audio: failed to get audplay0 dsp module\n");
-               dma_free_coherent(NULL, pmem_sz,
-               audio->data, audio->phys);
-               audmgr_close(&audio->audmgr);
-               goto done;
-       }
-
-       audio->out_dma_sz = pmem_sz;
-       pmem_sz >>= 1; /* Shift by 1 to get size of ping pong buffer */
-
-       audio->out_sample_rate = 44100;
-       audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
-       audio->dec_id = 0;
-
-       audio->out[0].data = audio->data + 0;
-       audio->out[0].addr = audio->phys + 0;
-       audio->out[0].size = pmem_sz;
-
-       audio->out[1].data = audio->data + pmem_sz;
-       audio->out[1].addr = audio->phys + pmem_sz;
-       audio->out[1].size = pmem_sz;
-
-       audio->volume = 0x2000; /* equal to Q13 number 1.0 Unit Gain */
-
-       audio_flush(audio);
-
-       file->private_data = audio;
-       audio->opened = 1;
-       rc = 0;
-done:
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static struct file_operations audio_mp3_fops = {
-       .owner          = THIS_MODULE,
-       .open           = audio_open,
-       .release        = audio_release,
-       .read           = audio_read,
-       .write          = audio_write,
-       .unlocked_ioctl = audio_ioctl,
-       .llseek         = noop_llseek,
-};
-
-struct miscdevice audio_mp3_misc = {
-       .minor  = MISC_DYNAMIC_MINOR,
-       .name   = "msm_mp3",
-       .fops   = &audio_mp3_fops,
-};
-
-static int __init audio_init(void)
-{
-       mutex_init(&the_mp3_audio.lock);
-       mutex_init(&the_mp3_audio.write_lock);
-       mutex_init(&the_mp3_audio.read_lock);
-       spin_lock_init(&the_mp3_audio.dsp_lock);
-       init_waitqueue_head(&the_mp3_audio.write_wait);
-       init_waitqueue_head(&the_mp3_audio.read_wait);
-       the_mp3_audio.read_data = NULL;
-       return misc_register(&audio_mp3_misc);
-}
-
-device_initcall(audio_init);
diff --git a/drivers/staging/dream/qdsp5/audio_out.c b/drivers/staging/dream/qdsp5/audio_out.c
deleted file mode 100644 (file)
index d20e895..0000000
+++ /dev/null
@@ -1,841 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/audio_out.c
- *
- * pcm audio output device
- *
- * Copyright (C) 2008 Google, Inc.
- * Copyright (C) 2008 HTC Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/kthread.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include <linux/wakelock.h>
-#include <linux/gfp.h>
-
-#include <linux/msm_audio.h>
-
-#include <asm/atomic.h>
-#include <asm/ioctls.h>
-#include <mach/msm_adsp.h>
-
-#include "audmgr.h"
-
-#include <mach/qdsp5/qdsp5audppcmdi.h>
-#include <mach/qdsp5/qdsp5audppmsg.h>
-
-#include "evlog.h"
-
-#define LOG_AUDIO_EVENTS 1
-#define LOG_AUDIO_FAULTS 0
-
-enum {
-       EV_NULL,
-       EV_OPEN,
-       EV_WRITE,
-       EV_RETURN,
-       EV_IOCTL,
-       EV_WRITE_WAIT,
-       EV_WAIT_EVENT,
-       EV_FILL_BUFFER,
-       EV_SEND_BUFFER,
-       EV_DSP_EVENT,
-       EV_ENABLE,
-};
-
-#if (LOG_AUDIO_EVENTS != 1)
-static inline void LOG(unsigned id, unsigned arg) {}
-#else
-static const char *pcm_log_strings[] = {
-       "NULL",
-       "OPEN",
-       "WRITE",
-       "RETURN",
-       "IOCTL",
-       "WRITE_WAIT",
-       "WAIT_EVENT",
-       "FILL_BUFFER",
-       "SEND_BUFFER",
-       "DSP_EVENT",
-       "ENABLE",
-};
-
-DECLARE_LOG(pcm_log, 64, pcm_log_strings);
-
-static int __init _pcm_log_init(void)
-{
-       return ev_log_init(&pcm_log);
-}
-module_init(_pcm_log_init);
-
-#define LOG(id,arg) ev_log_write(&pcm_log, id, arg)
-#endif
-
-
-
-
-
-#define BUFSZ (960 * 5)
-#define DMASZ (BUFSZ * 2)
-
-#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000
-#define AUDPP_CMD_EQ_FLAG_DIS  0x0000
-#define AUDPP_CMD_EQ_FLAG_ENA  -1
-#define AUDPP_CMD_IIR_FLAG_DIS   0x0000
-#define AUDPP_CMD_IIR_FLAG_ENA   -1
-
-#define AUDPP_CMD_IIR_TUNING_FILTER  1
-#define AUDPP_CMD_EQUALIZER    2
-#define AUDPP_CMD_ADRC 3
-
-#define ADRC_ENABLE  0x0001
-#define EQ_ENABLE    0x0002
-#define IIR_ENABLE   0x0004
-
-struct adrc_filter {
-       uint16_t compression_th;
-       uint16_t compression_slope;
-       uint16_t rms_time;
-       uint16_t attack_const_lsw;
-       uint16_t attack_const_msw;
-       uint16_t release_const_lsw;
-       uint16_t release_const_msw;
-       uint16_t adrc_system_delay;
-};
-
-struct eqalizer {
-       uint16_t num_bands;
-       uint16_t eq_params[132];
-};
-
-struct rx_iir_filter {
-       uint16_t num_bands;
-       uint16_t iir_params[48];
-};
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common common;
-       uint16_t eq_flag;
-       uint16_t num_bands;
-       uint16_t eq_params[132];
-} audpp_cmd_cfg_object_params_eq;
-
-typedef struct {
-       audpp_cmd_cfg_object_params_common common;
-       uint16_t active_flag;
-       uint16_t num_bands;
-       uint16_t iir_params[48];
-} audpp_cmd_cfg_object_params_rx_iir;
-
-struct buffer {
-       void *data;
-       unsigned size;
-       unsigned used;
-       unsigned addr;
-};
-
-struct audio {
-       struct buffer out[2];
-
-       spinlock_t dsp_lock;
-
-       uint8_t out_head;
-       uint8_t out_tail;
-       uint8_t out_needed; /* number of buffers the dsp is waiting for */
-
-       atomic_t out_bytes;
-
-       struct mutex lock;
-       struct mutex write_lock;
-       wait_queue_head_t wait;
-
-       /* configuration to use on next enable */
-       uint32_t out_sample_rate;
-       uint32_t out_channel_mode;
-       uint32_t out_weight;
-       uint32_t out_buffer_size;
-
-       struct audmgr audmgr;
-
-       /* data allocated for various buffers */
-       char *data;
-       dma_addr_t phys;
-
-       int opened;
-       int enabled;
-       int running;
-       int stopped; /* set when stopped, cleared on flush */
-       unsigned volume;
-
-       int adrc_enable;
-       struct adrc_filter adrc;
-
-       int eq_enable;
-       struct eqalizer eq;
-
-       int rx_iir_enable;
-       struct rx_iir_filter iir;
-};
-
-static void audio_prevent_sleep(struct audio *audio)
-{
-       printk(KERN_INFO "++++++++++++++++++++++++++++++\n");
-}
-
-static void audio_allow_sleep(struct audio *audio)
-{
-       printk(KERN_INFO "------------------------------\n");
-}
-
-static int audio_dsp_out_enable(struct audio *audio, int yes);
-static int audio_dsp_send_buffer(struct audio *audio, unsigned id, unsigned len);
-static int audio_dsp_set_adrc(struct audio *audio);
-static int audio_dsp_set_eq(struct audio *audio);
-static int audio_dsp_set_rx_iir(struct audio *audio);
-
-static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
-
-/* must be called with audio->lock held */
-static int audio_enable(struct audio *audio)
-{
-       struct audmgr_config cfg;
-       int rc;
-
-       pr_info("audio_enable()\n");
-
-       if (audio->enabled)
-               return 0;
-
-       /* refuse to start if we're not ready */
-       if (!audio->out[0].used || !audio->out[1].used)
-               return -EIO;
-
-       /* we start buffers 0 and 1, so buffer 0 will be the
-        * next one the dsp will want
-        */
-       audio->out_tail = 0;
-       audio->out_needed = 0;
-
-       cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
-       cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
-       cfg.def_method = RPC_AUD_DEF_METHOD_HOST_PCM;
-       cfg.codec = RPC_AUD_DEF_CODEC_PCM;
-       cfg.snd_method = RPC_SND_METHOD_MIDI;
-
-       audio_prevent_sleep(audio);
-       rc = audmgr_enable(&audio->audmgr, &cfg);
-       if (rc < 0) {
-               audio_allow_sleep(audio);
-               return rc;
-       }
-
-       if (audpp_enable(-1, audio_dsp_event, audio)) {
-               pr_err("audio: audpp_enable() failed\n");
-               audmgr_disable(&audio->audmgr);
-               audio_allow_sleep(audio);
-               return -ENODEV;
-       }
-
-       audio->enabled = 1;
-       return 0;
-}
-
-/* must be called with audio->lock held */
-static int audio_disable(struct audio *audio)
-{
-       pr_info("audio_disable()\n");
-       if (audio->enabled) {
-               audio->enabled = 0;
-               audio_dsp_out_enable(audio, 0);
-
-               audpp_disable(-1, audio);
-
-               wake_up(&audio->wait);
-               audmgr_disable(&audio->audmgr);
-               audio->out_needed = 0;
-               audio_allow_sleep(audio);
-       }
-       return 0;
-}
-
-/* ------------------- dsp --------------------- */
-static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
-{
-       struct audio *audio = private;
-       struct buffer *frame;
-       unsigned long flags;
-
-       LOG(EV_DSP_EVENT, id);
-       switch (id) {
-       case AUDPP_MSG_HOST_PCM_INTF_MSG: {
-               unsigned id = msg[2];
-               unsigned idx = msg[3] - 1;
-
-               /* pr_info("audio_dsp_event: HOST_PCM id %d idx %d\n", id, idx); */
-               if (id != AUDPP_MSG_HOSTPCM_ID_ARM_RX) {
-                       pr_err("bogus id\n");
-                       break;
-               }
-               if (idx > 1) {
-                       pr_err("bogus buffer idx\n");
-                       break;
-               }
-
-               spin_lock_irqsave(&audio->dsp_lock, flags);
-               if (audio->running) {
-                       atomic_add(audio->out[idx].used, &audio->out_bytes);
-                       audio->out[idx].used = 0;
-
-                       frame = audio->out + audio->out_tail;
-                       if (frame->used) {
-                               audio_dsp_send_buffer(
-                                       audio, audio->out_tail, frame->used);
-                               audio->out_tail ^= 1;
-                       } else {
-                               audio->out_needed++;
-                       }
-                       wake_up(&audio->wait);
-               }
-               spin_unlock_irqrestore(&audio->dsp_lock, flags);
-               break;
-       }
-       case AUDPP_MSG_PCMDMAMISSED:
-               pr_info("audio_dsp_event: PCMDMAMISSED %d\n", msg[0]);
-               break;
-       case AUDPP_MSG_CFG_MSG:
-               if (msg[0] == AUDPP_MSG_ENA_ENA) {
-                       LOG(EV_ENABLE, 1);
-                       pr_info("audio_dsp_event: CFG_MSG ENABLE\n");
-                       audio->out_needed = 0;
-                       audio->running = 1;
-                       audpp_set_volume_and_pan(5, audio->volume, 0);
-                       audio_dsp_set_adrc(audio);
-                       audio_dsp_set_eq(audio);
-                       audio_dsp_set_rx_iir(audio);
-                       audio_dsp_out_enable(audio, 1);
-               } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
-                       LOG(EV_ENABLE, 0);
-                       pr_info("audio_dsp_event: CFG_MSG DISABLE\n");
-                       audio->running = 0;
-               } else {
-                       pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
-               }
-               break;
-       default:
-               pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
-       }
-}
-
-static int audio_dsp_out_enable(struct audio *audio, int yes)
-{
-       audpp_cmd_pcm_intf cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id      = AUDPP_CMD_PCM_INTF_2;
-       cmd.object_num  = AUDPP_CMD_PCM_INTF_OBJECT_NUM;
-       cmd.config      = AUDPP_CMD_PCM_INTF_CONFIG_CMD_V;
-       cmd.intf_type   = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V;
-
-       if (yes) {
-               cmd.write_buf1LSW       = audio->out[0].addr;
-               cmd.write_buf1MSW       = audio->out[0].addr >> 16;
-               cmd.write_buf1_len      = audio->out[0].size;
-               cmd.write_buf2LSW       = audio->out[1].addr;
-               cmd.write_buf2MSW       = audio->out[1].addr >> 16;
-               cmd.write_buf2_len      = audio->out[1].size;
-               cmd.arm_to_rx_flag      = AUDPP_CMD_PCM_INTF_ENA_V;
-               cmd.weight_decoder_to_rx = audio->out_weight;
-               cmd.weight_arm_to_rx    = 1;
-               cmd.partition_number_arm_to_dsp = 0;
-               cmd.sample_rate         = audio->out_sample_rate;
-               cmd.channel_mode        = audio->out_channel_mode;
-       }
-
-       return audpp_send_queue2(&cmd, sizeof(cmd));
-}
-
-static int audio_dsp_send_buffer(struct audio *audio, unsigned idx, unsigned len)
-{
-       audpp_cmd_pcm_intf_send_buffer cmd;
-
-       cmd.cmd_id              = AUDPP_CMD_PCM_INTF_2;
-       cmd.host_pcm_object     = AUDPP_CMD_PCM_INTF_OBJECT_NUM;
-       cmd.config              = AUDPP_CMD_PCM_INTF_BUFFER_CMD_V;
-       cmd.intf_type           = AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V;
-       cmd.dsp_to_arm_buf_id   = 0;
-       cmd.arm_to_dsp_buf_id   = idx + 1;
-       cmd.arm_to_dsp_buf_len  = len;
-
-       LOG(EV_SEND_BUFFER, idx);
-       return audpp_send_queue2(&cmd, sizeof(cmd));
-}
-
-static int audio_dsp_set_adrc(struct audio *audio)
-{
-       audpp_cmd_cfg_object_params_adrc cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
-       cmd.common.command_type = AUDPP_CMD_ADRC;
-
-       if (audio->adrc_enable) {
-               cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_ENA;
-               cmd.compression_th = audio->adrc.compression_th;
-               cmd.compression_slope = audio->adrc.compression_slope;
-               cmd.rms_time = audio->adrc.rms_time;
-               cmd.attack_const_lsw = audio->adrc.attack_const_lsw;
-               cmd.attack_const_msw = audio->adrc.attack_const_msw;
-               cmd.release_const_lsw = audio->adrc.release_const_lsw;
-               cmd.release_const_msw = audio->adrc.release_const_msw;
-               cmd.adrc_system_delay = audio->adrc.adrc_system_delay;
-       } else {
-               cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_DIS;
-       }
-       return audpp_send_queue3(&cmd, sizeof(cmd));
-}
-
-static int audio_dsp_set_eq(struct audio *audio)
-{
-       audpp_cmd_cfg_object_params_eq cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
-       cmd.common.command_type = AUDPP_CMD_EQUALIZER;
-
-       if (audio->eq_enable) {
-               cmd.eq_flag = AUDPP_CMD_EQ_FLAG_ENA;
-               cmd.num_bands = audio->eq.num_bands;
-               memcpy(&cmd.eq_params, audio->eq.eq_params,
-                      sizeof(audio->eq.eq_params));
-       } else {
-               cmd.eq_flag = AUDPP_CMD_EQ_FLAG_DIS;
-       }
-       return audpp_send_queue3(&cmd, sizeof(cmd));
-}
-
-static int audio_dsp_set_rx_iir(struct audio *audio)
-{
-       audpp_cmd_cfg_object_params_rx_iir cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
-       cmd.common.command_type = AUDPP_CMD_IIR_TUNING_FILTER;
-
-       if (audio->rx_iir_enable) {
-               cmd.active_flag = AUDPP_CMD_IIR_FLAG_ENA;
-               cmd.num_bands = audio->iir.num_bands;
-               memcpy(&cmd.iir_params, audio->iir.iir_params,
-                      sizeof(audio->iir.iir_params));
-       } else {
-               cmd.active_flag = AUDPP_CMD_IIR_FLAG_DIS;
-       }
-
-       return audpp_send_queue3(&cmd, sizeof(cmd));
-}
-
-/* ------------------- device --------------------- */
-
-static int audio_enable_adrc(struct audio *audio, int enable)
-{
-       if (audio->adrc_enable != enable) {
-               audio->adrc_enable = enable;
-               if (audio->running)
-                       audio_dsp_set_adrc(audio);
-       }
-       return 0;
-}
-
-static int audio_enable_eq(struct audio *audio, int enable)
-{
-       if (audio->eq_enable != enable) {
-               audio->eq_enable = enable;
-               if (audio->running)
-                       audio_dsp_set_eq(audio);
-       }
-       return 0;
-}
-
-static int audio_enable_rx_iir(struct audio *audio, int enable)
-{
-       if (audio->rx_iir_enable != enable) {
-               audio->rx_iir_enable = enable;
-               if (audio->running)
-                       audio_dsp_set_rx_iir(audio);
-       }
-       return 0;
-}
-
-static void audio_flush(struct audio *audio)
-{
-       audio->out[0].used = 0;
-       audio->out[1].used = 0;
-       audio->out_head = 0;
-       audio->out_tail = 0;
-       audio->stopped = 0;
-}
-
-static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct audio *audio = file->private_data;
-       int rc;
-
-       if (cmd == AUDIO_GET_STATS) {
-               struct msm_audio_stats stats;
-               stats.byte_count = atomic_read(&audio->out_bytes);
-               if (copy_to_user((void*) arg, &stats, sizeof(stats)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == AUDIO_SET_VOLUME) {
-               unsigned long flags;
-               spin_lock_irqsave(&audio->dsp_lock, flags);
-               audio->volume = arg;
-               if (audio->running)
-                       audpp_set_volume_and_pan(6, arg, 0);
-               spin_unlock_irqrestore(&audio->dsp_lock, flags);
-       }
-
-       LOG(EV_IOCTL, cmd);
-       mutex_lock(&audio->lock);
-       switch (cmd) {
-       case AUDIO_START:
-               rc = audio_enable(audio);
-               break;
-       case AUDIO_STOP:
-               rc = audio_disable(audio);
-               audio->stopped = 1;
-               break;
-       case AUDIO_FLUSH:
-               if (audio->stopped) {
-                       /* Make sure we're stopped and we wake any threads
-                        * that might be blocked holding the write_lock.
-                        * While audio->stopped write threads will always
-                        * exit immediately.
-                        */
-                       wake_up(&audio->wait);
-                       mutex_lock(&audio->write_lock);
-                       audio_flush(audio);
-                       mutex_unlock(&audio->write_lock);
-               }
-       case AUDIO_SET_CONFIG: {
-               struct msm_audio_config config;
-               if (copy_from_user(&config, (void*) arg, sizeof(config))) {
-                       rc = -EFAULT;
-                       break;
-               }
-               if (config.channel_count == 1) {
-                       config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
-               } else if (config.channel_count == 2) {
-                       config.channel_count= AUDPP_CMD_PCM_INTF_STEREO_V;
-               } else {
-                       rc = -EINVAL;
-                       break;
-               }
-               audio->out_sample_rate = config.sample_rate;
-               audio->out_channel_mode = config.channel_count;
-               rc = 0;
-               break;
-       }
-       case AUDIO_GET_CONFIG: {
-               struct msm_audio_config config;
-               config.buffer_size = BUFSZ;
-               config.buffer_count = 2;
-               config.sample_rate = audio->out_sample_rate;
-               if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) {
-                       config.channel_count = 1;
-               } else {
-                       config.channel_count = 2;
-               }
-               config.unused[0] = 0;
-               config.unused[1] = 0;
-               config.unused[2] = 0;
-               config.unused[3] = 0;
-               if (copy_to_user((void*) arg, &config, sizeof(config))) {
-                       rc = -EFAULT;
-               } else {
-                       rc = 0;
-               }
-               break;
-       }
-       default:
-               rc = -EINVAL;
-       }
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static ssize_t audio_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
-{
-       return -EINVAL;
-}
-
-static inline int rt_policy(int policy)
-{
-       if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
-               return 1;
-       return 0;
-}
-
-static inline int task_has_rt_policy(struct task_struct *p)
-{
-       return rt_policy(p->policy);
-}
-
-static ssize_t audio_write(struct file *file, const char __user *buf,
-                          size_t count, loff_t *pos)
-{
-       struct sched_param s = { .sched_priority = 1 };
-       struct audio *audio = file->private_data;
-       unsigned long flags;
-       const char __user *start = buf;
-       struct buffer *frame;
-       size_t xfer;
-       int old_prio = current->rt_priority;
-       int old_policy = current->policy;
-       int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE);
-       int rc = 0;
-
-       LOG(EV_WRITE, count | (audio->running << 28) | (audio->stopped << 24));
-
-       /* just for this write, set us real-time */
-       if (!task_has_rt_policy(current)) {
-               struct cred *new = prepare_creds();
-               cap_raise(new->cap_effective, CAP_SYS_NICE);
-               commit_creds(new);
-               sched_setscheduler(current, SCHED_RR, &s);
-       }
-
-       mutex_lock(&audio->write_lock);
-       while (count > 0) {
-               frame = audio->out + audio->out_head;
-
-               LOG(EV_WAIT_EVENT, 0);
-               rc = wait_event_interruptible(audio->wait,
-                                             (frame->used == 0) || (audio->stopped));
-               LOG(EV_WAIT_EVENT, 1);
-
-               if (rc < 0)
-                       break;
-               if (audio->stopped) {
-                       rc = -EBUSY;
-                       break;
-               }
-               xfer = count > frame->size ? frame->size : count;
-               if (copy_from_user(frame->data, buf, xfer)) {
-                       rc = -EFAULT;
-                       break;
-               }
-               frame->used = xfer;
-               audio->out_head ^= 1;
-               count -= xfer;
-               buf += xfer;
-
-               spin_lock_irqsave(&audio->dsp_lock, flags);
-               LOG(EV_FILL_BUFFER, audio->out_head ^ 1);
-               frame = audio->out + audio->out_tail;
-               if (frame->used && audio->out_needed) {
-                       audio_dsp_send_buffer(audio, audio->out_tail, frame->used);
-                       audio->out_tail ^= 1;
-                       audio->out_needed--;
-               }
-               spin_unlock_irqrestore(&audio->dsp_lock, flags);
-       }
-
-       mutex_unlock(&audio->write_lock);
-
-       /* restore scheduling policy and priority */
-       if (!rt_policy(old_policy)) {
-               struct sched_param v = { .sched_priority = old_prio };
-               sched_setscheduler(current, old_policy, &v);
-               if (likely(!cap_nice)) {
-                       struct cred *new = prepare_creds();
-                       cap_lower(new->cap_effective, CAP_SYS_NICE);
-                       commit_creds(new);
-                       sched_setscheduler(current, SCHED_RR, &s);
-               }
-       }
-
-       LOG(EV_RETURN,(buf > start) ? (buf - start) : rc);
-       if (buf > start)
-               return buf - start;
-       return rc;
-}
-
-static int audio_release(struct inode *inode, struct file *file)
-{
-       struct audio *audio = file->private_data;
-
-       LOG(EV_OPEN, 0);
-       mutex_lock(&audio->lock);
-       audio_disable(audio);
-       audio_flush(audio);
-       audio->opened = 0;
-       mutex_unlock(&audio->lock);
-       return 0;
-}
-
-static struct audio the_audio;
-
-static int audio_open(struct inode *inode, struct file *file)
-{
-       struct audio *audio = &the_audio;
-       int rc;
-
-       mutex_lock(&audio->lock);
-
-       if (audio->opened) {
-               pr_err("audio: busy\n");
-               rc = -EBUSY;
-               goto done;
-       }
-
-       if (!audio->data) {
-               audio->data = dma_alloc_coherent(NULL, DMASZ,
-                                                &audio->phys, GFP_KERNEL);
-               if (!audio->data) {
-                       pr_err("audio: could not allocate DMA buffers\n");
-                       rc = -ENOMEM;
-                       goto done;
-               }
-       }
-
-       rc = audmgr_open(&audio->audmgr);
-       if (rc)
-               goto done;
-
-       audio->out_buffer_size = BUFSZ;
-       audio->out_sample_rate = 44100;
-       audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
-       audio->out_weight = 100;
-
-       audio->out[0].data = audio->data + 0;
-       audio->out[0].addr = audio->phys + 0;
-       audio->out[0].size = BUFSZ;
-
-       audio->out[1].data = audio->data + BUFSZ;
-       audio->out[1].addr = audio->phys + BUFSZ;
-       audio->out[1].size = BUFSZ;
-
-       audio->volume = 0x2000;
-
-       audio_flush(audio);
-
-       file->private_data = audio;
-       audio->opened = 1;
-       rc = 0;
-       LOG(EV_OPEN, 1);
-done:
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static long audpp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct audio *audio = file->private_data;
-       int rc = 0, enable;
-       uint16_t enable_mask;
-
-       mutex_lock(&audio->lock);
-       switch (cmd) {
-       case AUDIO_ENABLE_AUDPP:
-               if (copy_from_user(&enable_mask, (void *) arg, sizeof(enable_mask)))
-                       goto out_fault;
-
-               enable = (enable_mask & ADRC_ENABLE)? 1 : 0;
-               audio_enable_adrc(audio, enable);
-               enable = (enable_mask & EQ_ENABLE)? 1 : 0;
-               audio_enable_eq(audio, enable);
-               enable = (enable_mask & IIR_ENABLE)? 1 : 0;
-               audio_enable_rx_iir(audio, enable);
-               break;
-
-       case AUDIO_SET_ADRC:
-               if (copy_from_user(&audio->adrc, (void*) arg, sizeof(audio->adrc)))
-                       goto out_fault;
-               break;
-
-       case AUDIO_SET_EQ:
-               if (copy_from_user(&audio->eq, (void*) arg, sizeof(audio->eq)))
-                       goto out_fault;
-               break;
-
-       case AUDIO_SET_RX_IIR:
-               if (copy_from_user(&audio->iir, (void*) arg, sizeof(audio->iir)))
-                       goto out_fault;
-               break;
-
-       default:
-               rc = -EINVAL;
-       }
-
-       goto out;
-
- out_fault:
-       rc = -EFAULT;
- out:
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static int audpp_open(struct inode *inode, struct file *file)
-{
-       struct audio *audio = &the_audio;
-
-       file->private_data = audio;
-       return 0;
-}
-
-static struct file_operations audio_fops = {
-       .owner          = THIS_MODULE,
-       .open           = audio_open,
-       .release        = audio_release,
-       .read           = audio_read,
-       .write          = audio_write,
-       .unlocked_ioctl = audio_ioctl,
-       .llseek         = noop_llseek,
-};
-
-static struct file_operations audpp_fops = {
-       .owner          = THIS_MODULE,
-       .open           = audpp_open,
-       .unlocked_ioctl = audpp_ioctl,
-       .llseek         = noop_llseek,
-};
-
-struct miscdevice audio_misc = {
-       .minor  = MISC_DYNAMIC_MINOR,
-       .name   = "msm_pcm_out",
-       .fops   = &audio_fops,
-};
-
-struct miscdevice audpp_misc = {
-       .minor  = MISC_DYNAMIC_MINOR,
-       .name   = "msm_pcm_ctl",
-       .fops   = &audpp_fops,
-};
-
-static int __init audio_init(void)
-{
-       mutex_init(&the_audio.lock);
-       mutex_init(&the_audio.write_lock);
-       spin_lock_init(&the_audio.dsp_lock);
-       init_waitqueue_head(&the_audio.wait);
-       return (misc_register(&audio_misc) || misc_register(&audpp_misc));
-}
-
-device_initcall(audio_init);
diff --git a/drivers/staging/dream/qdsp5/audio_qcelp.c b/drivers/staging/dream/qdsp5/audio_qcelp.c
deleted file mode 100644 (file)
index 911bab4..0000000
+++ /dev/null
@@ -1,858 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/audio_qcelp.c
- *
- * qcelp 13k audio decoder device
- *
- * Copyright (c) 2008 QUALCOMM USA, INC.
- *
- * This code is based in part on audio_mp3.c, which is
- * Copyright (C) 2008 Google, Inc.
- * Copyright (C) 2008 HTC Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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, you can find it at http://www.fsf.org.
- *
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <asm/ioctls.h>
-#include <mach/msm_adsp.h>
-#include <linux/msm_audio.h>
-#include <mach/qdsp5/qdsp5audppcmdi.h>
-#include <mach/qdsp5/qdsp5audppmsg.h>
-#include <mach/qdsp5/qdsp5audplaycmdi.h>
-#include <mach/qdsp5/qdsp5audplaymsg.h>
-
-#include "audmgr.h"
-/* for queue ids - should be relative to module number*/
-#include "adsp.h"
-
-#ifdef DEBUG
-#define dprintk(format, arg...) \
-printk(KERN_DEBUG format, ## arg)
-#else
-#define dprintk(format, arg...) do {} while (0)
-#endif
-
-#define BUFSZ 1080 /* QCELP 13K Hold 600ms packet data = 36 * 30 */
-#define BUF_COUNT 2
-#define DMASZ (BUFSZ * BUF_COUNT)
-
-#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
-#define PCM_BUF_MAX_COUNT 5
-
-#define AUDDEC_DEC_QCELP 9
-
-#define        ROUTING_MODE_FTRT       1
-#define        ROUTING_MODE_RT         2
-/* Decoder status received from AUDPPTASK */
-#define        AUDPP_DEC_STATUS_SLEEP  0
-#define        AUDPP_DEC_STATUS_INIT   1
-#define        AUDPP_DEC_STATUS_CFG    2
-#define        AUDPP_DEC_STATUS_PLAY   3
-
-struct buffer {
-       void *data;
-       unsigned size;
-       unsigned used;          /* Input usage actual DSP produced PCM size  */
-       unsigned addr;
-};
-
-struct audio {
-       struct buffer out[BUF_COUNT];
-
-       spinlock_t dsp_lock;
-
-       uint8_t out_head;
-       uint8_t out_tail;
-       uint8_t out_needed;     /* number of buffers the dsp is waiting for */
-
-       struct mutex lock;
-       struct mutex write_lock;
-       wait_queue_head_t write_wait;
-
-       /* Host PCM section - START */
-       struct buffer in[PCM_BUF_MAX_COUNT];
-       struct mutex read_lock;
-       wait_queue_head_t read_wait;    /* Wait queue for read */
-       char *read_data;        /* pointer to reader buffer */
-       dma_addr_t read_phys;   /* physical address of reader buffer */
-       uint8_t read_next;      /* index to input buffers to be read next */
-       uint8_t fill_next;      /* index to buffer that DSP should be filling */
-       uint8_t pcm_buf_count;  /* number of pcm buffer allocated */
-       /* Host PCM section - END */
-
-       struct msm_adsp_module *audplay;
-
-       struct audmgr audmgr;
-
-       /* data allocated for various buffers */
-       char *data;
-       dma_addr_t phys;
-
-       uint8_t opened:1;
-       uint8_t enabled:1;
-       uint8_t running:1;
-       uint8_t stopped:1;      /* set when stopped, cleared on flush */
-       uint8_t pcm_feedback:1; /* set when non-tunnel mode */
-       uint8_t buf_refresh:1;
-
-       unsigned volume;
-
-       uint16_t dec_id;
-};
-
-static struct audio the_qcelp_audio;
-
-static int auddec_dsp_config(struct audio *audio, int enable);
-static void audpp_cmd_cfg_adec_params(struct audio *audio);
-static void audpp_cmd_cfg_routing_mode(struct audio *audio);
-static void audqcelp_send_data(struct audio *audio, unsigned needed);
-static void audqcelp_config_hostpcm(struct audio *audio);
-static void audqcelp_buffer_refresh(struct audio *audio);
-static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg);
-
-/* must be called with audio->lock held */
-static int audqcelp_enable(struct audio *audio)
-{
-       struct audmgr_config cfg;
-       int rc;
-
-       dprintk("audqcelp_enable()\n");
-
-       if (audio->enabled)
-               return 0;
-
-       audio->out_tail = 0;
-       audio->out_needed = 0;
-
-       cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
-       cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
-       cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
-       cfg.codec = RPC_AUD_DEF_CODEC_13K;
-       cfg.snd_method = RPC_SND_METHOD_MIDI;
-
-       rc = audmgr_enable(&audio->audmgr, &cfg);
-       if (rc < 0)
-               return rc;
-
-       if (msm_adsp_enable(audio->audplay)) {
-               pr_err("audio: msm_adsp_enable(audplay) failed\n");
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-
-       if (audpp_enable(audio->dec_id, audqcelp_dsp_event, audio)) {
-               pr_err("audio: audpp_enable() failed\n");
-               msm_adsp_disable(audio->audplay);
-               audmgr_disable(&audio->audmgr);
-               return -ENODEV;
-       }
-       audio->enabled = 1;
-       return 0;
-}
-
-/* must be called with audio->lock held */
-static int audqcelp_disable(struct audio *audio)
-{
-       dprintk("audqcelp_disable()\n");
-       if (audio->enabled) {
-               audio->enabled = 0;
-               auddec_dsp_config(audio, 0);
-               wake_up(&audio->write_wait);
-               wake_up(&audio->read_wait);
-               msm_adsp_disable(audio->audplay);
-               audpp_disable(audio->dec_id, audio);
-               audmgr_disable(&audio->audmgr);
-               audio->out_needed = 0;
-       }
-       return 0;
-}
-
-/* ------------------- dsp --------------------- */
-static void audqcelp_update_pcm_buf_entry(struct audio *audio,
-       uint32_t *payload)
-{
-       uint8_t index;
-       unsigned long flags;
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       for (index = 0; index < payload[1]; index++) {
-               if (audio->in[audio->fill_next].addr ==
-                       payload[2 + index * 2]) {
-                       dprintk("audqcelp_update_pcm_buf_entry: in[%d] ready\n",
-                       audio->fill_next);
-                       audio->in[audio->fill_next].used =
-                       payload[3 + index * 2];
-                       if ((++audio->fill_next) == audio->pcm_buf_count)
-                               audio->fill_next = 0;
-               } else {
-                       pr_err(
-                       "audqcelp_update_pcm_buf_entry: expected=%x ret=%x\n",
-                       audio->in[audio->fill_next].addr,
-                       payload[1 + index * 2]);
-                       break;
-               }
-       }
-       if (audio->in[audio->fill_next].used == 0) {
-               audqcelp_buffer_refresh(audio);
-       } else {
-               dprintk("audqcelp_update_pcm_buf_entry: read cannot keep up\n");
-               audio->buf_refresh = 1;
-       }
-
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-       wake_up(&audio->read_wait);
-}
-
-static void audplay_dsp_event(void *data, unsigned id, size_t len,
-                             void (*getevent) (void *ptr, size_t len))
-{
-       struct audio *audio = data;
-       uint32_t msg[28];
-       getevent(msg, sizeof(msg));
-
-       dprintk("audplay_dsp_event: msg_id=%x\n", id);
-
-       switch (id) {
-       case AUDPLAY_MSG_DEC_NEEDS_DATA:
-               audqcelp_send_data(audio, 1);
-               break;
-
-       case AUDPLAY_MSG_BUFFER_UPDATE:
-               audqcelp_update_pcm_buf_entry(audio, msg);
-               break;
-
-       default:
-               pr_err("unexpected message from decoder \n");
-       }
-}
-
-static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg)
-{
-       struct audio *audio = private;
-
-       switch (id) {
-       case AUDPP_MSG_STATUS_MSG:{
-                       unsigned status = msg[1];
-
-                       switch (status) {
-                       case AUDPP_DEC_STATUS_SLEEP:
-                               dprintk("decoder status: sleep \n");
-                               break;
-
-                       case AUDPP_DEC_STATUS_INIT:
-                               dprintk("decoder status: init \n");
-                               audpp_cmd_cfg_routing_mode(audio);
-                               break;
-
-                       case AUDPP_DEC_STATUS_CFG:
-                               dprintk("decoder status: cfg \n");
-                               break;
-                       case AUDPP_DEC_STATUS_PLAY:
-                               dprintk("decoder status: play \n");
-                               if (audio->pcm_feedback) {
-                                       audqcelp_config_hostpcm(audio);
-                                       audqcelp_buffer_refresh(audio);
-                               }
-                               break;
-                       default:
-                               pr_err("unknown decoder status \n");
-                       }
-                       break;
-               }
-       case AUDPP_MSG_CFG_MSG:
-               if (msg[0] == AUDPP_MSG_ENA_ENA) {
-                       dprintk("audqcelp_dsp_event: CFG_MSG ENABLE\n");
-                       auddec_dsp_config(audio, 1);
-                       audio->out_needed = 0;
-                       audio->running = 1;
-                       audpp_set_volume_and_pan(audio->dec_id, audio->volume,
-                                                0);
-                       audpp_avsync(audio->dec_id, 22050);
-               } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
-                       dprintk("audqcelp_dsp_event: CFG_MSG DISABLE\n");
-                       audpp_avsync(audio->dec_id, 0);
-                       audio->running = 0;
-               } else {
-                       pr_err("audqcelp_dsp_event: CFG_MSG %d?\n", msg[0]);
-               }
-               break;
-       case AUDPP_MSG_ROUTING_ACK:
-               dprintk("audqcelp_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
-               audpp_cmd_cfg_adec_params(audio);
-               break;
-       default:
-               pr_err("audqcelp_dsp_event: UNKNOWN (%d)\n", id);
-       }
-
-}
-
-struct msm_adsp_ops audplay_adsp_ops_qcelp = {
-       .event = audplay_dsp_event,
-};
-
-#define audplay_send_queue0(audio, cmd, len) \
-       msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
-                      cmd, len)
-
-static int auddec_dsp_config(struct audio *audio, int enable)
-{
-       audpp_cmd_cfg_dec_type cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
-       if (enable)
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
-                   AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_QCELP;
-       else
-               cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
-
-       return audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_adec_params(struct audio *audio)
-{
-       struct audpp_cmd_cfg_adec_params_v13k cmd;
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
-       cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN;
-       cmd.common.dec_id = audio->dec_id;
-       cmd.common.input_sampling_frequency = 8000;
-       cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
-
-       audpp_send_queue2(&cmd, sizeof(cmd));
-}
-
-static void audpp_cmd_cfg_routing_mode(struct audio *audio)
-{
-       struct audpp_cmd_routing_mode cmd;
-       dprintk("audpp_cmd_cfg_routing_mode()\n");
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
-       cmd.object_number = audio->dec_id;
-       if (audio->pcm_feedback)
-               cmd.routing_mode = ROUTING_MODE_FTRT;
-       else
-               cmd.routing_mode = ROUTING_MODE_RT;
-       audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static int audplay_dsp_send_data_avail(struct audio *audio,
-                                      unsigned idx, unsigned len)
-{
-       audplay_cmd_bitstream_data_avail cmd;
-
-       cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
-       cmd.decoder_id = audio->dec_id;
-       cmd.buf_ptr = audio->out[idx].addr;
-       cmd.buf_size = len / 2;
-       cmd.partition_number = 0;
-       return audplay_send_queue0(audio, &cmd, sizeof(cmd));
-}
-
-static void audqcelp_buffer_refresh(struct audio *audio)
-{
-       struct audplay_cmd_buffer_refresh refresh_cmd;
-
-       refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
-       refresh_cmd.num_buffers = 1;
-       refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
-       refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
-       refresh_cmd.buf_read_count = 0;
-       dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
-               refresh_cmd.buf0_address, refresh_cmd.buf0_length);
-
-       (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
-}
-
-static void audqcelp_config_hostpcm(struct audio *audio)
-{
-       struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
-
-       dprintk("audqcelp_config_hostpcm()\n");
-       cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
-       cfg_cmd.max_buffers = audio->pcm_buf_count;
-       cfg_cmd.byte_swap = 0;
-       cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
-       cfg_cmd.feedback_frequency = 1;
-       cfg_cmd.partition_number = 0;
-
-       (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
-}
-
-static void audqcelp_send_data(struct audio *audio, unsigned needed)
-{
-       struct buffer *frame;
-       unsigned long flags;
-
-       spin_lock_irqsave(&audio->dsp_lock, flags);
-       if (!audio->running)
-               goto done;
-
-       if (needed) {
-               /* We were called from the callback because the DSP
-                * requested more data.  Note that the DSP does want
-                * more data, and if a buffer was in-flight, mark it
-                * as available (since the DSP must now be done with
-                * it).
-                */
-               audio->out_needed = 1;
-               frame = audio->out + audio->out_tail;
-               if (frame->used == 0xffffffff) {
-                       dprintk("frame %d free\n", audio->out_tail);
-                       frame->used = 0;
-                       audio->out_tail ^= 1;
-                       wake_up(&audio->write_wait);
-               }
-       }
-
-       if (audio->out_needed) {
-               /* If the DSP currently wants data and we have a
-                * buffer available, we will send it and reset
-                * the needed flag.  We'll mark the buffer as in-flight
-                * so that it won't be recycled until the next buffer
-                * is requested
-                */
-
-               frame = audio->out + audio->out_tail;
-               if (frame->used) {
-                       BUG_ON(frame->used == 0xffffffff);
-                       dprintk("frame %d busy\n", audio->out_tail);
-                       audplay_dsp_send_data_avail(audio, audio->out_tail,
-                                                   frame->used);
-                       frame->used = 0xffffffff;
-                       audio->out_needed = 0;
-               }
-       }
- done:
-       spin_unlock_irqrestore(&audio->dsp_lock, flags);
-}
-
-/* ------------------- device --------------------- */
-
-static void audqcelp_flush(struct audio *audio)
-{
-       audio->out[0].used = 0;
-       audio->out[1].used = 0;
-       audio->out_head = 0;
-       audio->out_tail = 0;
-       audio->stopped = 0;
-}
-
-static void audqcelp_flush_pcm_buf(struct audio *audio)
-{
-       uint8_t index;
-
-       for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
-               audio->in[index].used = 0;
-
-       audio->read_next = 0;
-       audio->fill_next = 0;
-}
-
-static long audqcelp_ioctl(struct file *file, unsigned int cmd,
-               unsigned long arg)
-{
-       struct audio *audio = file->private_data;
-       int rc = 0;
-
-       dprintk("audqcelp_ioctl() cmd = %d\n", cmd);
-
-       if (cmd == AUDIO_GET_STATS) {
-               struct msm_audio_stats stats;
-               stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
-               stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
-               if (copy_to_user((void *)arg, &stats, sizeof(stats)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == AUDIO_SET_VOLUME) {
-               unsigned long flags;
-               spin_lock_irqsave(&audio->dsp_lock, flags);
-               audio->volume = arg;
-               if (audio->running)
-                       audpp_set_volume_and_pan(audio->dec_id, arg, 0);
-               spin_unlock_irqrestore(&audio->dsp_lock, flags);
-               return 0;
-       }
-       mutex_lock(&audio->lock);
-       switch (cmd) {
-       case AUDIO_START:
-               rc = audqcelp_enable(audio);
-               break;
-       case AUDIO_STOP:
-               rc = audqcelp_disable(audio);
-               audio->stopped = 1;
-               break;
-       case AUDIO_FLUSH:
-               if (audio->stopped) {
-                       /* Make sure we're stopped and we wake any threads
-                        * that might be blocked holding the write_lock.
-                        * While audio->stopped write threads will always
-                        * exit immediately.
-                        */
-                       wake_up(&audio->write_wait);
-                       mutex_lock(&audio->write_lock);
-                       audqcelp_flush(audio);
-                       mutex_unlock(&audio->write_lock);
-                       wake_up(&audio->read_wait);
-                       mutex_lock(&audio->read_lock);
-                       audqcelp_flush_pcm_buf(audio);
-                       mutex_unlock(&audio->read_lock);
-                       break;
-               }
-               break;
-       case AUDIO_SET_CONFIG:
-               dprintk("AUDIO_SET_CONFIG not applicable \n");
-               break;
-       case AUDIO_GET_CONFIG:{
-                       struct msm_audio_config config;
-                       config.buffer_size = BUFSZ;
-                       config.buffer_count = BUF_COUNT;
-                       config.sample_rate = 8000;
-                       config.channel_count = 1;
-                       config.unused[0] = 0;
-                       config.unused[1] = 0;
-                       config.unused[2] = 0;
-                       config.unused[3] = 0;
-                       if (copy_to_user((void *)arg, &config,
-                                        sizeof(config)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-
-                       break;
-               }
-       case AUDIO_GET_PCM_CONFIG:{
-                       struct msm_audio_pcm_config config;
-
-                       config.pcm_feedback = 0;
-                       config.buffer_count = PCM_BUF_MAX_COUNT;
-                       config.buffer_size = PCM_BUFSZ_MIN;
-                       if (copy_to_user((void *)arg, &config,
-                               sizeof(config)))
-                               rc = -EFAULT;
-                       else
-                               rc = 0;
-                       break;
-               }
-       case AUDIO_SET_PCM_CONFIG:{
-                       struct msm_audio_pcm_config config;
-
-                       if (copy_from_user(&config, (void *)arg,
-                               sizeof(config))) {
-                               rc = -EFAULT;
-                               break;
-                       }
-                       if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
-                               (config.buffer_count == 1))
-                               config.buffer_count = PCM_BUF_MAX_COUNT;
-
-                       if (config.buffer_size < PCM_BUFSZ_MIN)
-                               config.buffer_size = PCM_BUFSZ_MIN;
-
-                       /* Check if pcm feedback is required */
-                       if ((config.pcm_feedback) && (!audio->read_data)) {
-                               dprintk(
-                               "audqcelp_ioctl: allocate PCM buf %d\n",
-                               config.buffer_count * config.buffer_size);
-                               audio->read_data = dma_alloc_coherent(NULL,
-                               config.buffer_size * config.buffer_count,
-                               &audio->read_phys, GFP_KERNEL);
-                               if (!audio->read_data) {
-                                       pr_err(
-                                       "audqcelp_ioctl: no mem for pcm buf\n"
-                                       );
-                                       rc = -ENOMEM;
-                               } else {
-                                       uint8_t index;
-                                       uint32_t offset = 0;
-
-                                       audio->pcm_feedback = 1;
-                                       audio->buf_refresh = 0;
-                                       audio->pcm_buf_count =
-                                               config.buffer_count;
-                                       audio->read_next = 0;
-                                       audio->fill_next = 0;
-
-                                       for (index = 0;
-                                       index < config.buffer_count; index++) {
-                                               audio->in[index].data =
-                                               audio->read_data + offset;
-                                               audio->in[index].addr =
-                                               audio->read_phys + offset;
-                                               audio->in[index].size =
-                                               config.buffer_size;
-                                               audio->in[index].used = 0;
-                                               offset += config.buffer_size;
-                                       }
-                                       rc = 0;
-                               }
-                       } else {
-                               rc = 0;
-                       }
-                       break;
-               }
-       case AUDIO_PAUSE:
-               dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
-               rc = audpp_pause(audio->dec_id, (int) arg);
-               break;
-       default:
-               rc = -EINVAL;
-       }
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static ssize_t audqcelp_read(struct file *file, char __user *buf, size_t count,
-                       loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       int rc = 0;
-
-       if (!audio->pcm_feedback)
-               return 0; /* PCM feedback is not enabled. Nothing to read */
-
-       mutex_lock(&audio->read_lock);
-       dprintk("audqcelp_read() %d \n", count);
-       while (count > 0) {
-               rc = wait_event_interruptible(audio->read_wait,
-                               (audio->in[audio->read_next].used > 0) ||
-                               (audio->stopped));
-               if (rc < 0)
-                       break;
-
-               if (audio->stopped) {
-                       rc = -EBUSY;
-                       break;
-               }
-
-               if (count < audio->in[audio->read_next].used) {
-                       /* Read must happen in frame boundary. Since driver does
-                       not know frame size, read count must be greater or equal
-                       to size of PCM samples */
-                       dprintk("audqcelp_read:read stop - partial frame\n");
-                       break;
-               } else {
-                       dprintk("audqcelp_read: read from in[%d]\n",
-                               audio->read_next);
-                       if (copy_to_user(buf,
-                               audio->in[audio->read_next].data,
-                               audio->in[audio->read_next].used)) {
-                               pr_err("audqcelp_read: invalid addr %x \n",
-                                       (unsigned int)buf);
-                               rc = -EFAULT;
-                               break;
-                       }
-                       count -= audio->in[audio->read_next].used;
-                       buf += audio->in[audio->read_next].used;
-                       audio->in[audio->read_next].used = 0;
-                       if ((++audio->read_next) == audio->pcm_buf_count)
-                               audio->read_next = 0;
-               }
-       }
-
-       if (audio->buf_refresh) {
-               audio->buf_refresh = 0;
-               dprintk("audqcelp_read: kick start pcm feedback again\n");
-               audqcelp_buffer_refresh(audio);
-       }
-
-       mutex_unlock(&audio->read_lock);
-
-       if (buf > start)
-               rc = buf - start;
-
-       dprintk("audqcelp_read: read %d bytes\n", rc);
-       return rc;
-}
-
-static ssize_t audqcelp_write(struct file *file, const char __user *buf,
-                          size_t count, loff_t *pos)
-{
-       struct audio *audio = file->private_data;
-       const char __user *start = buf;
-       struct buffer *frame;
-       size_t xfer;
-       int rc = 0;
-
-       if (count & 1)
-               return -EINVAL;
-       dprintk("audqcelp_write() \n");
-       mutex_lock(&audio->write_lock);
-       while (count > 0) {
-               frame = audio->out + audio->out_head;
-               rc = wait_event_interruptible(audio->write_wait,
-                                             (frame->used == 0)
-                                             || (audio->stopped));
-               dprintk("audqcelp_write() buffer available\n");
-               if (rc < 0)
-                       break;
-               if (audio->stopped) {
-                       rc = -EBUSY;
-                       break;
-               }
-               xfer = (count > frame->size) ? frame->size : count;
-               if (copy_from_user(frame->data, buf, xfer)) {
-                       rc = -EFAULT;
-                       break;
-               }
-
-               frame->used = xfer;
-               audio->out_head ^= 1;
-               count -= xfer;
-               buf += xfer;
-
-               audqcelp_send_data(audio, 0);
-
-       }
-       mutex_unlock(&audio->write_lock);
-       if (buf > start)
-               return buf - start;
-       return rc;
-}
-
-static int audqcelp_release(struct inode *inode, struct file *file)
-{
-       struct audio *audio = file->private_data;
-
-       dprintk("audqcelp_release()\n");
-
-       mutex_lock(&audio->lock);
-       audqcelp_disable(audio);
-       audqcelp_flush(audio);
-       audqcelp_flush_pcm_buf(audio);
-       msm_adsp_put(audio->audplay);
-       audio->audplay = NULL;
-       audio->opened = 0;
-       if (audio->data)
-               dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
-       audio->data = NULL;
-       if (audio->read_data) {
-               dma_free_coherent(NULL,
-                                audio->in[0].size * audio->pcm_buf_count,
-                                audio->read_data, audio->read_phys);
-               audio->read_data = NULL;
-       }
-       audio->pcm_feedback = 0;
-       mutex_unlock(&audio->lock);
-       return 0;
-}
-
-static int audqcelp_open(struct inode *inode, struct file *file)
-{
-       struct audio *audio = &the_qcelp_audio;
-       int rc;
-
-       mutex_lock(&audio->lock);
-
-       if (audio->opened) {
-               pr_err("audio: busy\n");
-               rc = -EBUSY;
-               goto done;
-       }
-
-       audio->data = dma_alloc_coherent(NULL, DMASZ,
-                                        &audio->phys, GFP_KERNEL);
-       if (!audio->data) {
-               pr_err("audio: could not allocate DMA buffers\n");
-               rc = -ENOMEM;
-               goto done;
-       }
-
-       rc = audmgr_open(&audio->audmgr);
-       if (rc)
-               goto err;
-
-       rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
-               &audplay_adsp_ops_qcelp, audio);
-       if (rc) {
-               pr_err("audio: failed to get audplay0 dsp module\n");
-               audmgr_close(&audio->audmgr);
-               goto err;
-       }
-
-       audio->dec_id = 0;
-
-       audio->out[0].data = audio->data + 0;
-       audio->out[0].addr = audio->phys + 0;
-       audio->out[0].size = BUFSZ;
-
-       audio->out[1].data = audio->data + BUFSZ;
-       audio->out[1].addr = audio->phys + BUFSZ;
-       audio->out[1].size = BUFSZ;
-
-       audio->volume = 0x2000; /* Q13 1.0 */
-
-       audqcelp_flush(audio);
-
-       file->private_data = audio;
-       audio->opened = 1;
-       rc = 0;
-done:
-       mutex_unlock(&audio->lock);
-       return rc;
-err:
-       dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
-       mutex_unlock(&audio->lock);
-       return rc;
-}
-
-static struct file_operations audio_qcelp_fops = {
-       .owner = THIS_MODULE,
-       .open = audqcelp_open,
-       .release = audqcelp_release,
-       .read = audqcelp_read,
-       .write = audqcelp_write,
-       .unlocked_ioctl = audqcelp_ioctl,
-       .llseek = noop_llseek,
-};
-
-struct miscdevice audio_qcelp_misc = {
-       .minor = MISC_DYNAMIC_MINOR,
-       .name = "msm_qcelp",
-       .fops = &audio_qcelp_fops,
-};
-
-static int __init audqcelp_init(void)
-{
-       mutex_init(&the_qcelp_audio.lock);
-       mutex_init(&the_qcelp_audio.write_lock);
-       mutex_init(&the_qcelp_audio.read_lock);
-       spin_lock_init(&the_qcelp_audio.dsp_lock);
-       init_waitqueue_head(&the_qcelp_audio.write_wait);
-       init_waitqueue_head(&the_qcelp_audio.read_wait);
-       the_qcelp_audio.read_data = NULL;
-       return misc_register(&audio_qcelp_misc);
-}
-
-static void __exit audqcelp_exit(void)
-{
-       misc_deregister(&audio_qcelp_misc);
-}
-
-module_init(audqcelp_init);
-module_exit(audqcelp_exit);
-
-MODULE_DESCRIPTION("MSM QCELP 13K driver");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("QUALCOMM");
diff --git a/drivers/staging/dream/qdsp5/audmgr.c b/drivers/staging/dream/qdsp5/audmgr.c
deleted file mode 100644 (file)
index 427ae6c..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/audmgr.c
- *
- * interface to "audmgr" service on the baseband cpu
- *
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/kthread.h>
-#include <linux/wait.h>
-
-#include <asm/atomic.h>
-#include <mach/msm_rpcrouter.h>
-
-#include "audmgr.h"
-
-#define STATE_CLOSED    0
-#define STATE_DISABLED  1
-#define STATE_ENABLING  2
-#define STATE_ENABLED   3
-#define STATE_DISABLING 4
-#define STATE_ERROR    5
-
-static void rpc_ack(struct msm_rpc_endpoint *ept, uint32_t xid)
-{
-       uint32_t rep[6];
-
-       rep[0] = cpu_to_be32(xid);
-       rep[1] = cpu_to_be32(1);
-       rep[2] = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
-       rep[3] = cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS);
-       rep[4] = 0;
-       rep[5] = 0;
-
-       msm_rpc_write(ept, rep, sizeof(rep));
-}
-
-static void process_audmgr_callback(struct audmgr *am,
-                                  struct rpc_audmgr_cb_func_ptr *args,
-                                  int len)
-{
-       if (len < (sizeof(uint32_t) * 3))
-               return;
-       if (be32_to_cpu(args->set_to_one) != 1)
-               return;
-
-       switch (be32_to_cpu(args->status)) {
-       case RPC_AUDMGR_STATUS_READY:
-               if (len < sizeof(uint32_t) * 4)
-                       break;
-               am->handle = be32_to_cpu(args->u.handle);
-               pr_info("audmgr: rpc READY handle=0x%08x\n", am->handle);
-               break;
-       case RPC_AUDMGR_STATUS_CODEC_CONFIG: {
-               uint32_t volume;
-               if (len < sizeof(uint32_t) * 4)
-                       break;
-               volume = be32_to_cpu(args->u.volume);
-               pr_info("audmgr: rpc CODEC_CONFIG volume=0x%08x\n", volume);
-               am->state = STATE_ENABLED;
-               wake_up(&am->wait);
-               break;
-       }
-       case RPC_AUDMGR_STATUS_PENDING:
-               pr_err("audmgr: PENDING?\n");
-               break;
-       case RPC_AUDMGR_STATUS_SUSPEND:
-               pr_err("audmgr: SUSPEND?\n");
-               break;
-       case RPC_AUDMGR_STATUS_FAILURE:
-               pr_err("audmgr: FAILURE\n");
-               break;
-       case RPC_AUDMGR_STATUS_VOLUME_CHANGE:
-               pr_err("audmgr: VOLUME_CHANGE?\n");
-               break;
-       case RPC_AUDMGR_STATUS_DISABLED:
-               pr_err("audmgr: DISABLED\n");
-               am->state = STATE_DISABLED;
-               wake_up(&am->wait);
-               break;
-       case RPC_AUDMGR_STATUS_ERROR:
-               pr_err("audmgr: ERROR?\n");
-               am->state = STATE_ERROR;
-               wake_up(&am->wait);
-               break;
-       default:
-               break;
-       }
-}
-
-static void process_rpc_request(uint32_t proc, uint32_t xid,
-                               void *data, int len, void *private)
-{
-       struct audmgr *am = private;
-       uint32_t *x = data;
-
-       if (0) {
-               int n = len / 4;
-               pr_info("rpc_call proc %d:", proc);
-               while (n--)
-                       printk(" %08x", be32_to_cpu(*x++));
-               printk("\n");
-       }
-
-       if (proc == AUDMGR_CB_FUNC_PTR)
-               process_audmgr_callback(am, data, len);
-       else
-               pr_err("audmgr: unknown rpc proc %d\n", proc);
-       rpc_ack(am->ept, xid);
-}
-
-#define RPC_TYPE_REQUEST 0
-#define RPC_TYPE_REPLY 1
-
-#define RPC_VERSION 2
-
-#define RPC_COMMON_HDR_SZ  (sizeof(uint32_t) * 2)
-#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr))
-#define RPC_REPLY_HDR_SZ   (sizeof(uint32_t) * 3)
-#define RPC_REPLY_SZ       (sizeof(uint32_t) * 6)
-
-static int audmgr_rpc_thread(void *data)
-{
-       struct audmgr *am = data;
-       struct rpc_request_hdr *hdr = NULL;
-       uint32_t type;
-       int len;
-
-       pr_info("audmgr_rpc_thread() start\n");
-
-       while (!kthread_should_stop()) {
-               if (hdr) {
-                       kfree(hdr);
-                       hdr = NULL;
-               }
-               len = msm_rpc_read(am->ept, (void **) &hdr, -1, -1);
-               if (len < 0) {
-                       pr_err("audmgr: rpc read failed (%d)\n", len);
-                       break;
-               }
-               if (len < RPC_COMMON_HDR_SZ)
-                       continue;
-
-               type = be32_to_cpu(hdr->type);
-               if (type == RPC_TYPE_REPLY) {
-                       struct rpc_reply_hdr *rep = (void *) hdr;
-                       uint32_t status;
-                       if (len < RPC_REPLY_HDR_SZ)
-                               continue;
-                       status = be32_to_cpu(rep->reply_stat);
-                       if (status == RPCMSG_REPLYSTAT_ACCEPTED) {
-                               status = be32_to_cpu(rep->data.acc_hdr.accept_stat);
-                               pr_info("audmgr: rpc_reply status %d\n", status);
-                       } else {
-                               pr_info("audmgr: rpc_reply denied!\n");
-                       }
-                       /* process reply */
-                       continue;
-               }
-
-               if (len < RPC_REQUEST_HDR_SZ)
-                       continue;
-
-               process_rpc_request(be32_to_cpu(hdr->procedure),
-                                   be32_to_cpu(hdr->xid),
-                                   (void *) (hdr + 1),
-                                   len - sizeof(*hdr),
-                                   data);
-       }
-       pr_info("audmgr_rpc_thread() exit\n");
-       if (hdr) {
-               kfree(hdr);
-               hdr = NULL;
-       }
-       am->task = NULL;
-       wake_up(&am->wait);
-       return 0;
-}
-
-struct audmgr_enable_msg {
-       struct rpc_request_hdr hdr;
-       struct rpc_audmgr_enable_client_args args;
-};
-
-struct audmgr_disable_msg {
-       struct rpc_request_hdr hdr;
-       uint32_t handle;
-};
-
-int audmgr_open(struct audmgr *am)
-{
-       int rc;
-
-       if (am->state != STATE_CLOSED)
-               return 0;
-
-       am->ept = msm_rpc_connect(AUDMGR_PROG,
-                               AUDMGR_VERS,
-                               MSM_RPC_UNINTERRUPTIBLE);
-
-       init_waitqueue_head(&am->wait);
-
-       if (IS_ERR(am->ept)) {
-               rc = PTR_ERR(am->ept);
-               am->ept = NULL;
-               pr_err("audmgr: failed to connect to audmgr svc\n");
-               return rc;
-       }
-
-       am->task = kthread_run(audmgr_rpc_thread, am, "audmgr_rpc");
-       if (IS_ERR(am->task)) {
-               rc = PTR_ERR(am->task);
-               am->task = NULL;
-               msm_rpc_close(am->ept);
-               am->ept = NULL;
-               return rc;
-       }
-
-       am->state = STATE_DISABLED;
-       return 0;
-}
-EXPORT_SYMBOL(audmgr_open);
-
-int audmgr_close(struct audmgr *am)
-{
-       return -EBUSY;
-}
-EXPORT_SYMBOL(audmgr_close);
-
-int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg)
-{
-       struct audmgr_enable_msg msg;
-       int rc;
-
-       if (am->state == STATE_ENABLED)
-               return 0;
-
-       if (am->state == STATE_DISABLING)
-               pr_err("audmgr: state is DISABLING in enable?\n");
-       am->state = STATE_ENABLING;
-
-       msg.args.set_to_one = cpu_to_be32(1);
-       msg.args.tx_sample_rate = cpu_to_be32(cfg->tx_rate);
-       msg.args.rx_sample_rate = cpu_to_be32(cfg->rx_rate);
-       msg.args.def_method = cpu_to_be32(cfg->def_method);
-       msg.args.codec_type = cpu_to_be32(cfg->codec);
-       msg.args.snd_method = cpu_to_be32(cfg->snd_method);
-       msg.args.cb_func = cpu_to_be32(0x11111111);
-       msg.args.client_data = cpu_to_be32(0x11223344);
-
-       msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept),
-                         AUDMGR_ENABLE_CLIENT);
-
-       rc = msm_rpc_write(am->ept, &msg, sizeof(msg));
-       if (rc < 0)
-               return rc;
-
-       rc = wait_event_timeout(am->wait, am->state != STATE_ENABLING, 15 * HZ);
-       if (rc == 0) {
-               pr_err("audmgr_enable: ARM9 did not reply to RPC am->state = %d\n", am->state);
-               BUG();
-       }
-       if (am->state == STATE_ENABLED)
-               return 0;
-
-       pr_err("audmgr: unexpected state %d while enabling?!\n", am->state);
-       return -ENODEV;
-}
-EXPORT_SYMBOL(audmgr_enable);
-
-int audmgr_disable(struct audmgr *am)
-{
-       struct audmgr_disable_msg msg;
-       int rc;
-
-       if (am->state == STATE_DISABLED)
-               return 0;
-
-       msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept),
-                         AUDMGR_DISABLE_CLIENT);
-       msg.handle = cpu_to_be32(am->handle);
-
-       am->state = STATE_DISABLING;
-
-       rc = msm_rpc_write(am->ept, &msg, sizeof(msg));
-       if (rc < 0)
-               return rc;
-
-       rc = wait_event_timeout(am->wait, am->state != STATE_DISABLING, 15 * HZ);
-       if (rc == 0) {
-               pr_err("audmgr_disable: ARM9 did not reply to RPC am->state = %d\n", am->state);
-               BUG();
-       }
-
-       if (am->state == STATE_DISABLED)
-               return 0;
-
-       pr_err("audmgr: unexpected state %d while disabling?!\n", am->state);
-       return -ENODEV;
-}
-EXPORT_SYMBOL(audmgr_disable);
diff --git a/drivers/staging/dream/qdsp5/audmgr.h b/drivers/staging/dream/qdsp5/audmgr.h
deleted file mode 100644 (file)
index c07c36b..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/audmgr.h
- *
- * Copyright 2008 (c) QUALCOMM Incorporated.
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _ARCH_ARM_MACH_MSM_AUDMGR_H
-#define _ARCH_ARM_MACH_MSM_AUDMGR_H
-
-#if CONFIG_MSM_AMSS_VERSION==6350
-#include "audmgr_new.h"
-#else
-
-enum rpc_aud_def_sample_rate_type {
-       RPC_AUD_DEF_SAMPLE_RATE_NONE,
-       RPC_AUD_DEF_SAMPLE_RATE_8000,
-       RPC_AUD_DEF_SAMPLE_RATE_11025,
-       RPC_AUD_DEF_SAMPLE_RATE_12000,
-       RPC_AUD_DEF_SAMPLE_RATE_16000,
-       RPC_AUD_DEF_SAMPLE_RATE_22050,
-       RPC_AUD_DEF_SAMPLE_RATE_24000,
-       RPC_AUD_DEF_SAMPLE_RATE_32000,
-       RPC_AUD_DEF_SAMPLE_RATE_44100,
-       RPC_AUD_DEF_SAMPLE_RATE_48000,
-       RPC_AUD_DEF_SAMPLE_RATE_MAX,
-};
-
-enum rpc_aud_def_method_type {
-       RPC_AUD_DEF_METHOD_NONE,
-       RPC_AUD_DEF_METHOD_KEY_BEEP,
-       RPC_AUD_DEF_METHOD_PLAYBACK,
-       RPC_AUD_DEF_METHOD_VOICE,
-       RPC_AUD_DEF_METHOD_RECORD,
-       RPC_AUD_DEF_METHOD_HOST_PCM,
-       RPC_AUD_DEF_METHOD_MIDI_OUT,
-       RPC_AUD_DEF_METHOD_RECORD_SBC,
-       RPC_AUD_DEF_METHOD_DTMF_RINGER,
-       RPC_AUD_DEF_METHOD_MAX,
-};
-
-enum rpc_aud_def_codec_type {
-       RPC_AUD_DEF_CODEC_NONE,
-       RPC_AUD_DEF_CODEC_DTMF,
-       RPC_AUD_DEF_CODEC_MIDI,
-       RPC_AUD_DEF_CODEC_MP3,
-       RPC_AUD_DEF_CODEC_PCM,
-       RPC_AUD_DEF_CODEC_AAC,
-       RPC_AUD_DEF_CODEC_WMA,
-       RPC_AUD_DEF_CODEC_RA,
-       RPC_AUD_DEF_CODEC_ADPCM,
-       RPC_AUD_DEF_CODEC_GAUDIO,
-       RPC_AUD_DEF_CODEC_VOC_EVRC,
-       RPC_AUD_DEF_CODEC_VOC_13K,
-       RPC_AUD_DEF_CODEC_VOC_4GV_NB,
-       RPC_AUD_DEF_CODEC_VOC_AMR,
-       RPC_AUD_DEF_CODEC_VOC_EFR,
-       RPC_AUD_DEF_CODEC_VOC_FR,
-       RPC_AUD_DEF_CODEC_VOC_HR,
-       RPC_AUD_DEF_CODEC_VOC,
-       RPC_AUD_DEF_CODEC_SBC,
-       RPC_AUD_DEF_CODEC_VOC_PCM,
-       RPC_AUD_DEF_CODEC_AMR_WB,
-       RPC_AUD_DEF_CODEC_AMR_WB_PLUS,
-       RPC_AUD_DEF_CODEC_MAX,
-};
-
-enum rpc_snd_method_type {
-       RPC_SND_METHOD_VOICE = 0,
-       RPC_SND_METHOD_KEY_BEEP,
-       RPC_SND_METHOD_MESSAGE,
-       RPC_SND_METHOD_RING,
-       RPC_SND_METHOD_MIDI,
-       RPC_SND_METHOD_AUX,
-       RPC_SND_METHOD_MAX,
-};
-
-enum rpc_voc_codec_type {
-       RPC_VOC_CODEC_DEFAULT,
-       RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT,
-       RPC_VOC_CODEC_ON_CHIP_1,
-       RPC_VOC_CODEC_STEREO_HEADSET,
-       RPC_VOC_CODEC_ON_CHIP_AUX,
-       RPC_VOC_CODEC_BT_OFF_BOARD,
-       RPC_VOC_CODEC_BT_A2DP,
-       RPC_VOC_CODEC_OFF_BOARD,
-       RPC_VOC_CODEC_SDAC,
-       RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL,
-       RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET,
-       RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET,
-       RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM,
-       RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET,
-       RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET,
-       RPC_VOC_CODEC_TTY_ON_CHIP_1,
-       RPC_VOC_CODEC_TTY_OFF_BOARD,
-       RPC_VOC_CODEC_TTY_VCO,
-       RPC_VOC_CODEC_TTY_HCO,
-       RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC,
-       RPC_VOC_CODEC_MAX,
-       RPC_VOC_CODEC_NONE,
-};
-
-enum rpc_audmgr_status_type {
-       RPC_AUDMGR_STATUS_READY,
-       RPC_AUDMGR_STATUS_CODEC_CONFIG,
-       RPC_AUDMGR_STATUS_PENDING,
-       RPC_AUDMGR_STATUS_SUSPEND,
-       RPC_AUDMGR_STATUS_FAILURE,
-       RPC_AUDMGR_STATUS_VOLUME_CHANGE,
-       RPC_AUDMGR_STATUS_DISABLED,
-       RPC_AUDMGR_STATUS_ERROR,
-};
-
-struct rpc_audmgr_enable_client_args {
-       uint32_t set_to_one;
-       uint32_t tx_sample_rate;
-       uint32_t rx_sample_rate;
-       uint32_t def_method;
-       uint32_t codec_type;
-       uint32_t snd_method;
-
-       uint32_t cb_func;
-       uint32_t client_data;
-};
-
-#define AUDMGR_ENABLE_CLIENT                   2
-#define AUDMGR_DISABLE_CLIENT                  3
-#define AUDMGR_SUSPEND_EVENT_RSP               4
-#define AUDMGR_REGISTER_OPERATION_LISTENER     5
-#define AUDMGR_UNREGISTER_OPERATION_LISTENER   6
-#define AUDMGR_REGISTER_CODEC_LISTENER         7
-#define AUDMGR_GET_RX_SAMPLE_RATE              8
-#define AUDMGR_GET_TX_SAMPLE_RATE              9
-#define AUDMGR_SET_DEVICE_MODE                 10
-
-#if CONFIG_MSM_AMSS_VERSION < 6220
-#define AUDMGR_PROG_VERS "rs30000013:46255756"
-#define AUDMGR_PROG 0x30000013
-#define AUDMGR_VERS 0x46255756
-#else
-#define AUDMGR_PROG_VERS "rs30000013:e94e8f0c"
-#define AUDMGR_PROG 0x30000013
-#define AUDMGR_VERS 0xe94e8f0c
-#endif
-
-struct rpc_audmgr_cb_func_ptr {
-       uint32_t cb_id;
-       uint32_t set_to_one;
-       uint32_t status;
-       union {
-               uint32_t handle;
-               uint32_t volume;
-
-       } u;
-};
-
-#define AUDMGR_CB_FUNC_PTR                     1
-#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR           2
-#define AUDMGR_CODEC_LSTR_FUNC_PTR             3
-
-#if CONFIG_MSM_AMSS_VERSION < 6220
-#define AUDMGR_CB_PROG 0x31000013
-#define AUDMGR_CB_VERS 0x5fa922a9
-#else
-#define AUDMGR_CB_PROG 0x31000013
-#define AUDMGR_CB_VERS 0x21570ba7
-#endif
-
-struct audmgr {
-       wait_queue_head_t wait;
-       uint32_t handle;
-       struct msm_rpc_endpoint *ept;
-       struct task_struct *task;
-       int state;
-};
-
-struct audmgr_config {
-       uint32_t tx_rate;
-       uint32_t rx_rate;
-       uint32_t def_method;
-       uint32_t codec;
-       uint32_t snd_method;
-};
-
-int audmgr_open(struct audmgr *am);
-int audmgr_close(struct audmgr *am);
-int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
-int audmgr_disable(struct audmgr *am);
-
-typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
-
-int audpp_enable(int id, audpp_event_func func, void *private);
-void audpp_disable(int id, void *private);
-
-int audpp_send_queue1(void *cmd, unsigned len);
-int audpp_send_queue2(void *cmd, unsigned len);
-int audpp_send_queue3(void *cmd, unsigned len);
-
-int audpp_pause(unsigned id, int pause);
-int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
-void audpp_avsync(int id, unsigned rate);
-unsigned audpp_avsync_sample_count(int id);
-unsigned audpp_avsync_byte_count(int id);
-
-#endif
-#endif
diff --git a/drivers/staging/dream/qdsp5/audmgr_new.h b/drivers/staging/dream/qdsp5/audmgr_new.h
deleted file mode 100644 (file)
index 49670fe..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/audmgr.h
- *
- * Copyright 2008 (c) QUALCOMM Incorporated.
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H
-#define _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H
-
-enum rpc_aud_def_sample_rate_type {
-       RPC_AUD_DEF_SAMPLE_RATE_NONE,
-       RPC_AUD_DEF_SAMPLE_RATE_8000,
-       RPC_AUD_DEF_SAMPLE_RATE_11025,
-       RPC_AUD_DEF_SAMPLE_RATE_12000,
-       RPC_AUD_DEF_SAMPLE_RATE_16000,
-       RPC_AUD_DEF_SAMPLE_RATE_22050,
-       RPC_AUD_DEF_SAMPLE_RATE_24000,
-       RPC_AUD_DEF_SAMPLE_RATE_32000,
-       RPC_AUD_DEF_SAMPLE_RATE_44100,
-       RPC_AUD_DEF_SAMPLE_RATE_48000,
-       RPC_AUD_DEF_SAMPLE_RATE_MAX,
-};
-
-enum rpc_aud_def_method_type {
-       RPC_AUD_DEF_METHOD_NONE,
-       RPC_AUD_DEF_METHOD_KEY_BEEP,
-       RPC_AUD_DEF_METHOD_PLAYBACK,
-       RPC_AUD_DEF_METHOD_VOICE,
-       RPC_AUD_DEF_METHOD_RECORD,
-       RPC_AUD_DEF_METHOD_HOST_PCM,
-       RPC_AUD_DEF_METHOD_MIDI_OUT,
-       RPC_AUD_DEF_METHOD_RECORD_SBC,
-       RPC_AUD_DEF_METHOD_DTMF_RINGER,
-       RPC_AUD_DEF_METHOD_MAX,
-};
-
-enum rpc_aud_def_codec_type {
-       RPC_AUD_DEF_CODEC_NONE,
-       RPC_AUD_DEF_CODEC_DTMF,
-       RPC_AUD_DEF_CODEC_MIDI,
-       RPC_AUD_DEF_CODEC_MP3,
-       RPC_AUD_DEF_CODEC_PCM,
-       RPC_AUD_DEF_CODEC_AAC,
-       RPC_AUD_DEF_CODEC_WMA,
-       RPC_AUD_DEF_CODEC_RA,
-       RPC_AUD_DEF_CODEC_ADPCM,
-       RPC_AUD_DEF_CODEC_GAUDIO,
-       RPC_AUD_DEF_CODEC_VOC_EVRC,
-       RPC_AUD_DEF_CODEC_VOC_13K,
-       RPC_AUD_DEF_CODEC_VOC_4GV_NB,
-       RPC_AUD_DEF_CODEC_VOC_AMR,
-       RPC_AUD_DEF_CODEC_VOC_EFR,
-       RPC_AUD_DEF_CODEC_VOC_FR,
-       RPC_AUD_DEF_CODEC_VOC_HR,
-       RPC_AUD_DEF_CODEC_VOC_CDMA,
-       RPC_AUD_DEF_CODEC_VOC_CDMA_WB,
-       RPC_AUD_DEF_CODEC_VOC_UMTS,
-       RPC_AUD_DEF_CODEC_VOC_UMTS_WB,
-       RPC_AUD_DEF_CODEC_SBC,
-       RPC_AUD_DEF_CODEC_VOC_PCM,
-       RPC_AUD_DEF_CODEC_AMR_WB,
-       RPC_AUD_DEF_CODEC_AMR_WB_PLUS,
-       RPC_AUD_DEF_CODEC_AAC_BSAC,
-       RPC_AUD_DEF_CODEC_MAX,
-       RPC_AUD_DEF_CODEC_AMR_NB,
-       RPC_AUD_DEF_CODEC_13K,
-       RPC_AUD_DEF_CODEC_EVRC,
-       RPC_AUD_DEF_CODEC_MAX_002,
-};
-
-enum rpc_snd_method_type {
-       RPC_SND_METHOD_VOICE = 0,
-       RPC_SND_METHOD_KEY_BEEP,
-       RPC_SND_METHOD_MESSAGE,
-       RPC_SND_METHOD_RING,
-       RPC_SND_METHOD_MIDI,
-       RPC_SND_METHOD_AUX,
-       RPC_SND_METHOD_MAX,
-};
-
-enum rpc_voc_codec_type {
-       RPC_VOC_CODEC_DEFAULT,
-       RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT,
-       RPC_VOC_CODEC_ON_CHIP_1,
-       RPC_VOC_CODEC_STEREO_HEADSET,
-       RPC_VOC_CODEC_ON_CHIP_AUX,
-       RPC_VOC_CODEC_BT_OFF_BOARD,
-       RPC_VOC_CODEC_BT_A2DP,
-       RPC_VOC_CODEC_OFF_BOARD,
-       RPC_VOC_CODEC_SDAC,
-       RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL,
-       RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET,
-       RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET,
-       RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM,
-       RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET,
-       RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET,
-       RPC_VOC_CODEC_TTY_ON_CHIP_1,
-       RPC_VOC_CODEC_TTY_OFF_BOARD,
-       RPC_VOC_CODEC_TTY_VCO,
-       RPC_VOC_CODEC_TTY_HCO,
-       RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC,
-       RPC_VOC_CODEC_MAX,
-       RPC_VOC_CODEC_NONE,
-};
-
-enum rpc_audmgr_status_type {
-       RPC_AUDMGR_STATUS_READY,
-       RPC_AUDMGR_STATUS_CODEC_CONFIG,
-       RPC_AUDMGR_STATUS_PENDING,
-       RPC_AUDMGR_STATUS_SUSPEND,
-       RPC_AUDMGR_STATUS_FAILURE,
-       RPC_AUDMGR_STATUS_VOLUME_CHANGE,
-       RPC_AUDMGR_STATUS_DISABLED,
-       RPC_AUDMGR_STATUS_ERROR,
-};
-
-struct rpc_audmgr_enable_client_args {
-       uint32_t set_to_one;
-       uint32_t tx_sample_rate;
-       uint32_t rx_sample_rate;
-       uint32_t def_method;
-       uint32_t codec_type;
-       uint32_t snd_method;
-
-       uint32_t cb_func;
-       uint32_t client_data;
-};
-
-#define AUDMGR_ENABLE_CLIENT                   2
-#define AUDMGR_DISABLE_CLIENT                  3
-#define AUDMGR_SUSPEND_EVENT_RSP               4
-#define AUDMGR_REGISTER_OPERATION_LISTENER     5
-#define AUDMGR_UNREGISTER_OPERATION_LISTENER   6
-#define AUDMGR_REGISTER_CODEC_LISTENER         7
-#define AUDMGR_GET_RX_SAMPLE_RATE              8
-#define AUDMGR_GET_TX_SAMPLE_RATE              9
-#define AUDMGR_SET_DEVICE_MODE                 10
-
-#define AUDMGR_PROG 0x30000013
-#define AUDMGR_VERS MSM_RPC_VERS(1,0)
-
-struct rpc_audmgr_cb_func_ptr {
-       uint32_t cb_id;
-       uint32_t status; /* Audmgr status */
-       uint32_t set_to_one;  /* Pointer status (1 = valid, 0  = invalid) */
-       uint32_t disc;
-       /* disc = AUDMGR_STATUS_READY => data=handle
-          disc = AUDMGR_STATUS_CODEC_CONFIG => data = handle
-          disc = AUDMGR_STATUS_DISABLED => data =status_disabled
-          disc = AUDMGR_STATUS_VOLUME_CHANGE => data = volume-change */
-       union {
-               uint32_t handle;
-               uint32_t volume;
-               uint32_t status_disabled;
-               uint32_t volume_change;
-       } u;
-};
-
-#define AUDMGR_CB_FUNC_PTR                     1
-#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR           2
-#define AUDMGR_CODEC_LSTR_FUNC_PTR             3
-
-#define AUDMGR_CB_PROG 0x31000013
-#define AUDMGR_CB_VERS 0xf8e3e2d9
-
-struct audmgr {
-       wait_queue_head_t wait;
-       uint32_t handle;
-       struct msm_rpc_endpoint *ept;
-       struct task_struct *task;
-       int state;
-};
-
-struct audmgr_config {
-       uint32_t tx_rate;
-       uint32_t rx_rate;
-       uint32_t def_method;
-       uint32_t codec;
-       uint32_t snd_method;
-};
-
-int audmgr_open(struct audmgr *am);
-int audmgr_close(struct audmgr *am);
-int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
-int audmgr_disable(struct audmgr *am);
-
-typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
-
-int audpp_enable(int id, audpp_event_func func, void *private);
-void audpp_disable(int id, void *private);
-
-int audpp_send_queue1(void *cmd, unsigned len);
-int audpp_send_queue2(void *cmd, unsigned len);
-int audpp_send_queue3(void *cmd, unsigned len);
-
-int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
-int audpp_pause(unsigned id, int pause);
-int audpp_flush(unsigned id);
-void audpp_avsync(int id, unsigned rate);
-unsigned audpp_avsync_sample_count(int id);
-unsigned audpp_avsync_byte_count(int id);
-
-#endif
diff --git a/drivers/staging/dream/qdsp5/audpp.c b/drivers/staging/dream/qdsp5/audpp.c
deleted file mode 100644 (file)
index d06556e..0000000
+++ /dev/null
@@ -1,429 +0,0 @@
-
-/* arch/arm/mach-msm/qdsp5/audpp.c
- *
- * common code to deal with the AUDPP dsp task (audio postproc)
- *
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-
-#include <asm/atomic.h>
-#include <asm/ioctls.h>
-#include <mach/msm_adsp.h>
-
-#include "audmgr.h"
-
-#include <mach/qdsp5/qdsp5audppcmdi.h>
-#include <mach/qdsp5/qdsp5audppmsg.h>
-
-/* for queue ids - should be relative to module number*/
-#include "adsp.h"
-
-#include "evlog.h"
-
-
-enum {
-       EV_NULL,
-       EV_ENABLE,
-       EV_DISABLE,
-       EV_EVENT,
-       EV_DATA,
-};
-
-static const char *dsp_log_strings[] = {
-       "NULL",
-       "ENABLE",
-       "DISABLE",
-       "EVENT",
-       "DATA",
-};
-
-DECLARE_LOG(dsp_log, 64, dsp_log_strings);
-
-static int __init _dsp_log_init(void)
-{
-       return ev_log_init(&dsp_log);
-}
-module_init(_dsp_log_init);
-#define LOG(id,arg) ev_log_write(&dsp_log, id, arg)
-
-static DEFINE_MUTEX(audpp_lock);
-
-#define CH_COUNT 5
-#define AUDPP_CLNT_MAX_COUNT 6
-#define AUDPP_AVSYNC_INFO_SIZE 7
-
-struct audpp_state {
-       struct msm_adsp_module *mod;
-       audpp_event_func func[AUDPP_CLNT_MAX_COUNT];
-       void *private[AUDPP_CLNT_MAX_COUNT];
-       struct mutex *lock;
-       unsigned open_count;
-       unsigned enabled;
-
-       /* which channels are actually enabled */
-       unsigned avsync_mask;
-
-       /* flags, 48 bits sample/bytes counter per channel */
-       uint16_t avsync[CH_COUNT * AUDPP_CLNT_MAX_COUNT + 1];
-};
-
-struct audpp_state the_audpp_state = {
-       .lock = &audpp_lock,
-};
-
-int audpp_send_queue1(void *cmd, unsigned len)
-{
-       return msm_adsp_write(the_audpp_state.mod,
-                             QDSP_uPAudPPCmd1Queue, cmd, len);
-}
-EXPORT_SYMBOL(audpp_send_queue1);
-
-int audpp_send_queue2(void *cmd, unsigned len)
-{
-       return msm_adsp_write(the_audpp_state.mod,
-                             QDSP_uPAudPPCmd2Queue, cmd, len);
-}
-EXPORT_SYMBOL(audpp_send_queue2);
-
-int audpp_send_queue3(void *cmd, unsigned len)
-{
-       return msm_adsp_write(the_audpp_state.mod,
-                             QDSP_uPAudPPCmd3Queue, cmd, len);
-}
-EXPORT_SYMBOL(audpp_send_queue3);
-
-static int audpp_dsp_config(int enable)
-{
-       audpp_cmd_cfg cmd;
-
-       cmd.cmd_id = AUDPP_CMD_CFG;
-       cmd.cfg = enable ? AUDPP_CMD_CFG_ENABLE : AUDPP_CMD_CFG_SLEEP;
-
-       return audpp_send_queue1(&cmd, sizeof(cmd));
-}
-
-static void audpp_broadcast(struct audpp_state *audpp, unsigned id,
-                           uint16_t *msg)
-{
-       unsigned n;
-       for (n = 0; n < AUDPP_CLNT_MAX_COUNT; n++) {
-               if (audpp->func[n])
-                       audpp->func[n] (audpp->private[n], id, msg);
-       }
-}
-
-static void audpp_notify_clnt(struct audpp_state *audpp, unsigned clnt_id,
-                             unsigned id, uint16_t *msg)
-{
-       if (clnt_id < AUDPP_CLNT_MAX_COUNT && audpp->func[clnt_id])
-               audpp->func[clnt_id] (audpp->private[clnt_id], id, msg);
-}
-
-static void audpp_dsp_event(void *data, unsigned id, size_t len,
-                           void (*getevent)(void *ptr, size_t len))
-{
-       struct audpp_state *audpp = data;
-       uint16_t msg[8];
-
-       if (id == AUDPP_MSG_AVSYNC_MSG) {
-               getevent(audpp->avsync, sizeof(audpp->avsync));
-
-               /* mask off any channels we're not watching to avoid
-                * cases where we might get one last update after
-                * disabling avsync and end up in an odd state when
-                * we next read...
-                */
-               audpp->avsync[0] &= audpp->avsync_mask;
-               return;
-       }
-
-       getevent(msg, sizeof(msg));
-
-       LOG(EV_EVENT, (id << 16) | msg[0]);
-       LOG(EV_DATA, (msg[1] << 16) | msg[2]);
-
-       switch (id) {
-       case AUDPP_MSG_STATUS_MSG:{
-                       unsigned cid = msg[0];
-                       pr_info("audpp: status %d %d %d\n", cid, msg[1],
-                               msg[2]);
-                       if ((cid < 5) && audpp->func[cid])
-                               audpp->func[cid] (audpp->private[cid], id, msg);
-                       break;
-               }
-       case AUDPP_MSG_HOST_PCM_INTF_MSG:
-               if (audpp->func[5])
-                       audpp->func[5] (audpp->private[5], id, msg);
-               break;
-       case AUDPP_MSG_PCMDMAMISSED:
-               pr_err("audpp: DMA missed obj=%x\n", msg[0]);
-               break;
-       case AUDPP_MSG_CFG_MSG:
-               if (msg[0] == AUDPP_MSG_ENA_ENA) {
-                       pr_info("audpp: ENABLE\n");
-                       audpp->enabled = 1;
-                       audpp_broadcast(audpp, id, msg);
-               } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
-                       pr_info("audpp: DISABLE\n");
-                       audpp->enabled = 0;
-                       audpp_broadcast(audpp, id, msg);
-               } else {
-                       pr_err("audpp: invalid config msg %d\n", msg[0]);
-               }
-               break;
-       case AUDPP_MSG_ROUTING_ACK:
-               audpp_broadcast(audpp, id, msg);
-               break;
-       case AUDPP_MSG_FLUSH_ACK:
-               audpp_notify_clnt(audpp, msg[0], id, msg);
-               break;
-       default:
-         pr_info("audpp: unhandled msg id %x\n", id);
-       }
-}
-
-static struct msm_adsp_ops adsp_ops = {
-       .event = audpp_dsp_event,
-};
-
-static void audpp_fake_event(struct audpp_state *audpp, int id,
-                            unsigned event, unsigned arg)
-{
-       uint16_t msg[1];
-       msg[0] = arg;
-       audpp->func[id] (audpp->private[id], event, msg);
-}
-
-int audpp_enable(int id, audpp_event_func func, void *private)
-{
-       struct audpp_state *audpp = &the_audpp_state;
-       int res = 0;
-
-       if (id < -1 || id > 4)
-               return -EINVAL;
-
-       if (id == -1)
-               id = 5;
-
-       mutex_lock(audpp->lock);
-       if (audpp->func[id]) {
-               res = -EBUSY;
-               goto out;
-       }
-
-       audpp->func[id] = func;
-       audpp->private[id] = private;
-
-       LOG(EV_ENABLE, 1);
-       if (audpp->open_count++ == 0) {
-               pr_info("audpp: enable\n");
-               res = msm_adsp_get("AUDPPTASK", &audpp->mod, &adsp_ops, audpp);
-               if (res < 0) {
-                       pr_err("audpp: cannot open AUDPPTASK\n");
-                       audpp->open_count = 0;
-                       audpp->func[id] = NULL;
-                       audpp->private[id] = NULL;
-                       goto out;
-               }
-               LOG(EV_ENABLE, 2);
-               msm_adsp_enable(audpp->mod);
-               audpp_dsp_config(1);
-       } else {
-               unsigned long flags;
-               local_irq_save(flags);
-               if (audpp->enabled)
-                       audpp_fake_event(audpp, id,
-                                        AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_ENA);
-               local_irq_restore(flags);
-       }
-
-       res = 0;
-out:
-       mutex_unlock(audpp->lock);
-       return res;
-}
-EXPORT_SYMBOL(audpp_enable);
-
-void audpp_disable(int id, void *private)
-{
-       struct audpp_state *audpp = &the_audpp_state;
-       unsigned long flags;
-
-       if (id < -1 || id > 4)
-               return;
-
-       if (id == -1)
-               id = 5;
-
-       mutex_lock(audpp->lock);
-       LOG(EV_DISABLE, 1);
-       if (!audpp->func[id])
-               goto out;
-       if (audpp->private[id] != private)
-               goto out;
-
-       local_irq_save(flags);
-       audpp_fake_event(audpp, id, AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_DIS);
-       audpp->func[id] = NULL;
-       audpp->private[id] = NULL;
-       local_irq_restore(flags);
-
-       if (--audpp->open_count == 0) {
-               pr_info("audpp: disable\n");
-               LOG(EV_DISABLE, 2);
-               audpp_dsp_config(0);
-               msm_adsp_disable(audpp->mod);
-               msm_adsp_put(audpp->mod);
-               audpp->mod = NULL;
-       }
-out:
-       mutex_unlock(audpp->lock);
-}
-EXPORT_SYMBOL(audpp_disable);
-
-#define BAD_ID(id) ((id < 0) || (id >= CH_COUNT))
-
-void audpp_avsync(int id, unsigned rate)
-{
-       unsigned long flags;
-       audpp_cmd_avsync cmd;
-
-       if (BAD_ID(id))
-               return;
-
-       local_irq_save(flags);
-       if (rate)
-               the_audpp_state.avsync_mask |= (1 << id);
-       else
-               the_audpp_state.avsync_mask &= (~(1 << id));
-       the_audpp_state.avsync[0] &= the_audpp_state.avsync_mask;
-       local_irq_restore(flags);
-
-       cmd.cmd_id = AUDPP_CMD_AVSYNC;
-       cmd.object_number = id;
-       cmd.interrupt_interval_lsw = rate;
-       cmd.interrupt_interval_msw = rate >> 16;
-       audpp_send_queue1(&cmd, sizeof(cmd));
-}
-EXPORT_SYMBOL(audpp_avsync);
-
-unsigned audpp_avsync_sample_count(int id)
-{
-       uint16_t *avsync = the_audpp_state.avsync;
-       unsigned val;
-       unsigned long flags;
-       unsigned mask;
-
-       if (BAD_ID(id))
-               return 0;
-
-       mask = 1 << id;
-       id = id * AUDPP_AVSYNC_INFO_SIZE + 2;
-       local_irq_save(flags);
-       if (avsync[0] & mask)
-               val = (avsync[id] << 16) | avsync[id + 1];
-       else
-               val = 0;
-       local_irq_restore(flags);
-
-       return val;
-}
-EXPORT_SYMBOL(audpp_avsync_sample_count);
-
-unsigned audpp_avsync_byte_count(int id)
-{
-       uint16_t *avsync = the_audpp_state.avsync;
-       unsigned val;
-       unsigned long flags;
-       unsigned mask;
-
-       if (BAD_ID(id))
-               return 0;
-
-       mask = 1 << id;
-       id = id * AUDPP_AVSYNC_INFO_SIZE + 5;
-       local_irq_save(flags);
-       if (avsync[0] & mask)
-               val = (avsync[id] << 16) | avsync[id + 1];
-       else
-               val = 0;
-       local_irq_restore(flags);
-
-       return val;
-}
-EXPORT_SYMBOL(audpp_avsync_byte_count);
-
-#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000
-#define AUDPP_CMD_VOLUME_PAN 0
-
-int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan)
-{
-       /* cmd, obj_cfg[7], cmd_type, volume, pan */
-       uint16_t cmd[11];
-
-       if (id > 6)
-               return -EINVAL;
-
-       memset(cmd, 0, sizeof(cmd));
-       cmd[0] = AUDPP_CMD_CFG_OBJECT_PARAMS;
-       cmd[1 + id] = AUDPP_CMD_CFG_OBJ_UPDATE;
-       cmd[8] = AUDPP_CMD_VOLUME_PAN;
-       cmd[9] = volume;
-       cmd[10] = pan;
-
-       return audpp_send_queue3(cmd, sizeof(cmd));
-}
-EXPORT_SYMBOL(audpp_set_volume_and_pan);
-
-int audpp_pause(unsigned id, int pause)
-{
-       /* pause 1 = pause 0 = resume */
-       u16 pause_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)];
-
-       if (id >= CH_COUNT)
-               return -EINVAL;
-
-       memset(pause_cmd, 0, sizeof(pause_cmd));
-
-       pause_cmd[0] = AUDPP_CMD_DEC_CTRL;
-       if (pause == 1)
-               pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_PAUSE_V;
-       else if (pause == 0)
-               pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_RESUME_V;
-       else
-               return -EINVAL;
-
-       return audpp_send_queue1(pause_cmd, sizeof(pause_cmd));
-}
-EXPORT_SYMBOL(audpp_pause);
-
-int audpp_flush(unsigned id)
-{
-       u16 flush_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)];
-
-       if (id >= CH_COUNT)
-               return -EINVAL;
-
-       memset(flush_cmd, 0, sizeof(flush_cmd));
-
-       flush_cmd[0] = AUDPP_CMD_DEC_CTRL;
-       flush_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_FLUSH_V;
-
-       return audpp_send_queue1(flush_cmd, sizeof(flush_cmd));
-}
-EXPORT_SYMBOL(audpp_flush);
diff --git a/drivers/staging/dream/qdsp5/evlog.h b/drivers/staging/dream/qdsp5/evlog.h
deleted file mode 100644 (file)
index e5ab86b..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/evlog.h
- *
- * simple event log debugging facility
- *
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/fs.h>
-#include <linux/hrtimer.h>
-#include <linux/debugfs.h>
-
-#define EV_LOG_ENTRY_NAME(n) n##_entry
-
-#define DECLARE_LOG(_name, _size, _str) \
-static struct ev_entry EV_LOG_ENTRY_NAME(_name)[_size]; \
-static struct ev_log _name = { \
-       .name = #_name, \
-       .strings = _str, \
-       .num_strings = ARRAY_SIZE(_str), \
-       .entry = EV_LOG_ENTRY_NAME(_name), \
-       .max = ARRAY_SIZE(EV_LOG_ENTRY_NAME(_name)), \
-}
-
-struct ev_entry {
-       ktime_t when;
-       uint32_t id;
-       uint32_t arg;
-};
-
-struct ev_log {
-       struct ev_entry *entry;
-       unsigned max;
-       unsigned next;
-       unsigned fault;
-       const char **strings;
-       unsigned num_strings;
-       const char *name;
-};
-
-static char ev_buf[4096];
-
-static ssize_t ev_log_read(struct file *file, char __user *buf,
-                          size_t count, loff_t *ppos)
-{
-       struct ev_log *log = file->private_data;
-       struct ev_entry *entry;
-       unsigned long flags;
-       int size = 0;
-       unsigned n, id, max;
-       ktime_t now, t;
-
-       max = log->max;
-       now = ktime_get();
-       local_irq_save(flags);
-       n = (log->next - 1) & (max - 1);
-       entry = log->entry;
-       while (n != log->next) {
-               t = ktime_sub(now, entry[n].when);
-               id = entry[n].id;
-               if (id) {
-                       const char *str;
-                       if (id < log->num_strings)
-                               str = log->strings[id];
-                       else
-                               str = "UNKNOWN";
-                       size += scnprintf(ev_buf + size, 4096 - size,
-                                         "%8d.%03d %08x %s\n",
-                                         t.tv.sec, t.tv.nsec / 1000000,
-                                         entry[n].arg, str);
-               }
-               n = (n - 1) & (max - 1);
-       }
-       log->fault = 0;
-       local_irq_restore(flags);
-       return simple_read_from_buffer(buf, count, ppos, ev_buf, size);
-}
-
-static void ev_log_write(struct ev_log *log, unsigned id, unsigned arg)
-{
-       struct ev_entry *entry;
-       unsigned long flags;
-       local_irq_save(flags);
-
-       if (log->fault) {
-               if (log->fault == 1)
-                       goto done;
-               log->fault--;
-       }
-
-       entry = log->entry + log->next;
-       entry->when = ktime_get();
-       entry->id = id;
-       entry->arg = arg;
-       log->next = (log->next + 1) & (log->max - 1);
-done:
-       local_irq_restore(flags);
-}
-
-static void ev_log_freeze(struct ev_log *log, unsigned count)
-{
-       unsigned long flags;
-       local_irq_save(flags);
-       log->fault = count;
-       local_irq_restore(flags);
-}
-
-static int ev_log_open(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-static const struct file_operations ev_log_ops = {
-       .read = ev_log_read,
-       .open = ev_log_open,
-       .llseek = default_llseek,
-};
-
-static int ev_log_init(struct ev_log *log)
-{
-       debugfs_create_file(log->name, 0444, 0, log, &ev_log_ops);
-       return 0;
-}
-
diff --git a/drivers/staging/dream/qdsp5/snd.c b/drivers/staging/dream/qdsp5/snd.c
deleted file mode 100644 (file)
index e0f2f7b..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/* arch/arm/mach-msm/qdsp5/snd.c
- *
- * interface to "snd" service on the baseband cpu
- *
- * Copyright (C) 2008 HTC Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/kthread.h>
-#include <linux/delay.h>
-#include <linux/msm_audio.h>
-
-#include <asm/atomic.h>
-#include <asm/ioctls.h>
-#include <mach/board.h>
-#include <mach/msm_rpcrouter.h>
-
-struct snd_ctxt {
-       struct mutex lock;
-       int opened;
-       struct msm_rpc_endpoint *ept;
-       struct msm_snd_endpoints *snd_epts;
-};
-
-static struct snd_ctxt the_snd;
-
-#define RPC_SND_PROG    0x30000002
-#define RPC_SND_CB_PROG 0x31000002
-#if CONFIG_MSM_AMSS_VERSION == 6210
-#define RPC_SND_VERS   0x94756085 /* 2490720389 */
-#elif (CONFIG_MSM_AMSS_VERSION == 6220) || \
-      (CONFIG_MSM_AMSS_VERSION == 6225)
-#define RPC_SND_VERS   0xaa2b1a44 /* 2854951492 */
-#elif CONFIG_MSM_AMSS_VERSION == 6350
-#define RPC_SND_VERS   MSM_RPC_VERS(1,0)
-#endif
-
-#define SND_SET_DEVICE_PROC 2
-#define SND_SET_VOLUME_PROC 3
-
-struct rpc_snd_set_device_args {
-       uint32_t device;
-       uint32_t ear_mute;
-       uint32_t mic_mute;
-
-       uint32_t cb_func;
-       uint32_t client_data;
-};
-
-struct rpc_snd_set_volume_args {
-       uint32_t device;
-       uint32_t method;
-       uint32_t volume;
-
-       uint32_t cb_func;
-       uint32_t client_data;
-};
-
-struct snd_set_device_msg {
-       struct rpc_request_hdr hdr;
-       struct rpc_snd_set_device_args args;
-};
-
-struct snd_set_volume_msg {
-       struct rpc_request_hdr hdr;
-       struct rpc_snd_set_volume_args args;
-};
-
-struct snd_endpoint *get_snd_endpoints(int *size);
-
-static inline int check_mute(int mute)
-{
-       return (mute == SND_MUTE_MUTED ||
-               mute == SND_MUTE_UNMUTED) ? 0 : -EINVAL;
-}
-
-static int get_endpoint(struct snd_ctxt *snd, unsigned long arg)
-{
-       int rc = 0, index;
-       struct msm_snd_endpoint ept;
-
-       if (copy_from_user(&ept, (void __user *)arg, sizeof(ept))) {
-               pr_err("snd_ioctl get endpoint: invalid read pointer.\n");
-               return -EFAULT;
-       }
-
-       index = ept.id;
-       if (index < 0 || index >= snd->snd_epts->num) {
-               pr_err("snd_ioctl get endpoint: invalid index!\n");
-               return -EINVAL;
-       }
-
-       ept.id = snd->snd_epts->endpoints[index].id;
-       strncpy(ept.name,
-               snd->snd_epts->endpoints[index].name,
-               sizeof(ept.name));
-
-       if (copy_to_user((void __user *)arg, &ept, sizeof(ept))) {
-               pr_err("snd_ioctl get endpoint: invalid write pointer.\n");
-               rc = -EFAULT;
-       }
-
-       return rc;
-}
-
-static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct snd_set_device_msg dmsg;
-       struct snd_set_volume_msg vmsg;
-       struct msm_snd_device_config dev;
-       struct msm_snd_volume_config vol;
-       struct snd_ctxt *snd = file->private_data;
-       int rc = 0;
-
-       mutex_lock(&snd->lock);
-       switch (cmd) {
-       case SND_SET_DEVICE:
-               if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
-                       pr_err("snd_ioctl set device: invalid pointer.\n");
-                       rc = -EFAULT;
-                       break;
-               }
-
-               dmsg.args.device = cpu_to_be32(dev.device);
-               dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
-               dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
-               if (check_mute(dev.ear_mute) < 0 ||
-                               check_mute(dev.mic_mute) < 0) {
-                       pr_err("snd_ioctl set device: invalid mute status.\n");
-                       rc = -EINVAL;
-                       break;
-               }
-               dmsg.args.cb_func = -1;
-               dmsg.args.client_data = 0;
-
-               pr_info("snd_set_device %d %d %d\n", dev.device,
-                                                dev.ear_mute, dev.mic_mute);
-
-               rc = msm_rpc_call(snd->ept,
-                       SND_SET_DEVICE_PROC,
-                       &dmsg, sizeof(dmsg), 5 * HZ);
-               break;
-
-       case SND_SET_VOLUME:
-               if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
-                       pr_err("snd_ioctl set volume: invalid pointer.\n");
-                       rc = -EFAULT;
-                       break;
-               }
-
-               vmsg.args.device = cpu_to_be32(vol.device);
-               vmsg.args.method = cpu_to_be32(vol.method);
-               if (vol.method != SND_METHOD_VOICE) {
-                       pr_err("snd_ioctl set volume: invalid method.\n");
-                       rc = -EINVAL;
-                       break;
-               }
-
-               vmsg.args.volume = cpu_to_be32(vol.volume);
-               vmsg.args.cb_func = -1;
-               vmsg.args.client_data = 0;
-
-               pr_info("snd_set_volume %d %d %d\n", vol.device,
-                                               vol.method, vol.volume);
-
-               rc = msm_rpc_call(snd->ept,
-                       SND_SET_VOLUME_PROC,
-                       &vmsg, sizeof(vmsg), 5 * HZ);
-               break;
-
-       case SND_GET_NUM_ENDPOINTS:
-               if (copy_to_user((void __user *)arg,
-                               &snd->snd_epts->num, sizeof(unsigned))) {
-                       pr_err("snd_ioctl get endpoint: invalid pointer.\n");
-                       rc = -EFAULT;
-               }
-               break;
-
-       case SND_GET_ENDPOINT:
-               rc = get_endpoint(snd, arg);
-               break;
-
-       default:
-               pr_err("snd_ioctl unknown command.\n");
-               rc = -EINVAL;
-               break;
-       }
-       mutex_unlock(&snd->lock);
-
-       return rc;
-}
-
-static int snd_release(struct inode *inode, struct file *file)
-{
-       struct snd_ctxt *snd = file->private_data;
-
-       mutex_lock(&snd->lock);
-       snd->opened = 0;
-       mutex_unlock(&snd->lock);
-       return 0;
-}
-
-static int snd_open(struct inode *inode, struct file *file)
-{
-       struct snd_ctxt *snd = &the_snd;
-       int rc = 0;
-
-       mutex_lock(&snd->lock);
-       if (snd->opened == 0) {
-               if (snd->ept == NULL) {
-                       snd->ept = msm_rpc_connect(RPC_SND_PROG, RPC_SND_VERS,
-                                       MSM_RPC_UNINTERRUPTIBLE);
-                       if (IS_ERR(snd->ept)) {
-                               rc = PTR_ERR(snd->ept);
-                               snd->ept = NULL;
-                               pr_err("snd: failed to connect snd svc\n");
-                               goto err;
-                       }
-               }
-               file->private_data = snd;
-               snd->opened = 1;
-       } else {
-               pr_err("snd already opened.\n");
-               rc = -EBUSY;
-       }
-
-err:
-       mutex_unlock(&snd->lock);
-       return rc;
-}
-
-static struct file_operations snd_fops = {
-       .owner          = THIS_MODULE,
-       .open           = snd_open,
-       .release        = snd_release,
-       .unlocked_ioctl = snd_ioctl,
-       .llseek         = noop_llseek,
-};
-
-struct miscdevice snd_misc = {
-       .minor  = MISC_DYNAMIC_MINOR,
-       .name   = "msm_snd",
-       .fops   = &snd_fops,
-};
-
-static int snd_probe(struct platform_device *pdev)
-{
-       struct snd_ctxt *snd = &the_snd;
-       mutex_init(&snd->lock);
-       snd->snd_epts = (struct msm_snd_endpoints *)pdev->dev.platform_data;
-       return misc_register(&snd_misc);
-}
-
-static struct platform_driver snd_plat_driver = {
-       .probe = snd_probe,
-       .driver = {
-               .name = "msm_snd",
-               .owner = THIS_MODULE,
-       },
-};
-
-static int __init snd_init(void)
-{
-       return platform_driver_register(&snd_plat_driver);
-}
-
-module_init(snd_init);
diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c
deleted file mode 100644 (file)
index 3320359..0000000
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * Support for synaptics touchscreen.
- *
- * Copyright (C) 2007 Google, Inc.
- * Author: Arve Hjønnevåg <arve@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- * http://www.synaptics.com/sites/default/files/511_000099_01F.pdf
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif
-#include <linux/hrtimer.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include "synaptics_i2c_rmi.h"
-
-static struct workqueue_struct *synaptics_wq;
-
-struct synaptics_ts_data {
-       u16 addr;
-       struct i2c_client *client;
-       struct input_dev *input_dev;
-       int use_irq;
-       struct hrtimer timer;
-       struct work_struct  work;
-       u16 max[2];
-       int snap_state[2][2];
-       int snap_down_on[2];
-       int snap_down_off[2];
-       int snap_up_on[2];
-       int snap_up_off[2];
-       int snap_down[2];
-       int snap_up[2];
-       u32 flags;
-       int (*power)(int on);
-#ifdef CONFIG_HAS_EARLYSUSPEND
-       struct early_suspend early_suspend;
-#endif
-};
-
-static int i2c_set(struct synaptics_ts_data *ts, u8 reg, u8 val, char *msg)
-{
-       int ret = i2c_smbus_write_byte_data(ts->client, reg, val);
-       if (ret < 0)
-               pr_err("i2c_smbus_write_byte_data failed (%s)\n", msg);
-       return ret;
-}
-
-static int i2c_read(struct synaptics_ts_data *ts, u8 reg, char *msg)
-{
-       int ret = i2c_smbus_read_byte_data(ts->client, reg);
-       if (ret < 0)
-               pr_err("i2c_smbus_read_byte_data failed (%s)\n", msg);
-       return ret;
-}
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void synaptics_ts_early_suspend(struct early_suspend *h);
-static void synaptics_ts_late_resume(struct early_suspend *h);
-#endif
-
-static int synaptics_init_panel(struct synaptics_ts_data *ts)
-{
-       int ret;
-
-       ret = i2c_set(ts, 0xff, 0x10, "set page select");
-       if (ret == 0)
-               ret = i2c_set(ts, 0x41, 0x04, "set No Clip Z");
-
-       ret = i2c_set(ts, 0xff, 0x04, "fallback page select");
-       ret = i2c_set(ts, 0xf0, 0x81, "select 80 reports per second");
-       return ret;
-}
-
-static void decode_report(struct synaptics_ts_data *ts, u8 *buf)
-{
-/*
- * This sensor sends two 6-byte absolute finger reports, an optional
- * 2-byte relative report followed by a status byte. This function
- * reads the two finger reports and transforms the coordinates
- * according the platform data so they can be aligned with the lcd
- * behind the touchscreen. Typically we flip the y-axis since the
- * sensor uses the bottom left corner as the origin, but if the sensor
- * is mounted upside down the platform data will request that the
- * x-axis should be flipped instead. The snap to inactive edge border
- * are used to allow tapping the edges of the screen on the G1. The
- * active area of the touchscreen is smaller than the lcd. When the
- * finger gets close the edge of the screen we snap it to the
- * edge. This allows ui elements at the edge of the screen to be hit,
- * and it prevents hitting ui elements that are not at the edge of the
- * screen when the finger is touching the edge.
- */
-       int pos[2][2];
-       int f, a;
-       int base = 2;
-       int z = buf[1];
-       int finger = buf[0] & 7;
-
-       for (f = 0; f < 2; f++) {
-               u32 flip_flag = SYNAPTICS_FLIP_X;
-               for (a = 0; a < 2; a++) {
-                       int p = buf[base + 1];
-                       p |= (u16)(buf[base] & 0x1f) << 8;
-                       if (ts->flags & flip_flag)
-                               p = ts->max[a] - p;
-                       if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) {
-                               if (ts->snap_state[f][a]) {
-                                       if (p <= ts->snap_down_off[a])
-                                               p = ts->snap_down[a];
-                                       else if (p >= ts->snap_up_off[a])
-                                               p = ts->snap_up[a];
-                                       else
-                                               ts->snap_state[f][a] = 0;
-                               } else {
-                                       if (p <= ts->snap_down_on[a]) {
-                                               p = ts->snap_down[a];
-                                               ts->snap_state[f][a] = 1;
-                                       } else if (p >= ts->snap_up_on[a]) {
-                                               p = ts->snap_up[a];
-                                               ts->snap_state[f][a] = 1;
-                                       }
-                               }
-                       }
-                       pos[f][a] = p;
-                       base += 2;
-                       flip_flag <<= 1;
-               }
-               base += 2;
-               if (ts->flags & SYNAPTICS_SWAP_XY)
-                       swap(pos[f][0], pos[f][1]);
-       }
-       if (z) {
-               input_report_abs(ts->input_dev, ABS_X, pos[0][0]);
-               input_report_abs(ts->input_dev, ABS_Y, pos[0][1]);
-       }
-       input_report_abs(ts->input_dev, ABS_PRESSURE, z);
-       input_report_key(ts->input_dev, BTN_TOUCH, finger);
-       input_sync(ts->input_dev);
-}
-
-static void synaptics_ts_work_func(struct work_struct *work)
-{
-       int i;
-       int ret;
-       int bad_data = 0;
-       struct i2c_msg msg[2];
-       u8 start_reg = 0;
-       u8 buf[15];
-       struct synaptics_ts_data *ts =
-               container_of(work, struct synaptics_ts_data, work);
-
-       msg[0].addr = ts->client->addr;
-       msg[0].flags = 0;
-       msg[0].len = 1;
-       msg[0].buf = &start_reg;
-       msg[1].addr = ts->client->addr;
-       msg[1].flags = I2C_M_RD;
-       msg[1].len = sizeof(buf);
-       msg[1].buf = buf;
-
-       for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) {
-               ret = i2c_transfer(ts->client->adapter, msg, 2);
-               if (ret < 0) {
-                       pr_err("ts_work: i2c_transfer failed\n");
-                       bad_data = 1;
-                       continue;
-               }
-               if ((buf[14] & 0xc0) != 0x40) {
-                       pr_warning("synaptics_ts_work_func:"
-                              " bad read %x %x %x %x %x %x %x %x %x"
-                              " %x %x %x %x %x %x, ret %d\n",
-                              buf[0], buf[1], buf[2], buf[3],
-                              buf[4], buf[5], buf[6], buf[7],
-                              buf[8], buf[9], buf[10], buf[11],
-                              buf[12], buf[13], buf[14], ret);
-                       if (bad_data)
-                               synaptics_init_panel(ts);
-                       bad_data = 1;
-                       continue;
-               }
-               bad_data = 0;
-               if ((buf[14] & 1) == 0)
-                       break;
-
-               decode_report(ts, buf);
-       }
-}
-
-static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer)
-{
-       struct synaptics_ts_data *ts =
-               container_of(timer, struct synaptics_ts_data, timer);
-
-       queue_work(synaptics_wq, &ts->work);
-
-       hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
-       return HRTIMER_NORESTART;
-}
-
-static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id)
-{
-       struct synaptics_ts_data *ts = dev_id;
-
-       synaptics_ts_work_func(&ts->work);
-       return IRQ_HANDLED;
-}
-
-static int detect(struct synaptics_ts_data *ts, u32 *panel_version)
-{
-       int ret;
-       int retry = 10;
-
-       ret = i2c_set(ts, 0xf4, 0x01, "reset device");
-
-       while (retry-- > 0) {
-               ret = i2c_smbus_read_byte_data(ts->client, 0xe4);
-               if (ret >= 0)
-                       break;
-               msleep(100);
-       }
-       if (ret < 0) {
-               pr_err("i2c_smbus_read_byte_data failed\n");
-               return ret;
-       }
-
-       *panel_version = ret << 8;
-       ret = i2c_read(ts, 0xe5, "product minor");
-       if (ret < 0)
-               return ret;
-       *panel_version |= ret;
-
-       ret = i2c_read(ts, 0xe3, "property");
-       if (ret < 0)
-               return ret;
-
-       pr_info("synaptics: version %x, product property %x\n",
-               *panel_version, ret);
-       return 0;
-}
-
-static void compute_areas(struct synaptics_ts_data *ts,
-                         struct synaptics_i2c_rmi_platform_data *pdata,
-                         u16 max_x, u16 max_y)
-{
-       int inactive_area_left;
-       int inactive_area_right;
-       int inactive_area_top;
-       int inactive_area_bottom;
-       int snap_left_on;
-       int snap_left_off;
-       int snap_right_on;
-       int snap_right_off;
-       int snap_top_on;
-       int snap_top_off;
-       int snap_bottom_on;
-       int snap_bottom_off;
-       int fuzz_x;
-       int fuzz_y;
-       int fuzz_p;
-       int fuzz_w;
-       int swapped = !!(ts->flags & SYNAPTICS_SWAP_XY);
-
-       inactive_area_left = pdata->inactive_left;
-       inactive_area_right = pdata->inactive_right;
-       inactive_area_top = pdata->inactive_top;
-       inactive_area_bottom = pdata->inactive_bottom;
-       snap_left_on = pdata->snap_left_on;
-       snap_left_off = pdata->snap_left_off;
-       snap_right_on = pdata->snap_right_on;
-       snap_right_off = pdata->snap_right_off;
-       snap_top_on = pdata->snap_top_on;
-       snap_top_off = pdata->snap_top_off;
-       snap_bottom_on = pdata->snap_bottom_on;
-       snap_bottom_off = pdata->snap_bottom_off;
-       fuzz_x = pdata->fuzz_x;
-       fuzz_y = pdata->fuzz_y;
-       fuzz_p = pdata->fuzz_p;
-       fuzz_w = pdata->fuzz_w;
-
-       inactive_area_left = inactive_area_left * max_x / 0x10000;
-       inactive_area_right = inactive_area_right * max_x / 0x10000;
-       inactive_area_top = inactive_area_top * max_y / 0x10000;
-       inactive_area_bottom = inactive_area_bottom * max_y / 0x10000;
-       snap_left_on = snap_left_on * max_x / 0x10000;
-       snap_left_off = snap_left_off * max_x / 0x10000;
-       snap_right_on = snap_right_on * max_x / 0x10000;
-       snap_right_off = snap_right_off * max_x / 0x10000;
-       snap_top_on = snap_top_on * max_y / 0x10000;
-       snap_top_off = snap_top_off * max_y / 0x10000;
-       snap_bottom_on = snap_bottom_on * max_y / 0x10000;
-       snap_bottom_off = snap_bottom_off * max_y / 0x10000;
-       fuzz_x = fuzz_x * max_x / 0x10000;
-       fuzz_y = fuzz_y * max_y / 0x10000;
-
-
-       ts->snap_down[swapped] = -inactive_area_left;
-       ts->snap_up[swapped] = max_x + inactive_area_right;
-       ts->snap_down[!swapped] = -inactive_area_top;
-       ts->snap_up[!swapped] = max_y + inactive_area_bottom;
-       ts->snap_down_on[swapped] = snap_left_on;
-       ts->snap_down_off[swapped] = snap_left_off;
-       ts->snap_up_on[swapped] = max_x - snap_right_on;
-       ts->snap_up_off[swapped] = max_x - snap_right_off;
-       ts->snap_down_on[!swapped] = snap_top_on;
-       ts->snap_down_off[!swapped] = snap_top_off;
-       ts->snap_up_on[!swapped] = max_y - snap_bottom_on;
-       ts->snap_up_off[!swapped] = max_y - snap_bottom_off;
-       pr_info("synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y);
-       pr_info("synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n",
-              inactive_area_left, inactive_area_right,
-              inactive_area_top, inactive_area_bottom);
-       pr_info("synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n",
-              snap_left_on, snap_left_off, snap_right_on, snap_right_off,
-              snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off);
-
-       input_set_abs_params(ts->input_dev, ABS_X,
-                            -inactive_area_left, max_x + inactive_area_right,
-                            fuzz_x, 0);
-       input_set_abs_params(ts->input_dev, ABS_Y,
-                            -inactive_area_top, max_y + inactive_area_bottom,
-                            fuzz_y, 0);
-       input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0);
-}
-
-static struct synaptics_i2c_rmi_platform_data fake_pdata;
-
-static int __devinit synaptics_ts_probe(
-       struct i2c_client *client, const struct i2c_device_id *id)
-{
-       struct synaptics_ts_data *ts;
-       u8 buf0[4];
-       u8 buf1[8];
-       struct i2c_msg msg[2];
-       int ret = 0;
-       struct synaptics_i2c_rmi_platform_data *pdata;
-       u32 panel_version = 0;
-       u16 max_x, max_y;
-
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-               pr_err("synaptics_ts_probe: need I2C_FUNC_I2C\n");
-               ret = -ENODEV;
-               goto err_check_functionality_failed;
-       }
-
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
-               pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n");
-               ret = -ENODEV;
-               goto err_check_functionality_failed;
-       }
-
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
-               pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n");
-               ret = -ENODEV;
-               goto err_check_functionality_failed;
-       }
-
-       ts = kzalloc(sizeof(*ts), GFP_KERNEL);
-       if (ts == NULL) {
-               ret = -ENOMEM;
-               goto err_alloc_data_failed;
-       }
-       INIT_WORK(&ts->work, synaptics_ts_work_func);
-       ts->client = client;
-       i2c_set_clientdata(client, ts);
-       pdata = client->dev.platform_data;
-       if (pdata)
-               ts->power = pdata->power;
-       else
-               pdata = &fake_pdata;
-
-       if (ts->power) {
-               ret = ts->power(1);
-               if (ret < 0) {
-                       pr_err("synaptics_ts_probe power on failed\n");
-                       goto err_power_failed;
-               }
-       }
-
-       ret = detect(ts, &panel_version);
-       if (ret)
-               goto err_detect_failed;
-
-       while (pdata->version > panel_version)
-               pdata++;
-       ts->flags = pdata->flags;
-
-       ret = i2c_read(ts, 0xf0, "device control");
-       if (ret < 0)
-               goto err_detect_failed;
-       pr_info("synaptics: device control %x\n", ret);
-
-       ret = i2c_read(ts, 0xf1, "interrupt enable");
-       if (ret < 0)
-               goto err_detect_failed;
-       pr_info("synaptics_ts_probe: interrupt enable %x\n", ret);
-
-       ret = i2c_set(ts, 0xf1, 0, "disable interrupt");
-       if (ret < 0)
-               goto err_detect_failed;
-
-       msg[0].addr = ts->client->addr;
-       msg[0].flags = 0;
-       msg[0].len = 1;
-       msg[0].buf = buf0;
-       buf0[0] = 0xe0;
-       msg[1].addr = ts->client->addr;
-       msg[1].flags = I2C_M_RD;
-       msg[1].len = 8;
-       msg[1].buf = buf1;
-       ret = i2c_transfer(ts->client->adapter, msg, 2);
-       if (ret < 0) {
-               pr_err("i2c_transfer failed\n");
-               goto err_detect_failed;
-       }
-       pr_info("synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n",
-              buf1[0], buf1[1], buf1[2], buf1[3],
-              buf1[4], buf1[5], buf1[6], buf1[7]);
-
-       ret = i2c_set(ts, 0xff, 0x10, "page select = 0x10");
-       if (ret < 0)
-               goto err_detect_failed;
-
-       ret = i2c_smbus_read_word_data(ts->client, 0x04);
-       if (ret < 0) {
-               pr_err("i2c_smbus_read_word_data failed\n");
-               goto err_detect_failed;
-       }
-       ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
-       ret = i2c_smbus_read_word_data(ts->client, 0x06);
-       if (ret < 0) {
-               pr_err("i2c_smbus_read_word_data failed\n");
-               goto err_detect_failed;
-       }
-       ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
-       if (ts->flags & SYNAPTICS_SWAP_XY)
-               swap(max_x, max_y);
-
-       /* will also switch back to page 0x04 */
-       ret = synaptics_init_panel(ts);
-       if (ret < 0) {
-               pr_err("synaptics_init_panel failed\n");
-               goto err_detect_failed;
-       }
-
-       ts->input_dev = input_allocate_device();
-       if (ts->input_dev == NULL) {
-               ret = -ENOMEM;
-               pr_err("synaptics: Failed to allocate input device\n");
-               goto err_input_dev_alloc_failed;
-       }
-       ts->input_dev->name = "synaptics-rmi-touchscreen";
-       ts->input_dev->phys = "msm/input0";
-       ts->input_dev->id.bustype = BUS_I2C;
-
-       __set_bit(EV_SYN, ts->input_dev->evbit);
-       __set_bit(EV_KEY, ts->input_dev->evbit);
-       __set_bit(BTN_TOUCH, ts->input_dev->keybit);
-       __set_bit(EV_ABS, ts->input_dev->evbit);
-
-       compute_areas(ts, pdata, max_x, max_y);
-
-
-       ret = input_register_device(ts->input_dev);
-       if (ret) {
-               pr_err("synaptics: Unable to register %s input device\n",
-                      ts->input_dev->name);
-               goto err_input_register_device_failed;
-       }
-       if (client->irq) {
-               ret = request_threaded_irq(client->irq, NULL,
-                                       synaptics_ts_irq_handler,
-                                       IRQF_TRIGGER_LOW|IRQF_ONESHOT,
-                                       client->name, ts);
-               if (ret == 0) {
-                       ret = i2c_set(ts, 0xf1, 0x01, "enable abs int");
-                       if (ret)
-                               free_irq(client->irq, ts);
-               }
-               if (ret == 0)
-                       ts->use_irq = 1;
-               else
-                       dev_err(&client->dev, "request_irq failed\n");
-       }
-       if (!ts->use_irq) {
-               hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-               ts->timer.function = synaptics_ts_timer_func;
-               hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
-       }
-#ifdef CONFIG_HAS_EARLYSUSPEND
-       ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
-       ts->early_suspend.suspend = synaptics_ts_early_suspend;
-       ts->early_suspend.resume = synaptics_ts_late_resume;
-       register_early_suspend(&ts->early_suspend);
-#endif
-
-       pr_info("synaptics: Start touchscreen %s in %s mode\n",
-               ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
-
-       return 0;
-
-err_input_register_device_failed:
-       input_free_device(ts->input_dev);
-
-err_input_dev_alloc_failed:
-err_detect_failed:
-err_power_failed:
-       kfree(ts);
-err_alloc_data_failed:
-err_check_functionality_failed:
-       return ret;
-}
-
-static int synaptics_ts_remove(struct i2c_client *client)
-{
-       struct synaptics_ts_data *ts = i2c_get_clientdata(client);
-#ifdef CONFIG_HAS_EARLYSUSPEND
-       unregister_early_suspend(&ts->early_suspend);
-#endif
-       if (ts->use_irq)
-               free_irq(client->irq, ts);
-       else
-               hrtimer_cancel(&ts->timer);
-       input_unregister_device(ts->input_dev);
-       kfree(ts);
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg)
-{
-       int ret;
-       struct synaptics_ts_data *ts = i2c_get_clientdata(client);
-
-       if (ts->use_irq)
-               disable_irq(client->irq);
-       else
-               hrtimer_cancel(&ts->timer);
-       ret = cancel_work_sync(&ts->work);
-       if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
-               enable_irq(client->irq);
-       i2c_set(ts, 0xf1, 0, "disable interrupt");
-       i2c_set(ts, 0xf0, 0x86, "deep sleep");
-
-       if (ts->power) {
-               ret = ts->power(0);
-               if (ret < 0)
-                       pr_err("synaptics_ts_suspend power off failed\n");
-       }
-       return 0;
-}
-
-static int synaptics_ts_resume(struct i2c_client *client)
-{
-       int ret;
-       struct synaptics_ts_data *ts = i2c_get_clientdata(client);
-
-       if (ts->power) {
-               ret = ts->power(1);
-               if (ret < 0)
-                       pr_err("synaptics_ts_resume power on failed\n");
-       }
-
-       synaptics_init_panel(ts);
-
-       if (ts->use_irq) {
-               enable_irq(client->irq);
-               i2c_set(ts, 0xf1, 0x01, "enable abs int");
-       } else
-               hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
-
-       return 0;
-}
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void synaptics_ts_early_suspend(struct early_suspend *h)
-{
-       struct synaptics_ts_data *ts;
-       ts = container_of(h, struct synaptics_ts_data, early_suspend);
-       synaptics_ts_suspend(ts->client, PMSG_SUSPEND);
-}
-
-static void synaptics_ts_late_resume(struct early_suspend *h)
-{
-       struct synaptics_ts_data *ts;
-       ts = container_of(h, struct synaptics_ts_data, early_suspend);
-       synaptics_ts_resume(ts->client);
-}
-#endif
-#else
-#define synaptics_ts_suspend NULL
-#define synaptics_ts_resume NULL
-#endif
-
-
-
-static const struct i2c_device_id synaptics_ts_id[] = {
-       { SYNAPTICS_I2C_RMI_NAME, 0 },
-       { }
-};
-
-static struct i2c_driver synaptics_ts_driver = {
-       .probe          = synaptics_ts_probe,
-       .remove         = synaptics_ts_remove,
-#ifndef CONFIG_HAS_EARLYSUSPEND
-       .suspend        = synaptics_ts_suspend,
-       .resume         = synaptics_ts_resume,
-#endif
-       .id_table       = synaptics_ts_id,
-       .driver = {
-               .name   = SYNAPTICS_I2C_RMI_NAME,
-       },
-};
-
-static int __devinit synaptics_ts_init(void)
-{
-       synaptics_wq = create_singlethread_workqueue("synaptics_wq");
-       if (!synaptics_wq)
-               return -ENOMEM;
-       return i2c_add_driver(&synaptics_ts_driver);
-}
-
-static void __exit synaptics_ts_exit(void)
-{
-       i2c_del_driver(&synaptics_ts_driver);
-       if (synaptics_wq)
-               destroy_workqueue(synaptics_wq);
-}
-
-module_init(synaptics_ts_init);
-module_exit(synaptics_ts_exit);
-
-MODULE_DESCRIPTION("Synaptics Touchscreen Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Arve Hjønnevåg <arve@android.com>");
diff --git a/drivers/staging/dream/synaptics_i2c_rmi.h b/drivers/staging/dream/synaptics_i2c_rmi.h
deleted file mode 100644 (file)
index ca51b2f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * include/linux/synaptics_i2c_rmi.h - platform data structure for f75375s sensor
- *
- * Copyright (C) 2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef _LINUX_SYNAPTICS_I2C_RMI_H
-#define _LINUX_SYNAPTICS_I2C_RMI_H
-
-#define SYNAPTICS_I2C_RMI_NAME "synaptics-rmi-ts"
-
-enum {
-       SYNAPTICS_FLIP_X = 1UL << 0,
-       SYNAPTICS_FLIP_Y = 1UL << 1,
-       SYNAPTICS_SWAP_XY = 1UL << 2,
-       SYNAPTICS_SNAP_TO_INACTIVE_EDGE = 1UL << 3,
-};
-
-struct synaptics_i2c_rmi_platform_data {
-       uint32_t version;       /* Use this entry for panels with */
-                               /* (major << 8 | minor) version or above. */
-                               /* If non-zero another array entry follows */
-       int (*power)(int on);   /* Only valid in first array entry */
-       uint32_t flags;
-       uint32_t inactive_left; /* 0x10000 = screen width */
-       uint32_t inactive_right; /* 0x10000 = screen width */
-       uint32_t inactive_top; /* 0x10000 = screen height */
-       uint32_t inactive_bottom; /* 0x10000 = screen height */
-       uint32_t snap_left_on; /* 0x10000 = screen width */
-       uint32_t snap_left_off; /* 0x10000 = screen width */
-       uint32_t snap_right_on; /* 0x10000 = screen width */
-       uint32_t snap_right_off; /* 0x10000 = screen width */
-       uint32_t snap_top_on; /* 0x10000 = screen height */
-       uint32_t snap_top_off; /* 0x10000 = screen height */
-       uint32_t snap_bottom_on; /* 0x10000 = screen height */
-       uint32_t snap_bottom_off; /* 0x10000 = screen height */
-       uint32_t fuzz_x; /* 0x10000 = screen width */
-       uint32_t fuzz_y; /* 0x10000 = screen height */
-       int fuzz_p;
-       int fuzz_w;
-};
-
-#endif /* _LINUX_SYNAPTICS_I2C_RMI_H */
index 87a6487531c2262e95357fac2987bc62a5d18e96..20d509836d9e24b9ef7e67ac185caeb1c960a993 100644 (file)
@@ -286,7 +286,6 @@ int ft1000_CreateDevice(struct ft1000_device *dev)
     pid = kernel_thread (exec_mknod, (void *)info, 0);
 
     // initialize application information
-    info->appcnt = 0;
 
 //    if (ft1000_flarion_cnt == 0) {
 //
index 702a478d554203c663d1bdbb0b7f0a450f7f3620..a99e900ec4c9faf8f5f96aa815cc3af5d01766c1 100644 (file)
@@ -211,9 +211,6 @@ static void heartbeat_onchannelcallback(void *context)
                DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld",
                           recvlen, requestid);
 
-               icmsghdrp = (struct icmsg_hdr *)&buf[
-                       sizeof(struct vmbuspipe_hdr)];
-
                icmsghdrp = (struct icmsg_hdr *)&buf[
                                sizeof(struct vmbuspipe_hdr)];
 
index 463e5cba8307fd5694b4e48e81d6f37533ba231d..9618c79974611f682a8d4dd575f704cf00f92443 100644 (file)
@@ -244,12 +244,12 @@ static int intel_sst_mmap_play_capture(u32 str_id,
        int retval, i;
        struct stream_info *stream;
        struct snd_sst_mmap_buff_entry *buf_entry;
+       struct snd_sst_mmap_buff_entry *tmp_buf;
 
        pr_debug("sst:called for str_id %d\n", str_id);
        retval = sst_validate_strid(str_id);
        if (retval)
                return -EINVAL;
-       BUG_ON(!mmap_buf);
 
        stream = &sst_drv_ctx->streams[str_id];
        if (stream->mmapped != true)
@@ -262,14 +262,24 @@ static int intel_sst_mmap_play_capture(u32 str_id,
        stream->curr_bytes = 0;
        stream->cumm_bytes = 0;
 
+       tmp_buf = kcalloc(mmap_buf->entries, sizeof(*tmp_buf), GFP_KERNEL);
+       if (!tmp_buf)
+               return -ENOMEM;
+       if (copy_from_user(tmp_buf, (void __user *)mmap_buf->buff,
+                       mmap_buf->entries * sizeof(*tmp_buf))) {
+               retval = -EFAULT;
+               goto out_free;
+       }
+
        pr_debug("sst:new buffers count %d status %d\n",
                        mmap_buf->entries, stream->status);
-       buf_entry = mmap_buf->buff;
+       buf_entry = tmp_buf;
        for (i = 0; i < mmap_buf->entries; i++) {
-               BUG_ON(!buf_entry);
                bufs = kzalloc(sizeof(*bufs), GFP_KERNEL);
-               if (!bufs)
-                       return -ENOMEM;
+               if (!bufs) {
+                       retval = -ENOMEM;
+                       goto out_free;
+               }
                bufs->size = buf_entry->size;
                bufs->offset = buf_entry->offset;
                bufs->addr = sst_drv_ctx->mmap_mem;
@@ -293,13 +303,15 @@ static int intel_sst_mmap_play_capture(u32 str_id,
                        if (sst_play_frame(str_id) < 0) {
                                pr_warn("sst: play frames fail\n");
                                mutex_unlock(&stream->lock);
-                               return -EIO;
+                               retval = -EIO;
+                               goto out_free;
                        }
                } else if (stream->ops == STREAM_OPS_CAPTURE) {
                        if (sst_capture_frame(str_id) < 0) {
                                pr_warn("sst: capture frame fail\n");
                                mutex_unlock(&stream->lock);
-                               return -EIO;
+                               retval = -EIO;
+                               goto out_free;
                        }
                }
        }
@@ -314,6 +326,9 @@ static int intel_sst_mmap_play_capture(u32 str_id,
        if (retval >= 0)
                retval = stream->cumm_bytes;
        pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval);
+
+out_free:
+       kfree(tmp_buf);
        return retval;
 }
 
@@ -377,7 +392,7 @@ static int snd_sst_fill_kernel_list(struct stream_info *stream,
 {
        struct sst_stream_bufs *stream_bufs;
        unsigned long index, mmap_len;
-       unsigned char *bufp;
+       unsigned char __user *bufp;
        unsigned long size, copied_size;
        int retval = 0, add_to_list = 0;
        static int sent_offset;
@@ -512,9 +527,7 @@ static int snd_sst_copy_userbuf_capture(struct stream_info *stream,
                        /* copy to user */
                        list_for_each_entry_safe(entry, _entry,
                                                copy_to_list, node) {
-                               if (copy_to_user((void *)
-                                            iovec[entry->iov_index].iov_base +
-                                            entry->iov_offset,
+                               if (copy_to_user(iovec[entry->iov_index].iov_base + entry->iov_offset,
                                             kbufs->addr + entry->offset,
                                             entry->size)) {
                                        /* Clean up the list and return error */
@@ -590,7 +603,7 @@ static int intel_sst_read_write(unsigned int str_id, char __user *buf,
                        buf, (int) count, (int) stream->status);
 
        stream->buf_type = SST_BUF_USER_STATIC;
-       iovec.iov_base = (void *)buf;
+       iovec.iov_base = buf;
        iovec.iov_len  = count;
        nr_segs = 1;
 
@@ -838,7 +851,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                break;
 
        case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): {
-               struct snd_sst_params *str_param = (struct snd_sst_params *)arg;
+               struct snd_sst_params str_param;
 
                pr_debug("sst: IOCTL_SET_PARAMS recieved!\n");
                if (minor != STREAM_MODULE) {
@@ -846,17 +859,25 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                        break;
                }
 
+               if (copy_from_user(&str_param, (void __user *)arg,
+                               sizeof(str_param))) {
+                       retval = -EFAULT;
+                       break;
+               }
+
                if (!str_id) {
 
-                       retval = sst_get_stream(str_param);
+                       retval = sst_get_stream(&str_param);
                        if (retval > 0) {
                                struct stream_info *str_info;
+                               char __user *dest;
+
                                sst_drv_ctx->stream_cnt++;
                                data->str_id = retval;
                                str_info = &sst_drv_ctx->streams[retval];
                                str_info->src = SST_DRV;
-                               retval = copy_to_user(&str_param->stream_id,
-                                               &retval, sizeof(__u32));
+                               dest = (char __user *)arg + offsetof(struct snd_sst_params, stream_id);
+                               retval = copy_to_user(dest, &retval, sizeof(__u32));
                                if (retval)
                                        retval = -EFAULT;
                        } else {
@@ -866,16 +887,14 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                } else {
                        pr_debug("sst: SET_STREAM_PARAMS recieved!\n");
                        /* allocated set params only */
-                       retval = sst_set_stream_param(str_id, str_param);
+                       retval = sst_set_stream_param(str_id, &str_param);
                        /* Block the call for reply */
                        if (!retval) {
                                int sfreq = 0, word_size = 0, num_channel = 0;
-                               sfreq = str_param->sparams.uc.pcm_params.sfreq;
-                               word_size = str_param->sparams.
-                                               uc.pcm_params.pcm_wd_sz;
-                               num_channel = str_param->
-                                       sparams.uc.pcm_params.num_chan;
-                               if (str_param->ops == STREAM_OPS_CAPTURE) {
+                               sfreq = str_param.sparams.uc.pcm_params.sfreq;
+                               word_size = str_param.sparams.uc.pcm_params.pcm_wd_sz;
+                               num_channel = str_param.sparams.uc.pcm_params.num_chan;
+                               if (str_param.ops == STREAM_OPS_CAPTURE) {
                                        sst_drv_ctx->scard_ops->\
                                        set_pcm_audio_params(sfreq,
                                                word_size, num_channel);
@@ -885,41 +904,39 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                break;
        }
        case _IOC_NR(SNDRV_SST_SET_VOL): {
-               struct snd_sst_vol *set_vol;
-               struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg;
+               struct snd_sst_vol set_vol;
+
+               if (copy_from_user(&set_vol, (void __user *)arg,
+                               sizeof(set_vol))) {
+                       pr_debug("sst: copy failed\n");
+                       retval = -EFAULT;
+                       break;
+               }
                pr_debug("sst: SET_VOLUME recieved for %d!\n",
-                               rec_vol->stream_id);
-               if (minor == STREAM_MODULE && rec_vol->stream_id == 0) {
+                               set_vol.stream_id);
+               if (minor == STREAM_MODULE && set_vol.stream_id == 0) {
                        pr_debug("sst: invalid operation!\n");
                        retval = -EPERM;
                        break;
                }
-               set_vol = kzalloc(sizeof(*set_vol), GFP_ATOMIC);
-               if (!set_vol) {
-                       pr_debug("sst: mem allocation failed\n");
-                       retval = -ENOMEM;
-                       break;
-               }
-               if (copy_from_user(set_vol, rec_vol, sizeof(*set_vol))) {
-                       pr_debug("sst: copy failed\n");
-                       retval = -EFAULT;
-                       break;
-               }
-               retval = sst_set_vol(set_vol);
-               kfree(set_vol);
+               retval = sst_set_vol(&set_vol);
                break;
        }
        case _IOC_NR(SNDRV_SST_GET_VOL): {
-               struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg;
                struct snd_sst_vol get_vol;
+
+               if (copy_from_user(&get_vol, (void __user *)arg,
+                               sizeof(get_vol))) {
+                       retval = -EFAULT;
+                       break;
+               }
                pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n",
-                               rec_vol->stream_id);
-               if (minor == STREAM_MODULE && rec_vol->stream_id == 0) {
+                               get_vol.stream_id);
+               if (minor == STREAM_MODULE && get_vol.stream_id == 0) {
                        pr_debug("sst: invalid operation!\n");
                        retval = -EPERM;
                        break;
                }
-               get_vol.stream_id = rec_vol->stream_id;
                retval = sst_get_vol(&get_vol);
                if (retval) {
                        retval = -EIO;
@@ -928,7 +945,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                pr_debug("sst: id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
                                get_vol.stream_id, get_vol.volume,
                                get_vol.ramp_duration, get_vol.ramp_type);
-               if (copy_to_user((struct snd_sst_vol *)arg,
+               if (copy_to_user((struct snd_sst_vol __user *)arg,
                                &get_vol, sizeof(get_vol))) {
                        retval = -EFAULT;
                        break;
@@ -938,25 +955,20 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
        }
 
        case _IOC_NR(SNDRV_SST_MUTE): {
-               struct snd_sst_mute *set_mute;
-               struct snd_sst_vol *rec_mute = (struct snd_sst_vol *)arg;
-               pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n",
-                       rec_mute->stream_id);
-               if (minor == STREAM_MODULE && rec_mute->stream_id == 0) {
-                       retval = -EPERM;
-                       break;
-               }
-               set_mute = kzalloc(sizeof(*set_mute), GFP_ATOMIC);
-               if (!set_mute) {
-                       retval = -ENOMEM;
+               struct snd_sst_mute set_mute;
+
+               if (copy_from_user(&set_mute, (void __user *)arg,
+                               sizeof(set_mute))) {
+                       retval = -EFAULT;
                        break;
                }
-               if (copy_from_user(set_mute, rec_mute, sizeof(*set_mute))) {
-                       retval = -EFAULT;
+               pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n",
+                       set_mute.stream_id);
+               if (minor == STREAM_MODULE && set_mute.stream_id == 0) {
+                       retval = -EPERM;
                        break;
                }
-               retval = sst_set_mute(set_mute);
-               kfree(set_mute);
+               retval = sst_set_mute(&set_mute);
                break;
        }
        case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): {
@@ -973,7 +985,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                        retval = -EIO;
                        break;
                }
-               if (copy_to_user((struct snd_sst_get_stream_params *)arg,
+               if (copy_to_user((struct snd_sst_get_stream_params __user *)arg,
                                        &get_params, sizeof(get_params))) {
                        retval = -EFAULT;
                        break;
@@ -983,16 +995,22 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
        }
 
        case _IOC_NR(SNDRV_SST_MMAP_PLAY):
-       case _IOC_NR(SNDRV_SST_MMAP_CAPTURE):
+       case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): {
+               struct snd_sst_mmap_buffs mmap_buf;
+
                pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
                if (minor != STREAM_MODULE) {
                        retval = -EBADRQC;
                        break;
                }
-               retval = intel_sst_mmap_play_capture(str_id,
-                               (struct snd_sst_mmap_buffs *)arg);
+               if (copy_from_user(&mmap_buf, (void __user *)arg,
+                               sizeof(mmap_buf))) {
+                       retval = -EFAULT;
+                       break;
+               }
+               retval = intel_sst_mmap_play_capture(str_id, &mmap_buf);
                break;
-
+       }
        case _IOC_NR(SNDRV_SST_STREAM_DROP):
                pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n");
                if (minor != STREAM_MODULE) {
@@ -1003,7 +1021,6 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                break;
 
        case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP): {
-               unsigned long long *ms = (unsigned long long *)arg;
                struct snd_sst_tstamp tstamp = {0};
                unsigned long long time, freq, mod;
 
@@ -1013,14 +1030,14 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                        break;
                }
                memcpy_fromio(&tstamp,
-                       ((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP)
-                       +(str_id * sizeof(tstamp))),
+                       sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
                        sizeof(tstamp));
                time = tstamp.samples_rendered;
                freq = (unsigned long long) tstamp.sampling_frequency;
                time = time * 1000; /* converting it to ms */
                mod = do_div(time, freq);
-               if (copy_to_user(ms, &time, sizeof(*ms)))
+               if (copy_to_user((void __user *)arg, &time,
+                               sizeof(unsigned long long)))
                        retval = -EFAULT;
                break;
        }
@@ -1065,92 +1082,118 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
        }
 
        case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): {
-               struct snd_sst_target_device *target_device;
+               struct snd_sst_target_device target_device;
 
                pr_debug("sst: SET_TARGET_DEVICE recieved!\n");
-               target_device = (struct snd_sst_target_device *)arg;
-               BUG_ON(!target_device);
+               if (copy_from_user(&target_device, (void __user *)arg,
+                               sizeof(target_device))) {
+                       retval = -EFAULT;
+                       break;
+               }
                if (minor != AM_MODULE) {
                        retval = -EBADRQC;
                        break;
                }
-               retval = sst_target_device_select(target_device);
+               retval = sst_target_device_select(&target_device);
                break;
        }
 
        case _IOC_NR(SNDRV_SST_DRIVER_INFO): {
-               struct snd_sst_driver_info *info =
-                       (struct snd_sst_driver_info *)arg;
+               struct snd_sst_driver_info info;
 
                pr_debug("sst: SNDRV_SST_DRIVER_INFO recived\n");
-               info->version = SST_VERSION_NUM;
+               info.version = SST_VERSION_NUM;
                /* hard coding, shud get sumhow later */
-               info->active_pcm_streams = sst_drv_ctx->stream_cnt -
+               info.active_pcm_streams = sst_drv_ctx->stream_cnt -
                                                sst_drv_ctx->encoded_cnt;
-               info->active_enc_streams = sst_drv_ctx->encoded_cnt;
-               info->max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM;
-               info->max_enc_streams = MAX_ENC_STREAM;
-               info->buf_per_stream = sst_drv_ctx->mmap_len;
+               info.active_enc_streams = sst_drv_ctx->encoded_cnt;
+               info.max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM;
+               info.max_enc_streams = MAX_ENC_STREAM;
+               info.buf_per_stream = sst_drv_ctx->mmap_len;
+               if (copy_to_user((void __user *)arg, &info,
+                               sizeof(info)))
+                       retval = -EFAULT;
                break;
        }
 
        case _IOC_NR(SNDRV_SST_STREAM_DECODE): {
-               struct snd_sst_dbufs *param =
-                               (struct snd_sst_dbufs *)arg, dbufs_local;
-               int i;
+               struct snd_sst_dbufs param;
+               struct snd_sst_dbufs dbufs_local;
                struct snd_sst_buffs ibufs, obufs;
-               struct snd_sst_buff_entry ibuf_temp[param->ibufs->entries],
-                               obuf_temp[param->obufs->entries];
+               struct snd_sst_buff_entry *ibuf_tmp, *obuf_tmp;
+               char __user *dest;
 
                pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n");
                if (minor != STREAM_MODULE) {
                        retval = -EBADRQC;
                        break;
                }
-               if (!param) {
-                       retval = -EINVAL;
+               if (copy_from_user(&param, (void __user *)arg,
+                               sizeof(param))) {
+                       retval = -EFAULT;
                        break;
                }
 
-               dbufs_local.input_bytes_consumed = param->input_bytes_consumed;
+               dbufs_local.input_bytes_consumed = param.input_bytes_consumed;
                dbufs_local.output_bytes_produced =
-                                       param->output_bytes_produced;
-               dbufs_local.ibufs = &ibufs;
-               dbufs_local.obufs = &obufs;
-               dbufs_local.ibufs->entries = param->ibufs->entries;
-               dbufs_local.ibufs->type = param->ibufs->type;
-               dbufs_local.obufs->entries = param->obufs->entries;
-               dbufs_local.obufs->type = param->obufs->type;
-
-               dbufs_local.ibufs->buff_entry = ibuf_temp;
-               for (i = 0; i < dbufs_local.ibufs->entries; i++) {
-                       ibuf_temp[i].buffer =
-                               param->ibufs->buff_entry[i].buffer;
-                       ibuf_temp[i].size =
-                               param->ibufs->buff_entry[i].size;
+                                       param.output_bytes_produced;
+
+               if (copy_from_user(&ibufs, (void __user *)param.ibufs, sizeof(ibufs))) {
+                       retval = -EFAULT;
+                       break;
+               }
+               if (copy_from_user(&obufs, (void __user *)param.obufs, sizeof(obufs))) {
+                       retval = -EFAULT;
+                       break;
                }
-               dbufs_local.obufs->buff_entry = obuf_temp;
-               for (i = 0; i < dbufs_local.obufs->entries; i++) {
-                       obuf_temp[i].buffer =
-                               param->obufs->buff_entry[i].buffer;
-                       obuf_temp[i].size =
-                               param->obufs->buff_entry[i].size;
+
+               ibuf_tmp = kcalloc(ibufs.entries, sizeof(*ibuf_tmp), GFP_KERNEL);
+               obuf_tmp = kcalloc(obufs.entries, sizeof(*obuf_tmp), GFP_KERNEL);
+               if (!ibuf_tmp || !obuf_tmp) {
+                       retval = -ENOMEM;
+                       goto free_iobufs;
+               }
+
+               if (copy_from_user(ibuf_tmp, (void __user *)ibufs.buff_entry,
+                               ibufs.entries * sizeof(*ibuf_tmp))) {
+                       retval = -EFAULT;
+                       goto free_iobufs;
                }
+               ibufs.buff_entry = ibuf_tmp;
+               dbufs_local.ibufs = &ibufs;
+
+               if (copy_from_user(obuf_tmp, (void __user *)obufs.buff_entry,
+                               obufs.entries * sizeof(*obuf_tmp))) {
+                       retval = -EFAULT;
+                       goto free_iobufs;
+               }
+               obufs.buff_entry = obuf_tmp;
+               dbufs_local.obufs = &obufs;
+
                retval = sst_decode(str_id, &dbufs_local);
-               if (retval)
-                       retval =  -EAGAIN;
-               if (copy_to_user(&param->input_bytes_consumed,
+               if (retval) {
+                       retval = -EAGAIN;
+                       goto free_iobufs;
+               }
+
+               dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed);
+               if (copy_to_user(dest,
                                &dbufs_local.input_bytes_consumed,
                                sizeof(unsigned long long))) {
-                       retval =  -EFAULT;
-                       break;
+                       retval = -EFAULT;
+                       goto free_iobufs;
                }
-               if (copy_to_user(&param->output_bytes_produced,
+
+               dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed);
+               if (copy_to_user(dest,
                                &dbufs_local.output_bytes_produced,
                                sizeof(unsigned long long))) {
-                       retval =  -EFAULT;
-                       break;
+                       retval = -EFAULT;
+                       goto free_iobufs;
                }
+free_iobufs:
+               kfree(ibuf_tmp);
+               kfree(obuf_tmp);
                break;
        }
 
@@ -1164,7 +1207,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                break;
 
        case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED): {
-               unsigned long long *bytes = (unsigned long long *)arg;
+               unsigned long long __user *bytes = (unsigned long long __user *)arg;
                struct snd_sst_tstamp tstamp = {0};
 
                pr_debug("sst: STREAM_BYTES_DECODED recieved!\n");
@@ -1173,8 +1216,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                        break;
                }
                memcpy_fromio(&tstamp,
-                       ((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP)
-                       +(str_id * sizeof(tstamp))),
+                       sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
                        sizeof(tstamp));
                if (copy_to_user(bytes, &tstamp.bytes_processed,
                                sizeof(*bytes)))
@@ -1197,7 +1239,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
                        kfree(fw_info);
                        break;
                }
-               if (copy_to_user((struct snd_sst_dbufs *)arg,
+               if (copy_to_user((struct snd_sst_dbufs __user *)arg,
                                fw_info, sizeof(*fw_info))) {
                        kfree(fw_info);
                        retval = -EFAULT;
index 73a98c851e4adfa70de483f61b4bc05bc40e6e9d..bf0ead78bfae4e967c2c9ed7abefe01116a17b0a 100644 (file)
@@ -231,8 +231,8 @@ struct stream_info {
        spinlock_t          pcm_lock;
        bool                    mmapped;
        unsigned int            sg_index; /*  current buf Index  */
-       unsigned char           *cur_ptr; /*  Current static bufs  */
-       struct snd_sst_buf_entry *buf_entry;
+       unsigned char __user    *cur_ptr; /*  Current static bufs  */
+       struct snd_sst_buf_entry __user *buf_entry;
        struct sst_block        data_blk; /* stream ops block */
        struct sst_block        ctrl_blk; /* stream control cmd block */
        enum snd_sst_buf_type   buf_type;
index 1934805844f21247239e047e4093f4e47d634680..978bf87ff13d50ff3659b8168874f2fc1a01947a 100644 (file)
@@ -22,7 +22,7 @@ int ENE_InitMedia(struct us_data *us)
        int     result;
        BYTE    MiscReg03 = 0;
 
-       printk("--- Initial Nedia ---\n");
+       printk("--- Init Media ---\n");
        result = ENE_Read_BYTE(us, REG_CARD_STATUS, &MiscReg03);
        if (result != USB_STOR_XFER_GOOD)
        {
@@ -64,7 +64,7 @@ int ENE_Read_BYTE(struct us_data *us, WORD index, void *buf)
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
        int result;
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x01;
        bcb->Flags                      = 0x80;
@@ -92,7 +92,7 @@ int ENE_SDInit(struct us_data *us)
                return USB_STOR_TRANSPORT_ERROR;
        }
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->Flags = 0x80;
        bcb->CDB[0] = 0xF2;
@@ -112,7 +112,7 @@ int ENE_SDInit(struct us_data *us)
                return USB_STOR_TRANSPORT_ERROR;
        }
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200;
        bcb->Flags                      = 0x80;
@@ -161,7 +161,7 @@ int ENE_MSInit(struct us_data *us)
                return USB_STOR_TRANSPORT_ERROR;
        }
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200;
        bcb->Flags                      = 0x80;
@@ -219,7 +219,7 @@ int ENE_SMInit(struct us_data *us)
                return USB_STOR_TRANSPORT_ERROR;
        }
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200;
        bcb->Flags                      = 0x80;
@@ -341,7 +341,7 @@ int ENE_LoadBinCode(struct us_data *us, BYTE flag)
                break;
        }
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x800;
        bcb->Flags =0x00;
@@ -433,7 +433,7 @@ int ENE_Read_Data(struct us_data *us, void *buf, unsigned int length)
 
        //printk("transport --- ENE_Read_Data\n");
        // set up the command wrapper
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = length;
        bcb->Flags =0x80;
@@ -470,7 +470,7 @@ int ENE_Write_Data(struct us_data *us, void *buf, unsigned int length)
 
        //printk("transport --- ENE_Write_Data\n");
        // set up the command wrapper
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = length;
        bcb->Flags =0x00;
index d4340a9da87dcde456856b8cc3cb18914237ea26..9a3fdb4e4fe46ecaddb48e46c468a6f69f247a64 100644 (file)
@@ -15,7 +15,7 @@ int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy, WORD PhyBlo
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200*len;
        bcb->Flags                      = 0x00;
@@ -53,7 +53,7 @@ int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, PDWO
                return USB_STOR_TRANSPORT_ERROR;
 
        // Read Page Data
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200;
        bcb->Flags                      = 0x80;
@@ -69,7 +69,7 @@ int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, PDWO
                return USB_STOR_TRANSPORT_ERROR;
 
        // Read Extra Data
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x4;
        bcb->Flags                      = 0x80;
@@ -108,7 +108,7 @@ int MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr)
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200;
        bcb->Flags                      = 0x80;
@@ -673,7 +673,7 @@ int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, BYTE PageNum, BYTE
        //printk("MS_LibReadExtraBlock --- PhyBlock = %x, PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen);
 
        // Read Extra Data
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x4 * blen;
        bcb->Flags                      = 0x80;
@@ -700,7 +700,7 @@ int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, BYTE PageNum, MS_LibType
        BYTE    ExtBuf[4];
 
        //printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum);
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x4;
        bcb->Flags                      = 0x80;
@@ -807,7 +807,7 @@ int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, B
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x4;
        bcb->Flags                      = 0x80;
index ad0c5c629935013f10b6b919e018806f2ba0ff3d..cb92d25acee07094ebd0653d40e07584fac79860 100644 (file)
@@ -145,7 +145,7 @@ int MS_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
                }
 
                // set up the command wrapper
-               memset(bcb, 0, sizeof(bcb));
+               memset(bcb, 0, sizeof(struct bulk_cb_wrap));
                bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
                bcb->DataTransferLength = blenByte;
                bcb->Flags  = 0x80;
@@ -193,7 +193,7 @@ int MS_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
                        blkno  = phyblk * 0x20 + PageNum;
 
                        // set up the command wrapper
-                       memset(bcb, 0, sizeof(bcb));
+                       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
                        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
                        bcb->DataTransferLength = 0x200 * len;
                        bcb->Flags  = 0x80;
@@ -250,7 +250,7 @@ int MS_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
                }
 
                // set up the command wrapper
-               memset(bcb, 0, sizeof(bcb));
+               memset(bcb, 0, sizeof(struct bulk_cb_wrap));
                bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
                bcb->DataTransferLength = blenByte;
                bcb->Flags  = 0x00;
index 6c332f850ebe2a647545d30712fd79d103ef3e72..d646507a361135f975b6e36b6fbd70014a0f40eb 100644 (file)
@@ -152,7 +152,7 @@ int SD_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
                bnByte = bn;
                
        // set up the command wrapper
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = blenByte;
        bcb->Flags  = 0x80;
@@ -192,7 +192,7 @@ int SD_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
                bnByte = bn;
 
        // set up the command wrapper
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = blenByte;
        bcb->Flags  = 0x00;
index 844b65988636a05e29335c88a64ac3dd8bc2584c..1b52535a388f534ea6307a50026306799f410c08 100644 (file)
@@ -266,7 +266,7 @@ int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant)
        addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
 
        // Read sect data
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200;
        bcb->Flags                      = 0x80;
@@ -281,7 +281,7 @@ int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant)
                return USB_STOR_TRANSPORT_ERROR;
 
        // Read redundant
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x10;
        bcb->Flags                      = 0x80;
@@ -319,7 +319,7 @@ int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant)
        addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
 
        // Read sect data
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200*count;
        bcb->Flags                      = 0x80;
@@ -334,7 +334,7 @@ int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant)
                return USB_STOR_TRANSPORT_ERROR;
 
        // Read redundant
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x10;
        bcb->Flags                      = 0x80;
@@ -536,7 +536,7 @@ int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant)
        WriteAddr = WriteAddr*(WORD)Ssfdc.MaxSectors;
 
        // Write sect data
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200*count;
        bcb->Flags                      = 0x00;
@@ -754,7 +754,7 @@ int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant)
        addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
 
        // Write sect data
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200;
        bcb->Flags                      = 0x00;
@@ -791,7 +791,7 @@ int Ssfdc_D_EraseBlock(struct us_data *us)
        addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
        addr=addr*(WORD)Ssfdc.MaxSectors;
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x200;
        bcb->Flags                      = 0x80;
@@ -827,7 +827,7 @@ int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant)
        addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
        addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x10;
        bcb->Flags                      = 0x80;
@@ -870,7 +870,7 @@ int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant)
        addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock;
        addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector;
 
-       memset(bcb, 0, sizeof(bcb));
+       memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb->DataTransferLength = 0x10;
        bcb->Flags                      = 0x80;
index fd98df643ab0d999655b26c68ea4d844ee44729f..111160cce4419e7e77b80f3cd3d439b8646f7898 100644 (file)
@@ -40,7 +40,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
        us->current_urb->error_count = 0;
        us->current_urb->status = 0;
 
-//     us->current_urb->transfer_flags = URB_NO_SETUP_DMA_MAP;
+       us->current_urb->transfer_flags = 0;
        if (us->current_urb->transfer_buffer == us->iobuf)
                us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
        us->current_urb->transfer_dma = us->iobuf_dma;
index ea268edbf43b0916be95f4e0d5f20b38665a05fb..23fa049b51f22d941ebd8415f375c93ad3462898 100644 (file)
@@ -1158,7 +1158,7 @@ static int msm_fb_release(struct fb_info *info, int user)
        return ret;
 }
 
-DECLARE_MUTEX(msm_fb_pan_sem);
+DEFINE_SEMAPHORE(msm_fb_pan_sem);
 
 static int msm_fb_pan_display(struct fb_var_screeninfo *var,
                              struct fb_info *info)
@@ -1962,7 +1962,7 @@ static int msmfb_overlay_play(struct fb_info *info, unsigned long *argp)
 
 #endif
 
-DECLARE_MUTEX(msm_fb_ioctl_ppp_sem);
+DEFINE_SEMAPHORE(msm_fb_ioctl_ppp_sem);
 DEFINE_MUTEX(msm_fb_ioctl_lut_sem);
 DEFINE_MUTEX(msm_fb_ioctl_hist_sem);
 
index 75aa7a36307d8f23940bd1ae2e6ee91f49bb80cf..4ca45ec7fd84ef088e3258450e135fb7ccaacc72 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/console.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
-#include <linux/i2c-id.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include <linux/interrupt.h>
@@ -733,7 +732,6 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id)
  edev:
        platform_device_unregister(dcon_device);
        dcon_device = NULL;
-       i2c_set_clientdata(client, NULL);
  eirq:
        free_irq(DCON_IRQ, &dcon_driver);
  einit:
@@ -757,8 +755,6 @@ static int dcon_remove(struct i2c_client *client)
                platform_device_unregister(dcon_device);
        cancel_work_sync(&dcon_work);
 
-       i2c_set_clientdata(client, NULL);
-
        return 0;
 }
 
index c62d30017c07257bb7ac073a465f3e1adfa148ce..61685ccceda88c474bfaa97337d8e34eceeed1cb 100644 (file)
@@ -1937,11 +1937,10 @@ err_out_exit:
 /*
  * Some VFS magic here...
  */
-static int pohmelfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *pohmelfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, pohmelfs_fill_super,
-                               mnt);
+       return mount_nodev(fs_type, flags, data, pohmelfs_fill_super);
 }
 
 /*
@@ -1958,7 +1957,7 @@ static void pohmelfs_kill_super(struct super_block *sb)
 static struct file_system_type pohmel_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "pohmel",
-       .get_sb         = pohmelfs_get_sb,
+       .mount          = pohmelfs_mount,
        .kill_sb        = pohmelfs_kill_super,
 };
 
index 1d159ff82fd203e3d7be0313c522bf7946c209e3..a99879bada4279a5843ff3d3409b908f6c8f8a0b 100644 (file)
@@ -330,8 +330,6 @@ void construct_mic_iv(unsigned char *mic_iv,
        for (i = 8; i < 14; i++)
                mic_iv[i] = pn_vector[13 - i];  /* mic_iv[8:13] = PN[5:0] */
 #endif
-       i = (payload_length / 256);
-       i = (payload_length % 256);
        mic_iv[14] = (unsigned char)(payload_length / 256);
        mic_iv[15] = (unsigned char)(payload_length % 256);
 
index ebf9074a90838367fc7dde6aac3cba0fe6a3e131..ddacfc6c486179274394b330153c901dfc7c63b7 100644 (file)
@@ -65,6 +65,7 @@ struct usb_device_id rtusb_usb_id[] = {
        {USB_DEVICE(0x14B2, 0x3C07)},   /* AL */
        {USB_DEVICE(0x050D, 0x8053)},   /* Belkin */
        {USB_DEVICE(0x050D, 0x825B)},   /* Belkin */
+       {USB_DEVICE(0x050D, 0x935A)},   /* Belkin F6D4050 v1 */
        {USB_DEVICE(0x050D, 0x935B)},   /* Belkin F6D4050 v2 */
        {USB_DEVICE(0x14B2, 0x3C23)},   /* Airlink */
        {USB_DEVICE(0x14B2, 0x3C27)},   /* Airlink */
index a202194b5cbb15de11f3e58e739b0c9fb2630c53..b1786dcac24566dbffb6ab57a677be9f8de5a0c3 100644 (file)
@@ -5829,6 +5829,9 @@ static void rtl8192_rx(struct net_device *dev)
                     }
                 }
 
+               pci_unmap_single(priv->pdev, *((dma_addr_t *) skb->cb),
+                       priv->rxbuffersize, PCI_DMA_FROMDEVICE);
+
                 skb = new_skb;
                 priv->rx_buf[priv->rx_idx] = skb;
                 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
index 7fca42c7c0d40f9b0d103f8a3f93f789828d0b68..d1674cd282dcd7deb370cca6b75c8f0f69b3ed73 100644 (file)
@@ -161,7 +161,7 @@ static inline u32 _down_sema(struct semaphore *sema)
 
 static inline void _rtl_rwlock_init(struct semaphore *prwlock)
 {
-       init_MUTEX(prwlock);
+       sema_init(prwlock, 1);
 }
 
 static inline void _init_listhead(struct list_head *list)
index 552951aa749834ebc9d61baa4368d066e9f858ef..540a984bb5160d5942902575803c6c79b087d507 100644 (file)
@@ -537,7 +537,7 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        server->mnt = NULL;
        server->sock_file = NULL;
        init_waitqueue_head(&server->conn_wq);
-       init_MUTEX(&server->sem);
+       sema_init(&server->sem, 1);
        INIT_LIST_HEAD(&server->entry);
        INIT_LIST_HEAD(&server->xmitq);
        INIT_LIST_HEAD(&server->recvq);
@@ -793,16 +793,16 @@ out:
        return error;
 }
 
-static int smb_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *smb_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, smb_fill_super, mnt);
+       return mount_nodev(fs_type, flags, data, smb_fill_super);
 }
 
 static struct file_system_type smb_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "smbfs",
-       .get_sb         = smb_get_sb,
+       .mount          = smb_mount,
        .kill_sb        = kill_anon_super,
        .fs_flags       = FS_BINARY_MOUNTDATA,
 };
index bbf3d9c4abb03aa6dc4b17f9e3f0d123cc7306d7..097e82bc7a6315d92bd0c158bca8a10340f6c22c 100644 (file)
@@ -766,7 +766,7 @@ static int solo_enc_open(struct file *file)
                                    &solo_enc->lock,
                                    V4L2_BUF_TYPE_VIDEO_CAPTURE,
                                    V4L2_FIELD_INTERLACED,
-                                   sizeof(struct videobuf_buffer), fh);
+                                   sizeof(struct videobuf_buffer), fh, NULL);
 
        spin_unlock(&solo_enc->lock);
 
index 9731fa02b5e80702c380e42dfd57c996dad03a3e..6ffd21de837d8bf5161d6654206ce918439cc78f 100644 (file)
@@ -437,7 +437,7 @@ static int solo_v4l2_open(struct file *file)
                                    &solo_dev->pdev->dev, &fh->slock,
                                    V4L2_BUF_TYPE_VIDEO_CAPTURE,
                                    SOLO_DISP_PIX_FIELD,
-                                   sizeof(struct videobuf_buffer), fh);
+                                   sizeof(struct videobuf_buffer), fh, NULL);
 
        return 0;
 }
index a057824e7ebc25ac5e2b5102d002804a79c983d2..807dd7eb748f5e84bfafa9efaf0e2a4dc2118a81 100644 (file)
@@ -1286,6 +1286,7 @@ static long saa_ioctl(struct file *file,
        case VIDIOCGCAP:
                {
                        struct video_capability b;
+                       memset(&b, 0, sizeof(b));
                        strcpy(b.name, saa->video_dev.name);
                        b.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY |
                                VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM |
@@ -1416,6 +1417,7 @@ static long saa_ioctl(struct file *file,
        case VIDIOCGWIN:
                {
                        struct video_window vw;
+                       memset(&vw, 0, sizeof(vw));
                        vw.x = saa->win.x;
                        vw.y = saa->win.y;
                        vw.width = saa->win.width;
@@ -1448,6 +1450,7 @@ static long saa_ioctl(struct file *file,
        case VIDIOCGFBUF:
                {
                        struct video_buffer v;
+                       memset(&v, 0, sizeof(v));
                        v.base = (void *)saa->win.vidadr;
                        v.height = saa->win.sheight;
                        v.width = saa->win.swidth;
@@ -1492,6 +1495,7 @@ static long saa_ioctl(struct file *file,
        case VIDIOCGAUDIO:
                {
                        struct video_audio v;
+                       memset(&v, 0, sizeof(v));
                        v = saa->audio_dev;
                        v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
                        v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
@@ -1534,6 +1538,7 @@ static long saa_ioctl(struct file *file,
        case VIDIOCGUNIT:
                {
                        struct video_unit vu;
+                       memset(&vu, 0, sizeof(vu));
                        vu.video = saa->video_dev.minor;
                        vu.vbi = VIDEO_NO_UNIT;
                        vu.radio = VIDEO_NO_UNIT;
@@ -1888,6 +1893,7 @@ static int saa_open(struct file *file)
 
        saa->user++;
        if (saa->user > 1) {
+               saa->user--;
                unlock_kernel();
                return 0;       /* device open already, don't reset */
        }
@@ -2000,10 +2006,13 @@ static int __devinit configure_saa7146(struct pci_dev *pdev, int num)
        if (retval < 0) {
                dev_err(&pdev->dev, "%d: error in registering video device!\n",
                        num);
-               goto errio;
+               goto errirq;
        }
 
        return 0;
+
+errirq:
+       free_irq(saa->irq, saa);
 errio:
        iounmap(saa->saa7146_mem);
 err:
index ff64d464143c3cf5253c9fc09f10baa7945f2b07..93de4f2e8bf89defcd6e83e00c2cbe1cd93b8dd4 100644 (file)
@@ -6,7 +6,6 @@ menuconfig TIDSPBRIDGE
        tristate "DSP Bridge driver"
        depends on ARCH_OMAP3
        select OMAP_MBOX_FWK
-       select OMAP_IOMMU
        help
          DSP/BIOS Bridge is designed for platforms that contain a GPP and
          one or more attached DSPs.  The GPP is considered the master or
index 50decc2935c5d575acb8feb24c3bfa55b79376aa..41c644c3318f46fe632173d12f50aad2af8ea4f1 100644 (file)
@@ -2,18 +2,19 @@ obj-$(CONFIG_TIDSPBRIDGE)     += bridgedriver.o
 
 libgen = gen/gb.o gen/gs.o gen/gh.o gen/uuidutil.o
 libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \
-               core/tiomap3430_pwr.o core/tiomap_io.o core/dsp-mmu.o \
+               core/tiomap3430_pwr.o core/tiomap_io.o \
                core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o
 libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \
-               pmgr/cmm.o pmgr/dbll.o
+               pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o
 librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \
                rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \
                rmgr/nldr.o rmgr/drv_interface.o
 libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \
                 dynload/tramp.o
+libhw = hw/hw_mmu.o
 
 bridgedriver-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \
-                       $(libdload)
+                       $(libdload) $(libhw)
 
 #Machine dependent
 ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \
index 8ae263387a878a4dadc6d6ca72305597f30b6520..16723cd34831348613a09b8cf7a855292ca752db 100644 (file)
@@ -27,8 +27,9 @@
 struct deh_mgr {
        struct bridge_dev_context *hbridge_context;     /* Bridge context. */
        struct ntfy_object *ntfy_obj;   /* NTFY object */
-};
 
-int mmu_fault_isr(struct iommu *mmu);
+       /* MMU Fault DPC */
+       struct tasklet_struct dpc_tasklet;
+};
 
 #endif /* _DEH_ */
index e0a801c1cb98db8ca20681c446293ecdbd3c1780..1c1f157e167a645b4f630ba4ac41d9f9943fff61 100644 (file)
@@ -23,8 +23,8 @@
 #include <plat/clockdomain.h>
 #include <mach-omap2/prm-regbits-34xx.h>
 #include <mach-omap2/cm-regbits-34xx.h>
-#include <dspbridge/dsp-mmu.h>
 #include <dspbridge/devdefs.h>
+#include <hw_defs.h>
 #include <dspbridge/dspioctl.h>        /* for bridge_ioctl_extproc defn */
 #include <dspbridge/sync.h>
 #include <dspbridge/clk.h>
@@ -306,18 +306,6 @@ static const struct bpwr_clk_t bpwr_clks[] = {
 
 #define CLEAR_BIT_INDEX(reg, index)   (reg &= ~(1 << (index)))
 
-struct shm_segs {
-       u32 seg0_da;
-       u32 seg0_pa;
-       u32 seg0_va;
-       u32 seg0_size;
-       u32 seg1_da;
-       u32 seg1_pa;
-       u32 seg1_va;
-       u32 seg1_size;
-};
-
-
 /* This Bridge driver's device context: */
 struct bridge_dev_context {
        struct dev_object *hdev_obj;    /* Handle to Bridge device object. */
@@ -328,6 +316,7 @@ struct bridge_dev_context {
         */
        u32 dw_dsp_ext_base_addr;       /* See the comment above */
        u32 dw_api_reg_base;    /* API mem map'd registers */
+       void __iomem *dw_dsp_mmu_base;  /* DSP MMU Mapped registers */
        u32 dw_api_clk_base;    /* CLK Registers */
        u32 dw_dsp_clk_m2_base; /* DSP Clock Module m2 */
        u32 dw_public_rhea;     /* Pub Rhea */
@@ -339,8 +328,7 @@ struct bridge_dev_context {
        u32 dw_internal_size;   /* Internal memory size */
 
        struct omap_mbox *mbox;         /* Mail box handle */
-       struct iommu *dsp_mmu;      /* iommu for iva2 handler */
-       struct shm_segs sh_s;
+
        struct cfg_hostres *resources;  /* Host Resources */
 
        /*
@@ -353,6 +341,7 @@ struct bridge_dev_context {
 
        /* TC Settings */
        bool tc_word_swap_on;   /* Traffic Controller Word Swap */
+       struct pg_table_attrs *pt_attrs;
        u32 dsp_per_clks;
 };
 
diff --git a/drivers/staging/tidspbridge/core/dsp-mmu.c b/drivers/staging/tidspbridge/core/dsp-mmu.c
deleted file mode 100644 (file)
index 983c95a..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * dsp-mmu.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP iommu.
- *
- * Copyright (C) 2010 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <dspbridge/host_os.h>
-#include <plat/dmtimer.h>
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/dev.h>
-#include <dspbridge/io_sm.h>
-#include <dspbridge/dspdeh.h>
-#include "_tiomap.h"
-
-#include <dspbridge/dsp-mmu.h>
-
-#define MMU_CNTL_TWL_EN                (1 << 2)
-
-static struct tasklet_struct mmu_tasklet;
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-static void mmu_fault_print_stack(struct bridge_dev_context *dev_context)
-{
-       void *dummy_addr;
-       u32 fa, tmp;
-       struct iotlb_entry e;
-       struct iommu *mmu = dev_context->dsp_mmu;
-       dummy_addr = (void *)__get_free_page(GFP_ATOMIC);
-
-       /*
-        * Before acking the MMU fault, let's make sure MMU can only
-        * access entry #0. Then add a new entry so that the DSP OS
-        * can continue in order to dump the stack.
-        */
-       tmp = iommu_read_reg(mmu, MMU_CNTL);
-       tmp &= ~MMU_CNTL_TWL_EN;
-       iommu_write_reg(mmu, tmp, MMU_CNTL);
-       fa = iommu_read_reg(mmu, MMU_FAULT_AD);
-       e.da = fa & PAGE_MASK;
-       e.pa = virt_to_phys(dummy_addr);
-       e.valid = 1;
-       e.prsvd = 1;
-       e.pgsz = IOVMF_PGSZ_4K & MMU_CAM_PGSZ_MASK;
-       e.endian = MMU_RAM_ENDIAN_LITTLE;
-       e.elsz = MMU_RAM_ELSZ_32;
-       e.mixed = 0;
-
-       load_iotlb_entry(mmu, &e);
-
-       dsp_clk_enable(DSP_CLK_GPT8);
-
-       dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);
-
-       /* Clear MMU interrupt */
-       tmp = iommu_read_reg(mmu, MMU_IRQSTATUS);
-       iommu_write_reg(mmu, tmp, MMU_IRQSTATUS);
-
-       dump_dsp_stack(dev_context);
-       dsp_clk_disable(DSP_CLK_GPT8);
-
-       iopgtable_clear_entry(mmu, fa);
-       free_page((unsigned long)dummy_addr);
-}
-#endif
-
-
-static void fault_tasklet(unsigned long data)
-{
-       struct iommu *mmu = (struct iommu *)data;
-       struct bridge_dev_context *dev_ctx;
-       struct deh_mgr *dm;
-       u32 fa;
-       dev_get_deh_mgr(dev_get_first(), &dm);
-       dev_get_bridge_context(dev_get_first(), &dev_ctx);
-
-       if (!dm || !dev_ctx)
-               return;
-
-       fa = iommu_read_reg(mmu, MMU_FAULT_AD);
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-       print_dsp_trace_buffer(dev_ctx);
-       dump_dl_modules(dev_ctx);
-       mmu_fault_print_stack(dev_ctx);
-#endif
-
-       bridge_deh_notify(dm, DSP_MMUFAULT, fa);
-}
-
-/*
- *  ======== mmu_fault_isr ========
- *      ISR to be triggered by a DSP MMU fault interrupt.
- */
-static int mmu_fault_callback(struct iommu *mmu)
-{
-       if (!mmu)
-               return -EPERM;
-
-       iommu_write_reg(mmu, 0, MMU_IRQENABLE);
-       tasklet_schedule(&mmu_tasklet);
-       return 0;
-}
-
-/**
- * dsp_mmu_init() - initialize dsp_mmu module and returns a handle
- *
- * This function initialize dsp mmu module and returns a struct iommu
- * handle to use it for dsp maps.
- *
- */
-struct iommu *dsp_mmu_init()
-{
-       struct iommu *mmu;
-
-       mmu = iommu_get("iva2");
-
-       if (!IS_ERR(mmu)) {
-               tasklet_init(&mmu_tasklet, fault_tasklet, (unsigned long)mmu);
-               mmu->isr = mmu_fault_callback;
-       }
-
-       return mmu;
-}
-
-/**
- * dsp_mmu_exit() - destroy dsp mmu module
- * @mmu:       Pointer to iommu handle.
- *
- * This function destroys dsp mmu module.
- *
- */
-void dsp_mmu_exit(struct iommu *mmu)
-{
-       if (mmu)
-               iommu_put(mmu);
-       tasklet_kill(&mmu_tasklet);
-}
-
-/**
- * user_va2_pa() - get physical address from userspace address.
- * @mm:                mm_struct Pointer of the process.
- * @address:   Virtual user space address.
- *
- */
-static u32 user_va2_pa(struct mm_struct *mm, u32 address)
-{
-       pgd_t *pgd;
-       pmd_t *pmd;
-       pte_t *ptep, pte;
-
-       pgd = pgd_offset(mm, address);
-       if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
-               pmd = pmd_offset(pgd, address);
-               if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
-                       ptep = pte_offset_map(pmd, address);
-                       if (ptep) {
-                               pte = *ptep;
-                               if (pte_present(pte))
-                                       return pte & PAGE_MASK;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/**
- * get_io_pages() - pin and get pages of io user's buffer.
- * @mm:                mm_struct Pointer of the process.
- * @uva:               Virtual user space address.
- * @pages      Pages to be pined.
- * @usr_pgs    struct page array pointer where the user pages will be stored
- *
- */
-static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages,
-                                               struct page **usr_pgs)
-{
-       u32 pa;
-       int i;
-       struct page *pg;
-
-       for (i = 0; i < pages; i++) {
-               pa = user_va2_pa(mm, uva);
-
-               if (!pfn_valid(__phys_to_pfn(pa)))
-                       break;
-
-               pg = phys_to_page(pa);
-               usr_pgs[i] = pg;
-               get_page(pg);
-       }
-       return i;
-}
-
-/**
- * user_to_dsp_map() - maps user to dsp virtual address
- * @mmu:       Pointer to iommu handle.
- * @uva:               Virtual user space address.
- * @da         DSP address
- * @size               Buffer size to map.
- * @usr_pgs    struct page array pointer where the user pages will be stored
- *
- * This function maps a user space buffer into DSP virtual address.
- *
- */
-u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size,
-                               struct page **usr_pgs)
-{
-       int res, w;
-       unsigned pages;
-       int i;
-       struct vm_area_struct *vma;
-       struct mm_struct *mm = current->mm;
-       struct sg_table *sgt;
-       struct scatterlist *sg;
-
-       if (!size || !usr_pgs)
-               return -EINVAL;
-
-       pages = size / PG_SIZE4K;
-
-       down_read(&mm->mmap_sem);
-       vma = find_vma(mm, uva);
-       while (vma && (uva + size > vma->vm_end))
-               vma = find_vma(mm, vma->vm_end + 1);
-
-       if (!vma) {
-               pr_err("%s: Failed to get VMA region for 0x%x (%d)\n",
-                                               __func__, uva, size);
-               up_read(&mm->mmap_sem);
-               return -EINVAL;
-       }
-       if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
-               w = 1;
-
-       if (vma->vm_flags & VM_IO)
-               i = get_io_pages(mm, uva, pages, usr_pgs);
-       else
-               i = get_user_pages(current, mm, uva, pages, w, 1,
-                                                       usr_pgs, NULL);
-       up_read(&mm->mmap_sem);
-
-       if (i < 0)
-               return i;
-
-       if (i < pages) {
-               res = -EFAULT;
-               goto err_pages;
-       }
-
-       sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
-       if (!sgt) {
-               res = -ENOMEM;
-               goto err_pages;
-       }
-
-       res = sg_alloc_table(sgt, pages, GFP_KERNEL);
-
-       if (res < 0)
-               goto err_sg;
-
-       for_each_sg(sgt->sgl, sg, sgt->nents, i)
-               sg_set_page(sg, usr_pgs[i], PAGE_SIZE, 0);
-
-       da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
-
-       if (!IS_ERR_VALUE(da))
-               return da;
-       res = (int)da;
-
-       sg_free_table(sgt);
-err_sg:
-       kfree(sgt);
-       i = pages;
-err_pages:
-       while (i--)
-               put_page(usr_pgs[i]);
-       return res;
-}
-
-/**
- * user_to_dsp_unmap() - unmaps DSP virtual buffer.
- * @mmu:       Pointer to iommu handle.
- * @da         DSP address
- *
- * This function unmaps a user space buffer into DSP virtual address.
- *
- */
-int user_to_dsp_unmap(struct iommu *mmu, u32 da)
-{
-       unsigned i;
-       struct sg_table *sgt;
-       struct scatterlist *sg;
-
-       sgt = iommu_vunmap(mmu, da);
-       if (!sgt)
-               return -EFAULT;
-
-       for_each_sg(sgt->sgl, sg, sgt->nents, i)
-               put_page(sg_page(sg));
-       sg_free_table(sgt);
-       kfree(sgt);
-
-       return 0;
-}
index 194badaba0ed0fc1de9ada2970a631b372cc55c1..571864555ddd894c73f2649ca43996b5bf7d77a4 100644 (file)
 #include <dspbridge/ntfy.h>
 #include <dspbridge/sync.h>
 
+/* Hardware Abstraction Layer */
+#include <hw_defs.h>
+#include <hw_mmu.h>
+
 /* Bridge Driver */
 #include <dspbridge/dspdeh.h>
 #include <dspbridge/dspio.h>
@@ -287,7 +291,6 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
        struct cod_manager *cod_man;
        struct chnl_mgr *hchnl_mgr;
        struct msg_mgr *hmsg_mgr;
-       struct shm_segs *sm_sg;
        u32 ul_shm_base;
        u32 ul_shm_base_offset;
        u32 ul_shm_limit;
@@ -310,9 +313,18 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
        struct bridge_ioctl_extproc ae_proc[BRDIOCTL_NUMOFMMUTLB];
        struct cfg_hostres *host_res;
        struct bridge_dev_context *pbridge_context;
+       u32 map_attrs;
        u32 shm0_end;
        u32 ul_dyn_ext_base;
        u32 ul_seg1_size = 0;
+       u32 pa_curr = 0;
+       u32 va_curr = 0;
+       u32 gpp_va_curr = 0;
+       u32 num_bytes = 0;
+       u32 all_bits = 0;
+       u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB,
+               HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB
+       };
 
        status = dev_get_bridge_context(hio_mgr->hdev_obj, &pbridge_context);
        if (!pbridge_context) {
@@ -325,8 +337,6 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
                status = -EFAULT;
                goto func_end;
        }
-       sm_sg = &pbridge_context->sh_s;
-
        status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man);
        if (!cod_man) {
                status = -EFAULT;
@@ -461,14 +471,129 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
        if (status)
                goto func_end;
 
-       sm_sg->seg1_pa = ul_gpp_pa;
-       sm_sg->seg1_da = ul_dyn_ext_base;
-       sm_sg->seg1_va = ul_gpp_va;
-       sm_sg->seg1_size = ul_seg1_size;
-       sm_sg->seg0_pa = ul_gpp_pa + ul_pad_size + ul_seg1_size;
-       sm_sg->seg0_da = ul_dsp_va;
-       sm_sg->seg0_va = ul_gpp_va + ul_pad_size + ul_seg1_size;
-       sm_sg->seg0_size = ul_seg_size;
+       pa_curr = ul_gpp_pa;
+       va_curr = ul_dyn_ext_base * hio_mgr->word_size;
+       gpp_va_curr = ul_gpp_va;
+       num_bytes = ul_seg1_size;
+
+       /*
+        * Try to fit into TLB entries. If not possible, push them to page
+        * tables. It is quite possible that if sections are not on
+        * bigger page boundary, we may end up making several small pages.
+        * So, push them onto page tables, if that is the case.
+        */
+       map_attrs = 0x00000000;
+       map_attrs = DSP_MAPLITTLEENDIAN;
+       map_attrs |= DSP_MAPPHYSICALADDR;
+       map_attrs |= DSP_MAPELEMSIZE32;
+       map_attrs |= DSP_MAPDONOTLOCK;
+
+       while (num_bytes) {
+               /*
+                * To find the max. page size with which both PA & VA are
+                * aligned.
+                */
+               all_bits = pa_curr | va_curr;
+               dev_dbg(bridge, "all_bits %x, pa_curr %x, va_curr %x, "
+                       "num_bytes %x\n", all_bits, pa_curr, va_curr,
+                       num_bytes);
+               for (i = 0; i < 4; i++) {
+                       if ((num_bytes >= page_size[i]) && ((all_bits &
+                                                            (page_size[i] -
+                                                             1)) == 0)) {
+                               status =
+                                   hio_mgr->intf_fxns->
+                                   pfn_brd_mem_map(hio_mgr->hbridge_context,
+                                                   pa_curr, va_curr,
+                                                   page_size[i], map_attrs,
+                                                   NULL);
+                               if (status)
+                                       goto func_end;
+                               pa_curr += page_size[i];
+                               va_curr += page_size[i];
+                               gpp_va_curr += page_size[i];
+                               num_bytes -= page_size[i];
+                               /*
+                                * Don't try smaller sizes. Hopefully we have
+                                * reached an address aligned to a bigger page
+                                * size.
+                                */
+                               break;
+                       }
+               }
+       }
+       pa_curr += ul_pad_size;
+       va_curr += ul_pad_size;
+       gpp_va_curr += ul_pad_size;
+
+       /* Configure the TLB entries for the next cacheable segment */
+       num_bytes = ul_seg_size;
+       va_curr = ul_dsp_va * hio_mgr->word_size;
+       while (num_bytes) {
+               /*
+                * To find the max. page size with which both PA & VA are
+                * aligned.
+                */
+               all_bits = pa_curr | va_curr;
+               dev_dbg(bridge, "all_bits for Seg1 %x, pa_curr %x, "
+                       "va_curr %x, num_bytes %x\n", all_bits, pa_curr,
+                       va_curr, num_bytes);
+               for (i = 0; i < 4; i++) {
+                       if (!(num_bytes >= page_size[i]) ||
+                           !((all_bits & (page_size[i] - 1)) == 0))
+                               continue;
+                       if (ndx < MAX_LOCK_TLB_ENTRIES) {
+                               /*
+                                * This is the physical address written to
+                                * DSP MMU.
+                                */
+                               ae_proc[ndx].ul_gpp_pa = pa_curr;
+                               /*
+                                * This is the virtual uncached ioremapped
+                                * address!!!
+                                */
+                               ae_proc[ndx].ul_gpp_va = gpp_va_curr;
+                               ae_proc[ndx].ul_dsp_va =
+                                   va_curr / hio_mgr->word_size;
+                               ae_proc[ndx].ul_size = page_size[i];
+                               ae_proc[ndx].endianism = HW_LITTLE_ENDIAN;
+                               ae_proc[ndx].elem_size = HW_ELEM_SIZE16BIT;
+                               ae_proc[ndx].mixed_mode = HW_MMU_CPUES;
+                               dev_dbg(bridge, "shm MMU TLB entry PA %x"
+                                       " VA %x DSP_VA %x Size %x\n",
+                                       ae_proc[ndx].ul_gpp_pa,
+                                       ae_proc[ndx].ul_gpp_va,
+                                       ae_proc[ndx].ul_dsp_va *
+                                       hio_mgr->word_size, page_size[i]);
+                               ndx++;
+                       } else {
+                               status =
+                                   hio_mgr->intf_fxns->
+                                   pfn_brd_mem_map(hio_mgr->hbridge_context,
+                                                   pa_curr, va_curr,
+                                                   page_size[i], map_attrs,
+                                                   NULL);
+                               dev_dbg(bridge,
+                                       "shm MMU PTE entry PA %x"
+                                       " VA %x DSP_VA %x Size %x\n",
+                                       ae_proc[ndx].ul_gpp_pa,
+                                       ae_proc[ndx].ul_gpp_va,
+                                       ae_proc[ndx].ul_dsp_va *
+                                       hio_mgr->word_size, page_size[i]);
+                               if (status)
+                                       goto func_end;
+                       }
+                       pa_curr += page_size[i];
+                       va_curr += page_size[i];
+                       gpp_va_curr += page_size[i];
+                       num_bytes -= page_size[i];
+                       /*
+                        * Don't try smaller sizes. Hopefully we have reached
+                        * an address aligned to a bigger page size.
+                        */
+                       break;
+               }
+       }
 
        /*
         * Copy remaining entries from CDB. All entries are 1 MB and
@@ -509,12 +634,38 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
                                        "DSP_VA 0x%x\n", ae_proc[ndx].ul_gpp_pa,
                                        ae_proc[ndx].ul_dsp_va);
                                ndx++;
+                       } else {
+                               status = hio_mgr->intf_fxns->pfn_brd_mem_map
+                                   (hio_mgr->hbridge_context,
+                                    hio_mgr->ext_proc_info.ty_tlb[i].
+                                    ul_gpp_phys,
+                                    hio_mgr->ext_proc_info.ty_tlb[i].
+                                    ul_dsp_virt, 0x100000, map_attrs,
+                                    NULL);
                        }
                }
                if (status)
                        goto func_end;
        }
 
+       map_attrs = 0x00000000;
+       map_attrs = DSP_MAPLITTLEENDIAN;
+       map_attrs |= DSP_MAPPHYSICALADDR;
+       map_attrs |= DSP_MAPELEMSIZE32;
+       map_attrs |= DSP_MAPDONOTLOCK;
+
+       /* Map the L4 peripherals */
+       i = 0;
+       while (l4_peripheral_table[i].phys_addr) {
+               status = hio_mgr->intf_fxns->pfn_brd_mem_map
+                   (hio_mgr->hbridge_context, l4_peripheral_table[i].phys_addr,
+                    l4_peripheral_table[i].dsp_virt_addr, HW_PAGE_SIZE4KB,
+                    map_attrs, NULL);
+               if (status)
+                       goto func_end;
+               i++;
+       }
+
        for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) {
                ae_proc[i].ul_dsp_va = 0;
                ae_proc[i].ul_gpp_pa = 0;
@@ -537,12 +688,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
                status = -EFAULT;
                goto func_end;
        } else {
-               if (sm_sg->seg0_da > ul_shm_base) {
+               if (ae_proc[0].ul_dsp_va > ul_shm_base) {
                        status = -EPERM;
                        goto func_end;
                }
                /* ul_shm_base may not be at ul_dsp_va address */
-               ul_shm_base_offset = (ul_shm_base - sm_sg->seg0_da) *
+               ul_shm_base_offset = (ul_shm_base - ae_proc[0].ul_dsp_va) *
                    hio_mgr->word_size;
                /*
                 * bridge_dev_ctrl() will set dev context dsp-mmu info. In
@@ -566,7 +717,8 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
                        goto func_end;
                }
                /* Register SM */
-               status = register_shm_segs(hio_mgr, cod_man, sm_sg->seg0_pa);
+               status =
+                   register_shm_segs(hio_mgr, cod_man, ae_proc[0].ul_gpp_pa);
        }
 
        hio_mgr->shared_mem = (struct shm *)ul_shm_base;
index f22bc12bc0d343294a65eb364c6d3c62c4d5005c..1be081f917a73e643bac5326d7a49dea4bea4ea9 100644 (file)
@@ -23,7 +23,6 @@
 #include <dspbridge/host_os.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
-#include <plat/control.h>
 
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 #include <dspbridge/drv.h>
 #include <dspbridge/sync.h>
 
+/* ------------------------------------ Hardware Abstraction Layer */
+#include <hw_defs.h>
+#include <hw_mmu.h>
+
 /*  ----------------------------------- Link Driver */
 #include <dspbridge/dspdefs.h>
 #include <dspbridge/dspchnl.h>
@@ -47,6 +50,7 @@
 /*  ----------------------------------- Platform Manager */
 #include <dspbridge/dev.h>
 #include <dspbridge/dspapi.h>
+#include <dspbridge/dmm.h>
 #include <dspbridge/wdt.h>
 
 /*  ----------------------------------- Local */
 #define MMU_SMALL_PAGE_MASK      0xFFFFF000
 #define OMAP3_IVA2_BOOTADDR_MASK 0xFFFFFC00
 #define PAGES_II_LVL_TABLE   512
+#define PHYS_TO_PAGE(phys)      pfn_to_page((phys) >> PAGE_SHIFT)
+
+/*
+ * This is a totally ugly layer violation, but needed until
+ * omap_ctrl_set_dsp_boot*() are provided.
+ */
+#define OMAP3_IVA2_BOOTMOD_IDLE 1
+#define OMAP2_CONTROL_GENERAL 0x270
+#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
+#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
+
+#define OMAP343X_CTRL_REGADDR(reg) \
+       OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+
 
 /* Forward Declarations: */
 static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt);
@@ -91,6 +109,12 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt,
 static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
                                    u8 *host_buff, u32 dsp_addr,
                                    u32 ul_num_bytes, u32 mem_type);
+static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
+                                 u32 ul_mpu_addr, u32 virt_addr,
+                                 u32 ul_num_bytes, u32 ul_map_attr,
+                                 struct page **mapped_pages);
+static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
+                                    u32 virt_addr, u32 ul_num_bytes);
 static int bridge_dev_create(struct bridge_dev_context
                                        **dev_cntxt,
                                        struct dev_object *hdev_obj,
@@ -98,8 +122,57 @@ static int bridge_dev_create(struct bridge_dev_context
 static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
                                  u32 dw_cmd, void *pargs);
 static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt);
+static u32 user_va2_pa(struct mm_struct *mm, u32 address);
+static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
+                            u32 va, u32 size,
+                            struct hw_mmu_map_attrs_t *map_attrs);
+static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va,
+                         u32 size, struct hw_mmu_map_attrs_t *attrs);
+static int mem_map_vmalloc(struct bridge_dev_context *dev_context,
+                                 u32 ul_mpu_addr, u32 virt_addr,
+                                 u32 ul_num_bytes,
+                                 struct hw_mmu_map_attrs_t *hw_attrs);
+
 bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr);
 
+/*  ----------------------------------- Globals */
+
+/* Attributes of L2 page tables for DSP MMU */
+struct page_info {
+       u32 num_entries;        /* Number of valid PTEs in the L2 PT */
+};
+
+/* Attributes used to manage the DSP MMU page tables */
+struct pg_table_attrs {
+       spinlock_t pg_lock;     /* Critical section object handle */
+
+       u32 l1_base_pa;         /* Physical address of the L1 PT */
+       u32 l1_base_va;         /* Virtual  address of the L1 PT */
+       u32 l1_size;            /* Size of the L1 PT */
+       u32 l1_tbl_alloc_pa;
+       /* Physical address of Allocated mem for L1 table. May not be aligned */
+       u32 l1_tbl_alloc_va;
+       /* Virtual address of Allocated mem for L1 table. May not be aligned */
+       u32 l1_tbl_alloc_sz;
+       /* Size of consistent memory allocated for L1 table.
+        * May not be aligned */
+
+       u32 l2_base_pa;         /* Physical address of the L2 PT */
+       u32 l2_base_va;         /* Virtual  address of the L2 PT */
+       u32 l2_size;            /* Size of the L2 PT */
+       u32 l2_tbl_alloc_pa;
+       /* Physical address of Allocated mem for L2 table. May not be aligned */
+       u32 l2_tbl_alloc_va;
+       /* Virtual address of Allocated mem for L2 table. May not be aligned */
+       u32 l2_tbl_alloc_sz;
+       /* Size of consistent memory allocated for L2 table.
+        * May not be aligned */
+
+       u32 l2_num_pages;       /* Number of allocated L2 PT */
+       /* Array [l2_num_pages] of L2 PT info structs */
+       struct page_info *pg_info;
+};
+
 /*
  *  This Bridge driver's function interface table.
  */
@@ -119,6 +192,8 @@ static struct bridge_drv_interface drv_interface_fxns = {
        bridge_brd_set_state,
        bridge_brd_mem_copy,
        bridge_brd_mem_write,
+       bridge_brd_mem_map,
+       bridge_brd_mem_un_map,
        /* The following CHNL functions are provided by chnl_io.lib: */
        bridge_chnl_create,
        bridge_chnl_destroy,
@@ -148,6 +223,27 @@ static struct bridge_drv_interface drv_interface_fxns = {
        bridge_msg_set_queue_id,
 };
 
+static inline void flush_all(struct bridge_dev_context *dev_context)
+{
+       if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION ||
+           dev_context->dw_brd_state == BRD_HIBERNATION)
+               wake_dsp(dev_context, NULL);
+
+       hw_mmu_tlb_flush_all(dev_context->dw_dsp_mmu_base);
+}
+
+static void bad_page_dump(u32 pa, struct page *pg)
+{
+       pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa);
+       pr_emerg("Bad page state in process '%s'\n"
+                "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n"
+                "Backtrace:\n",
+                current->comm, pg, (int)(2 * sizeof(unsigned long)),
+                (unsigned long)pg->flags, pg->mapping,
+                page_mapcount(pg), page_count(pg));
+       dump_stack();
+}
+
 /*
  *  ======== bridge_drv_entry ========
  *  purpose:
@@ -203,7 +299,8 @@ static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt)
                (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_DISABLE_AUTO,
                                        OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
        }
-
+       (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
+                                       OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
        dsp_clk_enable(DSP_CLK_IVA2);
 
        /* set the device state to IDLE */
@@ -274,17 +371,14 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
 {
        int status = 0;
        struct bridge_dev_context *dev_context = dev_ctxt;
-       struct iommu *mmu = NULL;
-       struct shm_segs *sm_sg;
-       int l4_i = 0, tlb_i = 0;
-       u32 sg0_da = 0, sg1_da = 0;
-       struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry;
        u32 dw_sync_addr = 0;
        u32 ul_shm_base;        /* Gpp Phys SM base addr(byte) */
        u32 ul_shm_base_virt;   /* Dsp Virt SM base addr */
        u32 ul_tlb_base_virt;   /* Base of MMU TLB entry */
        /* Offset of shm_base_virt from tlb_base_virt */
        u32 ul_shm_offset_virt;
+       s32 entry_ndx;
+       s32 itmp_entry_ndx = 0; /* DSP-MMU TLB entry base address */
        struct cfg_hostres *resources = NULL;
        u32 temp;
        u32 ul_dsp_clk_rate;
@@ -305,12 +399,12 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
        ul_shm_base_virt *= DSPWORDSIZE;
        DBC_ASSERT(ul_shm_base_virt != 0);
        /* DSP Virtual address */
-       ul_tlb_base_virt = dev_context->sh_s.seg0_da;
+       ul_tlb_base_virt = dev_context->atlb_entry[0].ul_dsp_va;
        DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
        ul_shm_offset_virt =
            ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE);
        /* Kernel logical address */
-       ul_shm_base = dev_context->sh_s.seg0_va + ul_shm_offset_virt;
+       ul_shm_base = dev_context->atlb_entry[0].ul_gpp_va + ul_shm_offset_virt;
 
        DBC_ASSERT(ul_shm_base != 0);
        /* 2nd wd is used as sync field */
@@ -345,83 +439,78 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
                                        OMAP343X_CONTROL_IVA2_BOOTMOD));
                }
        }
-
        if (!status) {
+               /* Reset and Unreset the RST2, so that BOOTADDR is copied to
+                * IVA2 SYSC register */
+               (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK,
+                       OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+               udelay(100);
                (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
                                        OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
-               mmu = dev_context->dsp_mmu;
-               if (mmu)
-                       dsp_mmu_exit(mmu);
-               mmu = dsp_mmu_init();
-               if (IS_ERR(mmu)) {
-                       dev_err(bridge, "dsp_mmu_init failed!\n");
-                       dev_context->dsp_mmu = NULL;
-                       status = (int)mmu;
-               }
-       }
-       if (!status) {
-               dev_context->dsp_mmu = mmu;
-               sm_sg = &dev_context->sh_s;
-               sg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa,
-                       sm_sg->seg0_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
-               if (IS_ERR_VALUE(sg0_da)) {
-                       status = (int)sg0_da;
-                       sg0_da = 0;
-               }
-       }
-       if (!status) {
-               sg1_da = iommu_kmap(mmu, sm_sg->seg1_da, sm_sg->seg1_pa,
-                       sm_sg->seg1_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
-               if (IS_ERR_VALUE(sg1_da)) {
-                       status = (int)sg1_da;
-                       sg1_da = 0;
-               }
-       }
-       if (!status) {
-               u32 da;
-               for (tlb_i = 0; tlb_i < BRDIOCTL_NUMOFMMUTLB; tlb_i++) {
-                       if (!tlb[tlb_i].ul_gpp_pa)
+               udelay(100);
+
+               /* Disbale the DSP MMU */
+               hw_mmu_disable(resources->dw_dmmu_base);
+               /* Disable TWL */
+               hw_mmu_twl_disable(resources->dw_dmmu_base);
+
+               /* Only make TLB entry if both addresses are non-zero */
+               for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB;
+                    entry_ndx++) {
+                       struct bridge_ioctl_extproc *e = &dev_context->atlb_entry[entry_ndx];
+                       struct hw_mmu_map_attrs_t map_attrs = {
+                               .endianism = e->endianism,
+                               .element_size = e->elem_size,
+                               .mixed_size = e->mixed_mode,
+                       };
+
+                       if (!e->ul_gpp_pa || !e->ul_dsp_va)
                                continue;
 
-                       dev_dbg(bridge, "IOMMU %d GppPa: 0x%x DspVa 0x%x Size"
-                               " 0x%x\n", tlb_i, tlb[tlb_i].ul_gpp_pa,
-                               tlb[tlb_i].ul_dsp_va, tlb[tlb_i].ul_size);
-
-                       da = iommu_kmap(mmu, tlb[tlb_i].ul_dsp_va,
-                               tlb[tlb_i].ul_gpp_pa, PAGE_SIZE,
-                               IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
-                       if (IS_ERR_VALUE(da)) {
-                               status = (int)da;
-                               break;
-                       }
-               }
-       }
-       if (!status) {
-               u32 da;
-               l4_i = 0;
-               while (l4_peripheral_table[l4_i].phys_addr) {
-                       da = iommu_kmap(mmu, l4_peripheral_table[l4_i].
-                               dsp_virt_addr, l4_peripheral_table[l4_i].
-                               phys_addr, PAGE_SIZE,
-                               IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32);
-                       if (IS_ERR_VALUE(da)) {
-                               status = (int)da;
-                               break;
-                       }
-                       l4_i++;
+                       dev_dbg(bridge,
+                                       "MMU %d, pa: 0x%x, va: 0x%x, size: 0x%x",
+                                       itmp_entry_ndx,
+                                       e->ul_gpp_pa,
+                                       e->ul_dsp_va,
+                                       e->ul_size);
+
+                       hw_mmu_tlb_add(dev_context->dw_dsp_mmu_base,
+                                       e->ul_gpp_pa,
+                                       e->ul_dsp_va,
+                                       e->ul_size,
+                                       itmp_entry_ndx,
+                                       &map_attrs, 1, 1);
+
+                       itmp_entry_ndx++;
                }
        }
 
        /* Lock the above TLB entries and get the BIOS and load monitor timer
         * information */
        if (!status) {
+               hw_mmu_num_locked_set(resources->dw_dmmu_base, itmp_entry_ndx);
+               hw_mmu_victim_num_set(resources->dw_dmmu_base, itmp_entry_ndx);
+               hw_mmu_ttb_set(resources->dw_dmmu_base,
+                              dev_context->pt_attrs->l1_base_pa);
+               hw_mmu_twl_enable(resources->dw_dmmu_base);
+               /* Enable the SmartIdle and AutoIdle bit for MMU_SYSCONFIG */
+
+               temp = __raw_readl((resources->dw_dmmu_base) + 0x10);
+               temp = (temp & 0xFFFFFFEF) | 0x11;
+               __raw_writel(temp, (resources->dw_dmmu_base) + 0x10);
+
+               /* Let the DSP MMU run */
+               hw_mmu_enable(resources->dw_dmmu_base);
+
                /* Enable the BIOS clock */
                (void)dev_get_symbol(dev_context->hdev_obj,
                                     BRIDGEINIT_BIOSGPTIMER, &ul_bios_gp_timer);
                (void)dev_get_symbol(dev_context->hdev_obj,
                                     BRIDGEINIT_LOADMON_GPTIMER,
                                     &ul_load_monitor_timer);
+       }
 
+       if (!status) {
                if (ul_load_monitor_timer != 0xFFFF) {
                        clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
                            ul_load_monitor_timer;
@@ -430,7 +519,9 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
                        dev_dbg(bridge, "Not able to get the symbol for Load "
                                "Monitor Timer\n");
                }
+       }
 
+       if (!status) {
                if (ul_bios_gp_timer != 0xFFFF) {
                        clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
                            ul_bios_gp_timer;
@@ -439,7 +530,9 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
                        dev_dbg(bridge,
                                "Not able to get the symbol for BIOS Timer\n");
                }
+       }
 
+       if (!status) {
                /* Set the DSP clock rate */
                (void)dev_get_symbol(dev_context->hdev_obj,
                                     "_BRIDGEINIT_DSP_FREQ", &ul_dsp_clk_addr);
@@ -492,6 +585,9 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
 
                /* Let DSP go */
                dev_dbg(bridge, "%s Unreset\n", __func__);
+               /* Enable DSP MMU Interrupts */
+               hw_mmu_event_enable(resources->dw_dmmu_base,
+                                   HW_MMU_ALL_INTERRUPTS);
                /* release the RST1, DSP starts executing now .. */
                (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0,
                                        OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
@@ -521,23 +617,11 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
 
                        /* update board state */
                        dev_context->dw_brd_state = BRD_RUNNING;
-                       return 0;
+                       /* (void)chnlsm_enable_interrupt(dev_context); */
                } else {
                        dev_context->dw_brd_state = BRD_UNKNOWN;
                }
        }
-
-       while (tlb_i--) {
-               if (!tlb[tlb_i].ul_gpp_pa)
-                       continue;
-               iommu_kunmap(mmu, tlb[tlb_i].ul_gpp_va);
-       }
-       while (l4_i--)
-               iommu_kunmap(mmu, l4_peripheral_table[l4_i].dsp_virt_addr);
-       if (sg0_da)
-               iommu_kunmap(mmu, sg0_da);
-       if (sg1_da)
-               iommu_kunmap(mmu, sg1_da);
        return status;
 }
 
@@ -553,9 +637,8 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
 {
        int status = 0;
        struct bridge_dev_context *dev_context = dev_ctxt;
+       struct pg_table_attrs *pt_attrs;
        u32 dsp_pwr_state;
-       int i;
-       struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry;
        struct omap_dsp_platform_data *pdata =
                omap_dspbridge_dev->dev.platform_data;
 
@@ -591,37 +674,23 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
 
        dsp_wdt_enable(false);
 
-       /* Reset DSP */
-       (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK,
-               OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
-
+       /* This is a good place to clear the MMU page tables as well */
+       if (dev_context->pt_attrs) {
+               pt_attrs = dev_context->pt_attrs;
+               memset((u8 *) pt_attrs->l1_base_va, 0x00, pt_attrs->l1_size);
+               memset((u8 *) pt_attrs->l2_base_va, 0x00, pt_attrs->l2_size);
+               memset((u8 *) pt_attrs->pg_info, 0x00,
+                      (pt_attrs->l2_num_pages * sizeof(struct page_info)));
+       }
        /* Disable the mailbox interrupts */
        if (dev_context->mbox) {
                omap_mbox_disable_irq(dev_context->mbox, IRQ_RX);
                omap_mbox_put(dev_context->mbox);
                dev_context->mbox = NULL;
        }
-       if (dev_context->dsp_mmu) {
-               pr_err("Proc stop mmu if statement\n");
-               for (i = 0; i < BRDIOCTL_NUMOFMMUTLB; i++) {
-                       if (!tlb[i].ul_gpp_pa)
-                               continue;
-                       iommu_kunmap(dev_context->dsp_mmu, tlb[i].ul_gpp_va);
-               }
-               i = 0;
-               while (l4_peripheral_table[i].phys_addr) {
-                       iommu_kunmap(dev_context->dsp_mmu,
-                               l4_peripheral_table[i].dsp_virt_addr);
-                       i++;
-               }
-               iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg0_da);
-               iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg1_da);
-               dsp_mmu_exit(dev_context->dsp_mmu);
-               dev_context->dsp_mmu = NULL;
-       }
-       /* Reset IVA IOMMU*/
-       (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK,
-               OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+       /* Reset IVA2 clocks*/
+       (*pdata->dsp_prm_write)(OMAP3430_RST1_IVA2_MASK | OMAP3430_RST2_IVA2_MASK |
+                       OMAP3430_RST3_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
 
        dsp_clock_disable_all(dev_context->dsp_per_clks);
        dsp_clk_disable(DSP_CLK_IVA2);
@@ -681,6 +750,10 @@ static int bridge_dev_create(struct bridge_dev_context
        struct bridge_dev_context *dev_context = NULL;
        s32 entry_ndx;
        struct cfg_hostres *resources = config_param;
+       struct pg_table_attrs *pt_attrs;
+       u32 pg_tbl_pa;
+       u32 pg_tbl_va;
+       u32 align_size;
        struct drv_data *drv_datap = dev_get_drvdata(bridge);
 
        /* Allocate and initialize a data structure to contain the bridge driver
@@ -711,8 +784,97 @@ static int bridge_dev_create(struct bridge_dev_context
        if (!dev_context->dw_dsp_base_addr)
                status = -EPERM;
 
+       pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL);
+       if (pt_attrs != NULL) {
+               /* Assuming that we use only DSP's memory map
+                * until 0x4000:0000 , we would need only 1024
+                * L1 enties i.e L1 size = 4K */
+               pt_attrs->l1_size = 0x1000;
+               align_size = pt_attrs->l1_size;
+               /* Align sizes are expected to be power of 2 */
+               /* we like to get aligned on L1 table size */
+               pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l1_size,
+                                                    align_size, &pg_tbl_pa);
+
+               /* Check if the PA is aligned for us */
+               if ((pg_tbl_pa) & (align_size - 1)) {
+                       /* PA not aligned to page table size ,
+                        * try with more allocation and align */
+                       mem_free_phys_mem((void *)pg_tbl_va, pg_tbl_pa,
+                                         pt_attrs->l1_size);
+                       /* we like to get aligned on L1 table size */
+                       pg_tbl_va =
+                           (u32) mem_alloc_phys_mem((pt_attrs->l1_size) * 2,
+                                                    align_size, &pg_tbl_pa);
+                       /* We should be able to get aligned table now */
+                       pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
+                       pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
+                       pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size * 2;
+                       /* Align the PA to the next 'align'  boundary */
+                       pt_attrs->l1_base_pa =
+                           ((pg_tbl_pa) +
+                            (align_size - 1)) & (~(align_size - 1));
+                       pt_attrs->l1_base_va =
+                           pg_tbl_va + (pt_attrs->l1_base_pa - pg_tbl_pa);
+               } else {
+                       /* We got aligned PA, cool */
+                       pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
+                       pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
+                       pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size;
+                       pt_attrs->l1_base_pa = pg_tbl_pa;
+                       pt_attrs->l1_base_va = pg_tbl_va;
+               }
+               if (pt_attrs->l1_base_va)
+                       memset((u8 *) pt_attrs->l1_base_va, 0x00,
+                              pt_attrs->l1_size);
+
+               /* number of L2 page tables = DMM pool used + SHMMEM +EXTMEM +
+                * L4 pages */
+               pt_attrs->l2_num_pages = ((DMMPOOLSIZE >> 20) + 6);
+               pt_attrs->l2_size = HW_MMU_COARSE_PAGE_SIZE *
+                   pt_attrs->l2_num_pages;
+               align_size = 4; /* Make it u32 aligned */
+               /* we like to get aligned on L1 table size */
+               pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l2_size,
+                                                    align_size, &pg_tbl_pa);
+               pt_attrs->l2_tbl_alloc_pa = pg_tbl_pa;
+               pt_attrs->l2_tbl_alloc_va = pg_tbl_va;
+               pt_attrs->l2_tbl_alloc_sz = pt_attrs->l2_size;
+               pt_attrs->l2_base_pa = pg_tbl_pa;
+               pt_attrs->l2_base_va = pg_tbl_va;
+
+               if (pt_attrs->l2_base_va)
+                       memset((u8 *) pt_attrs->l2_base_va, 0x00,
+                              pt_attrs->l2_size);
+
+               pt_attrs->pg_info = kzalloc(pt_attrs->l2_num_pages *
+                                       sizeof(struct page_info), GFP_KERNEL);
+               dev_dbg(bridge,
+                       "L1 pa %x, va %x, size %x\n L2 pa %x, va "
+                       "%x, size %x\n", pt_attrs->l1_base_pa,
+                       pt_attrs->l1_base_va, pt_attrs->l1_size,
+                       pt_attrs->l2_base_pa, pt_attrs->l2_base_va,
+                       pt_attrs->l2_size);
+               dev_dbg(bridge, "pt_attrs %p L2 NumPages %x pg_info %p\n",
+                       pt_attrs, pt_attrs->l2_num_pages, pt_attrs->pg_info);
+       }
+       if ((pt_attrs != NULL) && (pt_attrs->l1_base_va != 0) &&
+           (pt_attrs->l2_base_va != 0) && (pt_attrs->pg_info != NULL))
+               dev_context->pt_attrs = pt_attrs;
+       else
+               status = -ENOMEM;
+
        if (!status) {
+               spin_lock_init(&pt_attrs->pg_lock);
                dev_context->tc_word_swap_on = drv_datap->tc_wordswapon;
+
+               /* Set the Clock Divisor for the DSP module */
+               udelay(5);
+               /* MMU address is obtained from the host
+                * resources struct */
+               dev_context->dw_dsp_mmu_base = resources->dw_dmmu_base;
+       }
+       if (!status) {
                dev_context->hdev_obj = hdev_obj;
                /* Store current board state. */
                dev_context->dw_brd_state = BRD_UNKNOWN;
@@ -722,6 +884,23 @@ static int bridge_dev_create(struct bridge_dev_context
                /* Return ptr to our device state to the DSP API for storage */
                *dev_cntxt = dev_context;
        } else {
+               if (pt_attrs != NULL) {
+                       kfree(pt_attrs->pg_info);
+
+                       if (pt_attrs->l2_tbl_alloc_va) {
+                               mem_free_phys_mem((void *)
+                                                 pt_attrs->l2_tbl_alloc_va,
+                                                 pt_attrs->l2_tbl_alloc_pa,
+                                                 pt_attrs->l2_tbl_alloc_sz);
+                       }
+                       if (pt_attrs->l1_tbl_alloc_va) {
+                               mem_free_phys_mem((void *)
+                                                 pt_attrs->l1_tbl_alloc_va,
+                                                 pt_attrs->l1_tbl_alloc_pa,
+                                                 pt_attrs->l1_tbl_alloc_sz);
+                       }
+               }
+               kfree(pt_attrs);
                kfree(dev_context);
        }
 func_end:
@@ -789,6 +968,7 @@ static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
  */
 static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
 {
+       struct pg_table_attrs *pt_attrs;
        int status = 0;
        struct bridge_dev_context *dev_context = (struct bridge_dev_context *)
            dev_ctxt;
@@ -802,6 +982,23 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
 
        /* first put the device to stop state */
        bridge_brd_stop(dev_context);
+       if (dev_context->pt_attrs) {
+               pt_attrs = dev_context->pt_attrs;
+               kfree(pt_attrs->pg_info);
+
+               if (pt_attrs->l2_tbl_alloc_va) {
+                       mem_free_phys_mem((void *)pt_attrs->l2_tbl_alloc_va,
+                                         pt_attrs->l2_tbl_alloc_pa,
+                                         pt_attrs->l2_tbl_alloc_sz);
+               }
+               if (pt_attrs->l1_tbl_alloc_va) {
+                       mem_free_phys_mem((void *)pt_attrs->l1_tbl_alloc_va,
+                                         pt_attrs->l1_tbl_alloc_pa,
+                                         pt_attrs->l1_tbl_alloc_sz);
+               }
+               kfree(pt_attrs);
+
+       }
 
        if (dev_context->resources) {
                host_res = dev_context->resources;
@@ -832,6 +1029,8 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
                        iounmap((void *)host_res->dw_mem_base[3]);
                if (host_res->dw_mem_base[4])
                        iounmap((void *)host_res->dw_mem_base[4]);
+               if (host_res->dw_dmmu_base)
+                       iounmap(host_res->dw_dmmu_base);
                if (host_res->dw_per_base)
                        iounmap(host_res->dw_per_base);
                if (host_res->dw_per_pm_base)
@@ -845,6 +1044,7 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
                host_res->dw_mem_base[2] = (u32) NULL;
                host_res->dw_mem_base[3] = (u32) NULL;
                host_res->dw_mem_base[4] = (u32) NULL;
+               host_res->dw_dmmu_base = NULL;
                host_res->dw_sys_ctrl_base = NULL;
 
                kfree(host_res);
@@ -927,6 +1127,673 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
        return status;
 }
 
+/*
+ *  ======== bridge_brd_mem_map ========
+ *      This function maps MPU buffer to the DSP address space. It performs
+ *  linear to physical address translation if required. It translates each
+ *  page since linear addresses can be physically non-contiguous
+ *  All address & size arguments are assumed to be page aligned (in proc.c)
+ *
+ *  TODO: Disable MMU while updating the page tables (but that'll stall DSP)
+ */
+static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
+                                 u32 ul_mpu_addr, u32 virt_addr,
+                                 u32 ul_num_bytes, u32 ul_map_attr,
+                                 struct page **mapped_pages)
+{
+       u32 attrs;
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       struct hw_mmu_map_attrs_t hw_attrs;
+       struct vm_area_struct *vma;
+       struct mm_struct *mm = current->mm;
+       u32 write = 0;
+       u32 num_usr_pgs = 0;
+       struct page *mapped_page, *pg;
+       s32 pg_num;
+       u32 va = virt_addr;
+       struct task_struct *curr_task = current;
+       u32 pg_i = 0;
+       u32 mpu_addr, pa;
+
+       dev_dbg(bridge,
+               "%s hDevCtxt %p, pa %x, va %x, size %x, ul_map_attr %x\n",
+               __func__, dev_ctxt, ul_mpu_addr, virt_addr, ul_num_bytes,
+               ul_map_attr);
+       if (ul_num_bytes == 0)
+               return -EINVAL;
+
+       if (ul_map_attr & DSP_MAP_DIR_MASK) {
+               attrs = ul_map_attr;
+       } else {
+               /* Assign default attributes */
+               attrs = ul_map_attr | (DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE16);
+       }
+       /* Take mapping properties */
+       if (attrs & DSP_MAPBIGENDIAN)
+               hw_attrs.endianism = HW_BIG_ENDIAN;
+       else
+               hw_attrs.endianism = HW_LITTLE_ENDIAN;
+
+       hw_attrs.mixed_size = (enum hw_mmu_mixed_size_t)
+           ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2);
+       /* Ignore element_size if mixed_size is enabled */
+       if (hw_attrs.mixed_size == 0) {
+               if (attrs & DSP_MAPELEMSIZE8) {
+                       /* Size is 8 bit */
+                       hw_attrs.element_size = HW_ELEM_SIZE8BIT;
+               } else if (attrs & DSP_MAPELEMSIZE16) {
+                       /* Size is 16 bit */
+                       hw_attrs.element_size = HW_ELEM_SIZE16BIT;
+               } else if (attrs & DSP_MAPELEMSIZE32) {
+                       /* Size is 32 bit */
+                       hw_attrs.element_size = HW_ELEM_SIZE32BIT;
+               } else if (attrs & DSP_MAPELEMSIZE64) {
+                       /* Size is 64 bit */
+                       hw_attrs.element_size = HW_ELEM_SIZE64BIT;
+               } else {
+                       /*
+                        * Mixedsize isn't enabled, so size can't be
+                        * zero here
+                        */
+                       return -EINVAL;
+               }
+       }
+       if (attrs & DSP_MAPDONOTLOCK)
+               hw_attrs.donotlockmpupage = 1;
+       else
+               hw_attrs.donotlockmpupage = 0;
+
+       if (attrs & DSP_MAPVMALLOCADDR) {
+               return mem_map_vmalloc(dev_ctxt, ul_mpu_addr, virt_addr,
+                                      ul_num_bytes, &hw_attrs);
+       }
+       /*
+        * Do OS-specific user-va to pa translation.
+        * Combine physically contiguous regions to reduce TLBs.
+        * Pass the translated pa to pte_update.
+        */
+       if ((attrs & DSP_MAPPHYSICALADDR)) {
+               status = pte_update(dev_context, ul_mpu_addr, virt_addr,
+                                   ul_num_bytes, &hw_attrs);
+               goto func_cont;
+       }
+
+       /*
+        * Important Note: ul_mpu_addr is mapped from user application process
+        * to current process - it must lie completely within the current
+        * virtual memory address space in order to be of use to us here!
+        */
+       down_read(&mm->mmap_sem);
+       vma = find_vma(mm, ul_mpu_addr);
+       if (vma)
+               dev_dbg(bridge,
+                       "VMAfor UserBuf: ul_mpu_addr=%x, ul_num_bytes=%x, "
+                       "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr,
+                       ul_num_bytes, vma->vm_start, vma->vm_end,
+                       vma->vm_flags);
+
+       /*
+        * It is observed that under some circumstances, the user buffer is
+        * spread across several VMAs. So loop through and check if the entire
+        * user buffer is covered
+        */
+       while ((vma) && (ul_mpu_addr + ul_num_bytes > vma->vm_end)) {
+               /* jump to the next VMA region */
+               vma = find_vma(mm, vma->vm_end + 1);
+               dev_dbg(bridge,
+                       "VMA for UserBuf ul_mpu_addr=%x ul_num_bytes=%x, "
+                       "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr,
+                       ul_num_bytes, vma->vm_start, vma->vm_end,
+                       vma->vm_flags);
+       }
+       if (!vma) {
+               pr_err("%s: Failed to get VMA region for 0x%x (%d)\n",
+                      __func__, ul_mpu_addr, ul_num_bytes);
+               status = -EINVAL;
+               up_read(&mm->mmap_sem);
+               goto func_cont;
+       }
+
+       if (vma->vm_flags & VM_IO) {
+               num_usr_pgs = ul_num_bytes / PG_SIZE4K;
+               mpu_addr = ul_mpu_addr;
+
+               /* Get the physical addresses for user buffer */
+               for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) {
+                       pa = user_va2_pa(mm, mpu_addr);
+                       if (!pa) {
+                               status = -EPERM;
+                               pr_err("DSPBRIDGE: VM_IO mapping physical"
+                                      "address is invalid\n");
+                               break;
+                       }
+                       if (pfn_valid(__phys_to_pfn(pa))) {
+                               pg = PHYS_TO_PAGE(pa);
+                               get_page(pg);
+                               if (page_count(pg) < 1) {
+                                       pr_err("Bad page in VM_IO buffer\n");
+                                       bad_page_dump(pa, pg);
+                               }
+                       }
+                       status = pte_set(dev_context->pt_attrs, pa,
+                                        va, HW_PAGE_SIZE4KB, &hw_attrs);
+                       if (status)
+                               break;
+
+                       va += HW_PAGE_SIZE4KB;
+                       mpu_addr += HW_PAGE_SIZE4KB;
+                       pa += HW_PAGE_SIZE4KB;
+               }
+       } else {
+               num_usr_pgs = ul_num_bytes / PG_SIZE4K;
+               if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
+                       write = 1;
+
+               for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) {
+                       pg_num = get_user_pages(curr_task, mm, ul_mpu_addr, 1,
+                                               write, 1, &mapped_page, NULL);
+                       if (pg_num > 0) {
+                               if (page_count(mapped_page) < 1) {
+                                       pr_err("Bad page count after doing"
+                                              "get_user_pages on"
+                                              "user buffer\n");
+                                       bad_page_dump(page_to_phys(mapped_page),
+                                                     mapped_page);
+                               }
+                               status = pte_set(dev_context->pt_attrs,
+                                                page_to_phys(mapped_page), va,
+                                                HW_PAGE_SIZE4KB, &hw_attrs);
+                               if (status)
+                                       break;
+
+                               if (mapped_pages)
+                                       mapped_pages[pg_i] = mapped_page;
+
+                               va += HW_PAGE_SIZE4KB;
+                               ul_mpu_addr += HW_PAGE_SIZE4KB;
+                       } else {
+                               pr_err("DSPBRIDGE: get_user_pages FAILED,"
+                                      "MPU addr = 0x%x,"
+                                      "vma->vm_flags = 0x%lx,"
+                                      "get_user_pages Err"
+                                      "Value = %d, Buffer"
+                                      "size=0x%x\n", ul_mpu_addr,
+                                      vma->vm_flags, pg_num, ul_num_bytes);
+                               status = -EPERM;
+                               break;
+                       }
+               }
+       }
+       up_read(&mm->mmap_sem);
+func_cont:
+       if (status) {
+               /*
+                * Roll out the mapped pages incase it failed in middle of
+                * mapping
+                */
+               if (pg_i) {
+                       bridge_brd_mem_un_map(dev_context, virt_addr,
+                                          (pg_i * PG_SIZE4K));
+               }
+               status = -EPERM;
+       }
+       /*
+        * In any case, flush the TLB
+        * This is called from here instead from pte_update to avoid unnecessary
+        * repetition while mapping non-contiguous physical regions of a virtual
+        * region
+        */
+       flush_all(dev_context);
+       dev_dbg(bridge, "%s status %x\n", __func__, status);
+       return status;
+}
+
+/*
+ *  ======== bridge_brd_mem_un_map ========
+ *      Invalidate the PTEs for the DSP VA block to be unmapped.
+ *
+ *      PTEs of a mapped memory block are contiguous in any page table
+ *      So, instead of looking up the PTE address for every 4K block,
+ *      we clear consecutive PTEs until we unmap all the bytes
+ */
+static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
+                                    u32 virt_addr, u32 ul_num_bytes)
+{
+       u32 l1_base_va;
+       u32 l2_base_va;
+       u32 l2_base_pa;
+       u32 l2_page_num;
+       u32 pte_val;
+       u32 pte_size;
+       u32 pte_count;
+       u32 pte_addr_l1;
+       u32 pte_addr_l2 = 0;
+       u32 rem_bytes;
+       u32 rem_bytes_l2;
+       u32 va_curr;
+       struct page *pg = NULL;
+       int status = 0;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       struct pg_table_attrs *pt = dev_context->pt_attrs;
+       u32 temp;
+       u32 paddr;
+       u32 numof4k_pages = 0;
+
+       va_curr = virt_addr;
+       rem_bytes = ul_num_bytes;
+       rem_bytes_l2 = 0;
+       l1_base_va = pt->l1_base_va;
+       pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr);
+       dev_dbg(bridge, "%s dev_ctxt %p, va %x, NumBytes %x l1_base_va %x, "
+               "pte_addr_l1 %x\n", __func__, dev_ctxt, virt_addr,
+               ul_num_bytes, l1_base_va, pte_addr_l1);
+
+       while (rem_bytes && !status) {
+               u32 va_curr_orig = va_curr;
+               /* Find whether the L1 PTE points to a valid L2 PT */
+               pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr);
+               pte_val = *(u32 *) pte_addr_l1;
+               pte_size = hw_mmu_pte_size_l1(pte_val);
+
+               if (pte_size != HW_MMU_COARSE_PAGE_SIZE)
+                       goto skip_coarse_page;
+
+               /*
+                * Get the L2 PA from the L1 PTE, and find
+                * corresponding L2 VA
+                */
+               l2_base_pa = hw_mmu_pte_coarse_l1(pte_val);
+               l2_base_va = l2_base_pa - pt->l2_base_pa + pt->l2_base_va;
+               l2_page_num =
+                   (l2_base_pa - pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE;
+               /*
+                * Find the L2 PTE address from which we will start
+                * clearing, the number of PTEs to be cleared on this
+                * page, and the size of VA space that needs to be
+                * cleared on this L2 page
+                */
+               pte_addr_l2 = hw_mmu_pte_addr_l2(l2_base_va, va_curr);
+               pte_count = pte_addr_l2 & (HW_MMU_COARSE_PAGE_SIZE - 1);
+               pte_count = (HW_MMU_COARSE_PAGE_SIZE - pte_count) / sizeof(u32);
+               if (rem_bytes < (pte_count * PG_SIZE4K))
+                       pte_count = rem_bytes / PG_SIZE4K;
+               rem_bytes_l2 = pte_count * PG_SIZE4K;
+
+               /*
+                * Unmap the VA space on this L2 PT. A quicker way
+                * would be to clear pte_count entries starting from
+                * pte_addr_l2. However, below code checks that we don't
+                * clear invalid entries or less than 64KB for a 64KB
+                * entry. Similar checking is done for L1 PTEs too
+                * below
+                */
+               while (rem_bytes_l2 && !status) {
+                       pte_val = *(u32 *) pte_addr_l2;
+                       pte_size = hw_mmu_pte_size_l2(pte_val);
+                       /* va_curr aligned to pte_size? */
+                       if (pte_size == 0 || rem_bytes_l2 < pte_size ||
+                           va_curr & (pte_size - 1)) {
+                               status = -EPERM;
+                               break;
+                       }
+
+                       /* Collect Physical addresses from VA */
+                       paddr = (pte_val & ~(pte_size - 1));
+                       if (pte_size == HW_PAGE_SIZE64KB)
+                               numof4k_pages = 16;
+                       else
+                               numof4k_pages = 1;
+                       temp = 0;
+                       while (temp++ < numof4k_pages) {
+                               if (!pfn_valid(__phys_to_pfn(paddr))) {
+                                       paddr += HW_PAGE_SIZE4KB;
+                                       continue;
+                               }
+                               pg = PHYS_TO_PAGE(paddr);
+                               if (page_count(pg) < 1) {
+                                       pr_info("DSPBRIDGE: UNMAP function: "
+                                               "COUNT 0 FOR PA 0x%x, size = "
+                                               "0x%x\n", paddr, ul_num_bytes);
+                                       bad_page_dump(paddr, pg);
+                               } else {
+                                       set_page_dirty(pg);
+                                       page_cache_release(pg);
+                               }
+                               paddr += HW_PAGE_SIZE4KB;
+                       }
+                       if (hw_mmu_pte_clear(pte_addr_l2, va_curr, pte_size)) {
+                               status = -EPERM;
+                               goto EXIT_LOOP;
+                       }
+
+                       status = 0;
+                       rem_bytes_l2 -= pte_size;
+                       va_curr += pte_size;
+                       pte_addr_l2 += (pte_size >> 12) * sizeof(u32);
+               }
+               spin_lock(&pt->pg_lock);
+               if (rem_bytes_l2 == 0) {
+                       pt->pg_info[l2_page_num].num_entries -= pte_count;
+                       if (pt->pg_info[l2_page_num].num_entries == 0) {
+                               /*
+                                * Clear the L1 PTE pointing to the L2 PT
+                                */
+                               if (!hw_mmu_pte_clear(l1_base_va, va_curr_orig,
+                                                    HW_MMU_COARSE_PAGE_SIZE))
+                                       status = 0;
+                               else {
+                                       status = -EPERM;
+                                       spin_unlock(&pt->pg_lock);
+                                       goto EXIT_LOOP;
+                               }
+                       }
+                       rem_bytes -= pte_count * PG_SIZE4K;
+               } else
+                       status = -EPERM;
+
+               spin_unlock(&pt->pg_lock);
+               continue;
+skip_coarse_page:
+               /* va_curr aligned to pte_size? */
+               /* pte_size = 1 MB or 16 MB */
+               if (pte_size == 0 || rem_bytes < pte_size ||
+                   va_curr & (pte_size - 1)) {
+                       status = -EPERM;
+                       break;
+               }
+
+               if (pte_size == HW_PAGE_SIZE1MB)
+                       numof4k_pages = 256;
+               else
+                       numof4k_pages = 4096;
+               temp = 0;
+               /* Collect Physical addresses from VA */
+               paddr = (pte_val & ~(pte_size - 1));
+               while (temp++ < numof4k_pages) {
+                       if (pfn_valid(__phys_to_pfn(paddr))) {
+                               pg = PHYS_TO_PAGE(paddr);
+                               if (page_count(pg) < 1) {
+                                       pr_info("DSPBRIDGE: UNMAP function: "
+                                               "COUNT 0 FOR PA 0x%x, size = "
+                                               "0x%x\n", paddr, ul_num_bytes);
+                                       bad_page_dump(paddr, pg);
+                               } else {
+                                       set_page_dirty(pg);
+                                       page_cache_release(pg);
+                               }
+                       }
+                       paddr += HW_PAGE_SIZE4KB;
+               }
+               if (!hw_mmu_pte_clear(l1_base_va, va_curr, pte_size)) {
+                       status = 0;
+                       rem_bytes -= pte_size;
+                       va_curr += pte_size;
+               } else {
+                       status = -EPERM;
+                       goto EXIT_LOOP;
+               }
+       }
+       /*
+        * It is better to flush the TLB here, so that any stale old entries
+        * get flushed
+        */
+EXIT_LOOP:
+       flush_all(dev_context);
+       dev_dbg(bridge,
+               "%s: va_curr %x, pte_addr_l1 %x pte_addr_l2 %x rem_bytes %x,"
+               " rem_bytes_l2 %x status %x\n", __func__, va_curr, pte_addr_l1,
+               pte_addr_l2, rem_bytes, rem_bytes_l2, status);
+       return status;
+}
+
+/*
+ *  ======== user_va2_pa ========
+ *  Purpose:
+ *      This function walks through the page tables to convert a userland
+ *      virtual address to physical address
+ */
+static u32 user_va2_pa(struct mm_struct *mm, u32 address)
+{
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *ptep, pte;
+
+       pgd = pgd_offset(mm, address);
+       if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
+               pmd = pmd_offset(pgd, address);
+               if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
+                       ptep = pte_offset_map(pmd, address);
+                       if (ptep) {
+                               pte = *ptep;
+                               if (pte_present(pte))
+                                       return pte & PAGE_MASK;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/*
+ *  ======== pte_update ========
+ *      This function calculates the optimum page-aligned addresses and sizes
+ *      Caller must pass page-aligned values
+ */
+static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
+                            u32 va, u32 size,
+                            struct hw_mmu_map_attrs_t *map_attrs)
+{
+       u32 i;
+       u32 all_bits;
+       u32 pa_curr = pa;
+       u32 va_curr = va;
+       u32 num_bytes = size;
+       struct bridge_dev_context *dev_context = dev_ctxt;
+       int status = 0;
+       u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB,
+               HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB
+       };
+
+       while (num_bytes && !status) {
+               /* To find the max. page size with which both PA & VA are
+                * aligned */
+               all_bits = pa_curr | va_curr;
+
+               for (i = 0; i < 4; i++) {
+                       if ((num_bytes >= page_size[i]) && ((all_bits &
+                                                            (page_size[i] -
+                                                             1)) == 0)) {
+                               status =
+                                   pte_set(dev_context->pt_attrs, pa_curr,
+                                           va_curr, page_size[i], map_attrs);
+                               pa_curr += page_size[i];
+                               va_curr += page_size[i];
+                               num_bytes -= page_size[i];
+                               /* Don't try smaller sizes. Hopefully we have
+                                * reached an address aligned to a bigger page
+                                * size */
+                               break;
+                       }
+               }
+       }
+
+       return status;
+}
+
+/*
+ *  ======== pte_set ========
+ *      This function calculates PTE address (MPU virtual) to be updated
+ *      It also manages the L2 page tables
+ */
+static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va,
+                         u32 size, struct hw_mmu_map_attrs_t *attrs)
+{
+       u32 i;
+       u32 pte_val;
+       u32 pte_addr_l1;
+       u32 pte_size;
+       /* Base address of the PT that will be updated */
+       u32 pg_tbl_va;
+       u32 l1_base_va;
+       /* Compiler warns that the next three variables might be used
+        * uninitialized in this function. Doesn't seem so. Working around,
+        * anyways. */
+       u32 l2_base_va = 0;
+       u32 l2_base_pa = 0;
+       u32 l2_page_num = 0;
+       int status = 0;
+
+       l1_base_va = pt->l1_base_va;
+       pg_tbl_va = l1_base_va;
+       if ((size == HW_PAGE_SIZE64KB) || (size == HW_PAGE_SIZE4KB)) {
+               /* Find whether the L1 PTE points to a valid L2 PT */
+               pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va);
+               if (pte_addr_l1 <= (pt->l1_base_va + pt->l1_size)) {
+                       pte_val = *(u32 *) pte_addr_l1;
+                       pte_size = hw_mmu_pte_size_l1(pte_val);
+               } else {
+                       return -EPERM;
+               }
+               spin_lock(&pt->pg_lock);
+               if (pte_size == HW_MMU_COARSE_PAGE_SIZE) {
+                       /* Get the L2 PA from the L1 PTE, and find
+                        * corresponding L2 VA */
+                       l2_base_pa = hw_mmu_pte_coarse_l1(pte_val);
+                       l2_base_va =
+                           l2_base_pa - pt->l2_base_pa + pt->l2_base_va;
+                       l2_page_num =
+                           (l2_base_pa -
+                            pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE;
+               } else if (pte_size == 0) {
+                       /* L1 PTE is invalid. Allocate a L2 PT and
+                        * point the L1 PTE to it */
+                       /* Find a free L2 PT. */
+                       for (i = 0; (i < pt->l2_num_pages) &&
+                            (pt->pg_info[i].num_entries != 0); i++)
+                               ;;
+                       if (i < pt->l2_num_pages) {
+                               l2_page_num = i;
+                               l2_base_pa = pt->l2_base_pa + (l2_page_num *
+                                               HW_MMU_COARSE_PAGE_SIZE);
+                               l2_base_va = pt->l2_base_va + (l2_page_num *
+                                               HW_MMU_COARSE_PAGE_SIZE);
+                               /* Endianness attributes are ignored for
+                                * HW_MMU_COARSE_PAGE_SIZE */
+                               status =
+                                   hw_mmu_pte_set(l1_base_va, l2_base_pa, va,
+                                                  HW_MMU_COARSE_PAGE_SIZE,
+                                                  attrs);
+                       } else {
+                               status = -ENOMEM;
+                       }
+               } else {
+                       /* Found valid L1 PTE of another size.
+                        * Should not overwrite it. */
+                       status = -EPERM;
+               }
+               if (!status) {
+                       pg_tbl_va = l2_base_va;
+                       if (size == HW_PAGE_SIZE64KB)
+                               pt->pg_info[l2_page_num].num_entries += 16;
+                       else
+                               pt->pg_info[l2_page_num].num_entries++;
+                       dev_dbg(bridge, "PTE: L2 BaseVa %x, BasePa %x, PageNum "
+                               "%x, num_entries %x\n", l2_base_va,
+                               l2_base_pa, l2_page_num,
+                               pt->pg_info[l2_page_num].num_entries);
+               }
+               spin_unlock(&pt->pg_lock);
+       }
+       if (!status) {
+               dev_dbg(bridge, "PTE: pg_tbl_va %x, pa %x, va %x, size %x\n",
+                       pg_tbl_va, pa, va, size);
+               dev_dbg(bridge, "PTE: endianism %x, element_size %x, "
+                       "mixed_size %x\n", attrs->endianism,
+                       attrs->element_size, attrs->mixed_size);
+               status = hw_mmu_pte_set(pg_tbl_va, pa, va, size, attrs);
+       }
+
+       return status;
+}
+
+/* Memory map kernel VA -- memory allocated with vmalloc */
+static int mem_map_vmalloc(struct bridge_dev_context *dev_context,
+                                 u32 ul_mpu_addr, u32 virt_addr,
+                                 u32 ul_num_bytes,
+                                 struct hw_mmu_map_attrs_t *hw_attrs)
+{
+       int status = 0;
+       struct page *page[1];
+       u32 i;
+       u32 pa_curr;
+       u32 pa_next;
+       u32 va_curr;
+       u32 size_curr;
+       u32 num_pages;
+       u32 pa;
+       u32 num_of4k_pages;
+       u32 temp = 0;
+
+       /*
+        * Do Kernel va to pa translation.
+        * Combine physically contiguous regions to reduce TLBs.
+        * Pass the translated pa to pte_update.
+        */
+       num_pages = ul_num_bytes / PAGE_SIZE;   /* PAGE_SIZE = OS page size */
+       i = 0;
+       va_curr = ul_mpu_addr;
+       page[0] = vmalloc_to_page((void *)va_curr);
+       pa_next = page_to_phys(page[0]);
+       while (!status && (i < num_pages)) {
+               /*
+                * Reuse pa_next from the previous iteraion to avoid
+                * an extra va2pa call
+                */
+               pa_curr = pa_next;
+               size_curr = PAGE_SIZE;
+               /*
+                * If the next page is physically contiguous,
+                * map it with the current one by increasing
+                * the size of the region to be mapped
+                */
+               while (++i < num_pages) {
+                       page[0] =
+                           vmalloc_to_page((void *)(va_curr + size_curr));
+                       pa_next = page_to_phys(page[0]);
+
+                       if (pa_next == (pa_curr + size_curr))
+                               size_curr += PAGE_SIZE;
+                       else
+                               break;
+
+               }
+               if (pa_next == 0) {
+                       status = -ENOMEM;
+                       break;
+               }
+               pa = pa_curr;
+               num_of4k_pages = size_curr / HW_PAGE_SIZE4KB;
+               while (temp++ < num_of4k_pages) {
+                       get_page(PHYS_TO_PAGE(pa));
+                       pa += HW_PAGE_SIZE4KB;
+               }
+               status = pte_update(dev_context, pa_curr, virt_addr +
+                                   (va_curr - ul_mpu_addr), size_curr,
+                                   hw_attrs);
+               va_curr += size_curr;
+       }
+       /*
+        * In any case, flush the TLB
+        * This is called from here instead from pte_update to avoid unnecessary
+        * repetition while mapping non-contiguous physical regions of a virtual
+        * region
+        */
+       flush_all(dev_context);
+       dev_dbg(bridge, "%s status %x\n", __func__, status);
+       return status;
+}
+
 /*
  *  ======== wait_for_start ========
  *      Wait for the singal from DSP that it has started, or time out.
index b57a9fd5e757d98dac71c2f1de68dbd12dfaebd7..fb9026e1403c0d29f8e624681217d5286fc33d51 100644 (file)
 #include <dspbridge/dev.h>
 #include <dspbridge/iodefs.h>
 
+/* ------------------------------------ Hardware Abstraction Layer */
+#include <hw_defs.h>
+#include <hw_mmu.h>
+
 #include <dspbridge/pwr_sh.h>
 
 /*  ----------------------------------- Bridge Driver */
index 66dbf02549e40caef9b046335773679a2abb6577..ba2961049dad720d5f26cbb4cdb9b5cb6bb2952f 100644 (file)
@@ -134,16 +134,17 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
 
                if (!status) {
                        ul_tlb_base_virt =
-                           dev_context->sh_s.seg0_da * DSPWORDSIZE;
+                           dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE;
                        DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
-                       dw_ext_prog_virt_mem = dev_context->sh_s.seg0_va;
+                       dw_ext_prog_virt_mem =
+                           dev_context->atlb_entry[0].ul_gpp_va;
 
                        if (!trace_read) {
                                ul_shm_offset_virt =
                                    ul_shm_base_virt - ul_tlb_base_virt;
                                ul_shm_offset_virt +=
                                    PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base +
-                                                 1, PAGE_SIZE * 16);
+                                                 1, HW_PAGE_SIZE64KB);
                                dw_ext_prog_virt_mem -= ul_shm_offset_virt;
                                dw_ext_prog_virt_mem +=
                                    (ul_ext_base - ul_dyn_ext_base);
@@ -317,9 +318,8 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context,
                        ret = -EPERM;
 
                if (!ret) {
-                       ul_tlb_base_virt = dev_context->sh_s.seg0_da *
-                                                               DSPWORDSIZE;
-
+                       ul_tlb_base_virt =
+                           dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE;
                        DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
 
                        if (symbols_reloaded) {
@@ -337,7 +337,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context,
                            ul_shm_base_virt - ul_tlb_base_virt;
                        if (trace_load) {
                                dw_ext_prog_virt_mem =
-                                       dev_context->sh_s.seg0_va;
+                                   dev_context->atlb_entry[0].ul_gpp_va;
                        } else {
                                dw_ext_prog_virt_mem = host_res->dw_mem_base[1];
                                dw_ext_prog_virt_mem +=
@@ -393,6 +393,7 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val)
                omap_dspbridge_dev->dev.platform_data;
        struct cfg_hostres *resources = dev_context->resources;
        int status = 0;
+       u32 temp;
 
        if (!dev_context->mbox)
                return 0;
@@ -436,7 +437,7 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val)
                omap_mbox_restore_ctx(dev_context->mbox);
 
                /* Access MMU SYS CONFIG register to generate a short wakeup */
-               iommu_read_reg(dev_context->dsp_mmu, MMU_SYSCONFIG);
+               temp = readl(resources->dw_dmmu_base + 0x10);
 
                dev_context->dw_brd_state = BRD_RUNNING;
        } else if (dev_context->dw_brd_state == BRD_RETENTION) {
index e24ea0c7391491cef345e464cca0fde7dd944e92..3430418190da8fa62ad31c09843362b2c40edda1 100644 (file)
 #include <dspbridge/drv.h>
 #include <dspbridge/wdt.h>
 
+static u32 fault_addr;
+
+static void mmu_fault_dpc(unsigned long data)
+{
+       struct deh_mgr *deh = (void *)data;
+
+       if (!deh)
+               return;
+
+       bridge_deh_notify(deh, DSP_MMUFAULT, 0);
+}
+
+static irqreturn_t mmu_fault_isr(int irq, void *data)
+{
+       struct deh_mgr *deh = data;
+       struct cfg_hostres *resources;
+       u32 event;
+
+       if (!deh)
+               return IRQ_HANDLED;
+
+       resources = deh->hbridge_context->resources;
+       if (!resources) {
+               dev_dbg(bridge, "%s: Failed to get Host Resources\n",
+                               __func__);
+               return IRQ_HANDLED;
+       }
+
+       hw_mmu_event_status(resources->dw_dmmu_base, &event);
+       if (event == HW_MMU_TRANSLATION_FAULT) {
+               hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr);
+               dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__,
+                               event, fault_addr);
+               /*
+                * Schedule a DPC directly. In the future, it may be
+                * necessary to check if DSP MMU fault is intended for
+                * Bridge.
+                */
+               tasklet_schedule(&deh->dpc_tasklet);
+
+               /* Disable the MMU events, else once we clear it will
+                * start to raise INTs again */
+               hw_mmu_event_disable(resources->dw_dmmu_base,
+                               HW_MMU_TRANSLATION_FAULT);
+       } else {
+               hw_mmu_event_disable(resources->dw_dmmu_base,
+                               HW_MMU_ALL_INTERRUPTS);
+       }
+       return IRQ_HANDLED;
+}
+
 int bridge_deh_create(struct deh_mgr **ret_deh,
                struct dev_object *hdev_obj)
 {
@@ -58,9 +109,18 @@ int bridge_deh_create(struct deh_mgr **ret_deh,
        }
        ntfy_init(deh->ntfy_obj);
 
+       /* Create a MMUfault DPC */
+       tasklet_init(&deh->dpc_tasklet, mmu_fault_dpc, (u32) deh);
+
        /* Fill in context structure */
        deh->hbridge_context = hbridge_context;
 
+       /* Install ISR function for DSP MMU fault */
+       status = request_irq(INT_DSP_MMU_IRQ, mmu_fault_isr, 0,
+                       "DspBridge\tiommu fault", deh);
+       if (status < 0)
+               goto err;
+
        *ret_deh = deh;
        return 0;
 
@@ -80,6 +140,11 @@ int bridge_deh_destroy(struct deh_mgr *deh)
                ntfy_delete(deh->ntfy_obj);
                kfree(deh->ntfy_obj);
        }
+       /* Disable DSP MMU fault */
+       free_irq(INT_DSP_MMU_IRQ, deh);
+
+       /* Free DPC object */
+       tasklet_kill(&deh->dpc_tasklet);
 
        /* Deallocate the DEH manager object */
        kfree(deh);
@@ -101,6 +166,48 @@ int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask,
                return ntfy_unregister(deh->ntfy_obj, hnotification);
 }
 
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+static void mmu_fault_print_stack(struct bridge_dev_context *dev_context)
+{
+       struct cfg_hostres *resources;
+       struct hw_mmu_map_attrs_t map_attrs = {
+               .endianism = HW_LITTLE_ENDIAN,
+               .element_size = HW_ELEM_SIZE16BIT,
+               .mixed_size = HW_MMU_CPUES,
+       };
+       void *dummy_va_addr;
+
+       resources = dev_context->resources;
+       dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC);
+
+       /*
+        * Before acking the MMU fault, let's make sure MMU can only
+        * access entry #0. Then add a new entry so that the DSP OS
+        * can continue in order to dump the stack.
+        */
+       hw_mmu_twl_disable(resources->dw_dmmu_base);
+       hw_mmu_tlb_flush_all(resources->dw_dmmu_base);
+
+       hw_mmu_tlb_add(resources->dw_dmmu_base,
+                       virt_to_phys(dummy_va_addr), fault_addr,
+                       HW_PAGE_SIZE4KB, 1,
+                       &map_attrs, HW_SET, HW_SET);
+
+       dsp_clk_enable(DSP_CLK_GPT8);
+
+       dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);
+
+       /* Clear MMU interrupt */
+       hw_mmu_event_ack(resources->dw_dmmu_base,
+                       HW_MMU_TRANSLATION_FAULT);
+       dump_dsp_stack(dev_context);
+       dsp_clk_disable(DSP_CLK_GPT8);
+
+       hw_mmu_disable(resources->dw_dmmu_base);
+       free_page((unsigned long)dummy_va_addr);
+}
+#endif
+
 static inline const char *event_to_string(int event)
 {
        switch (event) {
@@ -133,7 +240,13 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info)
 #endif
                break;
        case DSP_MMUFAULT:
-               dev_err(bridge, "%s: %s, addr=0x%x", __func__, str, info);
+               dev_err(bridge, "%s: %s, addr=0x%x", __func__,
+                               str, fault_addr);
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
+               print_dsp_trace_buffer(dev_context);
+               dump_dl_modules(dev_context);
+               mmu_fault_print_stack(dev_context);
+#endif
                break;
        default:
                dev_err(bridge, "%s: %s", __func__, str);
diff --git a/drivers/staging/tidspbridge/hw/EasiGlobal.h b/drivers/staging/tidspbridge/hw/EasiGlobal.h
new file mode 100644 (file)
index 0000000..e48d7f6
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * EasiGlobal.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _EASIGLOBAL_H
+#define _EASIGLOBAL_H
+#include <linux/types.h>
+
+/*
+ * DEFINE:        READ_ONLY, WRITE_ONLY &  READ_WRITE
+ *
+ * DESCRIPTION: Defines used to describe register types for EASI-checker tests.
+ */
+
+#define READ_ONLY    1
+#define WRITE_ONLY   2
+#define READ_WRITE   3
+
+/*
+ * MACRO:        _DEBUG_LEVEL1_EASI
+ *
+ * DESCRIPTION:  A MACRO which can be used to indicate that a particular beach
+ *               register access function was called.
+ *
+ * NOTE:         We currently dont use this functionality.
+ */
+#define _DEBUG_LEVEL1_EASI(easi_num)     ((void)0)
+
+#endif /* _EASIGLOBAL_H */
diff --git a/drivers/staging/tidspbridge/hw/MMUAccInt.h b/drivers/staging/tidspbridge/hw/MMUAccInt.h
new file mode 100644 (file)
index 0000000..1cefca3
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * MMUAccInt.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _MMU_ACC_INT_H
+#define _MMU_ACC_INT_H
+
+/* Mappings of level 1 EASI function numbers to function names */
+
+#define EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32 (MMU_BASE_EASIL1 + 3)
+#define EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32  (MMU_BASE_EASIL1 + 17)
+#define EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32    (MMU_BASE_EASIL1 + 39)
+#define EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32   (MMU_BASE_EASIL1 + 51)
+#define EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32 (MMU_BASE_EASIL1 + 102)
+#define EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 103)
+#define EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32 (MMU_BASE_EASIL1 + 156)
+#define EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32 (MMU_BASE_EASIL1 + 174)
+#define EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32   (MMU_BASE_EASIL1 + 180)
+#define EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32     (MMU_BASE_EASIL1 + 190)
+#define EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32   (MMU_BASE_EASIL1 + 194)
+#define EASIL1_MMUMMU_TTB_WRITE_REGISTER32  (MMU_BASE_EASIL1 + 198)
+#define EASIL1_MMUMMU_LOCK_READ_REGISTER32   (MMU_BASE_EASIL1 + 203)
+#define EASIL1_MMUMMU_LOCK_WRITE_REGISTER32  (MMU_BASE_EASIL1 + 204)
+#define EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32  (MMU_BASE_EASIL1 + 205)
+#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32 (MMU_BASE_EASIL1 + 209)
+#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32 (MMU_BASE_EASIL1 + 211)
+#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32  (MMU_BASE_EASIL1 + 212)
+#define EASIL1_MMUMMU_LD_TLB_READ_REGISTER32    (MMU_BASE_EASIL1 + 213)
+#define EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32   (MMU_BASE_EASIL1 + 214)
+#define EASIL1_MMUMMU_CAM_WRITE_REGISTER32   (MMU_BASE_EASIL1 + 226)
+#define EASIL1_MMUMMU_RAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 268)
+#define EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32  (MMU_BASE_EASIL1 + 322)
+
+/* Register offset address definitions */
+#define MMU_MMU_SYSCONFIG_OFFSET   0x10
+#define MMU_MMU_IRQSTATUS_OFFSET  0x18
+#define MMU_MMU_IRQENABLE_OFFSET    0x1c
+#define MMU_MMU_WALKING_ST_OFFSET 0x40
+#define MMU_MMU_CNTL_OFFSET   0x44
+#define MMU_MMU_FAULT_AD_OFFSET  0x48
+#define MMU_MMU_TTB_OFFSET  0x4c
+#define MMU_MMU_LOCK_OFFSET   0x50
+#define MMU_MMU_LD_TLB_OFFSET  0x54
+#define MMU_MMU_CAM_OFFSET   0x58
+#define MMU_MMU_RAM_OFFSET   0x5c
+#define MMU_MMU_GFLUSH_OFFSET  0x60
+#define MMU_MMU_FLUSH_ENTRY_OFFSET  0x64
+/* Bitfield mask and offset declarations */
+#define MMU_MMU_SYSCONFIG_IDLE_MODE_MASK  0x18
+#define MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET  3
+#define MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK  0x1
+#define MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET   0
+#define MMU_MMU_WALKING_ST_TWL_RUNNING_MASK 0x1
+#define MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET  0
+#define MMU_MMU_CNTL_TWL_ENABLE_MASK 0x4
+#define MMU_MMU_CNTL_TWL_ENABLE_OFFSET 2
+#define MMU_MMU_CNTL_MMU_ENABLE_MASK    0x2
+#define MMU_MMU_CNTL_MMU_ENABLE_OFFSET   1
+#define MMU_MMU_LOCK_BASE_VALUE_MASK 0xfc00
+#define MMU_MMU_LOCK_BASE_VALUE_OFFSET   10
+#define MMU_MMU_LOCK_CURRENT_VICTIM_MASK   0x3f0
+#define MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET    4
+
+#endif /* _MMU_ACC_INT_H */
diff --git a/drivers/staging/tidspbridge/hw/MMURegAcM.h b/drivers/staging/tidspbridge/hw/MMURegAcM.h
new file mode 100644 (file)
index 0000000..ab1a16d
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * MMURegAcM.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _MMU_REG_ACM_H
+#define _MMU_REG_ACM_H
+
+#include <linux/io.h>
+#include <EasiGlobal.h>
+
+#include "MMUAccInt.h"
+
+#if defined(USE_LEVEL_1_MACROS)
+
+#define MMUMMU_SYSCONFIG_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_SYSCONFIG_OFFSET))
+
+#define MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32);\
+    data &= ~(MMU_MMU_SYSCONFIG_IDLE_MODE_MASK);\
+    new_value <<= MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET;\
+    new_value &= MMU_MMU_SYSCONFIG_IDLE_MODE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32);\
+    data &= ~(MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK);\
+    new_value <<= MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET;\
+    new_value &= MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_IRQSTATUS_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(easil1_mmummu_irqstatus_read_register32),\
+      __raw_readl((base_address)+MMU_MMU_IRQSTATUS_OFFSET))
+
+#define MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_IRQSTATUS_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_IRQENABLE_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_IRQENABLE_OFFSET))
+
+#define MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_WALKING_STTWL_RUNNING_READ32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32),\
+      (((__raw_readl(((base_address)+(MMU_MMU_WALKING_ST_OFFSET))))\
+      & MMU_MMU_WALKING_ST_TWL_RUNNING_MASK) >>\
+      MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET))
+
+#define MMUMMU_CNTLTWL_ENABLE_READ32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32),\
+      (((__raw_readl(((base_address)+(MMU_MMU_CNTL_OFFSET)))) &\
+      MMU_MMU_CNTL_TWL_ENABLE_MASK) >>\
+      MMU_MMU_CNTL_TWL_ENABLE_OFFSET))
+
+#define MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_CNTL_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32);\
+    data &= ~(MMU_MMU_CNTL_TWL_ENABLE_MASK);\
+    new_value <<= MMU_MMU_CNTL_TWL_ENABLE_OFFSET;\
+    new_value &= MMU_MMU_CNTL_TWL_ENABLE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_CNTL_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32);\
+    data &= ~(MMU_MMU_CNTL_MMU_ENABLE_MASK);\
+    new_value <<= MMU_MMU_CNTL_MMU_ENABLE_OFFSET;\
+    new_value &= MMU_MMU_CNTL_MMU_ENABLE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_FAULT_AD_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_FAULT_AD_OFFSET))
+
+#define MMUMMU_TTB_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_TTB_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_TTB_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_LOCK_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_LOCK_OFFSET))
+
+#define MMUMMU_LOCK_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_LOCK_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_LOCK_BASE_VALUE_READ32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32),\
+      (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\
+      MMU_MMU_LOCK_BASE_VALUE_MASK) >>\
+      MMU_MMU_LOCK_BASE_VALUE_OFFSET))
+
+#define MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_LOCK_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(easil1_mmummu_lock_base_value_write32);\
+    data &= ~(MMU_MMU_LOCK_BASE_VALUE_MASK);\
+    new_value <<= MMU_MMU_LOCK_BASE_VALUE_OFFSET;\
+    new_value &= MMU_MMU_LOCK_BASE_VALUE_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_LOCK_CURRENT_VICTIM_READ32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32),\
+      (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\
+      MMU_MMU_LOCK_CURRENT_VICTIM_MASK) >>\
+      MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET))
+
+#define MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_LOCK_OFFSET;\
+    register u32 data = __raw_readl((base_address)+offset);\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32);\
+    data &= ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK);\
+    new_value <<= MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET;\
+    new_value &= MMU_MMU_LOCK_CURRENT_VICTIM_MASK;\
+    new_value |= data;\
+    __raw_writel(new_value, base_address+offset);\
+}
+
+#define MMUMMU_LOCK_CURRENT_VICTIM_SET32(var, value)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32),\
+      (((var) & ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK)) |\
+      (((value) << MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET) &\
+      MMU_MMU_LOCK_CURRENT_VICTIM_MASK)))
+
+#define MMUMMU_LD_TLB_READ_REGISTER32(base_address)\
+    (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_READ_REGISTER32),\
+      __raw_readl((base_address)+MMU_MMU_LD_TLB_OFFSET))
+
+#define MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_LD_TLB_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_CAM_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_CAM_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CAM_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_RAM_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_RAM_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_RAM_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#define MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, value)\
+{\
+    const u32 offset = MMU_MMU_FLUSH_ENTRY_OFFSET;\
+    register u32 new_value = (value);\
+    _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32);\
+    __raw_writel(new_value, (base_address)+offset);\
+}
+
+#endif /* USE_LEVEL_1_MACROS */
+
+#endif /* _MMU_REG_ACM_H */
diff --git a/drivers/staging/tidspbridge/hw/hw_defs.h b/drivers/staging/tidspbridge/hw/hw_defs.h
new file mode 100644 (file)
index 0000000..d5266d4
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * hw_defs.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Global HW definitions
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _HW_DEFS_H
+#define _HW_DEFS_H
+
+/* Page size */
+#define HW_PAGE_SIZE4KB   0x1000
+#define HW_PAGE_SIZE64KB  0x10000
+#define HW_PAGE_SIZE1MB   0x100000
+#define HW_PAGE_SIZE16MB  0x1000000
+
+/* hw_status:  return type for HW API */
+typedef long hw_status;
+
+/*  Macro used to set and clear any bit */
+#define HW_CLEAR       0
+#define HW_SET         1
+
+/* hw_endianism_t:  Enumerated Type used to specify the endianism
+ *             Do NOT change these values. They are used as bit fields. */
+enum hw_endianism_t {
+       HW_LITTLE_ENDIAN,
+       HW_BIG_ENDIAN
+};
+
+/* hw_element_size_t:  Enumerated Type used to specify the element size
+ *             Do NOT change these values. They are used as bit fields. */
+enum hw_element_size_t {
+       HW_ELEM_SIZE8BIT,
+       HW_ELEM_SIZE16BIT,
+       HW_ELEM_SIZE32BIT,
+       HW_ELEM_SIZE64BIT
+};
+
+/* hw_idle_mode_t:  Enumerated Type used to specify Idle modes */
+enum hw_idle_mode_t {
+       HW_FORCE_IDLE,
+       HW_NO_IDLE,
+       HW_SMART_IDLE
+};
+
+#endif /* _HW_DEFS_H */
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c
new file mode 100644 (file)
index 0000000..014f5d5
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * hw_mmu.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * API definitions to setup MMU TLB and PTE
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/io.h>
+#include "MMURegAcM.h"
+#include <hw_defs.h>
+#include <hw_mmu.h>
+#include <linux/types.h>
+#include <linux/err.h>
+
+#define MMU_BASE_VAL_MASK      0xFC00
+#define MMU_PAGE_MAX        3
+#define MMU_ELEMENTSIZE_MAX      3
+#define MMU_ADDR_MASK      0xFFFFF000
+#define MMU_TTB_MASK        0xFFFFC000
+#define MMU_SECTION_ADDR_MASK    0xFFF00000
+#define MMU_SSECTION_ADDR_MASK   0xFF000000
+#define MMU_PAGE_TABLE_MASK      0xFFFFFC00
+#define MMU_LARGE_PAGE_MASK      0xFFFF0000
+#define MMU_SMALL_PAGE_MASK      0xFFFFF000
+
+#define MMU_LOAD_TLB   0x00000001
+#define MMU_GFLUSH     0x60
+
+/*
+ * hw_mmu_page_size_t: Enumerated Type used to specify the MMU Page Size(SLSS)
+ */
+enum hw_mmu_page_size_t {
+       HW_MMU_SECTION,
+       HW_MMU_LARGE_PAGE,
+       HW_MMU_SMALL_PAGE,
+       HW_MMU_SUPERSECTION
+};
+
+/*
+ * FUNCTION          : mmu_flush_entry
+ *
+ * INPUTS:
+ *
+ *       Identifier      : base_address
+ *       Type          : const u32
+ *       Description     : Base Address of instance of MMU module
+ *
+ * RETURNS:
+ *
+ *       Type          : hw_status
+ *       Description     : 0            -- No errors occured
+ *                      RET_BAD_NULL_PARAM     -- A Pointer
+ *                                             Paramater was set to NULL
+ *
+ * PURPOSE:          : Flush the TLB entry pointed by the
+ *                     lock counter register
+ *                     even if this entry is set protected
+ *
+ * METHOD:            : Check the Input parameter and Flush a
+ *                      single entry in the TLB.
+ */
+static hw_status mmu_flush_entry(const void __iomem *base_address);
+
+/*
+ * FUNCTION          : mmu_set_cam_entry
+ *
+ * INPUTS:
+ *
+ *       Identifier      : base_address
+ *       TypE          : const u32
+ *       Description     : Base Address of instance of MMU module
+ *
+ *       Identifier      : page_sz
+ *       TypE          : const u32
+ *       Description     : It indicates the page size
+ *
+ *       Identifier      : preserved_bit
+ *       Type          : const u32
+ *       Description     : It indicates the TLB entry is preserved entry
+ *                                                     or not
+ *
+ *       Identifier      : valid_bit
+ *       Type          : const u32
+ *       Description     : It indicates the TLB entry is valid entry or not
+ *
+ *
+ *       Identifier      : virtual_addr_tag
+ *       Type          : const u32
+ *       Description     : virtual Address
+ *
+ * RETURNS:
+ *
+ *       Type          : hw_status
+ *       Description     : 0            -- No errors occured
+ *                      RET_BAD_NULL_PARAM     -- A Pointer Paramater
+ *                                                was set to NULL
+ *                      RET_PARAM_OUT_OF_RANGE -- Input Parameter out
+ *                                                of Range
+ *
+ * PURPOSE:            : Set MMU_CAM reg
+ *
+ * METHOD:             : Check the Input parameters and set the CAM entry.
+ */
+static hw_status mmu_set_cam_entry(const void __iomem *base_address,
+                                  const u32 page_sz,
+                                  const u32 preserved_bit,
+                                  const u32 valid_bit,
+                                  const u32 virtual_addr_tag);
+
+/*
+ * FUNCTION          : mmu_set_ram_entry
+ *
+ * INPUTS:
+ *
+ *       Identifier      : base_address
+ *       Type          : const u32
+ *       Description     : Base Address of instance of MMU module
+ *
+ *       Identifier      : physical_addr
+ *       Type          : const u32
+ *       Description     : Physical Address to which the corresponding
+ *                      virtual   Address shouldpoint
+ *
+ *       Identifier      : endianism
+ *       Type          : hw_endianism_t
+ *       Description     : endianism for the given page
+ *
+ *       Identifier      : element_size
+ *       Type          : hw_element_size_t
+ *       Description     : The element size ( 8,16, 32 or 64 bit)
+ *
+ *       Identifier      : mixed_size
+ *       Type          : hw_mmu_mixed_size_t
+ *       Description     : Element Size to follow CPU or TLB
+ *
+ * RETURNS:
+ *
+ *       Type          : hw_status
+ *       Description     : 0            -- No errors occured
+ *                      RET_BAD_NULL_PARAM     -- A Pointer Paramater
+ *                                                     was set to NULL
+ *                      RET_PARAM_OUT_OF_RANGE -- Input Parameter
+ *                                                     out of Range
+ *
+ * PURPOSE:          : Set MMU_CAM reg
+ *
+ * METHOD:            : Check the Input parameters and set the RAM entry.
+ */
+static hw_status mmu_set_ram_entry(const void __iomem *base_address,
+                                  const u32 physical_addr,
+                                  enum hw_endianism_t endianism,
+                                  enum hw_element_size_t element_size,
+                                  enum hw_mmu_mixed_size_t mixed_size);
+
+/* HW FUNCTIONS */
+
+hw_status hw_mmu_enable(const void __iomem *base_address)
+{
+       hw_status status = 0;
+
+       MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_SET);
+
+       return status;
+}
+
+hw_status hw_mmu_disable(const void __iomem *base_address)
+{
+       hw_status status = 0;
+
+       MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_CLEAR);
+
+       return status;
+}
+
+hw_status hw_mmu_num_locked_set(const void __iomem *base_address,
+                               u32 num_locked_entries)
+{
+       hw_status status = 0;
+
+       MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, num_locked_entries);
+
+       return status;
+}
+
+hw_status hw_mmu_victim_num_set(const void __iomem *base_address,
+                               u32 victim_entry_num)
+{
+       hw_status status = 0;
+
+       MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, victim_entry_num);
+
+       return status;
+}
+
+hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask)
+{
+       hw_status status = 0;
+
+       MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, irq_mask);
+
+       return status;
+}
+
+hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask)
+{
+       hw_status status = 0;
+       u32 irq_reg;
+
+       irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
+
+       MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg & ~irq_mask);
+
+       return status;
+}
+
+hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask)
+{
+       hw_status status = 0;
+       u32 irq_reg;
+
+       irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
+
+       MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg | irq_mask);
+
+       return status;
+}
+
+hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask)
+{
+       hw_status status = 0;
+
+       *irq_mask = MMUMMU_IRQSTATUS_READ_REGISTER32(base_address);
+
+       return status;
+}
+
+hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr)
+{
+       hw_status status = 0;
+
+       /* read values from register */
+       *addr = MMUMMU_FAULT_AD_READ_REGISTER32(base_address);
+
+       return status;
+}
+
+hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr)
+{
+       hw_status status = 0;
+       u32 load_ttb;
+
+       load_ttb = ttb_phys_addr & ~0x7FUL;
+       /* write values to register */
+       MMUMMU_TTB_WRITE_REGISTER32(base_address, load_ttb);
+
+       return status;
+}
+
+hw_status hw_mmu_twl_enable(const void __iomem *base_address)
+{
+       hw_status status = 0;
+
+       MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_SET);
+
+       return status;
+}
+
+hw_status hw_mmu_twl_disable(const void __iomem *base_address)
+{
+       hw_status status = 0;
+
+       MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_CLEAR);
+
+       return status;
+}
+
+hw_status hw_mmu_tlb_flush(const void __iomem *base_address, u32 virtual_addr,
+                          u32 page_sz)
+{
+       hw_status status = 0;
+       u32 virtual_addr_tag;
+       enum hw_mmu_page_size_t pg_size_bits;
+
+       switch (page_sz) {
+       case HW_PAGE_SIZE4KB:
+               pg_size_bits = HW_MMU_SMALL_PAGE;
+               break;
+
+       case HW_PAGE_SIZE64KB:
+               pg_size_bits = HW_MMU_LARGE_PAGE;
+               break;
+
+       case HW_PAGE_SIZE1MB:
+               pg_size_bits = HW_MMU_SECTION;
+               break;
+
+       case HW_PAGE_SIZE16MB:
+               pg_size_bits = HW_MMU_SUPERSECTION;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       /* Generate the 20-bit tag from virtual address */
+       virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
+
+       mmu_set_cam_entry(base_address, pg_size_bits, 0, 0, virtual_addr_tag);
+
+       mmu_flush_entry(base_address);
+
+       return status;
+}
+
+hw_status hw_mmu_tlb_add(const void __iomem *base_address,
+                        u32 physical_addr,
+                        u32 virtual_addr,
+                        u32 page_sz,
+                        u32 entry_num,
+                        struct hw_mmu_map_attrs_t *map_attrs,
+                        s8 preserved_bit, s8 valid_bit)
+{
+       hw_status status = 0;
+       u32 lock_reg;
+       u32 virtual_addr_tag;
+       enum hw_mmu_page_size_t mmu_pg_size;
+
+       /*Check the input Parameters */
+       switch (page_sz) {
+       case HW_PAGE_SIZE4KB:
+               mmu_pg_size = HW_MMU_SMALL_PAGE;
+               break;
+
+       case HW_PAGE_SIZE64KB:
+               mmu_pg_size = HW_MMU_LARGE_PAGE;
+               break;
+
+       case HW_PAGE_SIZE1MB:
+               mmu_pg_size = HW_MMU_SECTION;
+               break;
+
+       case HW_PAGE_SIZE16MB:
+               mmu_pg_size = HW_MMU_SUPERSECTION;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       lock_reg = MMUMMU_LOCK_READ_REGISTER32(base_address);
+
+       /* Generate the 20-bit tag from virtual address */
+       virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
+
+       /* Write the fields in the CAM Entry Register */
+       mmu_set_cam_entry(base_address, mmu_pg_size, preserved_bit, valid_bit,
+                         virtual_addr_tag);
+
+       /* Write the different fields of the RAM Entry Register */
+       /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit) */
+       mmu_set_ram_entry(base_address, physical_addr, map_attrs->endianism,
+                         map_attrs->element_size, map_attrs->mixed_size);
+
+       /* Update the MMU Lock Register */
+       /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */
+       MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, entry_num);
+
+       /* Enable loading of an entry in TLB by writing 1
+          into LD_TLB_REG register */
+       MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, MMU_LOAD_TLB);
+
+       MMUMMU_LOCK_WRITE_REGISTER32(base_address, lock_reg);
+
+       return status;
+}
+
+hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
+                        u32 physical_addr,
+                        u32 virtual_addr,
+                        u32 page_sz, struct hw_mmu_map_attrs_t *map_attrs)
+{
+       hw_status status = 0;
+       u32 pte_addr, pte_val;
+       s32 num_entries = 1;
+
+       switch (page_sz) {
+       case HW_PAGE_SIZE4KB:
+               pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SMALL_PAGE_MASK);
+               pte_val =
+                   ((physical_addr & MMU_SMALL_PAGE_MASK) |
+                    (map_attrs->endianism << 9) | (map_attrs->
+                                                   element_size << 4) |
+                    (map_attrs->mixed_size << 11) | 2);
+               break;
+
+       case HW_PAGE_SIZE64KB:
+               num_entries = 16;
+               pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_LARGE_PAGE_MASK);
+               pte_val =
+                   ((physical_addr & MMU_LARGE_PAGE_MASK) |
+                    (map_attrs->endianism << 9) | (map_attrs->
+                                                   element_size << 4) |
+                    (map_attrs->mixed_size << 11) | 1);
+               break;
+
+       case HW_PAGE_SIZE1MB:
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SECTION_ADDR_MASK);
+               pte_val =
+                   ((((physical_addr & MMU_SECTION_ADDR_MASK) |
+                      (map_attrs->endianism << 15) | (map_attrs->
+                                                      element_size << 10) |
+                      (map_attrs->mixed_size << 17)) & ~0x40000) | 0x2);
+               break;
+
+       case HW_PAGE_SIZE16MB:
+               num_entries = 16;
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SSECTION_ADDR_MASK);
+               pte_val =
+                   (((physical_addr & MMU_SSECTION_ADDR_MASK) |
+                     (map_attrs->endianism << 15) | (map_attrs->
+                                                     element_size << 10) |
+                     (map_attrs->mixed_size << 17)
+                    ) | 0x40000 | 0x2);
+               break;
+
+       case HW_MMU_COARSE_PAGE_SIZE:
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SECTION_ADDR_MASK);
+               pte_val = (physical_addr & MMU_PAGE_TABLE_MASK) | 1;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       while (--num_entries >= 0)
+               ((u32 *) pte_addr)[num_entries] = pte_val;
+
+       return status;
+}
+
+hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size)
+{
+       hw_status status = 0;
+       u32 pte_addr;
+       s32 num_entries = 1;
+
+       switch (page_size) {
+       case HW_PAGE_SIZE4KB:
+               pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SMALL_PAGE_MASK);
+               break;
+
+       case HW_PAGE_SIZE64KB:
+               num_entries = 16;
+               pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_LARGE_PAGE_MASK);
+               break;
+
+       case HW_PAGE_SIZE1MB:
+       case HW_MMU_COARSE_PAGE_SIZE:
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SECTION_ADDR_MASK);
+               break;
+
+       case HW_PAGE_SIZE16MB:
+               num_entries = 16;
+               pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
+                                             virtual_addr &
+                                             MMU_SSECTION_ADDR_MASK);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       while (--num_entries >= 0)
+               ((u32 *) pte_addr)[num_entries] = 0;
+
+       return status;
+}
+
+/* mmu_flush_entry */
+static hw_status mmu_flush_entry(const void __iomem *base_address)
+{
+       hw_status status = 0;
+       u32 flush_entry_data = 0x1;
+
+       /* write values to register */
+       MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, flush_entry_data);
+
+       return status;
+}
+
+/* mmu_set_cam_entry */
+static hw_status mmu_set_cam_entry(const void __iomem *base_address,
+                                  const u32 page_sz,
+                                  const u32 preserved_bit,
+                                  const u32 valid_bit,
+                                  const u32 virtual_addr_tag)
+{
+       hw_status status = 0;
+       u32 mmu_cam_reg;
+
+       mmu_cam_reg = (virtual_addr_tag << 12);
+       mmu_cam_reg = (mmu_cam_reg) | (page_sz) | (valid_bit << 2) |
+           (preserved_bit << 3);
+
+       /* write values to register */
+       MMUMMU_CAM_WRITE_REGISTER32(base_address, mmu_cam_reg);
+
+       return status;
+}
+
+/* mmu_set_ram_entry */
+static hw_status mmu_set_ram_entry(const void __iomem *base_address,
+                                  const u32 physical_addr,
+                                  enum hw_endianism_t endianism,
+                                  enum hw_element_size_t element_size,
+                                  enum hw_mmu_mixed_size_t mixed_size)
+{
+       hw_status status = 0;
+       u32 mmu_ram_reg;
+
+       mmu_ram_reg = (physical_addr & MMU_ADDR_MASK);
+       mmu_ram_reg = (mmu_ram_reg) | ((endianism << 9) | (element_size << 7) |
+                                      (mixed_size << 6));
+
+       /* write values to register */
+       MMUMMU_RAM_WRITE_REGISTER32(base_address, mmu_ram_reg);
+
+       return status;
+
+}
+
+void hw_mmu_tlb_flush_all(const void __iomem *base)
+{
+       __raw_writeb(1, base + MMU_GFLUSH);
+}
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.h b/drivers/staging/tidspbridge/hw/hw_mmu.h
new file mode 100644 (file)
index 0000000..1458a2c
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * hw_mmu.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * MMU types and API declarations
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _HW_MMU_H
+#define _HW_MMU_H
+
+#include <linux/types.h>
+
+/* Bitmasks for interrupt sources */
+#define HW_MMU_TRANSLATION_FAULT   0x2
+#define HW_MMU_ALL_INTERRUPTS      0x1F
+
+#define HW_MMU_COARSE_PAGE_SIZE 0x400
+
+/* hw_mmu_mixed_size_t:  Enumerated Type used to specify whether to follow
+                       CPU/TLB Element size */
+enum hw_mmu_mixed_size_t {
+       HW_MMU_TLBES,
+       HW_MMU_CPUES
+};
+
+/* hw_mmu_map_attrs_t:  Struct containing MMU mapping attributes */
+struct hw_mmu_map_attrs_t {
+       enum hw_endianism_t endianism;
+       enum hw_element_size_t element_size;
+       enum hw_mmu_mixed_size_t mixed_size;
+       bool donotlockmpupage;
+};
+
+extern hw_status hw_mmu_enable(const void __iomem *base_address);
+
+extern hw_status hw_mmu_disable(const void __iomem *base_address);
+
+extern hw_status hw_mmu_num_locked_set(const void __iomem *base_address,
+                                      u32 num_locked_entries);
+
+extern hw_status hw_mmu_victim_num_set(const void __iomem *base_address,
+                                      u32 victim_entry_num);
+
+/* For MMU faults */
+extern hw_status hw_mmu_event_ack(const void __iomem *base_address,
+                                 u32 irq_mask);
+
+extern hw_status hw_mmu_event_disable(const void __iomem *base_address,
+                                     u32 irq_mask);
+
+extern hw_status hw_mmu_event_enable(const void __iomem *base_address,
+                                    u32 irq_mask);
+
+extern hw_status hw_mmu_event_status(const void __iomem *base_address,
+                                    u32 *irq_mask);
+
+extern hw_status hw_mmu_fault_addr_read(const void __iomem *base_address,
+                                       u32 *addr);
+
+/* Set the TT base address */
+extern hw_status hw_mmu_ttb_set(const void __iomem *base_address,
+                               u32 ttb_phys_addr);
+
+extern hw_status hw_mmu_twl_enable(const void __iomem *base_address);
+
+extern hw_status hw_mmu_twl_disable(const void __iomem *base_address);
+
+extern hw_status hw_mmu_tlb_flush(const void __iomem *base_address,
+                                 u32 virtual_addr, u32 page_sz);
+
+extern hw_status hw_mmu_tlb_add(const void __iomem *base_address,
+                               u32 physical_addr,
+                               u32 virtual_addr,
+                               u32 page_sz,
+                               u32 entry_num,
+                               struct hw_mmu_map_attrs_t *map_attrs,
+                               s8 preserved_bit, s8 valid_bit);
+
+/* For PTEs */
+extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
+                               u32 physical_addr,
+                               u32 virtual_addr,
+                               u32 page_sz,
+                               struct hw_mmu_map_attrs_t *map_attrs);
+
+extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va,
+                                 u32 virtual_addr, u32 page_size);
+
+void hw_mmu_tlb_flush_all(const void __iomem *base);
+
+static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va)
+{
+       u32 pte_addr;
+       u32 va31_to20;
+
+       va31_to20 = va >> (20 - 2);     /* Left-shift by 2 here itself */
+       va31_to20 &= 0xFFFFFFFCUL;
+       pte_addr = l1_base + va31_to20;
+
+       return pte_addr;
+}
+
+static inline u32 hw_mmu_pte_addr_l2(u32 l2_base, u32 va)
+{
+       u32 pte_addr;
+
+       pte_addr = (l2_base & 0xFFFFFC00) | ((va >> 10) & 0x3FC);
+
+       return pte_addr;
+}
+
+static inline u32 hw_mmu_pte_coarse_l1(u32 pte_val)
+{
+       u32 pte_coarse;
+
+       pte_coarse = pte_val & 0xFFFFFC00;
+
+       return pte_coarse;
+}
+
+static inline u32 hw_mmu_pte_size_l1(u32 pte_val)
+{
+       u32 pte_size = 0;
+
+       if ((pte_val & 0x3) == 0x1) {
+               /* Points to L2 PT */
+               pte_size = HW_MMU_COARSE_PAGE_SIZE;
+       }
+
+       if ((pte_val & 0x3) == 0x2) {
+               if (pte_val & (1 << 18))
+                       pte_size = HW_PAGE_SIZE16MB;
+               else
+                       pte_size = HW_PAGE_SIZE1MB;
+       }
+
+       return pte_size;
+}
+
+static inline u32 hw_mmu_pte_size_l2(u32 pte_val)
+{
+       u32 pte_size = 0;
+
+       if (pte_val & 0x2)
+               pte_size = HW_PAGE_SIZE4KB;
+       else if (pte_val & 0x1)
+               pte_size = HW_PAGE_SIZE64KB;
+
+       return pte_size;
+}
+
+#endif /* _HW_MMU_H */
index dfb55cca34c74a71fa1a75b8c9ec9ee47d09463a..38122dbf877a198c0e52a1ed21a358b2eb6828f1 100644 (file)
@@ -68,6 +68,7 @@ struct cfg_hostres {
        void __iomem *dw_per_base;
        u32 dw_per_pm_base;
        u32 dw_core_pm_base;
+       void __iomem *dw_dmmu_base;
        void __iomem *dw_sys_ctrl_base;
 };
 
index 9bdd48f5742994ab0376cf680944b1c57835035d..357458fadd2a3a50935efd751a20649512b86596 100644 (file)
@@ -27,6 +27,7 @@
 #include <dspbridge/nodedefs.h>
 #include <dspbridge/dispdefs.h>
 #include <dspbridge/dspdefs.h>
+#include <dspbridge/dmm.h>
 #include <dspbridge/host_os.h>
 
 /*  ----------------------------------- This */
@@ -232,6 +233,29 @@ extern int dev_get_chnl_mgr(struct dev_object *hdev_obj,
 extern int dev_get_cmm_mgr(struct dev_object *hdev_obj,
                                  struct cmm_object **mgr);
 
+/*
+ *  ======== dev_get_dmm_mgr ========
+ *  Purpose:
+ *      Retrieve the handle to the dynamic memory manager created for this
+ *      device.
+ *  Parameters:
+ *      hdev_obj:     Handle to device object created with
+ *                      dev_create_device().
+ *      *mgr:           Ptr to location to store handle.
+ *  Returns:
+ *      0:        Success.
+ *      -EFAULT:    Invalid hdev_obj.
+ *  Requires:
+ *      mgr != NULL.
+ *      DEV Initialized.
+ *  Ensures:
+ *      0:        *mgr contains a handle to a channel manager object,
+ *                      or NULL.
+ *      else:           *mgr is NULL.
+ */
+extern int dev_get_dmm_mgr(struct dev_object *hdev_obj,
+                                 struct dmm_object **mgr);
+
 /*
  *  ======== dev_get_cod_mgr ========
  *  Purpose:
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dmm.h b/drivers/staging/tidspbridge/include/dspbridge/dmm.h
new file mode 100644 (file)
index 0000000..6c58335
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * dmm.h
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address
+ * space that can be directly mapped to any MPU buffer or memory region.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef DMM_
+#define DMM_
+
+#include <dspbridge/dbdefs.h>
+
+struct dmm_object;
+
+/* DMM attributes used in dmm_create() */
+struct dmm_mgrattrs {
+       u32 reserved;
+};
+
+#define DMMPOOLSIZE      0x4000000
+
+/*
+ *  ======== dmm_get_handle ========
+ *  Purpose:
+ *      Return the dynamic memory manager object for this device.
+ *      This is typically called from the client process.
+ */
+
+extern int dmm_get_handle(void *hprocessor,
+                                struct dmm_object **dmm_manager);
+
+extern int dmm_reserve_memory(struct dmm_object *dmm_mgr,
+                                    u32 size, u32 *prsv_addr);
+
+extern int dmm_un_reserve_memory(struct dmm_object *dmm_mgr,
+                                       u32 rsv_addr);
+
+extern int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr,
+                                u32 size);
+
+extern int dmm_un_map_memory(struct dmm_object *dmm_mgr,
+                                   u32 addr, u32 *psize);
+
+extern int dmm_destroy(struct dmm_object *dmm_mgr);
+
+extern int dmm_delete_tables(struct dmm_object *dmm_mgr);
+
+extern int dmm_create(struct dmm_object **dmm_manager,
+                            struct dev_object *hdev_obj,
+                            const struct dmm_mgrattrs *mgr_attrts);
+
+extern bool dmm_init(void);
+
+extern void dmm_exit(void);
+
+extern int dmm_create_tables(struct dmm_object *dmm_mgr,
+                                   u32 addr, u32 size);
+
+#ifdef DSP_DMM_DEBUG
+u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr);
+#endif
+
+#endif /* DMM_ */
index 75a2c9b5c6f29cee45a86999eb081e8f2503b93f..c1f363ec9afab51b225c1fc0007c7edf62e5dbb7 100644 (file)
@@ -108,6 +108,12 @@ struct dmm_map_object {
        struct bridge_dma_map_info dma_info;
 };
 
+/* Used for DMM reserved memory accounting */
+struct dmm_rsv_object {
+       struct list_head link;
+       u32 dsp_reserved_addr;
+};
+
 /* New structure (member of process context) abstracts DMM resource info */
 struct dspheap_res_object {
        s32 heap_allocated;     /* DMM status */
@@ -159,6 +165,10 @@ struct process_context {
        struct list_head dmm_map_list;
        spinlock_t dmm_map_lock;
 
+       /* DMM reserved memory resources */
+       struct list_head dmm_rsv_list;
+       spinlock_t dmm_rsv_lock;
+
        /* DSP Heap resources */
        struct dspheap_res_object *pdspheap_list;
 
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h b/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h
deleted file mode 100644 (file)
index cb38d4c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * dsp-mmu.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP iommu.
- *
- * Copyright (C) 2005-2010 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _DSP_MMU_
-#define _DSP_MMU_
-
-#include <plat/iommu.h>
-#include <plat/iovmm.h>
-
-/**
- * dsp_mmu_init() - initialize dsp_mmu module and returns a handle
- *
- * This function initialize dsp mmu module and returns a struct iommu
- * handle to use it for dsp maps.
- *
- */
-struct iommu *dsp_mmu_init(void);
-
-/**
- * dsp_mmu_exit() - destroy dsp mmu module
- * @mmu:       Pointer to iommu handle.
- *
- * This function destroys dsp mmu module.
- *
- */
-void dsp_mmu_exit(struct iommu *mmu);
-
-/**
- * user_to_dsp_map() - maps user to dsp virtual address
- * @mmu:       Pointer to iommu handle.
- * @uva:               Virtual user space address.
- * @da         DSP address
- * @size               Buffer size to map.
- * @usr_pgs    struct page array pointer where the user pages will be stored
- *
- * This function maps a user space buffer into DSP virtual address.
- *
- */
-u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size,
-                                               struct page **usr_pgs);
-
-/**
- * user_to_dsp_unmap() - unmaps DSP virtual buffer.
- * @mmu:       Pointer to iommu handle.
- * @da         DSP address
- *
- * This function unmaps a user space buffer into DSP virtual address.
- *
- */
-int user_to_dsp_unmap(struct iommu *mmu, u32 da);
-
-#endif
index 615363474810e85c0f4b3c07191b8c744054e883..0ae7d1646a1bf74f4642a94fd27ddef262011a5d 100644 (file)
@@ -161,6 +161,48 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context
                                       u32 dsp_addr, u32 ul_num_bytes,
                                       u32 mem_type);
 
+/*
+ *  ======== bridge_brd_mem_map ========
+ *  Purpose:
+ *      Map a MPU memory region to a DSP/IVA memory space
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      ul_mpu_addr:      MPU memory region start address.
+ *      virt_addr:      DSP/IVA memory region u8 address.
+ *      ul_num_bytes:     Number of bytes to map.
+ *      map_attrs:       Mapping attributes (e.g. endianness).
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL;
+ *  Ensures:
+ */
+typedef int(*fxn_brd_memmap) (struct bridge_dev_context
+                                    * dev_ctxt, u32 ul_mpu_addr,
+                                    u32 virt_addr, u32 ul_num_bytes,
+                                    u32 map_attr,
+                                    struct page **mapped_pages);
+
+/*
+ *  ======== bridge_brd_mem_un_map ========
+ *  Purpose:
+ *      UnMap an MPU memory region from DSP/IVA memory space
+ *  Parameters:
+ *      dev_ctxt:    Handle to Bridge driver defined device info.
+ *      virt_addr:      DSP/IVA memory region u8 address.
+ *      ul_num_bytes:     Number of bytes to unmap.
+ *  Returns:
+ *      0:        Success.
+ *      -EPERM:      Other, unspecified error.
+ *  Requires:
+ *      dev_ctxt != NULL;
+ *  Ensures:
+ */
+typedef int(*fxn_brd_memunmap) (struct bridge_dev_context
+                                      * dev_ctxt,
+                                      u32 virt_addr, u32 ul_num_bytes);
+
 /*
  *  ======== bridge_brd_stop ========
  *  Purpose:
@@ -951,6 +993,8 @@ struct bridge_drv_interface {
        fxn_brd_setstate pfn_brd_set_state;     /* Sets the Board State */
        fxn_brd_memcopy pfn_brd_mem_copy;       /* Copies DSP Memory */
        fxn_brd_memwrite pfn_brd_mem_write;     /* Write DSP Memory w/o halt */
+       fxn_brd_memmap pfn_brd_mem_map; /* Maps MPU mem to DSP mem */
+       fxn_brd_memunmap pfn_brd_mem_un_map;    /* Unmaps MPU mem to DSP mem */
        fxn_chnl_create pfn_chnl_create;        /* Create channel manager. */
        fxn_chnl_destroy pfn_chnl_destroy;      /* Destroy channel manager. */
        fxn_chnl_open pfn_chnl_open;    /* Create a new channel. */
index bad180108adaae3fcf0d70811c37f56b0c2c2251..41e0594dff340d1cae3ab50f6e350c35dcc49969 100644 (file)
 #ifndef DSPIOCTL_
 #define DSPIOCTL_
 
+/* ------------------------------------ Hardware Abstraction Layer */
+#include <hw_defs.h>
+#include <hw_mmu.h>
+
 /*
  * Any IOCTLS at or above this value are reserved for standard Bridge driver
  * interfaces.
@@ -61,6 +65,9 @@ struct bridge_ioctl_extproc {
        /* GPP virtual address. __va does not work for ioremapped addresses */
        u32 ul_gpp_va;
        u32 ul_size;            /* Size of the mapped memory in bytes */
+       enum hw_endianism_t endianism;
+       enum hw_mmu_mixed_size_t mixed_mode;
+       enum hw_element_size_t elem_size;
 };
 
 #endif /* DSPIOCTL_ */
index 2d12aab6b5bf1ed218068ff5b480bc61a1b972be..5e09fd165d9d4c9294aaf76333ca290cde8e6f26 100644 (file)
@@ -550,6 +550,29 @@ extern int proc_map(void *hprocessor,
                           void **pp_map_addr, u32 ul_map_attr,
                           struct process_context *pr_ctxt);
 
+/*
+ *  ======== proc_reserve_memory ========
+ *  Purpose:
+ *      Reserve a virtually contiguous region of DSP address space.
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      ul_size          :   Size of the address space to reserve.
+ *      pp_rsv_addr       :   Ptr to DSP side reserved u8 address.
+ *  Returns:
+ *      0       :   Success.
+ *      -EFAULT     :   Invalid processor handle.
+ *      -EPERM       :   General failure.
+ *      -ENOMEM     :   Cannot reserve chunk of this size.
+ *  Requires:
+ *      pp_rsv_addr is not NULL
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_reserve_memory(void *hprocessor,
+                                     u32 ul_size, void **pp_rsv_addr,
+                                     struct process_context *pr_ctxt);
+
 /*
  *  ======== proc_un_map ========
  *  Purpose:
@@ -572,4 +595,27 @@ extern int proc_map(void *hprocessor,
 extern int proc_un_map(void *hprocessor, void *map_addr,
                              struct process_context *pr_ctxt);
 
+/*
+ *  ======== proc_un_reserve_memory ========
+ *  Purpose:
+ *      Frees a previously reserved region of DSP address space.
+ *  Parameters:
+ *      hprocessor      :   The processor handle.
+ *      prsv_addr      :   Ptr to DSP side reservedBYTE address.
+ *  Returns:
+ *      0       :   Success.
+ *      -EFAULT     :   Invalid processor handle.
+ *      -EPERM       :   General failure.
+ *      -ENOENT   :   Cannot find a reserved region starting with this
+ *                   :   address.
+ *  Requires:
+ *      prsv_addr is not NULL
+ *      PROC Initialized.
+ *  Ensures:
+ *  Details:
+ */
+extern int proc_un_reserve_memory(void *hprocessor,
+                                        void *prsv_addr,
+                                        struct process_context *pr_ctxt);
+
 #endif /* PROC_ */
index 7b30267ef0e29daa168eb2a09067708d59c05d4f..132e960967b970b75a6441cf65127de390efe973 100644 (file)
@@ -34,6 +34,7 @@
 #include <dspbridge/cod.h>
 #include <dspbridge/drv.h>
 #include <dspbridge/proc.h>
+#include <dspbridge/dmm.h>
 
 /*  ----------------------------------- Resource Manager */
 #include <dspbridge/mgr.h>
@@ -74,6 +75,7 @@ struct dev_object {
        struct msg_mgr *hmsg_mgr;       /* Message manager. */
        struct io_mgr *hio_mgr; /* IO manager (CHNL, msg_ctrl) */
        struct cmm_object *hcmm_mgr;    /* SM memory manager. */
+       struct dmm_object *dmm_mgr;     /* Dynamic memory manager. */
        struct ldr_module *module_obj;  /* Bridge Module handle. */
        u32 word_size;          /* DSP word size: quick access. */
        struct drv_object *hdrv_obj;    /* Driver Object */
@@ -248,6 +250,9 @@ int dev_create_device(struct dev_object **device_obj,
                        /* Instantiate the DEH module */
                        status = bridge_deh_create(&dev_obj->hdeh_mgr, dev_obj);
                }
+               /* Create DMM mgr . */
+               status = dmm_create(&dev_obj->dmm_mgr,
+                                   (struct dev_object *)dev_obj, NULL);
        }
        /* Add the new DEV_Object to the global list: */
        if (!status) {
@@ -273,6 +278,8 @@ leave:
                        kfree(dev_obj->proc_list);
                        if (dev_obj->cod_mgr)
                                cod_delete(dev_obj->cod_mgr);
+                       if (dev_obj->dmm_mgr)
+                               dmm_destroy(dev_obj->dmm_mgr);
                        kfree(dev_obj);
                }
 
@@ -382,6 +389,11 @@ int dev_destroy_device(struct dev_object *hdev_obj)
                        dev_obj->hcmm_mgr = NULL;
                }
 
+               if (dev_obj->dmm_mgr) {
+                       dmm_destroy(dev_obj->dmm_mgr);
+                       dev_obj->dmm_mgr = NULL;
+               }
+
                /* Call the driver's bridge_dev_destroy() function: */
                /* Require of DevDestroy */
                if (dev_obj->hbridge_context) {
@@ -461,6 +473,32 @@ int dev_get_cmm_mgr(struct dev_object *hdev_obj,
        return status;
 }
 
+/*
+ *  ======== dev_get_dmm_mgr ========
+ *  Purpose:
+ *      Retrieve the handle to the dynamic memory manager created for this
+ *      device.
+ */
+int dev_get_dmm_mgr(struct dev_object *hdev_obj,
+                          struct dmm_object **mgr)
+{
+       int status = 0;
+       struct dev_object *dev_obj = hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(mgr != NULL);
+
+       if (hdev_obj) {
+               *mgr = dev_obj->dmm_mgr;
+       } else {
+               *mgr = NULL;
+               status = -EFAULT;
+       }
+
+       DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
+       return status;
+}
+
 /*
  *  ======== dev_get_cod_mgr ========
  *  Purpose:
@@ -713,8 +751,10 @@ void dev_exit(void)
 
        refs--;
 
-       if (refs == 0)
+       if (refs == 0) {
                cmm_exit();
+               dmm_exit();
+       }
 
        DBC_ENSURE(refs >= 0);
 }
@@ -726,12 +766,25 @@ void dev_exit(void)
  */
 bool dev_init(void)
 {
-       bool ret = true;
+       bool cmm_ret, dmm_ret, ret = true;
 
        DBC_REQUIRE(refs >= 0);
 
-       if (refs == 0)
-               ret = cmm_init();
+       if (refs == 0) {
+               cmm_ret = cmm_init();
+               dmm_ret = dmm_init();
+
+               ret = cmm_ret && dmm_ret;
+
+               if (!ret) {
+                       if (cmm_ret)
+                               cmm_exit();
+
+                       if (dmm_ret)
+                               dmm_exit();
+
+               }
+       }
 
        if (ret)
                refs++;
@@ -1065,6 +1118,8 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
                STORE_FXN(fxn_brd_setstate, pfn_brd_set_state);
                STORE_FXN(fxn_brd_memcopy, pfn_brd_mem_copy);
                STORE_FXN(fxn_brd_memwrite, pfn_brd_mem_write);
+               STORE_FXN(fxn_brd_memmap, pfn_brd_mem_map);
+               STORE_FXN(fxn_brd_memunmap, pfn_brd_mem_un_map);
                STORE_FXN(fxn_chnl_create, pfn_chnl_create);
                STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy);
                STORE_FXN(fxn_chnl_open, pfn_chnl_open);
diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c
new file mode 100644 (file)
index 0000000..8685233
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * dmm.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address
+ * space that can be directly mapped to any MPU buffer or memory region
+ *
+ * Notes:
+ *   Region: Generic memory entitiy having a start address and a size
+ *   Chunk:  Reserved region
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#include <linux/types.h>
+
+/*  ----------------------------------- Host OS */
+#include <dspbridge/host_os.h>
+
+/*  ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/dbdefs.h>
+
+/*  ----------------------------------- Trace & Debug */
+#include <dspbridge/dbc.h>
+
+/*  ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/sync.h>
+
+/*  ----------------------------------- Platform Manager */
+#include <dspbridge/dev.h>
+#include <dspbridge/proc.h>
+
+/*  ----------------------------------- This */
+#include <dspbridge/dmm.h>
+
+/*  ----------------------------------- Defines, Data Structures, Typedefs */
+#define DMM_ADDR_VIRTUAL(a) \
+       (((struct map_page *)(a) - virtual_mapping_table) * PG_SIZE4K +\
+       dyn_mem_map_beg)
+#define DMM_ADDR_TO_INDEX(a) (((a) - dyn_mem_map_beg) / PG_SIZE4K)
+
+/* DMM Mgr */
+struct dmm_object {
+       /* Dmm Lock is used to serialize access mem manager for
+        * multi-threads. */
+       spinlock_t dmm_lock;    /* Lock to access dmm mgr */
+};
+
+/*  ----------------------------------- Globals */
+static u32 refs;               /* module reference count */
+struct map_page {
+       u32 region_size:15;
+       u32 mapped_size:15;
+       u32 reserved:1;
+       u32 mapped:1;
+};
+
+/*  Create the free list */
+static struct map_page *virtual_mapping_table;
+static u32 free_region;                /* The index of free region */
+static u32 free_size;
+static u32 dyn_mem_map_beg;    /* The Beginning of dynamic memory mapping */
+static u32 table_size;         /* The size of virt and phys pages tables */
+
+/*  ----------------------------------- Function Prototypes */
+static struct map_page *get_region(u32 addr);
+static struct map_page *get_free_region(u32 len);
+static struct map_page *get_mapped_region(u32 addrs);
+
+/*  ======== dmm_create_tables ========
+ *  Purpose:
+ *      Create table to hold the information of physical address
+ *      the buffer pages that is passed by the user, and the table
+ *      to hold the information of the virtual memory that is reserved
+ *      for DSP.
+ */
+int dmm_create_tables(struct dmm_object *dmm_mgr, u32 addr, u32 size)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       int status = 0;
+
+       status = dmm_delete_tables(dmm_obj);
+       if (!status) {
+               dyn_mem_map_beg = addr;
+               table_size = PG_ALIGN_HIGH(size, PG_SIZE4K) / PG_SIZE4K;
+               /*  Create the free list */
+               virtual_mapping_table = __vmalloc(table_size *
+                               sizeof(struct map_page), GFP_KERNEL |
+                               __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
+               if (virtual_mapping_table == NULL)
+                       status = -ENOMEM;
+               else {
+                       /* On successful allocation,
+                        * all entries are zero ('free') */
+                       free_region = 0;
+                       free_size = table_size * PG_SIZE4K;
+                       virtual_mapping_table[0].region_size = table_size;
+               }
+       }
+
+       if (status)
+               pr_err("%s: failure, status 0x%x\n", __func__, status);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_create ========
+ *  Purpose:
+ *      Create a dynamic memory manager object.
+ */
+int dmm_create(struct dmm_object **dmm_manager,
+                     struct dev_object *hdev_obj,
+                     const struct dmm_mgrattrs *mgr_attrts)
+{
+       struct dmm_object *dmm_obj = NULL;
+       int status = 0;
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dmm_manager != NULL);
+
+       *dmm_manager = NULL;
+       /* create, zero, and tag a cmm mgr object */
+       dmm_obj = kzalloc(sizeof(struct dmm_object), GFP_KERNEL);
+       if (dmm_obj != NULL) {
+               spin_lock_init(&dmm_obj->dmm_lock);
+               *dmm_manager = dmm_obj;
+       } else {
+               status = -ENOMEM;
+       }
+
+       return status;
+}
+
+/*
+ *  ======== dmm_destroy ========
+ *  Purpose:
+ *      Release the communication memory manager resources.
+ */
+int dmm_destroy(struct dmm_object *dmm_mgr)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       if (dmm_mgr) {
+               status = dmm_delete_tables(dmm_obj);
+               if (!status)
+                       kfree(dmm_obj);
+       } else
+               status = -EFAULT;
+
+       return status;
+}
+
+/*
+ *  ======== dmm_delete_tables ========
+ *  Purpose:
+ *      Delete DMM Tables.
+ */
+int dmm_delete_tables(struct dmm_object *dmm_mgr)
+{
+       int status = 0;
+
+       DBC_REQUIRE(refs > 0);
+       /* Delete all DMM tables */
+       if (dmm_mgr)
+               vfree(virtual_mapping_table);
+       else
+               status = -EFAULT;
+       return status;
+}
+
+/*
+ *  ======== dmm_exit ========
+ *  Purpose:
+ *      Discontinue usage of module; free resources when reference count
+ *      reaches 0.
+ */
+void dmm_exit(void)
+{
+       DBC_REQUIRE(refs > 0);
+
+       refs--;
+}
+
+/*
+ *  ======== dmm_get_handle ========
+ *  Purpose:
+ *      Return the dynamic memory manager object for this device.
+ *      This is typically called from the client process.
+ */
+int dmm_get_handle(void *hprocessor, struct dmm_object **dmm_manager)
+{
+       int status = 0;
+       struct dev_object *hdev_obj;
+
+       DBC_REQUIRE(refs > 0);
+       DBC_REQUIRE(dmm_manager != NULL);
+       if (hprocessor != NULL)
+               status = proc_get_dev_object(hprocessor, &hdev_obj);
+       else
+               hdev_obj = dev_get_first();     /* default */
+
+       if (!status)
+               status = dev_get_dmm_mgr(hdev_obj, dmm_manager);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_init ========
+ *  Purpose:
+ *      Initializes private state of DMM module.
+ */
+bool dmm_init(void)
+{
+       bool ret = true;
+
+       DBC_REQUIRE(refs >= 0);
+
+       if (ret)
+               refs++;
+
+       DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
+
+       virtual_mapping_table = NULL;
+       table_size = 0;
+
+       return ret;
+}
+
+/*
+ *  ======== dmm_map_memory ========
+ *  Purpose:
+ *      Add a mapping block to the reserved chunk. DMM assumes that this block
+ *  will be mapped in the DSP/IVA's address space. DMM returns an error if a
+ *  mapping overlaps another one. This function stores the info that will be
+ *  required later while unmapping the block.
+ */
+int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       struct map_page *chunk;
+       int status = 0;
+
+       spin_lock(&dmm_obj->dmm_lock);
+       /* Find the Reserved memory chunk containing the DSP block to
+        * be mapped */
+       chunk = (struct map_page *)get_region(addr);
+       if (chunk != NULL) {
+               /* Mark the region 'mapped', leave the 'reserved' info as-is */
+               chunk->mapped = true;
+               chunk->mapped_size = (size / PG_SIZE4K);
+       } else
+               status = -ENOENT;
+       spin_unlock(&dmm_obj->dmm_lock);
+
+       dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, "
+               "chunk %p", __func__, dmm_mgr, addr, size, status, chunk);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_reserve_memory ========
+ *  Purpose:
+ *      Reserve a chunk of virtually contiguous DSP/IVA address space.
+ */
+int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size,
+                             u32 *prsv_addr)
+{
+       int status = 0;
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       struct map_page *node;
+       u32 rsv_addr = 0;
+       u32 rsv_size = 0;
+
+       spin_lock(&dmm_obj->dmm_lock);
+
+       /* Try to get a DSP chunk from the free list */
+       node = get_free_region(size);
+       if (node != NULL) {
+               /*  DSP chunk of given size is available. */
+               rsv_addr = DMM_ADDR_VIRTUAL(node);
+               /* Calculate the number entries to use */
+               rsv_size = size / PG_SIZE4K;
+               if (rsv_size < node->region_size) {
+                       /* Mark remainder of free region */
+                       node[rsv_size].mapped = false;
+                       node[rsv_size].reserved = false;
+                       node[rsv_size].region_size =
+                           node->region_size - rsv_size;
+                       node[rsv_size].mapped_size = 0;
+               }
+               /*  get_region will return first fit chunk. But we only use what
+                  is requested. */
+               node->mapped = false;
+               node->reserved = true;
+               node->region_size = rsv_size;
+               node->mapped_size = 0;
+               /* Return the chunk's starting address */
+               *prsv_addr = rsv_addr;
+       } else
+               /*dSP chunk of given size is not available */
+               status = -ENOMEM;
+
+       spin_unlock(&dmm_obj->dmm_lock);
+
+       dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, "
+               "rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size,
+               prsv_addr, status, rsv_addr, rsv_size);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_un_map_memory ========
+ *  Purpose:
+ *      Remove the mapped block from the reserved chunk.
+ */
+int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       struct map_page *chunk;
+       int status = 0;
+
+       spin_lock(&dmm_obj->dmm_lock);
+       chunk = get_mapped_region(addr);
+       if (chunk == NULL)
+               status = -ENOENT;
+
+       if (!status) {
+               /* Unmap the region */
+               *psize = chunk->mapped_size * PG_SIZE4K;
+               chunk->mapped = false;
+               chunk->mapped_size = 0;
+       }
+       spin_unlock(&dmm_obj->dmm_lock);
+
+       dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, "
+               "chunk %p\n", __func__, dmm_mgr, addr, psize, status, chunk);
+
+       return status;
+}
+
+/*
+ *  ======== dmm_un_reserve_memory ========
+ *  Purpose:
+ *      Free a chunk of reserved DSP/IVA address space.
+ */
+int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr)
+{
+       struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
+       struct map_page *chunk;
+       u32 i;
+       int status = 0;
+       u32 chunk_size;
+
+       spin_lock(&dmm_obj->dmm_lock);
+
+       /* Find the chunk containing the reserved address */
+       chunk = get_mapped_region(rsv_addr);
+       if (chunk == NULL)
+               status = -ENOENT;
+
+       if (!status) {
+               /* Free all the mapped pages for this reserved region */
+               i = 0;
+               while (i < chunk->region_size) {
+                       if (chunk[i].mapped) {
+                               /* Remove mapping from the page tables. */
+                               chunk_size = chunk[i].mapped_size;
+                               /* Clear the mapping flags */
+                               chunk[i].mapped = false;
+                               chunk[i].mapped_size = 0;
+                               i += chunk_size;
+                       } else
+                               i++;
+               }
+               /* Clear the flags (mark the region 'free') */
+               chunk->reserved = false;
+               /* NOTE: We do NOT coalesce free regions here.
+                * Free regions are coalesced in get_region(), as it traverses
+                *the whole mapping table
+                */
+       }
+       spin_unlock(&dmm_obj->dmm_lock);
+
+       dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p",
+               __func__, dmm_mgr, rsv_addr, status, chunk);
+
+       return status;
+}
+
+/*
+ *  ======== get_region ========
+ *  Purpose:
+ *      Returns a region containing the specified memory region
+ */
+static struct map_page *get_region(u32 addr)
+{
+       struct map_page *curr_region = NULL;
+       u32 i = 0;
+
+       if (virtual_mapping_table != NULL) {
+               /* find page mapped by this address */
+               i = DMM_ADDR_TO_INDEX(addr);
+               if (i < table_size)
+                       curr_region = virtual_mapping_table + i;
+       }
+
+       dev_dbg(bridge, "%s: curr_region %p, free_region %d, free_size %d\n",
+               __func__, curr_region, free_region, free_size);
+       return curr_region;
+}
+
+/*
+ *  ======== get_free_region ========
+ *  Purpose:
+ *  Returns the requested free region
+ */
+static struct map_page *get_free_region(u32 len)
+{
+       struct map_page *curr_region = NULL;
+       u32 i = 0;
+       u32 region_size = 0;
+       u32 next_i = 0;
+
+       if (virtual_mapping_table == NULL)
+               return curr_region;
+       if (len > free_size) {
+               /* Find the largest free region
+                * (coalesce during the traversal) */
+               while (i < table_size) {
+                       region_size = virtual_mapping_table[i].region_size;
+                       next_i = i + region_size;
+                       if (virtual_mapping_table[i].reserved == false) {
+                               /* Coalesce, if possible */
+                               if (next_i < table_size &&
+                                   virtual_mapping_table[next_i].reserved
+                                   == false) {
+                                       virtual_mapping_table[i].region_size +=
+                                           virtual_mapping_table
+                                           [next_i].region_size;
+                                       continue;
+                               }
+                               region_size *= PG_SIZE4K;
+                               if (region_size > free_size) {
+                                       free_region = i;
+                                       free_size = region_size;
+                               }
+                       }
+                       i = next_i;
+               }
+       }
+       if (len <= free_size) {
+               curr_region = virtual_mapping_table + free_region;
+               free_region += (len / PG_SIZE4K);
+               free_size -= len;
+       }
+       return curr_region;
+}
+
+/*
+ *  ======== get_mapped_region ========
+ *  Purpose:
+ *  Returns the requestedmapped region
+ */
+static struct map_page *get_mapped_region(u32 addrs)
+{
+       u32 i = 0;
+       struct map_page *curr_region = NULL;
+
+       if (virtual_mapping_table == NULL)
+               return curr_region;
+
+       i = DMM_ADDR_TO_INDEX(addrs);
+       if (i < table_size && (virtual_mapping_table[i].mapped ||
+                              virtual_mapping_table[i].reserved))
+               curr_region = virtual_mapping_table + i;
+       return curr_region;
+}
+
+#ifdef DSP_DMM_DEBUG
+u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr)
+{
+       struct map_page *curr_node = NULL;
+       u32 i;
+       u32 freemem = 0;
+       u32 bigsize = 0;
+
+       spin_lock(&dmm_mgr->dmm_lock);
+
+       if (virtual_mapping_table != NULL) {
+               for (i = 0; i < table_size; i +=
+                    virtual_mapping_table[i].region_size) {
+                       curr_node = virtual_mapping_table + i;
+                       if (curr_node->reserved) {
+                               /*printk("RESERVED size = 0x%x, "
+                                  "Map size = 0x%x\n",
+                                  (curr_node->region_size * PG_SIZE4K),
+                                  (curr_node->mapped == false) ? 0 :
+                                  (curr_node->mapped_size * PG_SIZE4K));
+                                */
+                       } else {
+/*                             printk("UNRESERVED size = 0x%x\n",
+                                       (curr_node->region_size * PG_SIZE4K));
+ */
+                               freemem += (curr_node->region_size * PG_SIZE4K);
+                               if (curr_node->region_size > bigsize)
+                                       bigsize = curr_node->region_size;
+                       }
+               }
+       }
+       spin_unlock(&dmm_mgr->dmm_lock);
+       printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n",
+              freemem / (1024 * 1024));
+       printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n",
+              (((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024));
+       printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n",
+              (bigsize * PG_SIZE4K / (1024 * 1024)));
+
+       return 0;
+}
+#endif
index 981551ce4d78684e792957f974a4af39b84b9176..86ca785f191356ef865aac33d035a36e40373327 100644 (file)
@@ -993,10 +993,27 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt)
 /*
  * ======== procwrap_reserve_memory ========
  */
-u32 __deprecated procwrap_reserve_memory(union trapped_args *args,
-                                                       void *pr_ctxt)
+u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt)
 {
-       return 0;
+       int status;
+       void *prsv_addr;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       if ((args->args_proc_rsvmem.ul_size <= 0) ||
+           (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0)
+               return -EINVAL;
+
+       status = proc_reserve_memory(hprocessor,
+                                    args->args_proc_rsvmem.ul_size, &prsv_addr,
+                                    pr_ctxt);
+       if (!status) {
+               if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) {
+                       status = -EINVAL;
+                       proc_un_reserve_memory(args->args_proc_rsvmem.
+                                              hprocessor, prsv_addr, pr_ctxt);
+               }
+       }
+       return status;
 }
 
 /*
@@ -1025,10 +1042,15 @@ u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt)
 /*
  * ======== procwrap_un_reserve_memory ========
  */
-u32 __deprecated procwrap_un_reserve_memory(union trapped_args *args,
-                                                       void *pr_ctxt)
+u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt)
 {
-       return 0;
+       int status;
+       void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
+
+       status = proc_un_reserve_memory(hprocessor,
+                                       args->args_proc_unrsvmem.prsv_addr,
+                                       pr_ctxt);
+       return status;
 }
 
 /*
index 91cc168516e5e25f553b3cdb8fe317ea12720b2f..81b1b90135502b52a20d002760decbcd249f3196 100644 (file)
@@ -146,6 +146,7 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt)
        struct process_context *ctxt = (struct process_context *)process_ctxt;
        int status = 0;
        struct dmm_map_object *temp_map, *map_obj;
+       struct dmm_rsv_object *temp_rsv, *rsv_obj;
 
        /* Free DMM mapped memory resources */
        list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) {
@@ -155,6 +156,16 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt)
                        pr_err("%s: proc_un_map failed!"
                               " status = 0x%xn", __func__, status);
        }
+
+       /* Free DMM reserved memory resources */
+       list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) {
+               status = proc_un_reserve_memory(ctxt->hprocessor, (void *)
+                                               rsv_obj->dsp_reserved_addr,
+                                               ctxt);
+               if (status)
+                       pr_err("%s: proc_un_reserve_memory failed!"
+                              " status = 0x%xn", __func__, status);
+       }
        return status;
 }
 
@@ -732,6 +743,7 @@ static int request_bridge_resources(struct cfg_hostres *res)
        host_res->dw_sys_ctrl_base = ioremap(OMAP_SYSC_BASE, OMAP_SYSC_SIZE);
        dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]);
        dev_dbg(bridge, "dw_mem_base[3] 0x%x\n", host_res->dw_mem_base[3]);
+       dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base);
 
        /* for 24xx base port is not mapping the mamory for DSP
         * internal memory TODO Do a ioremap here */
@@ -785,6 +797,8 @@ int drv_request_bridge_res_dsp(void **phost_resources)
                                                         OMAP_PER_PRM_SIZE);
                host_res->dw_core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE,
                                                          OMAP_CORE_PRM_SIZE);
+               host_res->dw_dmmu_base = ioremap(OMAP_DMMU_BASE,
+                                                OMAP_DMMU_SIZE);
 
                dev_dbg(bridge, "dw_mem_base[0] 0x%x\n",
                        host_res->dw_mem_base[0]);
@@ -796,6 +810,7 @@ int drv_request_bridge_res_dsp(void **phost_resources)
                        host_res->dw_mem_base[3]);
                dev_dbg(bridge, "dw_mem_base[4] 0x%x\n",
                        host_res->dw_mem_base[4]);
+               dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base);
 
                shm_size = drv_datap->shm_size;
                if (shm_size >= 0x10000) {
index 34be43fec044da6ed15e3370c7c64963772f7454..324fcdffb3b36d74a1db1830b229f303e936d859 100644 (file)
@@ -509,6 +509,8 @@ static int bridge_open(struct inode *ip, struct file *filp)
                pr_ctxt->res_state = PROC_RES_ALLOCATED;
                spin_lock_init(&pr_ctxt->dmm_map_lock);
                INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
+               spin_lock_init(&pr_ctxt->dmm_rsv_lock);
+               INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
 
                pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
                if (pr_ctxt->node_id) {
index a660247f527ac6a6b92725372328aca17af8ff40..1562f3c1281c642af3a854da4de650afb000b362 100644 (file)
@@ -56,6 +56,7 @@
 /*  ----------------------------------- This */
 #include <dspbridge/nodepriv.h>
 #include <dspbridge/node.h>
+#include <dspbridge/dmm.h>
 
 /* Static/Dynamic Loader includes */
 #include <dspbridge/dbll.h>
@@ -316,6 +317,10 @@ int node_allocate(struct proc_object *hprocessor,
        u32 mapped_addr = 0;
        u32 map_attrs = 0x0;
        struct dsp_processorstate proc_state;
+#ifdef DSP_DMM_DEBUG
+       struct dmm_object *dmm_mgr;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+#endif
 
        void *node_res;
 
@@ -425,12 +430,34 @@ int node_allocate(struct proc_object *hprocessor,
        if (status)
                goto func_cont;
 
+       status = proc_reserve_memory(hprocessor,
+                                    pnode->create_args.asa.task_arg_obj.
+                                    heap_size + PAGE_SIZE,
+                                    (void **)&(pnode->create_args.asa.
+                                       task_arg_obj.udsp_heap_res_addr),
+                                    pr_ctxt);
+       if (status) {
+               pr_err("%s: Failed to reserve memory for heap: 0x%x\n",
+                      __func__, status);
+               goto func_cont;
+       }
+#ifdef DSP_DMM_DEBUG
+       status = dmm_get_handle(p_proc_object, &dmm_mgr);
+       if (!dmm_mgr) {
+               status = DSP_EHANDLE;
+               goto func_cont;
+       }
+
+       dmm_mem_map_dump(dmm_mgr);
+#endif
+
        map_attrs |= DSP_MAPLITTLEENDIAN;
        map_attrs |= DSP_MAPELEMSIZE32;
        map_attrs |= DSP_MAPVIRTUALADDR;
        status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr,
                          pnode->create_args.asa.task_arg_obj.heap_size,
-                         NULL, (void **)&mapped_addr, map_attrs,
+                         (void *)pnode->create_args.asa.task_arg_obj.
+                         udsp_heap_res_addr, (void **)&mapped_addr, map_attrs,
                          pr_ctxt);
        if (status)
                pr_err("%s: Failed to map memory for Heap: 0x%x\n",
@@ -2484,7 +2511,11 @@ static void delete_node(struct node_object *hnode,
        struct stream_chnl stream;
        struct node_msgargs node_msg_args;
        struct node_taskargs task_arg_obj;
-
+#ifdef DSP_DMM_DEBUG
+       struct dmm_object *dmm_mgr;
+       struct proc_object *p_proc_object =
+           (struct proc_object *)hnode->hprocessor;
+#endif
        int status;
        if (!hnode)
                goto func_end;
@@ -2545,6 +2576,19 @@ static void delete_node(struct node_object *hnode,
                        status = proc_un_map(hnode->hprocessor, (void *)
                                             task_arg_obj.udsp_heap_addr,
                                             pr_ctxt);
+
+                       status = proc_un_reserve_memory(hnode->hprocessor,
+                                                       (void *)
+                                                       task_arg_obj.
+                                                       udsp_heap_res_addr,
+                                                       pr_ctxt);
+#ifdef DSP_DMM_DEBUG
+                       status = dmm_get_handle(p_proc_object, &dmm_mgr);
+                       if (dmm_mgr)
+                               dmm_mem_map_dump(dmm_mgr);
+                       else
+                               status = DSP_EHANDLE;
+#endif
                }
        }
        if (node_type != NODE_MESSAGE) {
index 7a15a02efedf8b99bfc7c36d187179a096118369..b47d7aa747b1d95181fa228d79dec9ce322aa24f 100644 (file)
@@ -39,6 +39,7 @@
 #include <dspbridge/cod.h>
 #include <dspbridge/dev.h>
 #include <dspbridge/procpriv.h>
+#include <dspbridge/dmm.h>
 
 /*  ----------------------------------- Resource Manager */
 #include <dspbridge/mgr.h>
@@ -51,7 +52,6 @@
 #include <dspbridge/msg.h>
 #include <dspbridge/dspioctl.h>
 #include <dspbridge/drv.h>
-#include <_tiomap.h>
 
 /*  ----------------------------------- This */
 #include <dspbridge/proc.h>
@@ -151,21 +151,34 @@ static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt,
        return map_obj;
 }
 
+static int match_exact_map_obj(struct dmm_map_object *map_obj,
+                                       u32 dsp_addr, u32 size)
+{
+       if (map_obj->dsp_addr == dsp_addr && map_obj->size != size)
+               pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n",
+                               __func__, dsp_addr, map_obj->size, size);
+
+       return map_obj->dsp_addr == dsp_addr &&
+               map_obj->size == size;
+}
+
 static void remove_mapping_information(struct process_context *pr_ctxt,
-                                               u32 dsp_addr)
+                                               u32 dsp_addr, u32 size)
 {
        struct dmm_map_object *map_obj;
 
-       pr_debug("%s: looking for virt 0x%x\n", __func__, dsp_addr);
+       pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__,
+                                                       dsp_addr, size);
 
        spin_lock(&pr_ctxt->dmm_map_lock);
        list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
-               pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x\n",
+               pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
                                                        __func__,
                                                        map_obj->mpu_addr,
-                                                       map_obj->dsp_addr);
+                                                       map_obj->dsp_addr,
+                                                       map_obj->size);
 
-               if (map_obj->dsp_addr == dsp_addr) {
+               if (match_exact_map_obj(map_obj, dsp_addr, size)) {
                        pr_debug("%s: match, deleting map info\n", __func__);
                        list_del(&map_obj->link);
                        kfree(map_obj->dma_info.sg);
@@ -1077,6 +1090,7 @@ int proc_load(void *hprocessor, const s32 argc_index,
        s32 cnew_envp;          /* "  " in new_envp[] */
        s32 nproc_id = 0;       /* Anticipate MP version. */
        struct dcd_manager *hdcd_handle;
+       struct dmm_object *dmm_mgr;
        u32 dw_ext_end;
        u32 proc_id;
        int brd_state;
@@ -1267,6 +1281,25 @@ int proc_load(void *hprocessor, const s32 argc_index,
                        if (!status)
                                status = cod_get_sym_value(cod_mgr, EXTEND,
                                                           &dw_ext_end);
+
+                       /* Reset DMM structs and add an initial free chunk */
+                       if (!status) {
+                               status =
+                                   dev_get_dmm_mgr(p_proc_object->hdev_obj,
+                                                   &dmm_mgr);
+                               if (dmm_mgr) {
+                                       /* Set dw_ext_end to DMM START u8
+                                        * address */
+                                       dw_ext_end =
+                                           (dw_ext_end + 1) * DSPWORDSIZE;
+                                       /* DMM memory is from EXT_END */
+                                       status = dmm_create_tables(dmm_mgr,
+                                                                  dw_ext_end,
+                                                                  DMMPOOLSIZE);
+                               } else {
+                                       status = -EFAULT;
+                               }
+                       }
                }
        }
        /* Restore the original argv[0] */
@@ -1319,10 +1352,12 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
 {
        u32 va_align;
        u32 pa_align;
+       struct dmm_object *dmm_mgr;
        u32 size_align;
        int status = 0;
        struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
        struct dmm_map_object *map_obj;
+       u32 tmp_addr = 0;
 
 #ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK
        if ((ul_map_attr & BUFMODE_MASK) != RBUF) {
@@ -1347,30 +1382,33 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
        }
        /* Critical section */
        mutex_lock(&proc_lock);
+       dmm_get_handle(p_proc_object, &dmm_mgr);
+       if (dmm_mgr)
+               status = dmm_map_memory(dmm_mgr, va_align, size_align);
+       else
+               status = -EFAULT;
 
        /* Add mapping to the page tables. */
        if (!status) {
+
+               /* Mapped address = MSB of VA | LSB of PA */
+               tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1)));
                /* mapped memory resource tracking */
-               map_obj = add_mapping_info(pr_ctxt, pa_align, va_align,
+               map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr,
                                                size_align);
-               if (!map_obj) {
+               if (!map_obj)
                        status = -ENOMEM;
-               } else {
-                       va_align = user_to_dsp_map(
-                               p_proc_object->hbridge_context->dsp_mmu,
-                               pa_align, va_align, size_align,
-                               map_obj->pages);
-                       if (IS_ERR_VALUE(va_align))
-                               status = (int)va_align;
-               }
+               else
+                       status = (*p_proc_object->intf_fxns->pfn_brd_mem_map)
+                           (p_proc_object->hbridge_context, pa_align, va_align,
+                            size_align, ul_map_attr, map_obj->pages);
        }
        if (!status) {
                /* Mapped address = MSB of VA | LSB of PA */
-               map_obj->dsp_addr = (va_align |
-                                       ((u32)pmpu_addr & (PG_SIZE4K - 1)));
-               *pp_map_addr = (void *)map_obj->dsp_addr;
+               *pp_map_addr = (void *) tmp_addr;
        } else {
-               remove_mapping_information(pr_ctxt, va_align);
+               remove_mapping_information(pr_ctxt, tmp_addr, size_align);
+               dmm_un_map_memory(dmm_mgr, va_align, &size_align);
        }
        mutex_unlock(&proc_lock);
 
@@ -1462,6 +1500,55 @@ func_end:
        return status;
 }
 
+/*
+ *  ======== proc_reserve_memory ========
+ *  Purpose:
+ *      Reserve a virtually contiguous region of DSP address space.
+ */
+int proc_reserve_memory(void *hprocessor, u32 ul_size,
+                              void **pp_rsv_addr,
+                              struct process_context *pr_ctxt)
+{
+       struct dmm_object *dmm_mgr;
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct dmm_rsv_object *rsv_obj;
+
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = dmm_get_handle(p_proc_object, &dmm_mgr);
+       if (!dmm_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr);
+       if (status != 0)
+               goto func_end;
+
+       /*
+        * A successful reserve should be followed by insertion of rsv_obj
+        * into dmm_rsv_list, so that reserved memory resource tracking
+        * remains uptodate
+        */
+       rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL);
+       if (rsv_obj) {
+               rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr;
+               spin_lock(&pr_ctxt->dmm_rsv_lock);
+               list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list);
+               spin_unlock(&pr_ctxt->dmm_rsv_lock);
+       }
+
+func_end:
+       dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p "
+               "status 0x%x\n", __func__, hprocessor,
+               ul_size, pp_rsv_addr, status);
+       return status;
+}
+
 /*
  *  ======== proc_start ========
  *  Purpose:
@@ -1610,7 +1697,9 @@ int proc_un_map(void *hprocessor, void *map_addr,
 {
        int status = 0;
        struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct dmm_object *dmm_mgr;
        u32 va_align;
+       u32 size_align;
 
        va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K);
        if (!p_proc_object) {
@@ -1618,11 +1707,24 @@ int proc_un_map(void *hprocessor, void *map_addr,
                goto func_end;
        }
 
+       status = dmm_get_handle(hprocessor, &dmm_mgr);
+       if (!dmm_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
        /* Critical section */
        mutex_lock(&proc_lock);
+       /*
+        * Update DMM structures. Get the size to unmap.
+        * This function returns error if the VA is not mapped
+        */
+       status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);
        /* Remove mapping from the page tables. */
-       status = user_to_dsp_unmap(p_proc_object->hbridge_context->dsp_mmu,
-                                                               va_align);
+       if (!status) {
+               status = (*p_proc_object->intf_fxns->pfn_brd_mem_un_map)
+                   (p_proc_object->hbridge_context, va_align, size_align);
+       }
 
        mutex_unlock(&proc_lock);
        if (status)
@@ -1633,7 +1735,7 @@ int proc_un_map(void *hprocessor, void *map_addr,
         * from dmm_map_list, so that mapped memory resource tracking
         * remains uptodate
         */
-       remove_mapping_information(pr_ctxt, (u32) map_addr);
+       remove_mapping_information(pr_ctxt, (u32) map_addr, size_align);
 
 func_end:
        dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n",
@@ -1641,6 +1743,55 @@ func_end:
        return status;
 }
 
+/*
+ *  ======== proc_un_reserve_memory ========
+ *  Purpose:
+ *      Frees a previously reserved region of DSP address space.
+ */
+int proc_un_reserve_memory(void *hprocessor, void *prsv_addr,
+                                 struct process_context *pr_ctxt)
+{
+       struct dmm_object *dmm_mgr;
+       int status = 0;
+       struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
+       struct dmm_rsv_object *rsv_obj;
+
+       if (!p_proc_object) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = dmm_get_handle(p_proc_object, &dmm_mgr);
+       if (!dmm_mgr) {
+               status = -EFAULT;
+               goto func_end;
+       }
+
+       status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr);
+       if (status != 0)
+               goto func_end;
+
+       /*
+        * A successful unreserve should be followed by removal of rsv_obj
+        * from dmm_rsv_list, so that reserved memory resource tracking
+        * remains uptodate
+        */
+       spin_lock(&pr_ctxt->dmm_rsv_lock);
+       list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) {
+               if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) {
+                       list_del(&rsv_obj->link);
+                       kfree(rsv_obj);
+                       break;
+               }
+       }
+       spin_unlock(&pr_ctxt->dmm_rsv_lock);
+
+func_end:
+       dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n",
+               __func__, hprocessor, prsv_addr, status);
+       return status;
+}
+
 /*
  *  ======== = proc_monitor ======== ==
  *  Purpose:
index 3e46866dd2791dc3b66724bd64e96836a1159dfd..93f625fc852b20d991012ffa6d61b05b693690a6 100644 (file)
@@ -320,7 +320,6 @@ static struct i2c_algorithm tm6000_algo = {
 
 static struct i2c_adapter tm6000_adap_template = {
        .owner = THIS_MODULE,
-       .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
        .name = "tm6000",
        .algo = &tm6000_algo,
 };
index 9ec82796634ecf50cbd5da43dd8b30b0eddc3706..c5690b2a89244769f6af1bfc4b061f663599e32c 100644 (file)
@@ -1032,6 +1032,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm)
        struct tm6000_fh   *fh=priv;
        struct tm6000_core *dev = fh->dev;
 
+       dev->norm = *norm;
        rc = tm6000_init_analog_mode(dev);
 
        fh->width  = dev->width;
index 5969e848d297ea44951a8c7418e09d74bfd6422e..fed25105970a94d06ca185fa81603f79968d67f8 100644 (file)
@@ -887,7 +887,7 @@ static int dlfb_ops_open(struct fb_info *info, int user)
 
                struct fb_deferred_io *fbdefio;
 
-               fbdefio = kmalloc(GFP_KERNEL, sizeof(struct fb_deferred_io));
+               fbdefio = kmalloc(sizeof(struct fb_deferred_io), GFP_KERNEL);
 
                if (fbdefio) {
                        fbdefio->delay = DL_DEFIO_WRITE_DELAY;
index e992d5d9e15bc13e80031e99591f92c1e62357c0..7cc3d2407d1b604633a928ceb3b2593df1cd08af 100644 (file)
@@ -1675,13 +1675,14 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 
                {
                        char essid[IW_ESSID_MAX_SIZE+1];
-                       if (wrq->u.essid.pointer)
+                       if (wrq->u.essid.pointer) {
                                rc = iwctl_giwessid(dev, NULL,
                                                    &(wrq->u.essid), essid);
                                if (copy_to_user(wrq->u.essid.pointer,
                                                         essid,
                                                         wrq->u.essid.length) )
                                        rc = -EFAULT;
+                       }
                }
                break;
 
index 5a2197012065a492d073e16308d222a50aa00a25..7777d9a60a5238db70721f38c2c9c5ee41f07b62 100644 (file)
@@ -1417,7 +1417,6 @@ cy_as_usb_set_enum_config(cy_as_device_handle handle,
         */
        bus_mask   = 0;
        media_mask = 0;
-       media_mask = 0;
        for (bus = 0; bus < CY_AS_MAX_BUSES; bus++) {
                for (device = 0; device < CY_AS_MAX_STORAGE_DEVICES; device++) {
                        if (config_p->devices_to_enumerate[bus][device] ==
index f428a7af357a6812fe1f0c7ca8f73a7f88aecf24..e1851f00be568f07e17fbd6c45070bdc9d01de93 100644 (file)
@@ -157,7 +157,7 @@ struct cyasblkdev_blk_data {
 /* pointer to west bridge block data device superstructure */
 static struct cyasblkdev_blk_data *gl_bd;
 
-static DECLARE_MUTEX(open_lock);
+static DEFINE_SEMAPHORE(open_lock);
 
 /* local forwardd declarationss  */
 static cy_as_device_handle *cyas_dev_handle;
index 24e959eca4127a0db1078a60466723d569304be5..0bbb8a3e191df18963e98bafeaef480da125a3a2 100644 (file)
@@ -334,7 +334,7 @@ int cyasblkdev_init_queue(struct cyasblkdev_queue *bq, spinlock_t *lock)
 
        init_completion(&bq->thread_complete);
        init_waitqueue_head(&bq->thread_wq);
-       init_MUTEX(&bq->thread_sem);
+       sema_init(&bq->thread_sem, 1);
 
        ret = kernel_thread(cyasblkdev_queue_thread, bq, CLONE_KERNEL);
        if (ret >= 0) {
index 4af83d5318f2705d551cd65fc898645e217e339d..6a71f52c59b1f0a575b8ba69aeac20a9fd2c733a 100644 (file)
@@ -139,7 +139,7 @@ exit:
 }
 
 int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
-                  u8 key_index, const u8 *mac_addr,
+                  u8 key_index, bool pairwise, const u8 *mac_addr,
                   struct key_params *params)
 {
        wlandevice_t *wlandev = dev->ml_priv;
@@ -198,7 +198,7 @@ exit:
 }
 
 int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
-                  u8 key_index, const u8 *mac_addr, void *cookie,
+                  u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie,
                   void (*callback)(void *cookie, struct key_params*))
 {
        wlandevice_t *wlandev = dev->ml_priv;
@@ -227,7 +227,7 @@ int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
 }
 
 int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
-                  u8 key_index, const u8 *mac_addr)
+                  u8 key_index, bool pairwise, const u8 *mac_addr)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        u32 did;
index aa1792c8429ea4c049868f40f9374d9e326a3743..b7b4a733b467f69b95e864d41dcb1f4af79db8d7 100644 (file)
@@ -522,8 +522,8 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
                if (copy_to_user(useraddr, &edata, sizeof(edata)))
                        return -EFAULT;
                return 0;
-       }
 #endif
+       }
 
        return -EOPNOTSUPP;
 }
diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile
new file mode 100644 (file)
index 0000000..c43ef48
--- /dev/null
@@ -0,0 +1,11 @@
+obj-y                          += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
+                                  tty_buffer.o tty_port.o tty_mutex.o
+obj-$(CONFIG_LEGACY_PTYS)      += pty.o
+obj-$(CONFIG_UNIX98_PTYS)      += pty.o
+obj-$(CONFIG_AUDIT)            += tty_audit.o
+obj-$(CONFIG_MAGIC_SYSRQ)      += sysrq.o
+obj-$(CONFIG_N_HDLC)           += n_hdlc.o
+obj-$(CONFIG_N_GSM)            += n_gsm.o
+obj-$(CONFIG_R3964)            += n_r3964.o
+
+obj-y                          += vt/
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
new file mode 100644 (file)
index 0000000..81b4658
--- /dev/null
@@ -0,0 +1,2764 @@
+/*
+ * n_gsm.c GSM 0710 tty multiplexor
+ * Copyright (c) 2009/10 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *     * THIS IS A DEVELOPMENT SNAPSHOT IT IS NOT A FINAL RELEASE *
+ *
+ * TO DO:
+ *     Mostly done:    ioctls for setting modes/timing
+ *     Partly done:    hooks so you can pull off frames to non tty devs
+ *     Restart DLCI 0 when it closes ?
+ *     Test basic encoding
+ *     Improve the tx engine
+ *     Resolve tx side locking by adding a queue_head and routing
+ *             all control traffic via it
+ *     General tidy/document
+ *     Review the locking/move to refcounts more (mux now moved to an
+ *             alloc/free model ready)
+ *     Use newest tty open/close port helpers and install hooks
+ *     What to do about power functions ?
+ *     Termios setting and negotiation
+ *     Do we need a 'which mux are you' ioctl to correlate mux and tty sets
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/ctype.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/bitops.h>
+#include <linux/file.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/tty_flip.h>
+#include <linux/tty_driver.h>
+#include <linux/serial.h>
+#include <linux/kfifo.h>
+#include <linux/skbuff.h>
+#include <linux/gsmmux.h>
+
+static int debug;
+module_param(debug, int, 0600);
+
+#define T1     (HZ/10)
+#define T2     (HZ/3)
+#define N2     3
+
+/* Use long timers for testing at low speed with debug on */
+#ifdef DEBUG_TIMING
+#define T1     HZ
+#define T2     (2 * HZ)
+#endif
+
+/* Semi-arbitary buffer size limits. 0710 is normally run with 32-64 byte
+   limits so this is plenty */
+#define MAX_MRU 512
+#define MAX_MTU 512
+
+/*
+ *     Each block of data we have queued to go out is in the form of
+ *     a gsm_msg which holds everything we need in a link layer independant
+ *     format
+ */
+
+struct gsm_msg {
+       struct gsm_msg *next;
+       u8 addr;                /* DLCI address + flags */
+       u8 ctrl;                /* Control byte + flags */
+       unsigned int len;       /* Length of data block (can be zero) */
+       unsigned char *data;    /* Points into buffer but not at the start */
+       unsigned char buffer[0];
+};
+
+/*
+ *     Each active data link has a gsm_dlci structure associated which ties
+ *     the link layer to an optional tty (if the tty side is open). To avoid
+ *     complexity right now these are only ever freed up when the mux is
+ *     shut down.
+ *
+ *     At the moment we don't free DLCI objects until the mux is torn down
+ *     this avoid object life time issues but might be worth review later.
+ */
+
+struct gsm_dlci {
+       struct gsm_mux *gsm;
+       int addr;
+       int state;
+#define DLCI_CLOSED            0
+#define DLCI_OPENING           1       /* Sending SABM not seen UA */
+#define DLCI_OPEN              2       /* SABM/UA complete */
+#define DLCI_CLOSING           3       /* Sending DISC not seen UA/DM */
+
+       /* Link layer */
+       spinlock_t lock;        /* Protects the internal state */
+       struct timer_list t1;   /* Retransmit timer for SABM and UA */
+       int retries;
+       /* Uplink tty if active */
+       struct tty_port port;   /* The tty bound to this DLCI if there is one */
+       struct kfifo *fifo;     /* Queue fifo for the DLCI */
+       struct kfifo _fifo;     /* For new fifo API porting only */
+       int adaption;           /* Adaption layer in use */
+       u32 modem_rx;           /* Our incoming virtual modem lines */
+       u32 modem_tx;           /* Our outgoing modem lines */
+       int dead;               /* Refuse re-open */
+       /* Flow control */
+       int throttled;          /* Private copy of throttle state */
+       int constipated;        /* Throttle status for outgoing */
+       /* Packetised I/O */
+       struct sk_buff *skb;    /* Frame being sent */
+       struct sk_buff_head skb_list;   /* Queued frames */
+       /* Data handling callback */
+       void (*data)(struct gsm_dlci *dlci, u8 *data, int len);
+};
+
+/* DLCI 0, 62/63 are special or reseved see gsmtty_open */
+
+#define NUM_DLCI               64
+
+/*
+ *     DLCI 0 is used to pass control blocks out of band of the data
+ *     flow (and with a higher link priority). One command can be outstanding
+ *     at a time and we use this structure to manage them. They are created
+ *     and destroyed by the user context, and updated by the receive paths
+ *     and timers
+ */
+
+struct gsm_control {
+       u8 cmd;         /* Command we are issuing */
+       u8 *data;       /* Data for the command in case we retransmit */
+       int len;        /* Length of block for retransmission */
+       int done;       /* Done flag */
+       int error;      /* Error if any */
+};
+
+/*
+ *     Each GSM mux we have is represented by this structure. If we are
+ *     operating as an ldisc then we use this structure as our ldisc
+ *     state. We need to sort out lifetimes and locking with respect
+ *     to the gsm mux array. For now we don't free DLCI objects that
+ *     have been instantiated until the mux itself is terminated.
+ *
+ *     To consider further: tty open versus mux shutdown.
+ */
+
+struct gsm_mux {
+       struct tty_struct *tty;         /* The tty our ldisc is bound to */
+       spinlock_t lock;
+
+       /* Events on the GSM channel */
+       wait_queue_head_t event;
+
+       /* Bits for GSM mode decoding */
+
+       /* Framing Layer */
+       unsigned char *buf;
+       int state;
+#define GSM_SEARCH             0
+#define GSM_START              1
+#define GSM_ADDRESS            2
+#define GSM_CONTROL            3
+#define GSM_LEN                        4
+#define GSM_DATA               5
+#define GSM_FCS                        6
+#define GSM_OVERRUN            7
+       unsigned int len;
+       unsigned int address;
+       unsigned int count;
+       int escape;
+       int encoding;
+       u8 control;
+       u8 fcs;
+       u8 *txframe;                    /* TX framing buffer */
+
+       /* Methods for the receiver side */
+       void (*receive)(struct gsm_mux *gsm, u8 ch);
+       void (*error)(struct gsm_mux *gsm, u8 ch, u8 flag);
+       /* And transmit side */
+       int (*output)(struct gsm_mux *mux, u8 *data, int len);
+
+       /* Link Layer */
+       unsigned int mru;
+       unsigned int mtu;
+       int initiator;                  /* Did we initiate connection */
+       int dead;                       /* Has the mux been shut down */
+       struct gsm_dlci *dlci[NUM_DLCI];
+       int constipated;                /* Asked by remote to shut up */
+
+       spinlock_t tx_lock;
+       unsigned int tx_bytes;          /* TX data outstanding */
+#define TX_THRESH_HI           8192
+#define TX_THRESH_LO           2048
+       struct gsm_msg *tx_head;        /* Pending data packets */
+       struct gsm_msg *tx_tail;
+
+       /* Control messages */
+       struct timer_list t2_timer;     /* Retransmit timer for commands */
+       int cretries;                   /* Command retry counter */
+       struct gsm_control *pending_cmd;/* Our current pending command */
+       spinlock_t control_lock;        /* Protects the pending command */
+
+       /* Configuration */
+       int adaption;           /* 1 or 2 supported */
+       u8 ftype;               /* UI or UIH */
+       int t1, t2;             /* Timers in 1/100th of a sec */
+       int n2;                 /* Retry count */
+
+       /* Statistics (not currently exposed) */
+       unsigned long bad_fcs;
+       unsigned long malformed;
+       unsigned long io_error;
+       unsigned long bad_size;
+       unsigned long unsupported;
+};
+
+
+/*
+ *     Mux objects - needed so that we can translate a tty index into the
+ *     relevant mux and DLCI.
+ */
+
+#define MAX_MUX                4                       /* 256 minors */
+static struct gsm_mux *gsm_mux[MAX_MUX];       /* GSM muxes */
+static spinlock_t gsm_mux_lock;
+
+/*
+ *     This section of the driver logic implements the GSM encodings
+ *     both the basic and the 'advanced'. Reliable transport is not
+ *     supported.
+ */
+
+#define CR                     0x02
+#define EA                     0x01
+#define        PF                      0x10
+
+/* I is special: the rest are ..*/
+#define RR                     0x01
+#define UI                     0x03
+#define RNR                    0x05
+#define REJ                    0x09
+#define DM                     0x0F
+#define SABM                   0x2F
+#define DISC                   0x43
+#define UA                     0x63
+#define        UIH                     0xEF
+
+/* Channel commands */
+#define CMD_NSC                        0x09
+#define CMD_TEST               0x11
+#define CMD_PSC                        0x21
+#define CMD_RLS                        0x29
+#define CMD_FCOFF              0x31
+#define CMD_PN                 0x41
+#define CMD_RPN                        0x49
+#define CMD_FCON               0x51
+#define CMD_CLD                        0x61
+#define CMD_SNC                        0x69
+#define CMD_MSC                        0x71
+
+/* Virtual modem bits */
+#define MDM_FC                 0x01
+#define MDM_RTC                        0x02
+#define MDM_RTR                        0x04
+#define MDM_IC                 0x20
+#define MDM_DV                 0x40
+
+#define GSM0_SOF               0xF9
+#define GSM1_SOF               0x7E
+#define GSM1_ESCAPE            0x7D
+#define GSM1_ESCAPE_BITS       0x20
+#define XON                    0x11
+#define XOFF                   0x13
+
+static const struct tty_port_operations gsm_port_ops;
+
+/*
+ *     CRC table for GSM 0710
+ */
+
+static const u8 gsm_fcs8[256] = {
+       0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75,
+       0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
+       0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69,
+       0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
+       0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D,
+       0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
+       0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51,
+       0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,
+       0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05,
+       0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,
+       0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19,
+       0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,
+       0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D,
+       0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,
+       0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21,
+       0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,
+       0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95,
+       0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,
+       0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89,
+       0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,
+       0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD,
+       0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
+       0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1,
+       0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,
+       0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5,
+       0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,
+       0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9,
+       0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,
+       0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD,
+       0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
+       0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1,
+       0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
+};
+
+#define INIT_FCS       0xFF
+#define GOOD_FCS       0xCF
+
+/**
+ *     gsm_fcs_add     -       update FCS
+ *     @fcs: Current FCS
+ *     @c: Next data
+ *
+ *     Update the FCS to include c. Uses the algorithm in the specification
+ *     notes.
+ */
+
+static inline u8 gsm_fcs_add(u8 fcs, u8 c)
+{
+       return gsm_fcs8[fcs ^ c];
+}
+
+/**
+ *     gsm_fcs_add_block       -       update FCS for a block
+ *     @fcs: Current FCS
+ *     @c: buffer of data
+ *     @len: length of buffer
+ *
+ *     Update the FCS to include c. Uses the algorithm in the specification
+ *     notes.
+ */
+
+static inline u8 gsm_fcs_add_block(u8 fcs, u8 *c, int len)
+{
+       while (len--)
+               fcs = gsm_fcs8[fcs ^ *c++];
+       return fcs;
+}
+
+/**
+ *     gsm_read_ea             -       read a byte into an EA
+ *     @val: variable holding value
+ *     c: byte going into the EA
+ *
+ *     Processes one byte of an EA. Updates the passed variable
+ *     and returns 1 if the EA is now completely read
+ */
+
+static int gsm_read_ea(unsigned int *val, u8 c)
+{
+       /* Add the next 7 bits into the value */
+       *val <<= 7;
+       *val |= c >> 1;
+       /* Was this the last byte of the EA 1 = yes*/
+       return c & EA;
+}
+
+/**
+ *     gsm_encode_modem        -       encode modem data bits
+ *     @dlci: DLCI to encode from
+ *
+ *     Returns the correct GSM encoded modem status bits (6 bit field) for
+ *     the current status of the DLCI and attached tty object
+ */
+
+static u8 gsm_encode_modem(const struct gsm_dlci *dlci)
+{
+       u8 modembits = 0;
+       /* FC is true flow control not modem bits */
+       if (dlci->throttled)
+               modembits |= MDM_FC;
+       if (dlci->modem_tx & TIOCM_DTR)
+               modembits |= MDM_RTC;
+       if (dlci->modem_tx & TIOCM_RTS)
+               modembits |= MDM_RTR;
+       if (dlci->modem_tx & TIOCM_RI)
+               modembits |= MDM_IC;
+       if (dlci->modem_tx & TIOCM_CD)
+               modembits |= MDM_DV;
+       return modembits;
+}
+
+/**
+ *     gsm_print_packet        -       display a frame for debug
+ *     @hdr: header to print before decode
+ *     @addr: address EA from the frame
+ *     @cr: C/R bit from the frame
+ *     @control: control including PF bit
+ *     @data: following data bytes
+ *     @dlen: length of data
+ *
+ *     Displays a packet in human readable format for debugging purposes. The
+ *     style is based on amateur radio LAP-B dump display.
+ */
+
+static void gsm_print_packet(const char *hdr, int addr, int cr,
+                                       u8 control, const u8 *data, int dlen)
+{
+       if (!(debug & 1))
+               return;
+
+       printk(KERN_INFO "%s %d) %c: ", hdr, addr, "RC"[cr]);
+
+       switch (control & ~PF) {
+       case SABM:
+               printk(KERN_CONT "SABM");
+               break;
+       case UA:
+               printk(KERN_CONT "UA");
+               break;
+       case DISC:
+               printk(KERN_CONT "DISC");
+               break;
+       case DM:
+               printk(KERN_CONT "DM");
+               break;
+       case UI:
+               printk(KERN_CONT "UI");
+               break;
+       case UIH:
+               printk(KERN_CONT "UIH");
+               break;
+       default:
+               if (!(control & 0x01)) {
+                       printk(KERN_CONT "I N(S)%d N(R)%d",
+                               (control & 0x0E) >> 1, (control & 0xE)>> 5);
+               } else switch (control & 0x0F) {
+               case RR:
+                       printk("RR(%d)", (control & 0xE0) >> 5);
+                       break;
+               case RNR:
+                       printk("RNR(%d)", (control & 0xE0) >> 5);
+                       break;
+               case REJ:
+                       printk("REJ(%d)", (control & 0xE0) >> 5);
+                       break;
+               default:
+                       printk(KERN_CONT "[%02X]", control);
+               }
+       }
+
+       if (control & PF)
+               printk(KERN_CONT "(P)");
+       else
+               printk(KERN_CONT "(F)");
+
+       if (dlen) {
+               int ct = 0;
+               while (dlen--) {
+                       if (ct % 8 == 0)
+                               printk(KERN_CONT "\n    ");
+                       printk(KERN_CONT "%02X ", *data++);
+                       ct++;
+               }
+       }
+       printk(KERN_CONT "\n");
+}
+
+
+/*
+ *     Link level transmission side
+ */
+
+/**
+ *     gsm_stuff_packet        -       bytestuff a packet
+ *     @ibuf: input
+ *     @obuf: output
+ *     @len: length of input
+ *
+ *     Expand a buffer by bytestuffing it. The worst case size change
+ *     is doubling and the caller is responsible for handing out
+ *     suitable sized buffers.
+ */
+
+static int gsm_stuff_frame(const u8 *input, u8 *output, int len)
+{
+       int olen = 0;
+       while (len--) {
+               if (*input == GSM1_SOF || *input == GSM1_ESCAPE
+                   || *input == XON || *input == XOFF) {
+                       *output++ = GSM1_ESCAPE;
+                       *output++ = *input++ ^ GSM1_ESCAPE_BITS;
+                       olen++;
+               } else
+                       *output++ = *input++;
+               olen++;
+       }
+       return olen;
+}
+
+static void hex_packet(const unsigned char *p, int len)
+{
+       int i;
+       for (i = 0; i < len; i++) {
+               if (i && (i % 16) == 0)
+                       printk("\n");
+               printk("%02X ", *p++);
+       }
+       printk("\n");
+}
+
+/**
+ *     gsm_send        -       send a control frame
+ *     @gsm: our GSM mux
+ *     @addr: address for control frame
+ *     @cr: command/response bit
+ *     @control:  control byte including PF bit
+ *
+ *     Format up and transmit a control frame. These do not go via the
+ *     queueing logic as they should be transmitted ahead of data when
+ *     they are needed.
+ *
+ *     FIXME: Lock versus data TX path
+ */
+
+static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+{
+       int len;
+       u8 cbuf[10];
+       u8 ibuf[3];
+
+       switch (gsm->encoding) {
+       case 0:
+               cbuf[0] = GSM0_SOF;
+               cbuf[1] = (addr << 2) | (cr << 1) | EA;
+               cbuf[2] = control;
+               cbuf[3] = EA;   /* Length of data = 0 */
+               cbuf[4] = 0xFF - gsm_fcs_add_block(INIT_FCS, cbuf + 1, 3);
+               cbuf[5] = GSM0_SOF;
+               len = 6;
+               break;
+       case 1:
+       case 2:
+               /* Control frame + packing (but not frame stuffing) in mode 1 */
+               ibuf[0] = (addr << 2) | (cr << 1) | EA;
+               ibuf[1] = control;
+               ibuf[2] = 0xFF - gsm_fcs_add_block(INIT_FCS, ibuf, 2);
+               /* Stuffing may double the size worst case */
+               len = gsm_stuff_frame(ibuf, cbuf + 1, 3);
+               /* Now add the SOF markers */
+               cbuf[0] = GSM1_SOF;
+               cbuf[len + 1] = GSM1_SOF;
+               /* FIXME: we can omit the lead one in many cases */
+               len += 2;
+               break;
+       default:
+               WARN_ON(1);
+               return;
+       }
+       gsm->output(gsm, cbuf, len);
+       gsm_print_packet("-->", addr, cr, control, NULL, 0);
+}
+
+/**
+ *     gsm_response    -       send a control response
+ *     @gsm: our GSM mux
+ *     @addr: address for control frame
+ *     @control:  control byte including PF bit
+ *
+ *     Format up and transmit a link level response frame.
+ */
+
+static inline void gsm_response(struct gsm_mux *gsm, int addr, int control)
+{
+       gsm_send(gsm, addr, 0, control);
+}
+
+/**
+ *     gsm_command     -       send a control command
+ *     @gsm: our GSM mux
+ *     @addr: address for control frame
+ *     @control:  control byte including PF bit
+ *
+ *     Format up and transmit a link level command frame.
+ */
+
+static inline void gsm_command(struct gsm_mux *gsm, int addr, int control)
+{
+       gsm_send(gsm, addr, 1, control);
+}
+
+/* Data transmission */
+
+#define HDR_LEN                6       /* ADDR CTRL [LEN.2] DATA FCS */
+
+/**
+ *     gsm_data_alloc          -       allocate data frame
+ *     @gsm: GSM mux
+ *     @addr: DLCI address
+ *     @len: length excluding header and FCS
+ *     @ctrl: control byte
+ *
+ *     Allocate a new data buffer for sending frames with data. Space is left
+ *     at the front for header bytes but that is treated as an implementation
+ *     detail and not for the high level code to use
+ */
+
+static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
+                                                               u8 ctrl)
+{
+       struct gsm_msg *m = kmalloc(sizeof(struct gsm_msg) + len + HDR_LEN,
+                                                               GFP_ATOMIC);
+       if (m == NULL)
+               return NULL;
+       m->data = m->buffer + HDR_LEN - 1;      /* Allow for FCS */
+       m->len = len;
+       m->addr = addr;
+       m->ctrl = ctrl;
+       m->next = NULL;
+       return m;
+}
+
+/**
+ *     gsm_data_kick           -       poke the queue
+ *     @gsm: GSM Mux
+ *
+ *     The tty device has called us to indicate that room has appeared in
+ *     the transmit queue. Ram more data into the pipe if we have any
+ *
+ *     FIXME: lock against link layer control transmissions
+ */
+
+static void gsm_data_kick(struct gsm_mux *gsm)
+{
+       struct gsm_msg *msg = gsm->tx_head;
+       int len;
+       int skip_sof = 0;
+
+       /* FIXME: We need to apply this solely to data messages */
+       if (gsm->constipated)
+               return;
+
+       while (gsm->tx_head != NULL) {
+               msg = gsm->tx_head;
+               if (gsm->encoding != 0) {
+                       gsm->txframe[0] = GSM1_SOF;
+                       len = gsm_stuff_frame(msg->data,
+                                               gsm->txframe + 1, msg->len);
+                       gsm->txframe[len + 1] = GSM1_SOF;
+                       len += 2;
+               } else {
+                       gsm->txframe[0] = GSM0_SOF;
+                       memcpy(gsm->txframe + 1 , msg->data, msg->len);
+                       gsm->txframe[msg->len + 1] = GSM0_SOF;
+                       len = msg->len + 2;
+               }
+
+               if (debug & 4) {
+                       printk("gsm_data_kick: \n");
+                       hex_packet(gsm->txframe, len);
+               }
+
+               if (gsm->output(gsm, gsm->txframe + skip_sof,
+                                               len - skip_sof) < 0)
+                       break;
+               /* FIXME: Can eliminate one SOF in many more cases */
+               gsm->tx_head = msg->next;
+               if (gsm->tx_head == NULL)
+                       gsm->tx_tail = NULL;
+               gsm->tx_bytes -= msg->len;
+               kfree(msg);
+               /* For a burst of frames skip the extra SOF within the
+                  burst */
+               skip_sof = 1;
+       }
+}
+
+/**
+ *     __gsm_data_queue                -       queue a UI or UIH frame
+ *     @dlci: DLCI sending the data
+ *     @msg: message queued
+ *
+ *     Add data to the transmit queue and try and get stuff moving
+ *     out of the mux tty if not already doing so. The Caller must hold
+ *     the gsm tx lock.
+ */
+
+static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+{
+       struct gsm_mux *gsm = dlci->gsm;
+       u8 *dp = msg->data;
+       u8 *fcs = dp + msg->len;
+
+       /* Fill in the header */
+       if (gsm->encoding == 0) {
+               if (msg->len < 128)
+                       *--dp = (msg->len << 1) | EA;
+               else {
+                       *--dp = ((msg->len & 127) << 1) | EA;
+                       *--dp = (msg->len >> 6) & 0xfe;
+               }
+       }
+
+       *--dp = msg->ctrl;
+       if (gsm->initiator)
+               *--dp = (msg->addr << 2) | 2 | EA;
+       else
+               *--dp = (msg->addr << 2) | EA;
+       *fcs = gsm_fcs_add_block(INIT_FCS, dp , msg->data - dp);
+       /* Ugly protocol layering violation */
+       if (msg->ctrl == UI || msg->ctrl == (UI|PF))
+               *fcs = gsm_fcs_add_block(*fcs, msg->data, msg->len);
+       *fcs = 0xFF - *fcs;
+
+       gsm_print_packet("Q> ", msg->addr, gsm->initiator, msg->ctrl,
+                                                       msg->data, msg->len);
+
+       /* Move the header back and adjust the length, also allow for the FCS
+          now tacked on the end */
+       msg->len += (msg->data - dp) + 1;
+       msg->data = dp;
+
+       /* Add to the actual output queue */
+       if (gsm->tx_tail)
+               gsm->tx_tail->next = msg;
+       else
+               gsm->tx_head = msg;
+       gsm->tx_tail = msg;
+       gsm->tx_bytes += msg->len;
+       gsm_data_kick(gsm);
+}
+
+/**
+ *     gsm_data_queue          -       queue a UI or UIH frame
+ *     @dlci: DLCI sending the data
+ *     @msg: message queued
+ *
+ *     Add data to the transmit queue and try and get stuff moving
+ *     out of the mux tty if not already doing so. Take the
+ *     the gsm tx lock and dlci lock.
+ */
+
+static void gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+       __gsm_data_queue(dlci, msg);
+       spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
+}
+
+/**
+ *     gsm_dlci_data_output    -       try and push data out of a DLCI
+ *     @gsm: mux
+ *     @dlci: the DLCI to pull data from
+ *
+ *     Pull data from a DLCI and send it into the transmit queue if there
+ *     is data. Keep to the MRU of the mux. This path handles the usual tty
+ *     interface which is a byte stream with optional modem data.
+ *
+ *     Caller must hold the tx_lock of the mux.
+ */
+
+static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+{
+       struct gsm_msg *msg;
+       u8 *dp;
+       int len, size;
+       int h = dlci->adaption - 1;
+
+       len = kfifo_len(dlci->fifo);
+       if (len == 0)
+               return 0;
+
+       /* MTU/MRU count only the data bits */
+       if (len > gsm->mtu)
+               len = gsm->mtu;
+
+       size = len + h;
+
+       msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+       /* FIXME: need a timer or something to kick this so it can't
+          get stuck with no work outstanding and no buffer free */
+       if (msg == NULL)
+               return -ENOMEM;
+       dp = msg->data;
+       switch (dlci->adaption) {
+       case 1: /* Unstructured */
+               break;
+       case 2: /* Unstructed with modem bits. Always one byte as we never
+                  send inline break data */
+               *dp += gsm_encode_modem(dlci);
+               len--;
+               break;
+       }
+       WARN_ON(kfifo_out_locked(dlci->fifo, dp , len, &dlci->lock) != len);
+       __gsm_data_queue(dlci, msg);
+       /* Bytes of data we used up */
+       return size;
+}
+
+/**
+ *     gsm_dlci_data_output_framed  -  try and push data out of a DLCI
+ *     @gsm: mux
+ *     @dlci: the DLCI to pull data from
+ *
+ *     Pull data from a DLCI and send it into the transmit queue if there
+ *     is data. Keep to the MRU of the mux. This path handles framed data
+ *     queued as skbuffs to the DLCI.
+ *
+ *     Caller must hold the tx_lock of the mux.
+ */
+
+static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+                                               struct gsm_dlci *dlci)
+{
+       struct gsm_msg *msg;
+       u8 *dp;
+       int len, size;
+       int last = 0, first = 0;
+       int overhead = 0;
+
+       /* One byte per frame is used for B/F flags */
+       if (dlci->adaption == 4)
+               overhead = 1;
+
+       /* dlci->skb is locked by tx_lock */
+       if (dlci->skb == NULL) {
+               dlci->skb = skb_dequeue(&dlci->skb_list);
+               if (dlci->skb == NULL)
+                       return 0;
+               first = 1;
+       }
+       len = dlci->skb->len + overhead;
+
+       /* MTU/MRU count only the data bits */
+       if (len > gsm->mtu) {
+               if (dlci->adaption == 3) {
+                       /* Over long frame, bin it */
+                       kfree_skb(dlci->skb);
+                       dlci->skb = NULL;
+                       return 0;
+               }
+               len = gsm->mtu;
+       } else
+               last = 1;
+
+       size = len + overhead;
+       msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+
+       /* FIXME: need a timer or something to kick this so it can't
+          get stuck with no work outstanding and no buffer free */
+       if (msg == NULL)
+               return -ENOMEM;
+       dp = msg->data;
+
+       if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */
+               /* Flag byte to carry the start/end info */
+               *dp++ = last << 7 | first << 6 | 1;     /* EA */
+               len--;
+       }
+       memcpy(dp, skb_pull(dlci->skb, len), len);
+       __gsm_data_queue(dlci, msg);
+       if (last)
+               dlci->skb = NULL;
+       return size;
+}
+
+/**
+ *     gsm_dlci_data_sweep             -       look for data to send
+ *     @gsm: the GSM mux
+ *
+ *     Sweep the GSM mux channels in priority order looking for ones with
+ *     data to send. We could do with optimising this scan a bit. We aim
+ *     to fill the queue totally or up to TX_THRESH_HI bytes. Once we hit
+ *     TX_THRESH_LO we get called again
+ *
+ *     FIXME: We should round robin between groups and in theory you can
+ *     renegotiate DLCI priorities with optional stuff. Needs optimising.
+ */
+
+static void gsm_dlci_data_sweep(struct gsm_mux *gsm)
+{
+       int len;
+       /* Priority ordering: We should do priority with RR of the groups */
+       int i = 1;
+
+       while (i < NUM_DLCI) {
+               struct gsm_dlci *dlci;
+
+               if (gsm->tx_bytes > TX_THRESH_HI)
+                       break;
+               dlci = gsm->dlci[i];
+               if (dlci == NULL || dlci->constipated) {
+                       i++;
+                       continue;
+               }
+               if (dlci->adaption < 3)
+                       len = gsm_dlci_data_output(gsm, dlci);
+               else
+                       len = gsm_dlci_data_output_framed(gsm, dlci);
+               if (len < 0)
+                       break;
+               /* DLCI empty - try the next */
+               if (len == 0)
+                       i++;
+       }
+}
+
+/**
+ *     gsm_dlci_data_kick      -       transmit if possible
+ *     @dlci: DLCI to kick
+ *
+ *     Transmit data from this DLCI if the queue is empty. We can't rely on
+ *     a tty wakeup except when we filled the pipe so we need to fire off
+ *     new data ourselves in other cases.
+ */
+
+static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+       /* If we have nothing running then we need to fire up */
+       if (dlci->gsm->tx_bytes == 0)
+               gsm_dlci_data_output(dlci->gsm, dlci);
+       else if (dlci->gsm->tx_bytes < TX_THRESH_LO)
+               gsm_dlci_data_sweep(dlci->gsm);
+       spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
+}
+
+/*
+ *     Control message processing
+ */
+
+
+/**
+ *     gsm_control_reply       -       send a response frame to a control
+ *     @gsm: gsm channel
+ *     @cmd: the command to use
+ *     @data: data to follow encoded info
+ *     @dlen: length of data
+ *
+ *     Encode up and queue a UI/UIH frame containing our response.
+ */
+
+static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data,
+                                       int dlen)
+{
+       struct gsm_msg *msg;
+       msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype);
+       msg->data[0] = (cmd & 0xFE) << 1 | EA;  /* Clear C/R */
+       msg->data[1] = (dlen << 1) | EA;
+       memcpy(msg->data + 2, data, dlen);
+       gsm_data_queue(gsm->dlci[0], msg);
+}
+
+/**
+ *     gsm_process_modem       -       process received modem status
+ *     @tty: virtual tty bound to the DLCI
+ *     @dlci: DLCI to affect
+ *     @modem: modem bits (full EA)
+ *
+ *     Used when a modem control message or line state inline in adaption
+ *     layer 2 is processed. Sort out the local modem state and throttles
+ */
+
+static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
+                                                       u32 modem)
+{
+       int  mlines = 0;
+       u8 brk = modem >> 6;
+
+       /* Flow control/ready to communicate */
+       if (modem & MDM_FC) {
+               /* Need to throttle our output on this device */
+               dlci->constipated = 1;
+       }
+       if (modem & MDM_RTC) {
+               mlines |= TIOCM_DSR | TIOCM_DTR;
+               dlci->constipated = 0;
+               gsm_dlci_data_kick(dlci);
+       }
+       /* Map modem bits */
+       if (modem & MDM_RTR)
+               mlines |= TIOCM_RTS | TIOCM_CTS;
+       if (modem & MDM_IC)
+               mlines |= TIOCM_RI;
+       if (modem & MDM_DV)
+               mlines |= TIOCM_CD;
+
+       /* Carrier drop -> hangup */
+       if (tty) {
+               if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD))
+                       if (!(tty->termios->c_cflag & CLOCAL))
+                               tty_hangup(tty);
+               if (brk & 0x01)
+                       tty_insert_flip_char(tty, 0, TTY_BREAK);
+       }
+       dlci->modem_rx = mlines;
+}
+
+/**
+ *     gsm_control_modem       -       modem status received
+ *     @gsm: GSM channel
+ *     @data: data following command
+ *     @clen: command length
+ *
+ *     We have received a modem status control message. This is used by
+ *     the GSM mux protocol to pass virtual modem line status and optionally
+ *     to indicate break signals. Unpack it, convert to Linux representation
+ *     and if need be stuff a break message down the tty.
+ */
+
+static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
+{
+       unsigned int addr = 0;
+       unsigned int modem = 0;
+       struct gsm_dlci *dlci;
+       int len = clen;
+       u8 *dp = data;
+       struct tty_struct *tty;
+
+       while (gsm_read_ea(&addr, *dp++) == 0) {
+               len--;
+               if (len == 0)
+                       return;
+       }
+       /* Must be at least one byte following the EA */
+       len--;
+       if (len <= 0)
+               return;
+
+       addr >>= 1;
+       /* Closed port, or invalid ? */
+       if (addr == 0 || addr >= NUM_DLCI || gsm->dlci[addr] == NULL)
+               return;
+       dlci = gsm->dlci[addr];
+
+       while (gsm_read_ea(&modem, *dp++) == 0) {
+               len--;
+               if (len == 0)
+                       return;
+       }
+       tty = tty_port_tty_get(&dlci->port);
+       gsm_process_modem(tty, dlci, modem);
+       if (tty) {
+               tty_wakeup(tty);
+               tty_kref_put(tty);
+       }
+       gsm_control_reply(gsm, CMD_MSC, data, clen);
+}
+
+/**
+ *     gsm_control_rls         -       remote line status
+ *     @gsm: GSM channel
+ *     @data: data bytes
+ *     @clen: data length
+ *
+ *     The modem sends us a two byte message on the control channel whenever
+ *     it wishes to send us an error state from the virtual link. Stuff
+ *     this into the uplink tty if present
+ */
+
+static void gsm_control_rls(struct gsm_mux *gsm, u8 *data, int clen)
+{
+       struct tty_struct *tty;
+       unsigned int addr = 0 ;
+       u8 bits;
+       int len = clen;
+       u8 *dp = data;
+
+       while (gsm_read_ea(&addr, *dp++) == 0) {
+               len--;
+               if (len == 0)
+                       return;
+       }
+       /* Must be at least one byte following ea */
+       len--;
+       if (len <= 0)
+               return;
+       addr >>= 1;
+       /* Closed port, or invalid ? */
+       if (addr == 0 || addr >= NUM_DLCI || gsm->dlci[addr] == NULL)
+               return;
+       /* No error ? */
+       bits = *dp;
+       if ((bits & 1) == 0)
+               return;
+       /* See if we have an uplink tty */
+       tty = tty_port_tty_get(&gsm->dlci[addr]->port);
+
+       if (tty) {
+               if (bits & 2)
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+               if (bits & 4)
+                       tty_insert_flip_char(tty, 0, TTY_PARITY);
+               if (bits & 8)
+                       tty_insert_flip_char(tty, 0, TTY_FRAME);
+               tty_flip_buffer_push(tty);
+               tty_kref_put(tty);
+       }
+       gsm_control_reply(gsm, CMD_RLS, data, clen);
+}
+
+static void gsm_dlci_begin_close(struct gsm_dlci *dlci);
+
+/**
+ *     gsm_control_message     -       DLCI 0 control processing
+ *     @gsm: our GSM mux
+ *     @command:  the command EA
+ *     @data: data beyond the command/length EAs
+ *     @clen: length
+ *
+ *     Input processor for control messages from the other end of the link.
+ *     Processes the incoming request and queues a response frame or an
+ *     NSC response if not supported
+ */
+
+static void gsm_control_message(struct gsm_mux *gsm, unsigned int command,
+                                                       u8 *data, int clen)
+{
+       u8 buf[1];
+       switch (command) {
+       case CMD_CLD: {
+               struct gsm_dlci *dlci = gsm->dlci[0];
+               /* Modem wishes to close down */
+               if (dlci) {
+                       dlci->dead = 1;
+                       gsm->dead = 1;
+                       gsm_dlci_begin_close(dlci);
+               }
+               }
+               break;
+       case CMD_TEST:
+               /* Modem wishes to test, reply with the data */
+               gsm_control_reply(gsm, CMD_TEST, data, clen);
+               break;
+       case CMD_FCON:
+               /* Modem wants us to STFU */
+               gsm->constipated = 1;
+               gsm_control_reply(gsm, CMD_FCON, NULL, 0);
+               break;
+       case CMD_FCOFF:
+               /* Modem can accept data again */
+               gsm->constipated = 0;
+               gsm_control_reply(gsm, CMD_FCOFF, NULL, 0);
+               /* Kick the link in case it is idling */
+               gsm_data_kick(gsm);
+               break;
+       case CMD_MSC:
+               /* Out of band modem line change indicator for a DLCI */
+               gsm_control_modem(gsm, data, clen);
+               break;
+       case CMD_RLS:
+               /* Out of band error reception for a DLCI */
+               gsm_control_rls(gsm, data, clen);
+               break;
+       case CMD_PSC:
+               /* Modem wishes to enter power saving state */
+               gsm_control_reply(gsm, CMD_PSC, NULL, 0);
+               break;
+               /* Optional unsupported commands */
+       case CMD_PN:    /* Parameter negotiation */
+       case CMD_RPN:   /* Remote port negotation */
+       case CMD_SNC:   /* Service negotation command */
+       default:
+               /* Reply to bad commands with an NSC */
+               buf[0] = command;
+               gsm_control_reply(gsm, CMD_NSC, buf, 1);
+               break;
+       }
+}
+
+/**
+ *     gsm_control_response    -       process a response to our control
+ *     @gsm: our GSM mux
+ *     @command: the command (response) EA
+ *     @data: data beyond the command/length EA
+ *     @clen: length
+ *
+ *     Process a response to an outstanding command. We only allow a single
+ *     control message in flight so this is fairly easy. All the clean up
+ *     is done by the caller, we just update the fields, flag it as done
+ *     and return
+ */
+
+static void gsm_control_response(struct gsm_mux *gsm, unsigned int command,
+                                                       u8 *data, int clen)
+{
+       struct gsm_control *ctrl;
+       unsigned long flags;
+
+       spin_lock_irqsave(&gsm->control_lock, flags);
+
+       ctrl = gsm->pending_cmd;
+       /* Does the reply match our command */
+       command |= 1;
+       if (ctrl != NULL && (command == ctrl->cmd || command == CMD_NSC)) {
+               /* Our command was replied to, kill the retry timer */
+               del_timer(&gsm->t2_timer);
+               gsm->pending_cmd = NULL;
+               /* Rejected by the other end */
+               if (command == CMD_NSC)
+                       ctrl->error = -EOPNOTSUPP;
+               ctrl->done = 1;
+               wake_up(&gsm->event);
+       }
+       spin_unlock_irqrestore(&gsm->control_lock, flags);
+}
+
+/**
+ *     gsm_control_transmit    -       send control packet
+ *     @gsm: gsm mux
+ *     @ctrl: frame to send
+ *
+ *     Send out a pending control command (called under control lock)
+ */
+
+static void gsm_control_transmit(struct gsm_mux *gsm, struct gsm_control *ctrl)
+{
+       struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 1,
+                                                       gsm->ftype|PF);
+       if (msg == NULL)
+               return;
+       msg->data[0] = (ctrl->cmd << 1) | 2 | EA;       /* command */
+       memcpy(msg->data + 1, ctrl->data, ctrl->len);
+       gsm_data_queue(gsm->dlci[0], msg);
+}
+
+/**
+ *     gsm_control_retransmit  -       retransmit a control frame
+ *     @data: pointer to our gsm object
+ *
+ *     Called off the T2 timer expiry in order to retransmit control frames
+ *     that have been lost in the system somewhere. The control_lock protects
+ *     us from colliding with another sender or a receive completion event.
+ *     In that situation the timer may still occur in a small window but
+ *     gsm->pending_cmd will be NULL and we just let the timer expire.
+ */
+
+static void gsm_control_retransmit(unsigned long data)
+{
+       struct gsm_mux *gsm = (struct gsm_mux *)data;
+       struct gsm_control *ctrl;
+       unsigned long flags;
+       spin_lock_irqsave(&gsm->control_lock, flags);
+       ctrl = gsm->pending_cmd;
+       if (ctrl) {
+               gsm->cretries--;
+               if (gsm->cretries == 0) {
+                       gsm->pending_cmd = NULL;
+                       ctrl->error = -ETIMEDOUT;
+                       ctrl->done = 1;
+                       spin_unlock_irqrestore(&gsm->control_lock, flags);
+                       wake_up(&gsm->event);
+                       return;
+               }
+               gsm_control_transmit(gsm, ctrl);
+               mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
+       }
+       spin_unlock_irqrestore(&gsm->control_lock, flags);
+}
+
+/**
+ *     gsm_control_send        -       send a control frame on DLCI 0
+ *     @gsm: the GSM channel
+ *     @command: command  to send including CR bit
+ *     @data: bytes of data (must be kmalloced)
+ *     @len: length of the block to send
+ *
+ *     Queue and dispatch a control command. Only one command can be
+ *     active at a time. In theory more can be outstanding but the matching
+ *     gets really complicated so for now stick to one outstanding.
+ */
+
+static struct gsm_control *gsm_control_send(struct gsm_mux *gsm,
+               unsigned int command, u8 *data, int clen)
+{
+       struct gsm_control *ctrl = kzalloc(sizeof(struct gsm_control),
+                                               GFP_KERNEL);
+       unsigned long flags;
+       if (ctrl == NULL)
+               return NULL;
+retry:
+       wait_event(gsm->event, gsm->pending_cmd == NULL);
+       spin_lock_irqsave(&gsm->control_lock, flags);
+       if (gsm->pending_cmd != NULL) {
+               spin_unlock_irqrestore(&gsm->control_lock, flags);
+               goto retry;
+       }
+       ctrl->cmd = command;
+       ctrl->data = data;
+       ctrl->len = clen;
+       gsm->pending_cmd = ctrl;
+       gsm->cretries = gsm->n2;
+       mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
+       gsm_control_transmit(gsm, ctrl);
+       spin_unlock_irqrestore(&gsm->control_lock, flags);
+       return ctrl;
+}
+
+/**
+ *     gsm_control_wait        -       wait for a control to finish
+ *     @gsm: GSM mux
+ *     @control: control we are waiting on
+ *
+ *     Waits for the control to complete or time out. Frees any used
+ *     resources and returns 0 for success, or an error if the remote
+ *     rejected or ignored the request.
+ */
+
+static int gsm_control_wait(struct gsm_mux *gsm, struct gsm_control *control)
+{
+       int err;
+       wait_event(gsm->event, control->done == 1);
+       err = control->error;
+       kfree(control);
+       return err;
+}
+
+
+/*
+ *     DLCI level handling: Needs krefs
+ */
+
+/*
+ *     State transitions and timers
+ */
+
+/**
+ *     gsm_dlci_close          -       a DLCI has closed
+ *     @dlci: DLCI that closed
+ *
+ *     Perform processing when moving a DLCI into closed state. If there
+ *     is an attached tty this is hung up
+ */
+
+static void gsm_dlci_close(struct gsm_dlci *dlci)
+{
+       del_timer(&dlci->t1);
+       if (debug & 8)
+               printk("DLCI %d goes closed.\n", dlci->addr);
+       dlci->state = DLCI_CLOSED;
+       if (dlci->addr != 0) {
+               struct tty_struct  *tty = tty_port_tty_get(&dlci->port);
+               if (tty) {
+                       tty_hangup(tty);
+                       tty_kref_put(tty);
+               }
+               kfifo_reset(dlci->fifo);
+       } else
+               dlci->gsm->dead = 1;
+       wake_up(&dlci->gsm->event);
+       /* A DLCI 0 close is a MUX termination so we need to kick that
+          back to userspace somehow */
+}
+
+/**
+ *     gsm_dlci_open           -       a DLCI has opened
+ *     @dlci: DLCI that opened
+ *
+ *     Perform processing when moving a DLCI into open state.
+ */
+
+static void gsm_dlci_open(struct gsm_dlci *dlci)
+{
+       /* Note that SABM UA .. SABM UA first UA lost can mean that we go
+          open -> open */
+       del_timer(&dlci->t1);
+       /* This will let a tty open continue */
+       dlci->state = DLCI_OPEN;
+       if (debug & 8)
+               printk("DLCI %d goes open.\n", dlci->addr);
+       wake_up(&dlci->gsm->event);
+}
+
+/**
+ *     gsm_dlci_t1             -       T1 timer expiry
+ *     @dlci: DLCI that opened
+ *
+ *     The T1 timer handles retransmits of control frames (essentially of
+ *     SABM and DISC). We resend the command until the retry count runs out
+ *     in which case an opening port goes back to closed and a closing port
+ *     is simply put into closed state (any further frames from the other
+ *     end will get a DM response)
+ */
+
+static void gsm_dlci_t1(unsigned long data)
+{
+       struct gsm_dlci *dlci = (struct gsm_dlci *)data;
+       struct gsm_mux *gsm = dlci->gsm;
+
+       switch (dlci->state) {
+       case DLCI_OPENING:
+               dlci->retries--;
+               if (dlci->retries) {
+                       gsm_command(dlci->gsm, dlci->addr, SABM|PF);
+                       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+               } else
+                       gsm_dlci_close(dlci);
+               break;
+       case DLCI_CLOSING:
+               dlci->retries--;
+               if (dlci->retries) {
+                       gsm_command(dlci->gsm, dlci->addr, DISC|PF);
+                       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+               } else
+                       gsm_dlci_close(dlci);
+               break;
+       }
+}
+
+/**
+ *     gsm_dlci_begin_open     -       start channel open procedure
+ *     @dlci: DLCI to open
+ *
+ *     Commence opening a DLCI from the Linux side. We issue SABM messages
+ *     to the modem which should then reply with a UA, at which point we
+ *     will move into open state. Opening is done asynchronously with retry
+ *     running off timers and the responses.
+ */
+
+static void gsm_dlci_begin_open(struct gsm_dlci *dlci)
+{
+       struct gsm_mux *gsm = dlci->gsm;
+       if (dlci->state == DLCI_OPEN || dlci->state == DLCI_OPENING)
+               return;
+       dlci->retries = gsm->n2;
+       dlci->state = DLCI_OPENING;
+       gsm_command(dlci->gsm, dlci->addr, SABM|PF);
+       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+}
+
+/**
+ *     gsm_dlci_begin_close    -       start channel open procedure
+ *     @dlci: DLCI to open
+ *
+ *     Commence closing a DLCI from the Linux side. We issue DISC messages
+ *     to the modem which should then reply with a UA, at which point we
+ *     will move into closed state. Closing is done asynchronously with retry
+ *     off timers. We may also receive a DM reply from the other end which
+ *     indicates the channel was already closed.
+ */
+
+static void gsm_dlci_begin_close(struct gsm_dlci *dlci)
+{
+       struct gsm_mux *gsm = dlci->gsm;
+       if (dlci->state == DLCI_CLOSED || dlci->state == DLCI_CLOSING)
+               return;
+       dlci->retries = gsm->n2;
+       dlci->state = DLCI_CLOSING;
+       gsm_command(dlci->gsm, dlci->addr, DISC|PF);
+       mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+}
+
+/**
+ *     gsm_dlci_data           -       data arrived
+ *     @dlci: channel
+ *     @data: block of bytes received
+ *     @len: length of received block
+ *
+ *     A UI or UIH frame has arrived which contains data for a channel
+ *     other than the control channel. If the relevant virtual tty is
+ *     open we shovel the bits down it, if not we drop them.
+ */
+
+static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len)
+{
+       /* krefs .. */
+       struct tty_port *port = &dlci->port;
+       struct tty_struct *tty = tty_port_tty_get(port);
+       unsigned int modem = 0;
+
+       if (debug & 16)
+               printk("%d bytes for tty %p\n", len, tty);
+       if (tty) {
+               switch (dlci->adaption)  {
+                       /* Unsupported types */
+                       /* Packetised interruptible data */
+                       case 4:
+                               break;
+                       /* Packetised uininterruptible voice/data */
+                       case 3:
+                               break;
+                       /* Asynchronous serial with line state in each frame */
+                       case 2:
+                               while (gsm_read_ea(&modem, *data++) == 0) {
+                                       len--;
+                                       if (len == 0)
+                                               return;
+                               }
+                               gsm_process_modem(tty, dlci, modem);
+                       /* Line state will go via DLCI 0 controls only */
+                       case 1:
+                       default:
+                               tty_insert_flip_string(tty, data, len);
+                               tty_flip_buffer_push(tty);
+               }
+               tty_kref_put(tty);
+       }
+}
+
+/**
+ *     gsm_dlci_control        -       data arrived on control channel
+ *     @dlci: channel
+ *     @data: block of bytes received
+ *     @len: length of received block
+ *
+ *     A UI or UIH frame has arrived which contains data for DLCI 0 the
+ *     control channel. This should contain a command EA followed by
+ *     control data bytes. The command EA contains a command/response bit
+ *     and we divide up the work accordingly.
+ */
+
+static void gsm_dlci_command(struct gsm_dlci *dlci, u8 *data, int len)
+{
+       /* See what command is involved */
+       unsigned int command = 0;
+       while (len-- > 0) {
+               if (gsm_read_ea(&command, *data++) == 1) {
+                       int clen = *data++;
+                       len--;
+                       /* FIXME: this is properly an EA */
+                       clen >>= 1;
+                       /* Malformed command ? */
+                       if (clen > len)
+                               return;
+                       if (command & 1)
+                               gsm_control_message(dlci->gsm, command,
+                                                               data, clen);
+                       else
+                               gsm_control_response(dlci->gsm, command,
+                                                               data, clen);
+                       return;
+               }
+       }
+}
+
+/*
+ *     Allocate/Free DLCI channels
+ */
+
+/**
+ *     gsm_dlci_alloc          -       allocate a DLCI
+ *     @gsm: GSM mux
+ *     @addr: address of the DLCI
+ *
+ *     Allocate and install a new DLCI object into the GSM mux.
+ *
+ *     FIXME: review locking races
+ */
+
+static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
+{
+       struct gsm_dlci *dlci = kzalloc(sizeof(struct gsm_dlci), GFP_ATOMIC);
+       if (dlci == NULL)
+               return NULL;
+       spin_lock_init(&dlci->lock);
+       dlci->fifo = &dlci->_fifo;
+       if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) {
+               kfree(dlci);
+               return NULL;
+       }
+
+       skb_queue_head_init(&dlci->skb_list);
+       init_timer(&dlci->t1);
+       dlci->t1.function = gsm_dlci_t1;
+       dlci->t1.data = (unsigned long)dlci;
+       tty_port_init(&dlci->port);
+       dlci->port.ops = &gsm_port_ops;
+       dlci->gsm = gsm;
+       dlci->addr = addr;
+       dlci->adaption = gsm->adaption;
+       dlci->state = DLCI_CLOSED;
+       if (addr)
+               dlci->data = gsm_dlci_data;
+       else
+               dlci->data = gsm_dlci_command;
+       gsm->dlci[addr] = dlci;
+       return dlci;
+}
+
+/**
+ *     gsm_dlci_free           -       release DLCI
+ *     @dlci: DLCI to destroy
+ *
+ *     Free up a DLCI. Currently to keep the lifetime rules sane we only
+ *     clean up DLCI objects when the MUX closes rather than as the port
+ *     is closed down on both the tty and mux levels.
+ *
+ *     Can sleep.
+ */
+static void gsm_dlci_free(struct gsm_dlci *dlci)
+{
+       struct tty_struct *tty = tty_port_tty_get(&dlci->port);
+       if (tty) {
+               tty_vhangup(tty);
+               tty_kref_put(tty);
+       }
+       del_timer_sync(&dlci->t1);
+       dlci->gsm->dlci[dlci->addr] = NULL;
+       kfifo_free(dlci->fifo);
+       kfree(dlci);
+}
+
+
+/*
+ *     LAPBish link layer logic
+ */
+
+/**
+ *     gsm_queue               -       a GSM frame is ready to process
+ *     @gsm: pointer to our gsm mux
+ *
+ *     At this point in time a frame has arrived and been demangled from
+ *     the line encoding. All the differences between the encodings have
+ *     been handled below us and the frame is unpacked into the structures.
+ *     The fcs holds the header FCS but any data FCS must be added here.
+ */
+
+static void gsm_queue(struct gsm_mux *gsm)
+{
+       struct gsm_dlci *dlci;
+       u8 cr;
+       int address;
+       /* We have to sneak a look at the packet body to do the FCS.
+          A somewhat layering violation in the spec */
+
+       if ((gsm->control & ~PF) == UI)
+               gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len);
+       if (gsm->fcs != GOOD_FCS) {
+               gsm->bad_fcs++;
+               if (debug & 4)
+                       printk("BAD FCS %02x\n", gsm->fcs);
+               return;
+       }
+       address = gsm->address >> 1;
+       if (address >= NUM_DLCI)
+               goto invalid;
+
+       cr = gsm->address & 1;          /* C/R bit */
+
+       gsm_print_packet("<--", address, cr, gsm->control, gsm->buf, gsm->len);
+
+       cr ^= 1 - gsm->initiator;       /* Flip so 1 always means command */
+       dlci = gsm->dlci[address];
+
+       switch (gsm->control) {
+       case SABM|PF:
+               if (cr == 0)
+                       goto invalid;
+               if (dlci == NULL)
+                       dlci = gsm_dlci_alloc(gsm, address);
+               if (dlci == NULL)
+                       return;
+               if (dlci->dead)
+                       gsm_response(gsm, address, DM);
+               else {
+                       gsm_response(gsm, address, UA);
+                       gsm_dlci_open(dlci);
+               }
+               break;
+       case DISC|PF:
+               if (cr == 0)
+                       goto invalid;
+               if (dlci == NULL || dlci->state == DLCI_CLOSED) {
+                       gsm_response(gsm, address, DM);
+                       return;
+               }
+               /* Real close complete */
+               gsm_response(gsm, address, UA);
+               gsm_dlci_close(dlci);
+               break;
+       case UA:
+       case UA|PF:
+               if (cr == 0 || dlci == NULL)
+                       break;
+               switch (dlci->state) {
+               case DLCI_CLOSING:
+                       gsm_dlci_close(dlci);
+                       break;
+               case DLCI_OPENING:
+                       gsm_dlci_open(dlci);
+                       break;
+               }
+               break;
+       case DM:        /* DM can be valid unsolicited */
+       case DM|PF:
+               if (cr)
+                       goto invalid;
+               if (dlci == NULL)
+                       return;
+               gsm_dlci_close(dlci);
+               break;
+       case UI:
+       case UI|PF:
+       case UIH:
+       case UIH|PF:
+#if 0
+               if (cr)
+                       goto invalid;
+#endif
+               if (dlci == NULL || dlci->state != DLCI_OPEN) {
+                       gsm_command(gsm, address, DM|PF);
+                       return;
+               }
+               dlci->data(dlci, gsm->buf, gsm->len);
+               break;
+       default:
+               goto invalid;
+       }
+       return;
+invalid:
+       gsm->malformed++;
+       return;
+}
+
+
+/**
+ *     gsm0_receive    -       perform processing for non-transparency
+ *     @gsm: gsm data for this ldisc instance
+ *     @c: character
+ *
+ *     Receive bytes in gsm mode 0
+ */
+
+static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
+{
+       switch (gsm->state) {
+       case GSM_SEARCH:        /* SOF marker */
+               if (c == GSM0_SOF) {
+                       gsm->state = GSM_ADDRESS;
+                       gsm->address = 0;
+                       gsm->len = 0;
+                       gsm->fcs = INIT_FCS;
+               }
+               break;          /* Address EA */
+       case GSM_ADDRESS:
+               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
+               if (gsm_read_ea(&gsm->address, c))
+                       gsm->state = GSM_CONTROL;
+               break;
+       case GSM_CONTROL:       /* Control Byte */
+               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
+               gsm->control = c;
+               gsm->state = GSM_LEN;
+               break;
+       case GSM_LEN:           /* Length EA */
+               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
+               if (gsm_read_ea(&gsm->len, c)) {
+                       if (gsm->len > gsm->mru) {
+                               gsm->bad_size++;
+                               gsm->state = GSM_SEARCH;
+                               break;
+                       }
+                       gsm->count = 0;
+                       gsm->state = GSM_DATA;
+               }
+               break;
+       case GSM_DATA:          /* Data */
+               gsm->buf[gsm->count++] = c;
+               if (gsm->count == gsm->len)
+                       gsm->state = GSM_FCS;
+               break;
+       case GSM_FCS:           /* FCS follows the packet */
+               gsm->fcs = c;
+               gsm_queue(gsm);
+               /* And then back for the next frame */
+               gsm->state = GSM_SEARCH;
+               break;
+       }
+}
+
+/**
+ *     gsm0_receive    -       perform processing for non-transparency
+ *     @gsm: gsm data for this ldisc instance
+ *     @c: character
+ *
+ *     Receive bytes in mode 1 (Advanced option)
+ */
+
+static void gsm1_receive(struct gsm_mux *gsm, unsigned char c)
+{
+       if (c == GSM1_SOF) {
+               /* EOF is only valid in frame if we have got to the data state
+                  and received at least one byte (the FCS) */
+               if (gsm->state == GSM_DATA && gsm->count) {
+                       /* Extract the FCS */
+                       gsm->count--;
+                       gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->buf[gsm->count]);
+                       gsm->len = gsm->count;
+                       gsm_queue(gsm);
+                       gsm->state  = GSM_START;
+                       return;
+               }
+               /* Any partial frame was a runt so go back to start */
+               if (gsm->state != GSM_START) {
+                       gsm->malformed++;
+                       gsm->state = GSM_START;
+               }
+               /* A SOF in GSM_START means we are still reading idling or
+                  framing bytes */
+               return;
+       }
+
+       if (c == GSM1_ESCAPE) {
+               gsm->escape = 1;
+               return;
+       }
+
+       /* Only an unescaped SOF gets us out of GSM search */
+       if (gsm->state == GSM_SEARCH)
+               return;
+
+       if (gsm->escape) {
+               c ^= GSM1_ESCAPE_BITS;
+               gsm->escape = 0;
+       }
+       switch (gsm->state) {
+       case GSM_START:         /* First byte after SOF */
+               gsm->address = 0;
+               gsm->state = GSM_ADDRESS;
+               gsm->fcs = INIT_FCS;
+               /* Drop through */
+       case GSM_ADDRESS:       /* Address continuation */
+               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
+               if (gsm_read_ea(&gsm->address, c))
+                       gsm->state = GSM_CONTROL;
+               break;
+       case GSM_CONTROL:       /* Control Byte */
+               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
+               gsm->control = c;
+               gsm->count = 0;
+               gsm->state = GSM_DATA;
+               break;
+       case GSM_DATA:          /* Data */
+               if (gsm->count > gsm->mru ) {   /* Allow one for the FCS */
+                       gsm->state = GSM_OVERRUN;
+                       gsm->bad_size++;
+               } else
+                       gsm->buf[gsm->count++] = c;
+               break;
+       case GSM_OVERRUN:       /* Over-long - eg a dropped SOF */
+               break;
+       }
+}
+
+/**
+ *     gsm_error               -       handle tty error
+ *     @gsm: ldisc data
+ *     @data: byte received (may be invalid)
+ *     @flag: error received
+ *
+ *     Handle an error in the receipt of data for a frame. Currently we just
+ *     go back to hunting for a SOF.
+ *
+ *     FIXME: better diagnostics ?
+ */
+
+static void gsm_error(struct gsm_mux *gsm,
+                               unsigned char data, unsigned char flag)
+{
+       gsm->state = GSM_SEARCH;
+       gsm->io_error++;
+}
+
+/**
+ *     gsm_cleanup_mux         -       generic GSM protocol cleanup
+ *     @gsm: our mux
+ *
+ *     Clean up the bits of the mux which are the same for all framing
+ *     protocols. Remove the mux from the mux table, stop all the timers
+ *     and then shut down each device hanging up the channels as we go.
+ */
+
+void gsm_cleanup_mux(struct gsm_mux *gsm)
+{
+       int i;
+       struct gsm_dlci *dlci = gsm->dlci[0];
+       struct gsm_msg *txq;
+
+       gsm->dead = 1;
+
+       spin_lock(&gsm_mux_lock);
+       for (i = 0; i < MAX_MUX; i++) {
+               if (gsm_mux[i] == gsm) {
+                       gsm_mux[i] = NULL;
+                       break;
+               }
+       }
+       spin_unlock(&gsm_mux_lock);
+       WARN_ON(i == MAX_MUX);
+
+       del_timer_sync(&gsm->t2_timer);
+       /* Now we are sure T2 has stopped */
+       if (dlci) {
+               dlci->dead = 1;
+               gsm_dlci_begin_close(dlci);
+               wait_event_interruptible(gsm->event,
+                                       dlci->state == DLCI_CLOSED);
+       }
+       /* Free up any link layer users */
+       for (i = 0; i < NUM_DLCI; i++)
+               if (gsm->dlci[i])
+                       gsm_dlci_free(gsm->dlci[i]);
+       /* Now wipe the queues */
+       for (txq = gsm->tx_head; txq != NULL; txq = gsm->tx_head) {
+               gsm->tx_head = txq->next;
+               kfree(txq);
+       }
+       gsm->tx_tail = NULL;
+}
+EXPORT_SYMBOL_GPL(gsm_cleanup_mux);
+
+/**
+ *     gsm_activate_mux        -       generic GSM setup
+ *     @gsm: our mux
+ *
+ *     Set up the bits of the mux which are the same for all framing
+ *     protocols. Add the mux to the mux table so it can be opened and
+ *     finally kick off connecting to DLCI 0 on the modem.
+ */
+
+int gsm_activate_mux(struct gsm_mux *gsm)
+{
+       struct gsm_dlci *dlci;
+       int i = 0;
+
+       init_timer(&gsm->t2_timer);
+       gsm->t2_timer.function = gsm_control_retransmit;
+       gsm->t2_timer.data = (unsigned long)gsm;
+       init_waitqueue_head(&gsm->event);
+       spin_lock_init(&gsm->control_lock);
+       spin_lock_init(&gsm->tx_lock);
+
+       if (gsm->encoding == 0)
+               gsm->receive = gsm0_receive;
+       else
+               gsm->receive = gsm1_receive;
+       gsm->error = gsm_error;
+
+       spin_lock(&gsm_mux_lock);
+       for (i = 0; i < MAX_MUX; i++) {
+               if (gsm_mux[i] == NULL) {
+                       gsm_mux[i] = gsm;
+                       break;
+               }
+       }
+       spin_unlock(&gsm_mux_lock);
+       if (i == MAX_MUX)
+               return -EBUSY;
+
+       dlci = gsm_dlci_alloc(gsm, 0);
+       if (dlci == NULL)
+               return -ENOMEM;
+       gsm->dead = 0;          /* Tty opens are now permissible */
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gsm_activate_mux);
+
+/**
+ *     gsm_free_mux            -       free up a mux
+ *     @mux: mux to free
+ *
+ *     Dispose of allocated resources for a dead mux. No refcounting
+ *     at present so the mux must be truely dead.
+ */
+void gsm_free_mux(struct gsm_mux *gsm)
+{
+       kfree(gsm->txframe);
+       kfree(gsm->buf);
+       kfree(gsm);
+}
+EXPORT_SYMBOL_GPL(gsm_free_mux);
+
+/**
+ *     gsm_alloc_mux           -       allocate a mux
+ *
+ *     Creates a new mux ready for activation.
+ */
+
+struct gsm_mux *gsm_alloc_mux(void)
+{
+       struct gsm_mux *gsm = kzalloc(sizeof(struct gsm_mux), GFP_KERNEL);
+       if (gsm == NULL)
+               return NULL;
+       gsm->buf = kmalloc(MAX_MRU + 1, GFP_KERNEL);
+       if (gsm->buf == NULL) {
+               kfree(gsm);
+               return NULL;
+       }
+       gsm->txframe = kmalloc(2 * MAX_MRU + 2, GFP_KERNEL);
+       if (gsm->txframe == NULL) {
+               kfree(gsm->buf);
+               kfree(gsm);
+               return NULL;
+       }
+       spin_lock_init(&gsm->lock);
+
+       gsm->t1 = T1;
+       gsm->t2 = T2;
+       gsm->n2 = N2;
+       gsm->ftype = UIH;
+       gsm->initiator = 0;
+       gsm->adaption = 1;
+       gsm->encoding = 1;
+       gsm->mru = 64;  /* Default to encoding 1 so these should be 64 */
+       gsm->mtu = 64;
+       gsm->dead = 1;  /* Avoid early tty opens */
+
+       return gsm;
+}
+EXPORT_SYMBOL_GPL(gsm_alloc_mux);
+
+
+
+
+/**
+ *     gsmld_output            -       write to link
+ *     @gsm: our mux
+ *     @data: bytes to output
+ *     @len: size
+ *
+ *     Write a block of data from the GSM mux to the data channel. This
+ *     will eventually be serialized from above but at the moment isn't.
+ */
+
+static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len)
+{
+       if (tty_write_room(gsm->tty) < len) {
+               set_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
+               return -ENOSPC;
+       }
+       if (debug & 4) {
+               printk("-->%d bytes out\n", len);
+               hex_packet(data, len);
+       }
+       gsm->tty->ops->write(gsm->tty, data, len);
+       return len;
+}
+
+/**
+ *     gsmld_attach_gsm        -       mode set up
+ *     @tty: our tty structure
+ *     @gsm: our mux
+ *
+ *     Set up the MUX for basic mode and commence connecting to the
+ *     modem. Currently called from the line discipline set up but
+ *     will need moving to an ioctl path.
+ */
+
+static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+{
+       int ret;
+
+       gsm->tty = tty_kref_get(tty);
+       gsm->output = gsmld_output;
+       ret =  gsm_activate_mux(gsm);
+       if (ret != 0)
+               tty_kref_put(gsm->tty);
+       return ret;
+}
+
+
+/**
+ *     gsmld_detach_gsm        -       stop doing 0710 mux
+ *     @tty: tty atttached to the mux
+ *     @gsm: mux
+ *
+ *     Shutdown and then clean up the resources used by the line discipline
+ */
+
+static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+{
+       WARN_ON(tty != gsm->tty);
+       gsm_cleanup_mux(gsm);
+       tty_kref_put(gsm->tty);
+       gsm->tty = NULL;
+}
+
+static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+                             char *fp, int count)
+{
+       struct gsm_mux *gsm = tty->disc_data;
+       const unsigned char *dp;
+       char *f;
+       int i;
+       char buf[64];
+       char flags;
+
+       if (debug & 4) {
+               printk("Inbytes %dd\n", count);
+               hex_packet(cp, count);
+       }
+
+       for (i = count, dp = cp, f = fp; i; i--, dp++) {
+               flags = *f++;
+               switch (flags) {
+               case TTY_NORMAL:
+                       gsm->receive(gsm, *dp);
+                       break;
+               case TTY_OVERRUN:
+               case TTY_BREAK:
+               case TTY_PARITY:
+               case TTY_FRAME:
+                       gsm->error(gsm, *dp, flags);
+                       break;
+               default:
+                       printk(KERN_ERR "%s: unknown flag %d\n",
+                              tty_name(tty, buf), flags);
+                       break;
+               }
+       }
+       /* FASYNC if needed ? */
+       /* If clogged call tty_throttle(tty); */
+}
+
+/**
+ *     gsmld_chars_in_buffer   -       report available bytes
+ *     @tty: tty device
+ *
+ *     Report the number of characters buffered to be delivered to user
+ *     at this instant in time.
+ *
+ *     Locking: gsm lock
+ */
+
+static ssize_t gsmld_chars_in_buffer(struct tty_struct *tty)
+{
+       return 0;
+}
+
+/**
+ *     gsmld_flush_buffer      -       clean input queue
+ *     @tty:   terminal device
+ *
+ *     Flush the input buffer. Called when the line discipline is
+ *     being closed, when the tty layer wants the buffer flushed (eg
+ *     at hangup).
+ */
+
+static void gsmld_flush_buffer(struct tty_struct *tty)
+{
+}
+
+/**
+ *     gsmld_close             -       close the ldisc for this tty
+ *     @tty: device
+ *
+ *     Called from the terminal layer when this line discipline is
+ *     being shut down, either because of a close or becsuse of a
+ *     discipline change. The function will not be called while other
+ *     ldisc methods are in progress.
+ */
+
+static void gsmld_close(struct tty_struct *tty)
+{
+       struct gsm_mux *gsm = tty->disc_data;
+
+       gsmld_detach_gsm(tty, gsm);
+
+       gsmld_flush_buffer(tty);
+       /* Do other clean up here */
+       gsm_free_mux(gsm);
+}
+
+/**
+ *     gsmld_open              -       open an ldisc
+ *     @tty: terminal to open
+ *
+ *     Called when this line discipline is being attached to the
+ *     terminal device. Can sleep. Called serialized so that no
+ *     other events will occur in parallel. No further open will occur
+ *     until a close.
+ */
+
+static int gsmld_open(struct tty_struct *tty)
+{
+       struct gsm_mux *gsm;
+
+       if (tty->ops->write == NULL)
+               return -EINVAL;
+
+       /* Attach our ldisc data */
+       gsm = gsm_alloc_mux();
+       if (gsm == NULL)
+               return -ENOMEM;
+
+       tty->disc_data = gsm;
+       tty->receive_room = 65536;
+
+       /* Attach the initial passive connection */
+       gsm->encoding = 1;
+       return gsmld_attach_gsm(tty, gsm);
+}
+
+/**
+ *     gsmld_write_wakeup      -       asynchronous I/O notifier
+ *     @tty: tty device
+ *
+ *     Required for the ptys, serial driver etc. since processes
+ *     that attach themselves to the master and rely on ASYNC
+ *     IO must be woken up
+ */
+
+static void gsmld_write_wakeup(struct tty_struct *tty)
+{
+       struct gsm_mux *gsm = tty->disc_data;
+       unsigned long flags;
+
+       /* Queue poll */
+       clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+       gsm_data_kick(gsm);
+       if (gsm->tx_bytes < TX_THRESH_LO) {
+               spin_lock_irqsave(&gsm->tx_lock, flags);
+               gsm_dlci_data_sweep(gsm);
+               spin_unlock_irqrestore(&gsm->tx_lock, flags);
+       }
+}
+
+/**
+ *     gsmld_read              -       read function for tty
+ *     @tty: tty device
+ *     @file: file object
+ *     @buf: userspace buffer pointer
+ *     @nr: size of I/O
+ *
+ *     Perform reads for the line discipline. We are guaranteed that the
+ *     line discipline will not be closed under us but we may get multiple
+ *     parallel readers and must handle this ourselves. We may also get
+ *     a hangup. Always called in user context, may sleep.
+ *
+ *     This code must be sure never to sleep through a hangup.
+ */
+
+static ssize_t gsmld_read(struct tty_struct *tty, struct file *file,
+                        unsigned char __user *buf, size_t nr)
+{
+       return -EOPNOTSUPP;
+}
+
+/**
+ *     gsmld_write             -       write function for tty
+ *     @tty: tty device
+ *     @file: file object
+ *     @buf: userspace buffer pointer
+ *     @nr: size of I/O
+ *
+ *     Called when the owner of the device wants to send a frame
+ *     itself (or some other control data). The data is transferred
+ *     as-is and must be properly framed and checksummed as appropriate
+ *     by userspace. Frames are either sent whole or not at all as this
+ *     avoids pain user side.
+ */
+
+static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
+                          const unsigned char *buf, size_t nr)
+{
+       int space = tty_write_room(tty);
+       if (space >= nr)
+               return tty->ops->write(tty, buf, nr);
+       set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+       return -ENOBUFS;
+}
+
+/**
+ *     gsmld_poll              -       poll method for N_GSM0710
+ *     @tty: terminal device
+ *     @file: file accessing it
+ *     @wait: poll table
+ *
+ *     Called when the line discipline is asked to poll() for data or
+ *     for special events. This code is not serialized with respect to
+ *     other events save open/close.
+ *
+ *     This code must be sure never to sleep through a hangup.
+ *     Called without the kernel lock held - fine
+ */
+
+static unsigned int gsmld_poll(struct tty_struct *tty, struct file *file,
+                                                       poll_table *wait)
+{
+       unsigned int mask = 0;
+       struct gsm_mux *gsm = tty->disc_data;
+
+       poll_wait(file, &tty->read_wait, wait);
+       poll_wait(file, &tty->write_wait, wait);
+       if (tty_hung_up_p(file))
+               mask |= POLLHUP;
+       if (!tty_is_writelocked(tty) && tty_write_room(tty) > 0)
+               mask |= POLLOUT | POLLWRNORM;
+       if (gsm->dead)
+               mask |= POLLHUP;
+       return mask;
+}
+
+static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm,
+                                                       struct gsm_config *c)
+{
+       int need_close = 0;
+       int need_restart = 0;
+
+       /* Stuff we don't support yet - UI or I frame transport, windowing */
+       if ((c->adaption !=1 && c->adaption != 2) || c->k)
+               return -EOPNOTSUPP;
+       /* Check the MRU/MTU range looks sane */
+       if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8)
+               return -EINVAL;
+       if (c->n2 < 3)
+               return -EINVAL;
+       if (c->encapsulation > 1)       /* Basic, advanced, no I */
+               return -EINVAL;
+       if (c->initiator > 1)
+               return -EINVAL;
+       if (c->i == 0 || c->i > 2)      /* UIH and UI only */
+               return -EINVAL;
+       /*
+        *      See what is needed for reconfiguration
+        */
+
+       /* Timing fields */
+       if (c->t1 != 0 && c->t1 != gsm->t1)
+               need_restart = 1;
+       if (c->t2 != 0 && c->t2 != gsm->t2)
+               need_restart = 1;
+       if (c->encapsulation != gsm->encoding)
+               need_restart = 1;
+       if (c->adaption != gsm->adaption)
+               need_restart = 1;
+       /* Requires care */
+       if (c->initiator != gsm->initiator)
+               need_close = 1;
+       if (c->mru != gsm->mru)
+               need_restart = 1;
+       if (c->mtu != gsm->mtu)
+               need_restart = 1;
+
+       /*
+        *      Close down what is needed, restart and initiate the new
+        *      configuration
+        */
+
+       if (need_close || need_restart) {
+               gsm_dlci_begin_close(gsm->dlci[0]);
+               /* This will timeout if the link is down due to N2 expiring */
+               wait_event_interruptible(gsm->event,
+                               gsm->dlci[0]->state == DLCI_CLOSED);
+               if (signal_pending(current))
+                       return -EINTR;
+       }
+       if (need_restart)
+               gsm_cleanup_mux(gsm);
+
+       gsm->initiator = c->initiator;
+       gsm->mru = c->mru;
+       gsm->encoding = c->encapsulation;
+       gsm->adaption = c->adaption;
+       gsm->n2 = c->n2;
+
+       if (c->i == 1)
+               gsm->ftype = UIH;
+       else if (c->i == 2)
+               gsm->ftype = UI;
+
+       if (c->t1)
+               gsm->t1 = c->t1;
+       if (c->t2)
+               gsm->t2 = c->t2;
+
+       /* FIXME: We need to separate activation/deactivation from adding
+          and removing from the mux array */
+       if (need_restart)
+               gsm_activate_mux(gsm);
+       if (gsm->initiator && need_close)
+               gsm_dlci_begin_open(gsm->dlci[0]);
+       return 0;
+}
+
+static int gsmld_ioctl(struct tty_struct *tty, struct file *file,
+                      unsigned int cmd, unsigned long arg)
+{
+       struct gsm_config c;
+       struct gsm_mux *gsm = tty->disc_data;
+
+       switch (cmd) {
+       case GSMIOC_GETCONF:
+               memset(&c, 0, sizeof(c));
+               c.adaption = gsm->adaption;
+               c.encapsulation = gsm->encoding;
+               c.initiator = gsm->initiator;
+               c.t1 = gsm->t1;
+               c.t2 = gsm->t2;
+               c.t3 = 0;       /* Not supported */
+               c.n2 = gsm->n2;
+               if (gsm->ftype == UIH)
+                       c.i = 1;
+               else
+                       c.i = 2;
+               printk("Ftype %d i %d\n", gsm->ftype, c.i);
+               c.mru = gsm->mru;
+               c.mtu = gsm->mtu;
+               c.k = 0;
+               if (copy_to_user((void *)arg, &c, sizeof(c)))
+                       return -EFAULT;
+               return 0;
+       case GSMIOC_SETCONF:
+               if (copy_from_user(&c, (void *)arg, sizeof(c)))
+                       return -EFAULT;
+               return gsmld_config(tty, gsm, &c);
+       default:
+               return n_tty_ioctl_helper(tty, file, cmd, arg);
+       }
+}
+
+
+/* Line discipline for real tty */
+struct tty_ldisc_ops tty_ldisc_packet = {
+       .owner           = THIS_MODULE,
+       .magic           = TTY_LDISC_MAGIC,
+       .name            = "n_gsm",
+       .open            = gsmld_open,
+       .close           = gsmld_close,
+       .flush_buffer    = gsmld_flush_buffer,
+       .chars_in_buffer = gsmld_chars_in_buffer,
+       .read            = gsmld_read,
+       .write           = gsmld_write,
+       .ioctl           = gsmld_ioctl,
+       .poll            = gsmld_poll,
+       .receive_buf     = gsmld_receive_buf,
+       .write_wakeup    = gsmld_write_wakeup
+};
+
+/*
+ *     Virtual tty side
+ */
+
+#define TX_SIZE                512
+
+static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk)
+{
+       u8 modembits[5];
+       struct gsm_control *ctrl;
+       int len = 2;
+
+       if (brk)
+               len++;
+
+       modembits[0] = len << 1 | EA;           /* Data bytes */
+       modembits[1] = dlci->addr << 2 | 3;     /* DLCI, EA, 1 */
+       modembits[2] = gsm_encode_modem(dlci) << 1 | EA;
+       if (brk)
+               modembits[3] = brk << 4 | 2 | EA;       /* Valid, EA */
+       ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len + 1);
+       if (ctrl == NULL)
+               return -ENOMEM;
+       return gsm_control_wait(dlci->gsm, ctrl);
+}
+
+static int gsm_carrier_raised(struct tty_port *port)
+{
+       struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
+       /* Not yet open so no carrier info */
+       if (dlci->state != DLCI_OPEN)
+               return 0;
+       if (debug & 2)
+               return 1;
+       return dlci->modem_rx & TIOCM_CD;
+}
+
+static void gsm_dtr_rts(struct tty_port *port, int onoff)
+{
+       struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
+       unsigned int modem_tx = dlci->modem_tx;
+       if (onoff)
+               modem_tx |= TIOCM_DTR | TIOCM_RTS;
+       else
+               modem_tx &= ~(TIOCM_DTR | TIOCM_RTS);
+       if (modem_tx != dlci->modem_tx) {
+               dlci->modem_tx = modem_tx;
+               gsmtty_modem_update(dlci, 0);
+       }
+}
+
+static const struct tty_port_operations gsm_port_ops = {
+       .carrier_raised = gsm_carrier_raised,
+       .dtr_rts = gsm_dtr_rts,
+};
+
+
+static int gsmtty_open(struct tty_struct *tty, struct file *filp)
+{
+       struct gsm_mux *gsm;
+       struct gsm_dlci *dlci;
+       struct tty_port *port;
+       unsigned int line = tty->index;
+       unsigned int mux = line >> 6;
+
+       line = line & 0x3F;
+
+       if (mux >= MAX_MUX)
+               return -ENXIO;
+       /* FIXME: we need to lock gsm_mux for lifetimes of ttys eventually */
+       if (gsm_mux[mux] == NULL)
+               return -EUNATCH;
+       if (line == 0 || line > 61)     /* 62/63 reserved */
+               return -ECHRNG;
+       gsm = gsm_mux[mux];
+       if (gsm->dead)
+               return -EL2HLT;
+       dlci = gsm->dlci[line];
+       if (dlci == NULL)
+               dlci = gsm_dlci_alloc(gsm, line);
+       if (dlci == NULL)
+               return -ENOMEM;
+       port = &dlci->port;
+       port->count++;
+       tty->driver_data = dlci;
+       tty_port_tty_set(port, tty);
+
+       dlci->modem_rx = 0;
+       /* We could in theory open and close before we wait - eg if we get
+          a DM straight back. This is ok as that will have caused a hangup */
+       set_bit(ASYNCB_INITIALIZED, &port->flags);
+       /* Start sending off SABM messages */
+       gsm_dlci_begin_open(dlci);
+       /* And wait for virtual carrier */
+       return tty_port_block_til_ready(port, tty, filp);
+}
+
+static void gsmtty_close(struct tty_struct *tty, struct file *filp)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       if (dlci == NULL)
+               return;
+       if (tty_port_close_start(&dlci->port, tty, filp) == 0)
+               return;
+       gsm_dlci_begin_close(dlci);
+       tty_port_close_end(&dlci->port, tty);
+       tty_port_tty_set(&dlci->port, NULL);
+}
+
+static void gsmtty_hangup(struct tty_struct *tty)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       tty_port_hangup(&dlci->port);
+       gsm_dlci_begin_close(dlci);
+}
+
+static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf,
+                                                                   int len)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       /* Stuff the bytes into the fifo queue */
+       int sent = kfifo_in_locked(dlci->fifo, buf, len, &dlci->lock);
+       /* Need to kick the channel */
+       gsm_dlci_data_kick(dlci);
+       return sent;
+}
+
+static int gsmtty_write_room(struct tty_struct *tty)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       return TX_SIZE - kfifo_len(dlci->fifo);
+}
+
+static int gsmtty_chars_in_buffer(struct tty_struct *tty)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       return kfifo_len(dlci->fifo);
+}
+
+static void gsmtty_flush_buffer(struct tty_struct *tty)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       /* Caution needed: If we implement reliable transport classes
+          then the data being transmitted can't simply be junked once
+          it has first hit the stack. Until then we can just blow it
+          away */
+       kfifo_reset(dlci->fifo);
+       /* Need to unhook this DLCI from the transmit queue logic */
+}
+
+static void gsmtty_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+       /* The FIFO handles the queue so the kernel will do the right
+          thing waiting on chars_in_buffer before calling us. No work
+          to do here */
+}
+
+static int gsmtty_tiocmget(struct tty_struct *tty, struct file *filp)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       return dlci->modem_rx;
+}
+
+static int gsmtty_tiocmset(struct tty_struct *tty, struct file *filp,
+       unsigned int set, unsigned int clear)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       unsigned int modem_tx = dlci->modem_tx;
+
+       modem_tx &= clear;
+       modem_tx |= set;
+
+       if (modem_tx != dlci->modem_tx) {
+               dlci->modem_tx = modem_tx;
+               return gsmtty_modem_update(dlci, 0);
+       }
+       return 0;
+}
+
+
+static int gsmtty_ioctl(struct tty_struct *tty, struct file *filp,
+                       unsigned int cmd, unsigned long arg)
+{
+       return -ENOIOCTLCMD;
+}
+
+static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old)
+{
+       /* For the moment its fixed. In actual fact the speed information
+          for the virtual channel can be propogated in both directions by
+          the RPN control message. This however rapidly gets nasty as we
+          then have to remap modem signals each way according to whether
+          our virtual cable is null modem etc .. */
+       tty_termios_copy_hw(tty->termios, old);
+}
+
+static void gsmtty_throttle(struct tty_struct *tty)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       if (tty->termios->c_cflag & CRTSCTS)
+               dlci->modem_tx &= ~TIOCM_DTR;
+       dlci->throttled = 1;
+       /* Send an MSC with DTR cleared */
+       gsmtty_modem_update(dlci, 0);
+}
+
+static void gsmtty_unthrottle(struct tty_struct *tty)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       if (tty->termios->c_cflag & CRTSCTS)
+               dlci->modem_tx |= TIOCM_DTR;
+       dlci->throttled = 0;
+       /* Send an MSC with DTR set */
+       gsmtty_modem_update(dlci, 0);
+}
+
+static int gsmtty_break_ctl(struct tty_struct *tty, int state)
+{
+       struct gsm_dlci *dlci = tty->driver_data;
+       int encode = 0; /* Off */
+
+       if (state == -1)        /* "On indefinitely" - we can't encode this
+                                   properly */
+               encode = 0x0F;
+       else if (state > 0) {
+               encode = state / 200;   /* mS to encoding */
+               if (encode > 0x0F)
+                       encode = 0x0F;  /* Best effort */
+       }
+       return gsmtty_modem_update(dlci, encode);
+}
+
+static struct tty_driver *gsm_tty_driver;
+
+/* Virtual ttys for the demux */
+static const struct tty_operations gsmtty_ops = {
+       .open                   = gsmtty_open,
+       .close                  = gsmtty_close,
+       .write                  = gsmtty_write,
+       .write_room             = gsmtty_write_room,
+       .chars_in_buffer        = gsmtty_chars_in_buffer,
+       .flush_buffer           = gsmtty_flush_buffer,
+       .ioctl                  = gsmtty_ioctl,
+       .throttle               = gsmtty_throttle,
+       .unthrottle             = gsmtty_unthrottle,
+       .set_termios            = gsmtty_set_termios,
+       .hangup                 = gsmtty_hangup,
+       .wait_until_sent        = gsmtty_wait_until_sent,
+       .tiocmget               = gsmtty_tiocmget,
+       .tiocmset               = gsmtty_tiocmset,
+       .break_ctl              = gsmtty_break_ctl,
+};
+
+
+
+static int __init gsm_init(void)
+{
+       /* Fill in our line protocol discipline, and register it */
+       int status = tty_register_ldisc(N_GSM0710, &tty_ldisc_packet);
+       if (status != 0) {
+               printk(KERN_ERR "n_gsm: can't register line discipline (err = %d)\n", status);
+               return status;
+       }
+
+       gsm_tty_driver = alloc_tty_driver(256);
+       if (!gsm_tty_driver) {
+               tty_unregister_ldisc(N_GSM0710);
+               printk(KERN_ERR "gsm_init: tty allocation failed.\n");
+               return -EINVAL;
+       }
+       gsm_tty_driver->owner   = THIS_MODULE;
+       gsm_tty_driver->driver_name     = "gsmtty";
+       gsm_tty_driver->name            = "gsmtty";
+       gsm_tty_driver->major           = 0;    /* Dynamic */
+       gsm_tty_driver->minor_start     = 0;
+       gsm_tty_driver->type            = TTY_DRIVER_TYPE_SERIAL;
+       gsm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+       gsm_tty_driver->flags   = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV
+                                                       | TTY_DRIVER_HARDWARE_BREAK;
+       gsm_tty_driver->init_termios    = tty_std_termios;
+       /* Fixme */
+       gsm_tty_driver->init_termios.c_lflag &= ~ECHO;
+       tty_set_operations(gsm_tty_driver, &gsmtty_ops);
+
+       spin_lock_init(&gsm_mux_lock);
+
+       if (tty_register_driver(gsm_tty_driver)) {
+               put_tty_driver(gsm_tty_driver);
+               tty_unregister_ldisc(N_GSM0710);
+               printk(KERN_ERR "gsm_init: tty registration failed.\n");
+               return -EBUSY;
+       }
+       printk(KERN_INFO "gsm_init: loaded as %d,%d.\n", gsm_tty_driver->major, gsm_tty_driver->minor_start);
+       return 0;
+}
+
+static void __exit gsm_exit(void)
+{
+       int status = tty_unregister_ldisc(N_GSM0710);
+       if (status != 0)
+               printk(KERN_ERR "n_gsm: can't unregister line discipline (err = %d)\n", status);
+       tty_unregister_driver(gsm_tty_driver);
+       put_tty_driver(gsm_tty_driver);
+       printk(KERN_INFO "gsm_init: unloaded.\n");
+}
+
+module_init(gsm_init);
+module_exit(gsm_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_GSM0710);
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c
new file mode 100644 (file)
index 0000000..47d3228
--- /dev/null
@@ -0,0 +1,1007 @@
+/* generic HDLC line discipline for Linux
+ *
+ * Written by Paul Fulghum paulkf@microgate.com
+ * for Microgate Corporation
+ *
+ * Microgate and SyncLink are registered trademarks of Microgate Corporation
+ *
+ * Adapted from ppp.c, written by Michael Callahan <callahan@maths.ox.ac.uk>,
+ *     Al Longyear <longyear@netcom.com>,
+ *     Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
+ *
+ * Original release 01/11/99
+ *
+ * This code is released under the GNU General Public License (GPL)
+ *
+ * This module implements the tty line discipline N_HDLC for use with
+ * tty device drivers that support bit-synchronous HDLC communications.
+ *
+ * All HDLC data is frame oriented which means:
+ *
+ * 1. tty write calls represent one complete transmit frame of data
+ *    The device driver should accept the complete frame or none of 
+ *    the frame (busy) in the write method. Each write call should have
+ *    a byte count in the range of 2-65535 bytes (2 is min HDLC frame
+ *    with 1 addr byte and 1 ctrl byte). The max byte count of 65535
+ *    should include any crc bytes required. For example, when using
+ *    CCITT CRC32, 4 crc bytes are required, so the maximum size frame
+ *    the application may transmit is limited to 65531 bytes. For CCITT
+ *    CRC16, the maximum application frame size would be 65533.
+ *
+ *
+ * 2. receive callbacks from the device driver represents
+ *    one received frame. The device driver should bypass
+ *    the tty flip buffer and call the line discipline receive
+ *    callback directly to avoid fragmenting or concatenating
+ *    multiple frames into a single receive callback.
+ *
+ *    The HDLC line discipline queues the receive frames in separate
+ *    buffers so complete receive frames can be returned by the
+ *    tty read calls.
+ *
+ * 3. tty read calls returns an entire frame of data or nothing.
+ *    
+ * 4. all send and receive data is considered raw. No processing
+ *    or translation is performed by the line discipline, regardless
+ *    of the tty flags
+ *
+ * 5. When line discipline is queried for the amount of receive
+ *    data available (FIOC), 0 is returned if no data available,
+ *    otherwise the count of the next available frame is returned.
+ *    (instead of the sum of all received frame counts).
+ *
+ * These conventions allow the standard tty programming interface
+ * to be used for synchronous HDLC applications when used with
+ * this line discipline (or another line discipline that is frame
+ * oriented such as N_PPP).
+ *
+ * The SyncLink driver (synclink.c) implements both asynchronous
+ * (using standard line discipline N_TTY) and synchronous HDLC
+ * (using N_HDLC) communications, with the latter using the above
+ * conventions.
+ *
+ * This implementation is very basic and does not maintain
+ * any statistics. The main point is to enforce the raw data
+ * and frame orientation of HDLC communications.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define HDLC_MAGIC 0x239e
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+
+#undef VERSION
+#define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
+
+#include <linux/poll.h>
+#include <linux/in.h>
+#include <linux/ioctl.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/smp_lock.h>
+#include <linux/string.h>      /* used in new tty drivers */
+#include <linux/signal.h>      /* used in new tty drivers */
+#include <linux/if.h>
+#include <linux/bitops.h>
+
+#include <asm/system.h>
+#include <asm/termios.h>
+#include <asm/uaccess.h>
+
+/*
+ * Buffers for individual HDLC frames
+ */
+#define MAX_HDLC_FRAME_SIZE 65535 
+#define DEFAULT_RX_BUF_COUNT 10
+#define MAX_RX_BUF_COUNT 60
+#define DEFAULT_TX_BUF_COUNT 3
+
+struct n_hdlc_buf {
+       struct n_hdlc_buf *link;
+       int               count;
+       char              buf[1];
+};
+
+#define        N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe)
+
+struct n_hdlc_buf_list {
+       struct n_hdlc_buf *head;
+       struct n_hdlc_buf *tail;
+       int               count;
+       spinlock_t        spinlock;
+};
+
+/**
+ * struct n_hdlc - per device instance data structure
+ * @magic - magic value for structure
+ * @flags - miscellaneous control flags
+ * @tty - ptr to TTY structure
+ * @backup_tty - TTY to use if tty gets closed
+ * @tbusy - reentrancy flag for tx wakeup code
+ * @woke_up - FIXME: describe this field
+ * @tbuf - currently transmitting tx buffer
+ * @tx_buf_list - list of pending transmit frame buffers
+ * @rx_buf_list - list of received frame buffers
+ * @tx_free_buf_list - list unused transmit frame buffers
+ * @rx_free_buf_list - list unused received frame buffers
+ */
+struct n_hdlc {
+       int                     magic;
+       __u32                   flags;
+       struct tty_struct       *tty;
+       struct tty_struct       *backup_tty;
+       int                     tbusy;
+       int                     woke_up;
+       struct n_hdlc_buf       *tbuf;
+       struct n_hdlc_buf_list  tx_buf_list;
+       struct n_hdlc_buf_list  rx_buf_list;
+       struct n_hdlc_buf_list  tx_free_buf_list;
+       struct n_hdlc_buf_list  rx_free_buf_list;
+};
+
+/*
+ * HDLC buffer list manipulation functions
+ */
+static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list);
+static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
+                          struct n_hdlc_buf *buf);
+static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list);
+
+/* Local functions */
+
+static struct n_hdlc *n_hdlc_alloc (void);
+
+/* debug level can be set by insmod for debugging purposes */
+#define DEBUG_LEVEL_INFO       1
+static int debuglevel;
+
+/* max frame size for memory allocations */
+static int maxframe = 4096;
+
+/* TTY callbacks */
+
+static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
+                          __u8 __user *buf, size_t nr);
+static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
+                           const unsigned char *buf, size_t nr);
+static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
+                           unsigned int cmd, unsigned long arg);
+static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
+                                   poll_table *wait);
+static int n_hdlc_tty_open(struct tty_struct *tty);
+static void n_hdlc_tty_close(struct tty_struct *tty);
+static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
+                              char *fp, int count);
+static void n_hdlc_tty_wakeup(struct tty_struct *tty);
+
+#define bset(p,b)      ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
+
+#define tty2n_hdlc(tty)        ((struct n_hdlc *) ((tty)->disc_data))
+#define n_hdlc2tty(n_hdlc)     ((n_hdlc)->tty)
+
+static void flush_rx_queue(struct tty_struct *tty)
+{
+       struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
+       struct n_hdlc_buf *buf;
+
+       while ((buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list)))
+               n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, buf);
+}
+
+static void flush_tx_queue(struct tty_struct *tty)
+{
+       struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
+       struct n_hdlc_buf *buf;
+       unsigned long flags;
+
+       while ((buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list)))
+               n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, buf);
+       spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
+       if (n_hdlc->tbuf) {
+               n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, n_hdlc->tbuf);
+               n_hdlc->tbuf = NULL;
+       }
+       spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
+}
+
+static struct tty_ldisc_ops n_hdlc_ldisc = {
+       .owner          = THIS_MODULE,
+       .magic          = TTY_LDISC_MAGIC,
+       .name           = "hdlc",
+       .open           = n_hdlc_tty_open,
+       .close          = n_hdlc_tty_close,
+       .read           = n_hdlc_tty_read,
+       .write          = n_hdlc_tty_write,
+       .ioctl          = n_hdlc_tty_ioctl,
+       .poll           = n_hdlc_tty_poll,
+       .receive_buf    = n_hdlc_tty_receive,
+       .write_wakeup   = n_hdlc_tty_wakeup,
+       .flush_buffer   = flush_rx_queue,
+};
+
+/**
+ * n_hdlc_release - release an n_hdlc per device line discipline info structure
+ * @n_hdlc - per device line discipline info structure
+ */
+static void n_hdlc_release(struct n_hdlc *n_hdlc)
+{
+       struct tty_struct *tty = n_hdlc2tty (n_hdlc);
+       struct n_hdlc_buf *buf;
+       
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_release() called\n",__FILE__,__LINE__);
+               
+       /* Ensure that the n_hdlcd process is not hanging on select()/poll() */
+       wake_up_interruptible (&tty->read_wait);
+       wake_up_interruptible (&tty->write_wait);
+
+       if (tty->disc_data == n_hdlc)
+               tty->disc_data = NULL;  /* Break the tty->n_hdlc link */
+
+       /* Release transmit and receive buffers */
+       for(;;) {
+               buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
+               if (buf) {
+                       kfree(buf);
+               } else
+                       break;
+       }
+       for(;;) {
+               buf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
+               if (buf) {
+                       kfree(buf);
+               } else
+                       break;
+       }
+       for(;;) {
+               buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
+               if (buf) {
+                       kfree(buf);
+               } else
+                       break;
+       }
+       for(;;) {
+               buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
+               if (buf) {
+                       kfree(buf);
+               } else
+                       break;
+       }
+       kfree(n_hdlc->tbuf);
+       kfree(n_hdlc);
+       
+}      /* end of n_hdlc_release() */
+
+/**
+ * n_hdlc_tty_close - line discipline close
+ * @tty - pointer to tty info structure
+ *
+ * Called when the line discipline is changed to something
+ * else, the tty is closed, or the tty detects a hangup.
+ */
+static void n_hdlc_tty_close(struct tty_struct *tty)
+{
+       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
+
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_close() called\n",__FILE__,__LINE__);
+               
+       if (n_hdlc != NULL) {
+               if (n_hdlc->magic != HDLC_MAGIC) {
+                       printk (KERN_WARNING"n_hdlc: trying to close unopened tty!\n");
+                       return;
+               }
+#if defined(TTY_NO_WRITE_SPLIT)
+               clear_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
+#endif
+               tty->disc_data = NULL;
+               if (tty == n_hdlc->backup_tty)
+                       n_hdlc->backup_tty = NULL;
+               if (tty != n_hdlc->tty)
+                       return;
+               if (n_hdlc->backup_tty) {
+                       n_hdlc->tty = n_hdlc->backup_tty;
+               } else {
+                       n_hdlc_release (n_hdlc);
+               }
+       }
+       
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_close() success\n",__FILE__,__LINE__);
+               
+}      /* end of n_hdlc_tty_close() */
+
+/**
+ * n_hdlc_tty_open - called when line discipline changed to n_hdlc
+ * @tty - pointer to tty info structure
+ *
+ * Returns 0 if success, otherwise error code
+ */
+static int n_hdlc_tty_open (struct tty_struct *tty)
+{
+       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
+
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_open() called (device=%s)\n",
+               __FILE__,__LINE__,
+               tty->name);
+               
+       /* There should not be an existing table for this slot. */
+       if (n_hdlc) {
+               printk (KERN_ERR"n_hdlc_tty_open:tty already associated!\n" );
+               return -EEXIST;
+       }
+       
+       n_hdlc = n_hdlc_alloc();
+       if (!n_hdlc) {
+               printk (KERN_ERR "n_hdlc_alloc failed\n");
+               return -ENFILE;
+       }
+               
+       tty->disc_data = n_hdlc;
+       n_hdlc->tty    = tty;
+       tty->receive_room = 65536;
+       
+#if defined(TTY_NO_WRITE_SPLIT)
+       /* change tty_io write() to not split large writes into 8K chunks */
+       set_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
+#endif
+       
+       /* flush receive data from driver */
+       tty_driver_flush_buffer(tty);
+               
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__);
+               
+       return 0;
+       
+}      /* end of n_tty_hdlc_open() */
+
+/**
+ * n_hdlc_send_frames - send frames on pending send buffer list
+ * @n_hdlc - pointer to ldisc instance data
+ * @tty - pointer to tty instance data
+ *
+ * Send frames on pending send buffer list until the driver does not accept a
+ * frame (busy) this function is called after adding a frame to the send buffer
+ * list and by the tty wakeup callback.
+ */
+static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
+{
+       register int actual;
+       unsigned long flags;
+       struct n_hdlc_buf *tbuf;
+
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__,__LINE__);
+ check_again:
+               
+       spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
+       if (n_hdlc->tbusy) {
+               n_hdlc->woke_up = 1;
+               spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
+               return;
+       }
+       n_hdlc->tbusy = 1;
+       n_hdlc->woke_up = 0;
+       spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
+
+       /* get current transmit buffer or get new transmit */
+       /* buffer from list of pending transmit buffers */
+               
+       tbuf = n_hdlc->tbuf;
+       if (!tbuf)
+               tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
+               
+       while (tbuf) {
+               if (debuglevel >= DEBUG_LEVEL_INFO)     
+                       printk("%s(%d)sending frame %p, count=%d\n",
+                               __FILE__,__LINE__,tbuf,tbuf->count);
+                       
+               /* Send the next block of data to device */
+               tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
+               actual = tty->ops->write(tty, tbuf->buf, tbuf->count);
+
+               /* rollback was possible and has been done */
+               if (actual == -ERESTARTSYS) {
+                       n_hdlc->tbuf = tbuf;
+                       break;
+               }
+               /* if transmit error, throw frame away by */
+               /* pretending it was accepted by driver */
+               if (actual < 0)
+                       actual = tbuf->count;
+               
+               if (actual == tbuf->count) {
+                       if (debuglevel >= DEBUG_LEVEL_INFO)     
+                               printk("%s(%d)frame %p completed\n",
+                                       __FILE__,__LINE__,tbuf);
+                                       
+                       /* free current transmit buffer */
+                       n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf);
+                       
+                       /* this tx buffer is done */
+                       n_hdlc->tbuf = NULL;
+                       
+                       /* wait up sleeping writers */
+                       wake_up_interruptible(&tty->write_wait);
+       
+                       /* get next pending transmit buffer */
+                       tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
+               } else {
+                       if (debuglevel >= DEBUG_LEVEL_INFO)     
+                               printk("%s(%d)frame %p pending\n",
+                                       __FILE__,__LINE__,tbuf);
+                                       
+                       /* buffer not accepted by driver */
+                       /* set this buffer as pending buffer */
+                       n_hdlc->tbuf = tbuf;
+                       break;
+               }
+       }
+       
+       if (!tbuf)
+               tty->flags  &= ~(1 << TTY_DO_WRITE_WAKEUP);
+       
+       /* Clear the re-entry flag */
+       spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
+       n_hdlc->tbusy = 0;
+       spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); 
+       
+        if (n_hdlc->woke_up)
+         goto check_again;
+
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_send_frames() exit\n",__FILE__,__LINE__);
+               
+}      /* end of n_hdlc_send_frames() */
+
+/**
+ * n_hdlc_tty_wakeup - Callback for transmit wakeup
+ * @tty        - pointer to associated tty instance data
+ *
+ * Called when low level device driver can accept more send data.
+ */
+static void n_hdlc_tty_wakeup(struct tty_struct *tty)
+{
+       struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
+
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_wakeup() called\n",__FILE__,__LINE__);
+               
+       if (!n_hdlc)
+               return;
+
+       if (tty != n_hdlc->tty) {
+               tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
+               return;
+       }
+
+       n_hdlc_send_frames (n_hdlc, tty);
+               
+}      /* end of n_hdlc_tty_wakeup() */
+
+/**
+ * n_hdlc_tty_receive - Called by tty driver when receive data is available
+ * @tty        - pointer to tty instance data
+ * @data - pointer to received data
+ * @flags - pointer to flags for data
+ * @count - count of received data in bytes
+ *
+ * Called by tty low level driver when receive data is available. Data is
+ * interpreted as one HDLC frame.
+ */
+static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
+                              char *flags, int count)
+{
+       register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
+       register struct n_hdlc_buf *buf;
+
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_receive() called count=%d\n",
+                       __FILE__,__LINE__, count);
+               
+       /* This can happen if stuff comes in on the backup tty */
+       if (!n_hdlc || tty != n_hdlc->tty)
+               return;
+               
+       /* verify line is using HDLC discipline */
+       if (n_hdlc->magic != HDLC_MAGIC) {
+               printk("%s(%d) line not using HDLC discipline\n",
+                       __FILE__,__LINE__);
+               return;
+       }
+       
+       if ( count>maxframe ) {
+               if (debuglevel >= DEBUG_LEVEL_INFO)     
+                       printk("%s(%d) rx count>maxframesize, data discarded\n",
+                              __FILE__,__LINE__);
+               return;
+       }
+
+       /* get a free HDLC buffer */    
+       buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
+       if (!buf) {
+               /* no buffers in free list, attempt to allocate another rx buffer */
+               /* unless the maximum count has been reached */
+               if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
+                       buf = kmalloc(N_HDLC_BUF_SIZE, GFP_ATOMIC);
+       }
+       
+       if (!buf) {
+               if (debuglevel >= DEBUG_LEVEL_INFO)     
+                       printk("%s(%d) no more rx buffers, data discarded\n",
+                              __FILE__,__LINE__);
+               return;
+       }
+               
+       /* copy received data to HDLC buffer */
+       memcpy(buf->buf,data,count);
+       buf->count=count;
+
+       /* add HDLC buffer to list of received frames */
+       n_hdlc_buf_put(&n_hdlc->rx_buf_list, buf);
+       
+       /* wake up any blocked reads and perform async signalling */
+       wake_up_interruptible (&tty->read_wait);
+       if (n_hdlc->tty->fasync != NULL)
+               kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
+
+}      /* end of n_hdlc_tty_receive() */
+
+/**
+ * n_hdlc_tty_read - Called to retrieve one frame of data (if available)
+ * @tty - pointer to tty instance data
+ * @file - pointer to open file object
+ * @buf - pointer to returned data buffer
+ * @nr - size of returned data buffer
+ *     
+ * Returns the number of bytes returned or error code.
+ */
+static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
+                          __u8 __user *buf, size_t nr)
+{
+       struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
+       int ret;
+       struct n_hdlc_buf *rbuf;
+
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__);
+               
+       /* Validate the pointers */
+       if (!n_hdlc)
+               return -EIO;
+
+       /* verify user access to buffer */
+       if (!access_ok(VERIFY_WRITE, buf, nr)) {
+               printk(KERN_WARNING "%s(%d) n_hdlc_tty_read() can't verify user "
+               "buffer\n", __FILE__, __LINE__);
+               return -EFAULT;
+       }
+
+       tty_lock();
+
+       for (;;) {
+               if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
+                       tty_unlock();
+                       return -EIO;
+               }
+
+               n_hdlc = tty2n_hdlc (tty);
+               if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
+                        tty != n_hdlc->tty) {
+                       tty_unlock();
+                       return 0;
+               }
+
+               rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
+               if (rbuf)
+                       break;
+                       
+               /* no data */
+               if (file->f_flags & O_NONBLOCK) {
+                       tty_unlock();
+                       return -EAGAIN;
+               }
+                       
+               interruptible_sleep_on (&tty->read_wait);
+               if (signal_pending(current)) {
+                       tty_unlock();
+                       return -EINTR;
+               }
+       }
+               
+       if (rbuf->count > nr)
+               /* frame too large for caller's buffer (discard frame) */
+               ret = -EOVERFLOW;
+       else {
+               /* Copy the data to the caller's buffer */
+               if (copy_to_user(buf, rbuf->buf, rbuf->count))
+                       ret = -EFAULT;
+               else
+                       ret = rbuf->count;
+       }
+       
+       /* return HDLC buffer to free list unless the free list */
+       /* count has exceeded the default value, in which case the */
+       /* buffer is freed back to the OS to conserve memory */
+       if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT)
+               kfree(rbuf);
+       else    
+               n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf);
+       tty_unlock();
+       return ret;
+       
+}      /* end of n_hdlc_tty_read() */
+
+/**
+ * n_hdlc_tty_write - write a single frame of data to device
+ * @tty        - pointer to associated tty device instance data
+ * @file - pointer to file object data
+ * @data - pointer to transmit data (one frame)
+ * @count - size of transmit frame in bytes
+ *             
+ * Returns the number of bytes written (or error code).
+ */
+static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
+                           const unsigned char *data, size_t count)
+{
+       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
+       int error = 0;
+       DECLARE_WAITQUEUE(wait, current);
+       struct n_hdlc_buf *tbuf;
+
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_write() called count=%Zd\n",
+                       __FILE__,__LINE__,count);
+               
+       /* Verify pointers */
+       if (!n_hdlc)
+               return -EIO;
+
+       if (n_hdlc->magic != HDLC_MAGIC)
+               return -EIO;
+
+       /* verify frame size */
+       if (count > maxframe ) {
+               if (debuglevel & DEBUG_LEVEL_INFO)
+                       printk (KERN_WARNING
+                               "n_hdlc_tty_write: truncating user packet "
+                               "from %lu to %d\n", (unsigned long) count,
+                               maxframe );
+               count = maxframe;
+       }
+       
+       tty_lock();
+
+       add_wait_queue(&tty->write_wait, &wait);
+       set_current_state(TASK_INTERRUPTIBLE);
+       
+       /* Allocate transmit buffer */
+       /* sleep until transmit buffer available */             
+       while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
+               if (file->f_flags & O_NONBLOCK) {
+                       error = -EAGAIN;
+                       break;
+               }
+               schedule();
+                       
+               n_hdlc = tty2n_hdlc (tty);
+               if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || 
+                   tty != n_hdlc->tty) {
+                       printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc);
+                       error = -EIO;
+                       break;
+               }
+                       
+               if (signal_pending(current)) {
+                       error = -EINTR;
+                       break;
+               }
+       }
+
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(&tty->write_wait, &wait);
+
+       if (!error) {           
+               /* Retrieve the user's buffer */
+               memcpy(tbuf->buf, data, count);
+
+               /* Send the data */
+               tbuf->count = error = count;
+               n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
+               n_hdlc_send_frames(n_hdlc,tty);
+       }
+       tty_unlock();
+       return error;
+       
+}      /* end of n_hdlc_tty_write() */
+
+/**
+ * n_hdlc_tty_ioctl - process IOCTL system call for the tty device.
+ * @tty - pointer to tty instance data
+ * @file - pointer to open file object for device
+ * @cmd - IOCTL command code
+ * @arg - argument for IOCTL call (cmd dependent)
+ *
+ * Returns command dependent result.
+ */
+static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
+                           unsigned int cmd, unsigned long arg)
+{
+       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
+       int error = 0;
+       int count;
+       unsigned long flags;
+       
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
+                       __FILE__,__LINE__,cmd);
+               
+       /* Verify the status of the device */
+       if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC)
+               return -EBADF;
+
+       switch (cmd) {
+       case FIONREAD:
+               /* report count of read data available */
+               /* in next available frame (if any) */
+               spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
+               if (n_hdlc->rx_buf_list.head)
+                       count = n_hdlc->rx_buf_list.head->count;
+               else
+                       count = 0;
+               spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
+               error = put_user(count, (int __user *)arg);
+               break;
+
+       case TIOCOUTQ:
+               /* get the pending tx byte count in the driver */
+               count = tty_chars_in_buffer(tty);
+               /* add size of next output frame in queue */
+               spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
+               if (n_hdlc->tx_buf_list.head)
+                       count += n_hdlc->tx_buf_list.head->count;
+               spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
+               error = put_user(count, (int __user *)arg);
+               break;
+
+       case TCFLSH:
+               switch (arg) {
+               case TCIOFLUSH:
+               case TCOFLUSH:
+                       flush_tx_queue(tty);
+               }
+               /* fall through to default */
+
+       default:
+               error = n_tty_ioctl_helper(tty, file, cmd, arg);
+               break;
+       }
+       return error;
+       
+}      /* end of n_hdlc_tty_ioctl() */
+
+/**
+ * n_hdlc_tty_poll - TTY callback for poll system call
+ * @tty - pointer to tty instance data
+ * @filp - pointer to open file object for device
+ * @poll_table - wait queue for operations
+ * 
+ * Determine which operations (read/write) will not block and return info
+ * to caller.
+ * Returns a bit mask containing info on which ops will not block.
+ */
+static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
+                                   poll_table *wait)
+{
+       struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
+       unsigned int mask = 0;
+
+       if (debuglevel >= DEBUG_LEVEL_INFO)     
+               printk("%s(%d)n_hdlc_tty_poll() called\n",__FILE__,__LINE__);
+               
+       if (n_hdlc && n_hdlc->magic == HDLC_MAGIC && tty == n_hdlc->tty) {
+               /* queue current process into any wait queue that */
+               /* may awaken in the future (read and write) */
+
+               poll_wait(filp, &tty->read_wait, wait);
+               poll_wait(filp, &tty->write_wait, wait);
+
+               /* set bits for operations that won't block */
+               if (n_hdlc->rx_buf_list.head)
+                       mask |= POLLIN | POLLRDNORM;    /* readable */
+               if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
+                       mask |= POLLHUP;
+               if (tty_hung_up_p(filp))
+                       mask |= POLLHUP;
+               if (!tty_is_writelocked(tty) &&
+                               n_hdlc->tx_free_buf_list.head)
+                       mask |= POLLOUT | POLLWRNORM;   /* writable */
+       }
+       return mask;
+}      /* end of n_hdlc_tty_poll() */
+
+/**
+ * n_hdlc_alloc - allocate an n_hdlc instance data structure
+ *
+ * Returns a pointer to newly created structure if success, otherwise %NULL
+ */
+static struct n_hdlc *n_hdlc_alloc(void)
+{
+       struct n_hdlc_buf *buf;
+       int i;
+       struct n_hdlc *n_hdlc = kmalloc(sizeof(*n_hdlc), GFP_KERNEL);
+
+       if (!n_hdlc)
+               return NULL;
+
+       memset(n_hdlc, 0, sizeof(*n_hdlc));
+
+       n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list);
+       n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list);
+       n_hdlc_buf_list_init(&n_hdlc->rx_buf_list);
+       n_hdlc_buf_list_init(&n_hdlc->tx_buf_list);
+       
+       /* allocate free rx buffer list */
+       for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
+               buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
+               if (buf)
+                       n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
+               else if (debuglevel >= DEBUG_LEVEL_INFO)        
+                       printk("%s(%d)n_hdlc_alloc(), kalloc() failed for rx buffer %d\n",__FILE__,__LINE__, i);
+       }
+       
+       /* allocate free tx buffer list */
+       for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
+               buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
+               if (buf)
+                       n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
+               else if (debuglevel >= DEBUG_LEVEL_INFO)        
+                       printk("%s(%d)n_hdlc_alloc(), kalloc() failed for tx buffer %d\n",__FILE__,__LINE__, i);
+       }
+       
+       /* Initialize the control block */
+       n_hdlc->magic  = HDLC_MAGIC;
+       n_hdlc->flags  = 0;
+       
+       return n_hdlc;
+       
+}      /* end of n_hdlc_alloc() */
+
+/**
+ * n_hdlc_buf_list_init - initialize specified HDLC buffer list
+ * @list - pointer to buffer list
+ */
+static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list)
+{
+       memset(list, 0, sizeof(*list));
+       spin_lock_init(&list->spinlock);
+}      /* end of n_hdlc_buf_list_init() */
+
+/**
+ * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
+ * @list - pointer to buffer list
+ * @buf        - pointer to buffer
+ */
+static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
+                          struct n_hdlc_buf *buf)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&list->spinlock,flags);
+       
+       buf->link=NULL;
+       if (list->tail)
+               list->tail->link = buf;
+       else
+               list->head = buf;
+       list->tail = buf;
+       (list->count)++;
+       
+       spin_unlock_irqrestore(&list->spinlock,flags);
+       
+}      /* end of n_hdlc_buf_put() */
+
+/**
+ * n_hdlc_buf_get - remove and return an HDLC buffer from list
+ * @list - pointer to HDLC buffer list
+ * 
+ * Remove and return an HDLC buffer from the head of the specified HDLC buffer
+ * list.
+ * Returns a pointer to HDLC buffer if available, otherwise %NULL.
+ */
+static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list)
+{
+       unsigned long flags;
+       struct n_hdlc_buf *buf;
+       spin_lock_irqsave(&list->spinlock,flags);
+       
+       buf = list->head;
+       if (buf) {
+               list->head = buf->link;
+               (list->count)--;
+       }
+       if (!list->head)
+               list->tail = NULL;
+       
+       spin_unlock_irqrestore(&list->spinlock,flags);
+       return buf;
+       
+}      /* end of n_hdlc_buf_get() */
+
+static char hdlc_banner[] __initdata =
+       KERN_INFO "HDLC line discipline maxframe=%u\n";
+static char hdlc_register_ok[] __initdata =
+       KERN_INFO "N_HDLC line discipline registered.\n";
+static char hdlc_register_fail[] __initdata =
+       KERN_ERR "error registering line discipline: %d\n";
+static char hdlc_init_fail[] __initdata =
+       KERN_INFO "N_HDLC: init failure %d\n";
+
+static int __init n_hdlc_init(void)
+{
+       int status;
+
+       /* range check maxframe arg */
+       if (maxframe < 4096)
+               maxframe = 4096;
+       else if (maxframe > 65535)
+               maxframe = 65535;
+
+       printk(hdlc_banner, maxframe);
+
+       status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc);
+       if (!status)
+               printk(hdlc_register_ok);
+       else
+               printk(hdlc_register_fail, status);
+
+       if (status)
+               printk(hdlc_init_fail, status);
+       return status;
+       
+}      /* end of init_module() */
+
+static char hdlc_unregister_ok[] __exitdata =
+       KERN_INFO "N_HDLC: line discipline unregistered\n";
+static char hdlc_unregister_fail[] __exitdata =
+       KERN_ERR "N_HDLC: can't unregister line discipline (err = %d)\n";
+
+static void __exit n_hdlc_exit(void)
+{
+       /* Release tty registration of line discipline */
+       int status = tty_unregister_ldisc(N_HDLC);
+
+       if (status)
+               printk(hdlc_unregister_fail, status);
+       else
+               printk(hdlc_unregister_ok);
+}
+
+module_init(n_hdlc_init);
+module_exit(n_hdlc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Paul Fulghum paulkf@microgate.com");
+module_param(debuglevel, int, 0);
+module_param(maxframe, int, 0);
+MODULE_ALIAS_LDISC(N_HDLC);
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c
new file mode 100644 (file)
index 0000000..88dda0c
--- /dev/null
@@ -0,0 +1,1264 @@
+/* r3964 linediscipline for linux
+ *
+ * -----------------------------------------------------------
+ * Copyright by 
+ * Philips Automation Projects
+ * Kassel (Germany)
+ * -----------------------------------------------------------
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License, incorporated herein by reference.
+ *
+ * Author:
+ * L. Haag
+ *
+ * $Log: n_r3964.c,v $
+ * Revision 1.10  2001/03/18 13:02:24  dwmw2
+ * Fix timer usage, use spinlocks properly.
+ *
+ * Revision 1.9  2001/03/18 12:52:14  dwmw2
+ * Merge changes in 2.4.2
+ *
+ * Revision 1.8  2000/03/23 14:14:54  dwmw2
+ * Fix race in sleeping in r3964_read()
+ *
+ * Revision 1.7  1999/28/08 11:41:50  dwmw2
+ * Port to 2.3 kernel
+ *
+ * Revision 1.6  1998/09/30 00:40:40  dwmw2
+ * Fixed compilation on 2.0.x kernels
+ * Updated to newly registered tty-ldisc number 9
+ *
+ * Revision 1.5  1998/09/04 21:57:36  dwmw2
+ * Signal handling bug fixes, port to 2.1.x.
+ *
+ * Revision 1.4  1998/04/02 20:26:59  lhaag
+ * select, blocking, ...
+ *
+ * Revision 1.3  1998/02/12 18:58:43  root
+ * fixed some memory leaks
+ * calculation of checksum characters
+ *
+ * Revision 1.2  1998/02/07 13:03:34  root
+ * ioctl read_telegram
+ *
+ * Revision 1.1  1998/02/06 19:21:03  root
+ * Initial revision
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/string.h>      /* used in new tty drivers */
+#include <linux/signal.h>      /* used in new tty drivers */
+#include <linux/ioctl.h>
+#include <linux/n_r3964.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+
+/*#define DEBUG_QUEUE*/
+
+/* Log successful handshake and protocol operations  */
+/*#define DEBUG_PROTO_S*/
+
+/* Log handshake and protocol errors: */
+/*#define DEBUG_PROTO_E*/
+
+/* Log Linediscipline operations (open, close, read, write...): */
+/*#define DEBUG_LDISC*/
+
+/* Log module and memory operations (init, cleanup; kmalloc, kfree): */
+/*#define DEBUG_MODUL*/
+
+/* Macro helpers for debug output: */
+#define TRACE(format, args...) printk("r3964: " format "\n" , ## args)
+
+#ifdef DEBUG_MODUL
+#define TRACE_M(format, args...) printk("r3964: " format "\n" , ## args)
+#else
+#define TRACE_M(fmt, arg...) do {} while (0)
+#endif
+#ifdef DEBUG_PROTO_S
+#define TRACE_PS(format, args...) printk("r3964: " format "\n" , ## args)
+#else
+#define TRACE_PS(fmt, arg...) do {} while (0)
+#endif
+#ifdef DEBUG_PROTO_E
+#define TRACE_PE(format, args...) printk("r3964: " format "\n" , ## args)
+#else
+#define TRACE_PE(fmt, arg...) do {} while (0)
+#endif
+#ifdef DEBUG_LDISC
+#define TRACE_L(format, args...) printk("r3964: " format "\n" , ## args)
+#else
+#define TRACE_L(fmt, arg...) do {} while (0)
+#endif
+#ifdef DEBUG_QUEUE
+#define TRACE_Q(format, args...) printk("r3964: " format "\n" , ## args)
+#else
+#define TRACE_Q(fmt, arg...) do {} while (0)
+#endif
+static void add_tx_queue(struct r3964_info *, struct r3964_block_header *);
+static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code);
+static void put_char(struct r3964_info *pInfo, unsigned char ch);
+static void trigger_transmit(struct r3964_info *pInfo);
+static void retry_transmit(struct r3964_info *pInfo);
+static void transmit_block(struct r3964_info *pInfo);
+static void receive_char(struct r3964_info *pInfo, const unsigned char c);
+static void receive_error(struct r3964_info *pInfo, const char flag);
+static void on_timeout(unsigned long priv);
+static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg);
+static int read_telegram(struct r3964_info *pInfo, struct pid *pid,
+               unsigned char __user * buf);
+static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
+               int error_code, struct r3964_block_header *pBlock);
+static struct r3964_message *remove_msg(struct r3964_info *pInfo,
+               struct r3964_client_info *pClient);
+static void remove_client_block(struct r3964_info *pInfo,
+               struct r3964_client_info *pClient);
+
+static int r3964_open(struct tty_struct *tty);
+static void r3964_close(struct tty_struct *tty);
+static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
+               unsigned char __user * buf, size_t nr);
+static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
+               const unsigned char *buf, size_t nr);
+static int r3964_ioctl(struct tty_struct *tty, struct file *file,
+               unsigned int cmd, unsigned long arg);
+static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old);
+static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
+               struct poll_table_struct *wait);
+static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+               char *fp, int count);
+
+static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
+       .owner = THIS_MODULE,
+       .magic = TTY_LDISC_MAGIC,
+       .name = "R3964",
+       .open = r3964_open,
+       .close = r3964_close,
+       .read = r3964_read,
+       .write = r3964_write,
+       .ioctl = r3964_ioctl,
+       .set_termios = r3964_set_termios,
+       .poll = r3964_poll,
+       .receive_buf = r3964_receive_buf,
+};
+
+static void dump_block(const unsigned char *block, unsigned int length)
+{
+       unsigned int i, j;
+       char linebuf[16 * 3 + 1];
+
+       for (i = 0; i < length; i += 16) {
+               for (j = 0; (j < 16) && (j + i < length); j++) {
+                       sprintf(linebuf + 3 * j, "%02x ", block[i + j]);
+               }
+               linebuf[3 * j] = '\0';
+               TRACE_PS("%s", linebuf);
+       }
+}
+
+/*************************************************************
+ * Driver initialisation
+ *************************************************************/
+
+/*************************************************************
+ * Module support routines
+ *************************************************************/
+
+static void __exit r3964_exit(void)
+{
+       int status;
+
+       TRACE_M("cleanup_module()");
+
+       status = tty_unregister_ldisc(N_R3964);
+
+       if (status != 0) {
+               printk(KERN_ERR "r3964: error unregistering linediscipline: "
+                               "%d\n", status);
+       } else {
+               TRACE_L("linediscipline successfully unregistered");
+       }
+}
+
+static int __init r3964_init(void)
+{
+       int status;
+
+       printk("r3964: Philips r3964 Driver $Revision: 1.10 $\n");
+
+       /*
+        * Register the tty line discipline
+        */
+
+       status = tty_register_ldisc(N_R3964, &tty_ldisc_N_R3964);
+       if (status == 0) {
+               TRACE_L("line discipline %d registered", N_R3964);
+               TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags,
+                       tty_ldisc_N_R3964.num);
+               TRACE_L("open=%p", tty_ldisc_N_R3964.open);
+               TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964);
+       } else {
+               printk(KERN_ERR "r3964: error registering line discipline: "
+                               "%d\n", status);
+       }
+       return status;
+}
+
+module_init(r3964_init);
+module_exit(r3964_exit);
+
+/*************************************************************
+ * Protocol implementation routines
+ *************************************************************/
+
+static void add_tx_queue(struct r3964_info *pInfo,
+                        struct r3964_block_header *pHeader)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pInfo->lock, flags);
+
+       pHeader->next = NULL;
+
+       if (pInfo->tx_last == NULL) {
+               pInfo->tx_first = pInfo->tx_last = pHeader;
+       } else {
+               pInfo->tx_last->next = pHeader;
+               pInfo->tx_last = pHeader;
+       }
+
+       spin_unlock_irqrestore(&pInfo->lock, flags);
+
+       TRACE_Q("add_tx_queue %p, length %d, tx_first = %p",
+               pHeader, pHeader->length, pInfo->tx_first);
+}
+
+static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
+{
+       struct r3964_block_header *pHeader;
+       unsigned long flags;
+#ifdef DEBUG_QUEUE
+       struct r3964_block_header *pDump;
+#endif
+
+       pHeader = pInfo->tx_first;
+
+       if (pHeader == NULL)
+               return;
+
+#ifdef DEBUG_QUEUE
+       printk("r3964: remove_from_tx_queue: %p, length %u - ",
+               pHeader, pHeader->length);
+       for (pDump = pHeader; pDump; pDump = pDump->next)
+               printk("%p ", pDump);
+       printk("\n");
+#endif
+
+       if (pHeader->owner) {
+               if (error_code) {
+                       add_msg(pHeader->owner, R3964_MSG_ACK, 0,
+                               error_code, NULL);
+               } else {
+                       add_msg(pHeader->owner, R3964_MSG_ACK, pHeader->length,
+                               error_code, NULL);
+               }
+               wake_up_interruptible(&pInfo->read_wait);
+       }
+
+       spin_lock_irqsave(&pInfo->lock, flags);
+
+       pInfo->tx_first = pHeader->next;
+       if (pInfo->tx_first == NULL) {
+               pInfo->tx_last = NULL;
+       }
+
+       spin_unlock_irqrestore(&pInfo->lock, flags);
+
+       kfree(pHeader);
+       TRACE_M("remove_from_tx_queue - kfree %p", pHeader);
+
+       TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p",
+               pInfo->tx_first, pInfo->tx_last);
+}
+
+static void add_rx_queue(struct r3964_info *pInfo,
+                        struct r3964_block_header *pHeader)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pInfo->lock, flags);
+
+       pHeader->next = NULL;
+
+       if (pInfo->rx_last == NULL) {
+               pInfo->rx_first = pInfo->rx_last = pHeader;
+       } else {
+               pInfo->rx_last->next = pHeader;
+               pInfo->rx_last = pHeader;
+       }
+       pInfo->blocks_in_rx_queue++;
+
+       spin_unlock_irqrestore(&pInfo->lock, flags);
+
+       TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d",
+               pHeader, pHeader->length,
+               pInfo->rx_first, pInfo->blocks_in_rx_queue);
+}
+
+static void remove_from_rx_queue(struct r3964_info *pInfo,
+                                struct r3964_block_header *pHeader)
+{
+       unsigned long flags;
+       struct r3964_block_header *pFind;
+
+       if (pHeader == NULL)
+               return;
+
+       TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
+               pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue);
+       TRACE_Q("remove_from_rx_queue: %p, length %u",
+               pHeader, pHeader->length);
+
+       spin_lock_irqsave(&pInfo->lock, flags);
+
+       if (pInfo->rx_first == pHeader) {
+               /* Remove the first block in the linked list: */
+               pInfo->rx_first = pHeader->next;
+
+               if (pInfo->rx_first == NULL) {
+                       pInfo->rx_last = NULL;
+               }
+               pInfo->blocks_in_rx_queue--;
+       } else {
+               /* Find block to remove: */
+               for (pFind = pInfo->rx_first; pFind; pFind = pFind->next) {
+                       if (pFind->next == pHeader) {
+                               /* Got it. */
+                               pFind->next = pHeader->next;
+                               pInfo->blocks_in_rx_queue--;
+                               if (pFind->next == NULL) {
+                                       /* Oh, removed the last one! */
+                                       pInfo->rx_last = pFind;
+                               }
+                               break;
+                       }
+               }
+       }
+
+       spin_unlock_irqrestore(&pInfo->lock, flags);
+
+       kfree(pHeader);
+       TRACE_M("remove_from_rx_queue - kfree %p", pHeader);
+
+       TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
+               pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue);
+}
+
+static void put_char(struct r3964_info *pInfo, unsigned char ch)
+{
+       struct tty_struct *tty = pInfo->tty;
+       /* FIXME: put_char should not be called from an IRQ */
+       tty_put_char(tty, ch);
+       pInfo->bcc ^= ch;
+}
+
+static void flush(struct r3964_info *pInfo)
+{
+       struct tty_struct *tty = pInfo->tty;
+
+       if (tty == NULL || tty->ops->flush_chars == NULL)
+               return;
+       tty->ops->flush_chars(tty);
+}
+
+static void trigger_transmit(struct r3964_info *pInfo)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pInfo->lock, flags);
+
+       if ((pInfo->state == R3964_IDLE) && (pInfo->tx_first != NULL)) {
+               pInfo->state = R3964_TX_REQUEST;
+               pInfo->nRetry = 0;
+               pInfo->flags &= ~R3964_ERROR;
+               mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+
+               spin_unlock_irqrestore(&pInfo->lock, flags);
+
+               TRACE_PS("trigger_transmit - sent STX");
+
+               put_char(pInfo, STX);
+               flush(pInfo);
+
+               pInfo->bcc = 0;
+       } else {
+               spin_unlock_irqrestore(&pInfo->lock, flags);
+       }
+}
+
+static void retry_transmit(struct r3964_info *pInfo)
+{
+       if (pInfo->nRetry < R3964_MAX_RETRIES) {
+               TRACE_PE("transmission failed. Retry #%d", pInfo->nRetry);
+               pInfo->bcc = 0;
+               put_char(pInfo, STX);
+               flush(pInfo);
+               pInfo->state = R3964_TX_REQUEST;
+               pInfo->nRetry++;
+               mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+       } else {
+               TRACE_PE("transmission failed after %d retries",
+                        R3964_MAX_RETRIES);
+
+               remove_from_tx_queue(pInfo, R3964_TX_FAIL);
+
+               put_char(pInfo, NAK);
+               flush(pInfo);
+               pInfo->state = R3964_IDLE;
+
+               trigger_transmit(pInfo);
+       }
+}
+
+static void transmit_block(struct r3964_info *pInfo)
+{
+       struct tty_struct *tty = pInfo->tty;
+       struct r3964_block_header *pBlock = pInfo->tx_first;
+       int room = 0;
+
+       if (tty == NULL || pBlock == NULL) {
+               return;
+       }
+
+       room = tty_write_room(tty);
+
+       TRACE_PS("transmit_block %p, room %d, length %d",
+                pBlock, room, pBlock->length);
+
+       while (pInfo->tx_position < pBlock->length) {
+               if (room < 2)
+                       break;
+
+               if (pBlock->data[pInfo->tx_position] == DLE) {
+                       /* send additional DLE char: */
+                       put_char(pInfo, DLE);
+               }
+               put_char(pInfo, pBlock->data[pInfo->tx_position++]);
+
+               room--;
+       }
+
+       if ((pInfo->tx_position == pBlock->length) && (room >= 3)) {
+               put_char(pInfo, DLE);
+               put_char(pInfo, ETX);
+               if (pInfo->flags & R3964_BCC) {
+                       put_char(pInfo, pInfo->bcc);
+               }
+               pInfo->state = R3964_WAIT_FOR_TX_ACK;
+               mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+       }
+       flush(pInfo);
+}
+
+static void on_receive_block(struct r3964_info *pInfo)
+{
+       unsigned int length;
+       struct r3964_client_info *pClient;
+       struct r3964_block_header *pBlock;
+
+       length = pInfo->rx_position;
+
+       /* compare byte checksum characters: */
+       if (pInfo->flags & R3964_BCC) {
+               if (pInfo->bcc != pInfo->last_rx) {
+                       TRACE_PE("checksum error - got %x but expected %x",
+                                pInfo->last_rx, pInfo->bcc);
+                       pInfo->flags |= R3964_CHECKSUM;
+               }
+       }
+
+       /* check for errors (parity, overrun,...): */
+       if (pInfo->flags & R3964_ERROR) {
+               TRACE_PE("on_receive_block - transmission failed error %x",
+                        pInfo->flags & R3964_ERROR);
+
+               put_char(pInfo, NAK);
+               flush(pInfo);
+               if (pInfo->nRetry < R3964_MAX_RETRIES) {
+                       pInfo->state = R3964_WAIT_FOR_RX_REPEAT;
+                       pInfo->nRetry++;
+                       mod_timer(&pInfo->tmr, jiffies + R3964_TO_RX_PANIC);
+               } else {
+                       TRACE_PE("on_receive_block - failed after max retries");
+                       pInfo->state = R3964_IDLE;
+               }
+               return;
+       }
+
+       /* received block; submit DLE: */
+       put_char(pInfo, DLE);
+       flush(pInfo);
+       del_timer_sync(&pInfo->tmr);
+       TRACE_PS(" rx success: got %d chars", length);
+
+       /* prepare struct r3964_block_header: */
+       pBlock = kmalloc(length + sizeof(struct r3964_block_header),
+                       GFP_KERNEL);
+       TRACE_M("on_receive_block - kmalloc %p", pBlock);
+
+       if (pBlock == NULL)
+               return;
+
+       pBlock->length = length;
+       pBlock->data = ((unsigned char *)pBlock) +
+                       sizeof(struct r3964_block_header);
+       pBlock->locks = 0;
+       pBlock->next = NULL;
+       pBlock->owner = NULL;
+
+       memcpy(pBlock->data, pInfo->rx_buf, length);
+
+       /* queue block into rx_queue: */
+       add_rx_queue(pInfo, pBlock);
+
+       /* notify attached client processes: */
+       for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) {
+               if (pClient->sig_flags & R3964_SIG_DATA) {
+                       add_msg(pClient, R3964_MSG_DATA, length, R3964_OK,
+                               pBlock);
+               }
+       }
+       wake_up_interruptible(&pInfo->read_wait);
+
+       pInfo->state = R3964_IDLE;
+
+       trigger_transmit(pInfo);
+}
+
+static void receive_char(struct r3964_info *pInfo, const unsigned char c)
+{
+       switch (pInfo->state) {
+       case R3964_TX_REQUEST:
+               if (c == DLE) {
+                       TRACE_PS("TX_REQUEST - got DLE");
+
+                       pInfo->state = R3964_TRANSMITTING;
+                       pInfo->tx_position = 0;
+
+                       transmit_block(pInfo);
+               } else if (c == STX) {
+                       if (pInfo->nRetry == 0) {
+                               TRACE_PE("TX_REQUEST - init conflict");
+                               if (pInfo->priority == R3964_SLAVE) {
+                                       goto start_receiving;
+                               }
+                       } else {
+                               TRACE_PE("TX_REQUEST - secondary init "
+                                       "conflict!? Switching to SLAVE mode "
+                                       "for next rx.");
+                               goto start_receiving;
+                       }
+               } else {
+                       TRACE_PE("TX_REQUEST - char != DLE: %x", c);
+                       retry_transmit(pInfo);
+               }
+               break;
+       case R3964_TRANSMITTING:
+               if (c == NAK) {
+                       TRACE_PE("TRANSMITTING - got NAK");
+                       retry_transmit(pInfo);
+               } else {
+                       TRACE_PE("TRANSMITTING - got invalid char");
+
+                       pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY;
+                       mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
+               }
+               break;
+       case R3964_WAIT_FOR_TX_ACK:
+               if (c == DLE) {
+                       TRACE_PS("WAIT_FOR_TX_ACK - got DLE");
+                       remove_from_tx_queue(pInfo, R3964_OK);
+
+                       pInfo->state = R3964_IDLE;
+                       trigger_transmit(pInfo);
+               } else {
+                       retry_transmit(pInfo);
+               }
+               break;
+       case R3964_WAIT_FOR_RX_REPEAT:
+               /* FALLTHROUGH */
+       case R3964_IDLE:
+               if (c == STX) {
+                       /* Prevent rx_queue from overflow: */
+                       if (pInfo->blocks_in_rx_queue >=
+                           R3964_MAX_BLOCKS_IN_RX_QUEUE) {
+                               TRACE_PE("IDLE - got STX but no space in "
+                                               "rx_queue!");
+                               pInfo->state = R3964_WAIT_FOR_RX_BUF;
+                               mod_timer(&pInfo->tmr,
+                                         jiffies + R3964_TO_NO_BUF);
+                               break;
+                       }
+start_receiving:
+                       /* Ok, start receiving: */
+                       TRACE_PS("IDLE - got STX");
+                       pInfo->rx_position = 0;
+                       pInfo->last_rx = 0;
+                       pInfo->flags &= ~R3964_ERROR;
+                       pInfo->state = R3964_RECEIVING;
+                       mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
+                       pInfo->nRetry = 0;
+                       put_char(pInfo, DLE);
+                       flush(pInfo);
+                       pInfo->bcc = 0;
+               }
+               break;
+       case R3964_RECEIVING:
+               if (pInfo->rx_position < RX_BUF_SIZE) {
+                       pInfo->bcc ^= c;
+
+                       if (c == DLE) {
+                               if (pInfo->last_rx == DLE) {
+                                       pInfo->last_rx = 0;
+                                       goto char_to_buf;
+                               }
+                               pInfo->last_rx = DLE;
+                               break;
+                       } else if ((c == ETX) && (pInfo->last_rx == DLE)) {
+                               if (pInfo->flags & R3964_BCC) {
+                                       pInfo->state = R3964_WAIT_FOR_BCC;
+                                       mod_timer(&pInfo->tmr,
+                                                 jiffies + R3964_TO_ZVZ);
+                               } else {
+                                       on_receive_block(pInfo);
+                               }
+                       } else {
+                               pInfo->last_rx = c;
+char_to_buf:
+                               pInfo->rx_buf[pInfo->rx_position++] = c;
+                               mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
+                       }
+               }
+               /* else: overflow-msg? BUF_SIZE>MTU; should not happen? */
+               break;
+       case R3964_WAIT_FOR_BCC:
+               pInfo->last_rx = c;
+               on_receive_block(pInfo);
+               break;
+       }
+}
+
+static void receive_error(struct r3964_info *pInfo, const char flag)
+{
+       switch (flag) {
+       case TTY_NORMAL:
+               break;
+       case TTY_BREAK:
+               TRACE_PE("received break");
+               pInfo->flags |= R3964_BREAK;
+               break;
+       case TTY_PARITY:
+               TRACE_PE("parity error");
+               pInfo->flags |= R3964_PARITY;
+               break;
+       case TTY_FRAME:
+               TRACE_PE("frame error");
+               pInfo->flags |= R3964_FRAME;
+               break;
+       case TTY_OVERRUN:
+               TRACE_PE("frame overrun");
+               pInfo->flags |= R3964_OVERRUN;
+               break;
+       default:
+               TRACE_PE("receive_error - unknown flag %d", flag);
+               pInfo->flags |= R3964_UNKNOWN;
+               break;
+       }
+}
+
+static void on_timeout(unsigned long priv)
+{
+       struct r3964_info *pInfo = (void *)priv;
+
+       switch (pInfo->state) {
+       case R3964_TX_REQUEST:
+               TRACE_PE("TX_REQUEST - timeout");
+               retry_transmit(pInfo);
+               break;
+       case R3964_WAIT_ZVZ_BEFORE_TX_RETRY:
+               put_char(pInfo, NAK);
+               flush(pInfo);
+               retry_transmit(pInfo);
+               break;
+       case R3964_WAIT_FOR_TX_ACK:
+               TRACE_PE("WAIT_FOR_TX_ACK - timeout");
+               retry_transmit(pInfo);
+               break;
+       case R3964_WAIT_FOR_RX_BUF:
+               TRACE_PE("WAIT_FOR_RX_BUF - timeout");
+               put_char(pInfo, NAK);
+               flush(pInfo);
+               pInfo->state = R3964_IDLE;
+               break;
+       case R3964_RECEIVING:
+               TRACE_PE("RECEIVING - timeout after %d chars",
+                        pInfo->rx_position);
+               put_char(pInfo, NAK);
+               flush(pInfo);
+               pInfo->state = R3964_IDLE;
+               break;
+       case R3964_WAIT_FOR_RX_REPEAT:
+               TRACE_PE("WAIT_FOR_RX_REPEAT - timeout");
+               pInfo->state = R3964_IDLE;
+               break;
+       case R3964_WAIT_FOR_BCC:
+               TRACE_PE("WAIT_FOR_BCC - timeout");
+               put_char(pInfo, NAK);
+               flush(pInfo);
+               pInfo->state = R3964_IDLE;
+               break;
+       }
+}
+
+static struct r3964_client_info *findClient(struct r3964_info *pInfo,
+               struct pid *pid)
+{
+       struct r3964_client_info *pClient;
+
+       for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) {
+               if (pClient->pid == pid) {
+                       return pClient;
+               }
+       }
+       return NULL;
+}
+
+static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg)
+{
+       struct r3964_client_info *pClient;
+       struct r3964_client_info **ppClient;
+       struct r3964_message *pMsg;
+
+       if ((arg & R3964_SIG_ALL) == 0) {
+               /* Remove client from client list */
+               for (ppClient = &pInfo->firstClient; *ppClient;
+                    ppClient = &(*ppClient)->next) {
+                       pClient = *ppClient;
+
+                       if (pClient->pid == pid) {
+                               TRACE_PS("removing client %d from client list",
+                                        pid_nr(pid));
+                               *ppClient = pClient->next;
+                               while (pClient->msg_count) {
+                                       pMsg = remove_msg(pInfo, pClient);
+                                       if (pMsg) {
+                                               kfree(pMsg);
+                                               TRACE_M("enable_signals - msg "
+                                                       "kfree %p", pMsg);
+                                       }
+                               }
+                               put_pid(pClient->pid);
+                               kfree(pClient);
+                               TRACE_M("enable_signals - kfree %p", pClient);
+                               return 0;
+                       }
+               }
+               return -EINVAL;
+       } else {
+               pClient = findClient(pInfo, pid);
+               if (pClient) {
+                       /* update signal options */
+                       pClient->sig_flags = arg;
+               } else {
+                       /* add client to client list */
+                       pClient = kmalloc(sizeof(struct r3964_client_info),
+                                       GFP_KERNEL);
+                       TRACE_M("enable_signals - kmalloc %p", pClient);
+                       if (pClient == NULL)
+                               return -ENOMEM;
+
+                       TRACE_PS("add client %d to client list", pid_nr(pid));
+                       spin_lock_init(&pClient->lock);
+                       pClient->sig_flags = arg;
+                       pClient->pid = get_pid(pid);
+                       pClient->next = pInfo->firstClient;
+                       pClient->first_msg = NULL;
+                       pClient->last_msg = NULL;
+                       pClient->next_block_to_read = NULL;
+                       pClient->msg_count = 0;
+                       pInfo->firstClient = pClient;
+               }
+       }
+
+       return 0;
+}
+
+static int read_telegram(struct r3964_info *pInfo, struct pid *pid,
+                        unsigned char __user * buf)
+{
+       struct r3964_client_info *pClient;
+       struct r3964_block_header *block;
+
+       if (!buf) {
+               return -EINVAL;
+       }
+
+       pClient = findClient(pInfo, pid);
+       if (pClient == NULL) {
+               return -EINVAL;
+       }
+
+       block = pClient->next_block_to_read;
+       if (!block) {
+               return 0;
+       } else {
+               if (copy_to_user(buf, block->data, block->length))
+                       return -EFAULT;
+
+               remove_client_block(pInfo, pClient);
+               return block->length;
+       }
+
+       return -EINVAL;
+}
+
+static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
+               int error_code, struct r3964_block_header *pBlock)
+{
+       struct r3964_message *pMsg;
+       unsigned long flags;
+
+       if (pClient->msg_count < R3964_MAX_MSG_COUNT - 1) {
+queue_the_message:
+
+               pMsg = kmalloc(sizeof(struct r3964_message),
+                               error_code ? GFP_ATOMIC : GFP_KERNEL);
+               TRACE_M("add_msg - kmalloc %p", pMsg);
+               if (pMsg == NULL) {
+                       return;
+               }
+
+               spin_lock_irqsave(&pClient->lock, flags);
+
+               pMsg->msg_id = msg_id;
+               pMsg->arg = arg;
+               pMsg->error_code = error_code;
+               pMsg->block = pBlock;
+               pMsg->next = NULL;
+
+               if (pClient->last_msg == NULL) {
+                       pClient->first_msg = pClient->last_msg = pMsg;
+               } else {
+                       pClient->last_msg->next = pMsg;
+                       pClient->last_msg = pMsg;
+               }
+
+               pClient->msg_count++;
+
+               if (pBlock != NULL) {
+                       pBlock->locks++;
+               }
+               spin_unlock_irqrestore(&pClient->lock, flags);
+       } else {
+               if ((pClient->last_msg->msg_id == R3964_MSG_ACK)
+                   && (pClient->last_msg->error_code == R3964_OVERFLOW)) {
+                       pClient->last_msg->arg++;
+                       TRACE_PE("add_msg - inc prev OVERFLOW-msg");
+               } else {
+                       msg_id = R3964_MSG_ACK;
+                       arg = 0;
+                       error_code = R3964_OVERFLOW;
+                       pBlock = NULL;
+                       TRACE_PE("add_msg - queue OVERFLOW-msg");
+                       goto queue_the_message;
+               }
+       }
+       /* Send SIGIO signal to client process: */
+       if (pClient->sig_flags & R3964_USE_SIGIO) {
+               kill_pid(pClient->pid, SIGIO, 1);
+       }
+}
+
+static struct r3964_message *remove_msg(struct r3964_info *pInfo,
+                                       struct r3964_client_info *pClient)
+{
+       struct r3964_message *pMsg = NULL;
+       unsigned long flags;
+
+       if (pClient->first_msg) {
+               spin_lock_irqsave(&pClient->lock, flags);
+
+               pMsg = pClient->first_msg;
+               pClient->first_msg = pMsg->next;
+               if (pClient->first_msg == NULL) {
+                       pClient->last_msg = NULL;
+               }
+
+               pClient->msg_count--;
+               if (pMsg->block) {
+                       remove_client_block(pInfo, pClient);
+                       pClient->next_block_to_read = pMsg->block;
+               }
+               spin_unlock_irqrestore(&pClient->lock, flags);
+       }
+       return pMsg;
+}
+
+static void remove_client_block(struct r3964_info *pInfo,
+                               struct r3964_client_info *pClient)
+{
+       struct r3964_block_header *block;
+
+       TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid));
+
+       block = pClient->next_block_to_read;
+       if (block) {
+               block->locks--;
+               if (block->locks == 0) {
+                       remove_from_rx_queue(pInfo, block);
+               }
+       }
+       pClient->next_block_to_read = NULL;
+}
+
+/*************************************************************
+ * Line discipline routines
+ *************************************************************/
+
+static int r3964_open(struct tty_struct *tty)
+{
+       struct r3964_info *pInfo;
+
+       TRACE_L("open");
+       TRACE_L("tty=%p, PID=%d, disc_data=%p",
+               tty, current->pid, tty->disc_data);
+
+       pInfo = kmalloc(sizeof(struct r3964_info), GFP_KERNEL);
+       TRACE_M("r3964_open - info kmalloc %p", pInfo);
+
+       if (!pInfo) {
+               printk(KERN_ERR "r3964: failed to alloc info structure\n");
+               return -ENOMEM;
+       }
+
+       pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
+       TRACE_M("r3964_open - rx_buf kmalloc %p", pInfo->rx_buf);
+
+       if (!pInfo->rx_buf) {
+               printk(KERN_ERR "r3964: failed to alloc receive buffer\n");
+               kfree(pInfo);
+               TRACE_M("r3964_open - info kfree %p", pInfo);
+               return -ENOMEM;
+       }
+
+       pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL);
+       TRACE_M("r3964_open - tx_buf kmalloc %p", pInfo->tx_buf);
+
+       if (!pInfo->tx_buf) {
+               printk(KERN_ERR "r3964: failed to alloc transmit buffer\n");
+               kfree(pInfo->rx_buf);
+               TRACE_M("r3964_open - rx_buf kfree %p", pInfo->rx_buf);
+               kfree(pInfo);
+               TRACE_M("r3964_open - info kfree %p", pInfo);
+               return -ENOMEM;
+       }
+
+       spin_lock_init(&pInfo->lock);
+       pInfo->tty = tty;
+       init_waitqueue_head(&pInfo->read_wait);
+       pInfo->priority = R3964_MASTER;
+       pInfo->rx_first = pInfo->rx_last = NULL;
+       pInfo->tx_first = pInfo->tx_last = NULL;
+       pInfo->rx_position = 0;
+       pInfo->tx_position = 0;
+       pInfo->last_rx = 0;
+       pInfo->blocks_in_rx_queue = 0;
+       pInfo->firstClient = NULL;
+       pInfo->state = R3964_IDLE;
+       pInfo->flags = R3964_DEBUG;
+       pInfo->nRetry = 0;
+
+       tty->disc_data = pInfo;
+       tty->receive_room = 65536;
+
+       setup_timer(&pInfo->tmr, on_timeout, (unsigned long)pInfo);
+
+       return 0;
+}
+
+static void r3964_close(struct tty_struct *tty)
+{
+       struct r3964_info *pInfo = tty->disc_data;
+       struct r3964_client_info *pClient, *pNext;
+       struct r3964_message *pMsg;
+       struct r3964_block_header *pHeader, *pNextHeader;
+       unsigned long flags;
+
+       TRACE_L("close");
+
+       /*
+        * Make sure that our task queue isn't activated.  If it
+        * is, take it out of the linked list.
+        */
+       del_timer_sync(&pInfo->tmr);
+
+       /* Remove client-structs and message queues: */
+       pClient = pInfo->firstClient;
+       while (pClient) {
+               pNext = pClient->next;
+               while (pClient->msg_count) {
+                       pMsg = remove_msg(pInfo, pClient);
+                       if (pMsg) {
+                               kfree(pMsg);
+                               TRACE_M("r3964_close - msg kfree %p", pMsg);
+                       }
+               }
+               put_pid(pClient->pid);
+               kfree(pClient);
+               TRACE_M("r3964_close - client kfree %p", pClient);
+               pClient = pNext;
+       }
+       /* Remove jobs from tx_queue: */
+       spin_lock_irqsave(&pInfo->lock, flags);
+       pHeader = pInfo->tx_first;
+       pInfo->tx_first = pInfo->tx_last = NULL;
+       spin_unlock_irqrestore(&pInfo->lock, flags);
+
+       while (pHeader) {
+               pNextHeader = pHeader->next;
+               kfree(pHeader);
+               pHeader = pNextHeader;
+       }
+
+       /* Free buffers: */
+       wake_up_interruptible(&pInfo->read_wait);
+       kfree(pInfo->rx_buf);
+       TRACE_M("r3964_close - rx_buf kfree %p", pInfo->rx_buf);
+       kfree(pInfo->tx_buf);
+       TRACE_M("r3964_close - tx_buf kfree %p", pInfo->tx_buf);
+       kfree(pInfo);
+       TRACE_M("r3964_close - info kfree %p", pInfo);
+}
+
+static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
+                         unsigned char __user * buf, size_t nr)
+{
+       struct r3964_info *pInfo = tty->disc_data;
+       struct r3964_client_info *pClient;
+       struct r3964_message *pMsg;
+       struct r3964_client_message theMsg;
+       int ret;
+
+       TRACE_L("read()");
+
+       tty_lock();
+
+       pClient = findClient(pInfo, task_pid(current));
+       if (pClient) {
+               pMsg = remove_msg(pInfo, pClient);
+               if (pMsg == NULL) {
+                       /* no messages available. */
+                       if (file->f_flags & O_NONBLOCK) {
+                               ret = -EAGAIN;
+                               goto unlock;
+                       }
+                       /* block until there is a message: */
+                       wait_event_interruptible_tty(pInfo->read_wait,
+                                       (pMsg = remove_msg(pInfo, pClient)));
+               }
+
+               /* If we still haven't got a message, we must have been signalled */
+
+               if (!pMsg) {
+                       ret = -EINTR;
+                       goto unlock;
+               }
+
+               /* deliver msg to client process: */
+               theMsg.msg_id = pMsg->msg_id;
+               theMsg.arg = pMsg->arg;
+               theMsg.error_code = pMsg->error_code;
+               ret = sizeof(struct r3964_client_message);
+
+               kfree(pMsg);
+               TRACE_M("r3964_read - msg kfree %p", pMsg);
+
+               if (copy_to_user(buf, &theMsg, ret)) {
+                       ret = -EFAULT;
+                       goto unlock;
+               }
+
+               TRACE_PS("read - return %d", ret);
+               goto unlock;
+       }
+       ret = -EPERM;
+unlock:
+       tty_unlock();
+       return ret;
+}
+
+static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
+                          const unsigned char *data, size_t count)
+{
+       struct r3964_info *pInfo = tty->disc_data;
+       struct r3964_block_header *pHeader;
+       struct r3964_client_info *pClient;
+       unsigned char *new_data;
+
+       TRACE_L("write request, %d characters", count);
+/* 
+ * Verify the pointers 
+ */
+
+       if (!pInfo)
+               return -EIO;
+
+/*
+ * Ensure that the caller does not wish to send too much.
+ */
+       if (count > R3964_MTU) {
+               if (pInfo->flags & R3964_DEBUG) {
+                       TRACE_L(KERN_WARNING "r3964_write: truncating user "
+                               "packet from %u to mtu %d", count, R3964_MTU);
+               }
+               count = R3964_MTU;
+       }
+/*
+ * Allocate a buffer for the data and copy it from the buffer with header prepended
+ */
+       new_data = kmalloc(count + sizeof(struct r3964_block_header),
+                       GFP_KERNEL);
+       TRACE_M("r3964_write - kmalloc %p", new_data);
+       if (new_data == NULL) {
+               if (pInfo->flags & R3964_DEBUG) {
+                       printk(KERN_ERR "r3964_write: no memory\n");
+               }
+               return -ENOSPC;
+       }
+
+       pHeader = (struct r3964_block_header *)new_data;
+       pHeader->data = new_data + sizeof(struct r3964_block_header);
+       pHeader->length = count;
+       pHeader->locks = 0;
+       pHeader->owner = NULL;
+
+       tty_lock();
+
+       pClient = findClient(pInfo, task_pid(current));
+       if (pClient) {
+               pHeader->owner = pClient;
+       }
+
+       memcpy(pHeader->data, data, count);     /* We already verified this */
+
+       if (pInfo->flags & R3964_DEBUG) {
+               dump_block(pHeader->data, count);
+       }
+
+/*
+ * Add buffer to transmit-queue:
+ */
+       add_tx_queue(pInfo, pHeader);
+       trigger_transmit(pInfo);
+
+       tty_unlock();
+
+       return 0;
+}
+
+static int r3964_ioctl(struct tty_struct *tty, struct file *file,
+               unsigned int cmd, unsigned long arg)
+{
+       struct r3964_info *pInfo = tty->disc_data;
+       if (pInfo == NULL)
+               return -EINVAL;
+       switch (cmd) {
+       case R3964_ENABLE_SIGNALS:
+               return enable_signals(pInfo, task_pid(current), arg);
+       case R3964_SETPRIORITY:
+               if (arg < R3964_MASTER || arg > R3964_SLAVE)
+                       return -EINVAL;
+               pInfo->priority = arg & 0xff;
+               return 0;
+       case R3964_USE_BCC:
+               if (arg)
+                       pInfo->flags |= R3964_BCC;
+               else
+                       pInfo->flags &= ~R3964_BCC;
+               return 0;
+       case R3964_READ_TELEGRAM:
+               return read_telegram(pInfo, task_pid(current),
+                               (unsigned char __user *)arg);
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+
+static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old)
+{
+       TRACE_L("set_termios");
+}
+
+/* Called without the kernel lock held - fine */
+static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
+                       struct poll_table_struct *wait)
+{
+       struct r3964_info *pInfo = tty->disc_data;
+       struct r3964_client_info *pClient;
+       struct r3964_message *pMsg = NULL;
+       unsigned long flags;
+       int result = POLLOUT;
+
+       TRACE_L("POLL");
+
+       pClient = findClient(pInfo, task_pid(current));
+       if (pClient) {
+               poll_wait(file, &pInfo->read_wait, wait);
+               spin_lock_irqsave(&pInfo->lock, flags);
+               pMsg = pClient->first_msg;
+               spin_unlock_irqrestore(&pInfo->lock, flags);
+               if (pMsg)
+                       result |= POLLIN | POLLRDNORM;
+       } else {
+               result = -EINVAL;
+       }
+       return result;
+}
+
+static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+                       char *fp, int count)
+{
+       struct r3964_info *pInfo = tty->disc_data;
+       const unsigned char *p;
+       char *f, flags = 0;
+       int i;
+
+       for (i = count, p = cp, f = fp; i; i--, p++) {
+               if (f)
+                       flags = *f++;
+               if (flags == TTY_NORMAL) {
+                       receive_char(pInfo, *p);
+               } else {
+                       receive_error(pInfo, flags);
+               }
+
+       }
+}
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_R3964);
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
new file mode 100644 (file)
index 0000000..428f4fe
--- /dev/null
@@ -0,0 +1,2121 @@
+/*
+ * n_tty.c --- implements the N_TTY line discipline.
+ *
+ * This code used to be in tty_io.c, but things are getting hairy
+ * enough that it made sense to split things off.  (The N_TTY
+ * processing has changed so much that it's hardly recognizable,
+ * anyway...)
+ *
+ * Note that the open routine for N_TTY is guaranteed never to return
+ * an error.  This is because Linux will fall back to setting a line
+ * to N_TTY if it can not switch to any other line discipline.
+ *
+ * Written by Theodore Ts'o, Copyright 1994.
+ *
+ * This file also contains code originally written by Linus Torvalds,
+ * Copyright 1991, 1992, 1993, and by Julian Cowley, Copyright 1994.
+ *
+ * This file may be redistributed under the terms of the GNU General Public
+ * License.
+ *
+ * Reduced memory usage for older ARM systems  - Russell King.
+ *
+ * 2000/01/20   Fixed SMP locking on put_tty_queue using bits of
+ *             the patch by Andrew J. Kroll <ag784@freenet.buffalo.edu>
+ *             who actually finally proved there really was a race.
+ *
+ * 2002/03/18   Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
+ *             waiting writing processes-Sapan Bhatia <sapan@corewars.org>.
+ *             Also fixed a bug in BLOCKING mode where n_tty_write returns
+ *             EAGAIN
+ */
+
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/timer.h>
+#include <linux/ctype.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/bitops.h>
+#include <linux/audit.h>
+#include <linux/file.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+
+#include <asm/system.h>
+
+/* number of characters left in xmit buffer before select has we have room */
+#define WAKEUP_CHARS 256
+
+/*
+ * This defines the low- and high-watermarks for throttling and
+ * unthrottling the TTY driver.  These watermarks are used for
+ * controlling the space in the read buffer.
+ */
+#define TTY_THRESHOLD_THROTTLE         128 /* now based on remaining room */
+#define TTY_THRESHOLD_UNTHROTTLE       128
+
+/*
+ * Special byte codes used in the echo buffer to represent operations
+ * or special handling of characters.  Bytes in the echo buffer that
+ * are not part of such special blocks are treated as normal character
+ * codes.
+ */
+#define ECHO_OP_START 0xff
+#define ECHO_OP_MOVE_BACK_COL 0x80
+#define ECHO_OP_SET_CANON_COL 0x81
+#define ECHO_OP_ERASE_TAB 0x82
+
+static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
+                              unsigned char __user *ptr)
+{
+       tty_audit_add_data(tty, &x, 1);
+       return put_user(x, ptr);
+}
+
+/**
+ *     n_tty_set__room -       receive space
+ *     @tty: terminal
+ *
+ *     Called by the driver to find out how much data it is
+ *     permitted to feed to the line discipline without any being lost
+ *     and thus to manage flow control. Not serialized. Answers for the
+ *     "instant".
+ */
+
+static void n_tty_set_room(struct tty_struct *tty)
+{
+       /* tty->read_cnt is not read locked ? */
+       int     left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
+
+       /*
+        * If we are doing input canonicalization, and there are no
+        * pending newlines, let characters through without limit, so
+        * that erase characters will be handled.  Other excess
+        * characters will be beeped.
+        */
+       if (left <= 0)
+               left = tty->icanon && !tty->canon_data;
+       tty->receive_room = left;
+}
+
+static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
+{
+       if (tty->read_cnt < N_TTY_BUF_SIZE) {
+               tty->read_buf[tty->read_head] = c;
+               tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1);
+               tty->read_cnt++;
+       }
+}
+
+/**
+ *     put_tty_queue           -       add character to tty
+ *     @c: character
+ *     @tty: tty device
+ *
+ *     Add a character to the tty read_buf queue. This is done under the
+ *     read_lock to serialize character addition and also to protect us
+ *     against parallel reads or flushes
+ */
+
+static void put_tty_queue(unsigned char c, struct tty_struct *tty)
+{
+       unsigned long flags;
+       /*
+        *      The problem of stomping on the buffers ends here.
+        *      Why didn't anyone see this one coming? --AJK
+       */
+       spin_lock_irqsave(&tty->read_lock, flags);
+       put_tty_queue_nolock(c, tty);
+       spin_unlock_irqrestore(&tty->read_lock, flags);
+}
+
+/**
+ *     check_unthrottle        -       allow new receive data
+ *     @tty; tty device
+ *
+ *     Check whether to call the driver unthrottle functions
+ *
+ *     Can sleep, may be called under the atomic_read_lock mutex but
+ *     this is not guaranteed.
+ */
+static void check_unthrottle(struct tty_struct *tty)
+{
+       if (tty->count)
+               tty_unthrottle(tty);
+}
+
+/**
+ *     reset_buffer_flags      -       reset buffer state
+ *     @tty: terminal to reset
+ *
+ *     Reset the read buffer counters, clear the flags,
+ *     and make sure the driver is unthrottled. Called
+ *     from n_tty_open() and n_tty_flush_buffer().
+ *
+ *     Locking: tty_read_lock for read fields.
+ */
+
+static void reset_buffer_flags(struct tty_struct *tty)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&tty->read_lock, flags);
+       tty->read_head = tty->read_tail = tty->read_cnt = 0;
+       spin_unlock_irqrestore(&tty->read_lock, flags);
+
+       mutex_lock(&tty->echo_lock);
+       tty->echo_pos = tty->echo_cnt = tty->echo_overrun = 0;
+       mutex_unlock(&tty->echo_lock);
+
+       tty->canon_head = tty->canon_data = tty->erasing = 0;
+       memset(&tty->read_flags, 0, sizeof tty->read_flags);
+       n_tty_set_room(tty);
+       check_unthrottle(tty);
+}
+
+/**
+ *     n_tty_flush_buffer      -       clean input queue
+ *     @tty:   terminal device
+ *
+ *     Flush the input buffer. Called when the line discipline is
+ *     being closed, when the tty layer wants the buffer flushed (eg
+ *     at hangup) or when the N_TTY line discipline internally has to
+ *     clean the pending queue (for example some signals).
+ *
+ *     Locking: ctrl_lock, read_lock.
+ */
+
+static void n_tty_flush_buffer(struct tty_struct *tty)
+{
+       unsigned long flags;
+       /* clear everything and unthrottle the driver */
+       reset_buffer_flags(tty);
+
+       if (!tty->link)
+               return;
+
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+       if (tty->link->packet) {
+               tty->ctrl_status |= TIOCPKT_FLUSHREAD;
+               wake_up_interruptible(&tty->link->read_wait);
+       }
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+}
+
+/**
+ *     n_tty_chars_in_buffer   -       report available bytes
+ *     @tty: tty device
+ *
+ *     Report the number of characters buffered to be delivered to user
+ *     at this instant in time.
+ *
+ *     Locking: read_lock
+ */
+
+static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
+{
+       unsigned long flags;
+       ssize_t n = 0;
+
+       spin_lock_irqsave(&tty->read_lock, flags);
+       if (!tty->icanon) {
+               n = tty->read_cnt;
+       } else if (tty->canon_data) {
+               n = (tty->canon_head > tty->read_tail) ?
+                       tty->canon_head - tty->read_tail :
+                       tty->canon_head + (N_TTY_BUF_SIZE - tty->read_tail);
+       }
+       spin_unlock_irqrestore(&tty->read_lock, flags);
+       return n;
+}
+
+/**
+ *     is_utf8_continuation    -       utf8 multibyte check
+ *     @c: byte to check
+ *
+ *     Returns true if the utf8 character 'c' is a multibyte continuation
+ *     character. We use this to correctly compute the on screen size
+ *     of the character when printing
+ */
+
+static inline int is_utf8_continuation(unsigned char c)
+{
+       return (c & 0xc0) == 0x80;
+}
+
+/**
+ *     is_continuation         -       multibyte check
+ *     @c: byte to check
+ *
+ *     Returns true if the utf8 character 'c' is a multibyte continuation
+ *     character and the terminal is in unicode mode.
+ */
+
+static inline int is_continuation(unsigned char c, struct tty_struct *tty)
+{
+       return I_IUTF8(tty) && is_utf8_continuation(c);
+}
+
+/**
+ *     do_output_char                  -       output one character
+ *     @c: character (or partial unicode symbol)
+ *     @tty: terminal device
+ *     @space: space available in tty driver write buffer
+ *
+ *     This is a helper function that handles one output character
+ *     (including special characters like TAB, CR, LF, etc.),
+ *     doing OPOST processing and putting the results in the
+ *     tty driver's write buffer.
+ *
+ *     Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY
+ *     and NLDLY.  They simply aren't relevant in the world today.
+ *     If you ever need them, add them here.
+ *
+ *     Returns the number of bytes of buffer space used or -1 if
+ *     no space left.
+ *
+ *     Locking: should be called under the output_lock to protect
+ *              the column state and space left in the buffer
+ */
+
+static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
+{
+       int     spaces;
+
+       if (!space)
+               return -1;
+
+       switch (c) {
+       case '\n':
+               if (O_ONLRET(tty))
+                       tty->column = 0;
+               if (O_ONLCR(tty)) {
+                       if (space < 2)
+                               return -1;
+                       tty->canon_column = tty->column = 0;
+                       tty->ops->write(tty, "\r\n", 2);
+                       return 2;
+               }
+               tty->canon_column = tty->column;
+               break;
+       case '\r':
+               if (O_ONOCR(tty) && tty->column == 0)
+                       return 0;
+               if (O_OCRNL(tty)) {
+                       c = '\n';
+                       if (O_ONLRET(tty))
+                               tty->canon_column = tty->column = 0;
+                       break;
+               }
+               tty->canon_column = tty->column = 0;
+               break;
+       case '\t':
+               spaces = 8 - (tty->column & 7);
+               if (O_TABDLY(tty) == XTABS) {
+                       if (space < spaces)
+                               return -1;
+                       tty->column += spaces;
+                       tty->ops->write(tty, "        ", spaces);
+                       return spaces;
+               }
+               tty->column += spaces;
+               break;
+       case '\b':
+               if (tty->column > 0)
+                       tty->column--;
+               break;
+       default:
+               if (!iscntrl(c)) {
+                       if (O_OLCUC(tty))
+                               c = toupper(c);
+                       if (!is_continuation(c, tty))
+                               tty->column++;
+               }
+               break;
+       }
+
+       tty_put_char(tty, c);
+       return 1;
+}
+
+/**
+ *     process_output                  -       output post processor
+ *     @c: character (or partial unicode symbol)
+ *     @tty: terminal device
+ *
+ *     Output one character with OPOST processing.
+ *     Returns -1 when the output device is full and the character
+ *     must be retried.
+ *
+ *     Locking: output_lock to protect column state and space left
+ *              (also, this is called from n_tty_write under the
+ *               tty layer write lock)
+ */
+
+static int process_output(unsigned char c, struct tty_struct *tty)
+{
+       int     space, retval;
+
+       mutex_lock(&tty->output_lock);
+
+       space = tty_write_room(tty);
+       retval = do_output_char(c, tty, space);
+
+       mutex_unlock(&tty->output_lock);
+       if (retval < 0)
+               return -1;
+       else
+               return 0;
+}
+
+/**
+ *     process_output_block            -       block post processor
+ *     @tty: terminal device
+ *     @buf: character buffer
+ *     @nr: number of bytes to output
+ *
+ *     Output a block of characters with OPOST processing.
+ *     Returns the number of characters output.
+ *
+ *     This path is used to speed up block console writes, among other
+ *     things when processing blocks of output data. It handles only
+ *     the simple cases normally found and helps to generate blocks of
+ *     symbols for the console driver and thus improve performance.
+ *
+ *     Locking: output_lock to protect column state and space left
+ *              (also, this is called from n_tty_write under the
+ *               tty layer write lock)
+ */
+
+static ssize_t process_output_block(struct tty_struct *tty,
+                                   const unsigned char *buf, unsigned int nr)
+{
+       int     space;
+       int     i;
+       const unsigned char *cp;
+
+       mutex_lock(&tty->output_lock);
+
+       space = tty_write_room(tty);
+       if (!space) {
+               mutex_unlock(&tty->output_lock);
+               return 0;
+       }
+       if (nr > space)
+               nr = space;
+
+       for (i = 0, cp = buf; i < nr; i++, cp++) {
+               unsigned char c = *cp;
+
+               switch (c) {
+               case '\n':
+                       if (O_ONLRET(tty))
+                               tty->column = 0;
+                       if (O_ONLCR(tty))
+                               goto break_out;
+                       tty->canon_column = tty->column;
+                       break;
+               case '\r':
+                       if (O_ONOCR(tty) && tty->column == 0)
+                               goto break_out;
+                       if (O_OCRNL(tty))
+                               goto break_out;
+                       tty->canon_column = tty->column = 0;
+                       break;
+               case '\t':
+                       goto break_out;
+               case '\b':
+                       if (tty->column > 0)
+                               tty->column--;
+                       break;
+               default:
+                       if (!iscntrl(c)) {
+                               if (O_OLCUC(tty))
+                                       goto break_out;
+                               if (!is_continuation(c, tty))
+                                       tty->column++;
+                       }
+                       break;
+               }
+       }
+break_out:
+       i = tty->ops->write(tty, buf, i);
+
+       mutex_unlock(&tty->output_lock);
+       return i;
+}
+
+/**
+ *     process_echoes  -       write pending echo characters
+ *     @tty: terminal device
+ *
+ *     Write previously buffered echo (and other ldisc-generated)
+ *     characters to the tty.
+ *
+ *     Characters generated by the ldisc (including echoes) need to
+ *     be buffered because the driver's write buffer can fill during
+ *     heavy program output.  Echoing straight to the driver will
+ *     often fail under these conditions, causing lost characters and
+ *     resulting mismatches of ldisc state information.
+ *
+ *     Since the ldisc state must represent the characters actually sent
+ *     to the driver at the time of the write, operations like certain
+ *     changes in column state are also saved in the buffer and executed
+ *     here.
+ *
+ *     A circular fifo buffer is used so that the most recent characters
+ *     are prioritized.  Also, when control characters are echoed with a
+ *     prefixed "^", the pair is treated atomically and thus not separated.
+ *
+ *     Locking: output_lock to protect column state and space left,
+ *              echo_lock to protect the echo buffer
+ */
+
+static void process_echoes(struct tty_struct *tty)
+{
+       int     space, nr;
+       unsigned char c;
+       unsigned char *cp, *buf_end;
+
+       if (!tty->echo_cnt)
+               return;
+
+       mutex_lock(&tty->output_lock);
+       mutex_lock(&tty->echo_lock);
+
+       space = tty_write_room(tty);
+
+       buf_end = tty->echo_buf + N_TTY_BUF_SIZE;
+       cp = tty->echo_buf + tty->echo_pos;
+       nr = tty->echo_cnt;
+       while (nr > 0) {
+               c = *cp;
+               if (c == ECHO_OP_START) {
+                       unsigned char op;
+                       unsigned char *opp;
+                       int no_space_left = 0;
+
+                       /*
+                        * If the buffer byte is the start of a multi-byte
+                        * operation, get the next byte, which is either the
+                        * op code or a control character value.
+                        */
+                       opp = cp + 1;
+                       if (opp == buf_end)
+                               opp -= N_TTY_BUF_SIZE;
+                       op = *opp;
+
+                       switch (op) {
+                               unsigned int num_chars, num_bs;
+
+                       case ECHO_OP_ERASE_TAB:
+                               if (++opp == buf_end)
+                                       opp -= N_TTY_BUF_SIZE;
+                               num_chars = *opp;
+
+                               /*
+                                * Determine how many columns to go back
+                                * in order to erase the tab.
+                                * This depends on the number of columns
+                                * used by other characters within the tab
+                                * area.  If this (modulo 8) count is from
+                                * the start of input rather than from a
+                                * previous tab, we offset by canon column.
+                                * Otherwise, tab spacing is normal.
+                                */
+                               if (!(num_chars & 0x80))
+                                       num_chars += tty->canon_column;
+                               num_bs = 8 - (num_chars & 7);
+
+                               if (num_bs > space) {
+                                       no_space_left = 1;
+                                       break;
+                               }
+                               space -= num_bs;
+                               while (num_bs--) {
+                                       tty_put_char(tty, '\b');
+                                       if (tty->column > 0)
+                                               tty->column--;
+                               }
+                               cp += 3;
+                               nr -= 3;
+                               break;
+
+                       case ECHO_OP_SET_CANON_COL:
+                               tty->canon_column = tty->column;
+                               cp += 2;
+                               nr -= 2;
+                               break;
+
+                       case ECHO_OP_MOVE_BACK_COL:
+                               if (tty->column > 0)
+                                       tty->column--;
+                               cp += 2;
+                               nr -= 2;
+                               break;
+
+                       case ECHO_OP_START:
+                               /* This is an escaped echo op start code */
+                               if (!space) {
+                                       no_space_left = 1;
+                                       break;
+                               }
+                               tty_put_char(tty, ECHO_OP_START);
+                               tty->column++;
+                               space--;
+                               cp += 2;
+                               nr -= 2;
+                               break;
+
+                       default:
+                               /*
+                                * If the op is not a special byte code,
+                                * it is a ctrl char tagged to be echoed
+                                * as "^X" (where X is the letter
+                                * representing the control char).
+                                * Note that we must ensure there is
+                                * enough space for the whole ctrl pair.
+                                *
+                                */
+                               if (space < 2) {
+                                       no_space_left = 1;
+                                       break;
+                               }
+                               tty_put_char(tty, '^');
+                               tty_put_char(tty, op ^ 0100);
+                               tty->column += 2;
+                               space -= 2;
+                               cp += 2;
+                               nr -= 2;
+                       }
+
+                       if (no_space_left)
+                               break;
+               } else {
+                       if (O_OPOST(tty) &&
+                           !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
+                               int retval = do_output_char(c, tty, space);
+                               if (retval < 0)
+                                       break;
+                               space -= retval;
+                       } else {
+                               if (!space)
+                                       break;
+                               tty_put_char(tty, c);
+                               space -= 1;
+                       }
+                       cp += 1;
+                       nr -= 1;
+               }
+
+               /* When end of circular buffer reached, wrap around */
+               if (cp >= buf_end)
+                       cp -= N_TTY_BUF_SIZE;
+       }
+
+       if (nr == 0) {
+               tty->echo_pos = 0;
+               tty->echo_cnt = 0;
+               tty->echo_overrun = 0;
+       } else {
+               int num_processed = tty->echo_cnt - nr;
+               tty->echo_pos += num_processed;
+               tty->echo_pos &= N_TTY_BUF_SIZE - 1;
+               tty->echo_cnt = nr;
+               if (num_processed > 0)
+                       tty->echo_overrun = 0;
+       }
+
+       mutex_unlock(&tty->echo_lock);
+       mutex_unlock(&tty->output_lock);
+
+       if (tty->ops->flush_chars)
+               tty->ops->flush_chars(tty);
+}
+
+/**
+ *     add_echo_byte   -       add a byte to the echo buffer
+ *     @c: unicode byte to echo
+ *     @tty: terminal device
+ *
+ *     Add a character or operation byte to the echo buffer.
+ *
+ *     Should be called under the echo lock to protect the echo buffer.
+ */
+
+static void add_echo_byte(unsigned char c, struct tty_struct *tty)
+{
+       int     new_byte_pos;
+
+       if (tty->echo_cnt == N_TTY_BUF_SIZE) {
+               /* Circular buffer is already at capacity */
+               new_byte_pos = tty->echo_pos;
+
+               /*
+                * Since the buffer start position needs to be advanced,
+                * be sure to step by a whole operation byte group.
+                */
+               if (tty->echo_buf[tty->echo_pos] == ECHO_OP_START) {
+                       if (tty->echo_buf[(tty->echo_pos + 1) &
+                                         (N_TTY_BUF_SIZE - 1)] ==
+                                               ECHO_OP_ERASE_TAB) {
+                               tty->echo_pos += 3;
+                               tty->echo_cnt -= 2;
+                       } else {
+                               tty->echo_pos += 2;
+                               tty->echo_cnt -= 1;
+                       }
+               } else {
+                       tty->echo_pos++;
+               }
+               tty->echo_pos &= N_TTY_BUF_SIZE - 1;
+
+               tty->echo_overrun = 1;
+       } else {
+               new_byte_pos = tty->echo_pos + tty->echo_cnt;
+               new_byte_pos &= N_TTY_BUF_SIZE - 1;
+               tty->echo_cnt++;
+       }
+
+       tty->echo_buf[new_byte_pos] = c;
+}
+
+/**
+ *     echo_move_back_col      -       add operation to move back a column
+ *     @tty: terminal device
+ *
+ *     Add an operation to the echo buffer to move back one column.
+ *
+ *     Locking: echo_lock to protect the echo buffer
+ */
+
+static void echo_move_back_col(struct tty_struct *tty)
+{
+       mutex_lock(&tty->echo_lock);
+
+       add_echo_byte(ECHO_OP_START, tty);
+       add_echo_byte(ECHO_OP_MOVE_BACK_COL, tty);
+
+       mutex_unlock(&tty->echo_lock);
+}
+
+/**
+ *     echo_set_canon_col      -       add operation to set the canon column
+ *     @tty: terminal device
+ *
+ *     Add an operation to the echo buffer to set the canon column
+ *     to the current column.
+ *
+ *     Locking: echo_lock to protect the echo buffer
+ */
+
+static void echo_set_canon_col(struct tty_struct *tty)
+{
+       mutex_lock(&tty->echo_lock);
+
+       add_echo_byte(ECHO_OP_START, tty);
+       add_echo_byte(ECHO_OP_SET_CANON_COL, tty);
+
+       mutex_unlock(&tty->echo_lock);
+}
+
+/**
+ *     echo_erase_tab  -       add operation to erase a tab
+ *     @num_chars: number of character columns already used
+ *     @after_tab: true if num_chars starts after a previous tab
+ *     @tty: terminal device
+ *
+ *     Add an operation to the echo buffer to erase a tab.
+ *
+ *     Called by the eraser function, which knows how many character
+ *     columns have been used since either a previous tab or the start
+ *     of input.  This information will be used later, along with
+ *     canon column (if applicable), to go back the correct number
+ *     of columns.
+ *
+ *     Locking: echo_lock to protect the echo buffer
+ */
+
+static void echo_erase_tab(unsigned int num_chars, int after_tab,
+                          struct tty_struct *tty)
+{
+       mutex_lock(&tty->echo_lock);
+
+       add_echo_byte(ECHO_OP_START, tty);
+       add_echo_byte(ECHO_OP_ERASE_TAB, tty);
+
+       /* We only need to know this modulo 8 (tab spacing) */
+       num_chars &= 7;
+
+       /* Set the high bit as a flag if num_chars is after a previous tab */
+       if (after_tab)
+               num_chars |= 0x80;
+
+       add_echo_byte(num_chars, tty);
+
+       mutex_unlock(&tty->echo_lock);
+}
+
+/**
+ *     echo_char_raw   -       echo a character raw
+ *     @c: unicode byte to echo
+ *     @tty: terminal device
+ *
+ *     Echo user input back onto the screen. This must be called only when
+ *     L_ECHO(tty) is true. Called from the driver receive_buf path.
+ *
+ *     This variant does not treat control characters specially.
+ *
+ *     Locking: echo_lock to protect the echo buffer
+ */
+
+static void echo_char_raw(unsigned char c, struct tty_struct *tty)
+{
+       mutex_lock(&tty->echo_lock);
+
+       if (c == ECHO_OP_START) {
+               add_echo_byte(ECHO_OP_START, tty);
+               add_echo_byte(ECHO_OP_START, tty);
+       } else {
+               add_echo_byte(c, tty);
+       }
+
+       mutex_unlock(&tty->echo_lock);
+}
+
+/**
+ *     echo_char       -       echo a character
+ *     @c: unicode byte to echo
+ *     @tty: terminal device
+ *
+ *     Echo user input back onto the screen. This must be called only when
+ *     L_ECHO(tty) is true. Called from the driver receive_buf path.
+ *
+ *     This variant tags control characters to be echoed as "^X"
+ *     (where X is the letter representing the control char).
+ *
+ *     Locking: echo_lock to protect the echo buffer
+ */
+
+static void echo_char(unsigned char c, struct tty_struct *tty)
+{
+       mutex_lock(&tty->echo_lock);
+
+       if (c == ECHO_OP_START) {
+               add_echo_byte(ECHO_OP_START, tty);
+               add_echo_byte(ECHO_OP_START, tty);
+       } else {
+               if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
+                       add_echo_byte(ECHO_OP_START, tty);
+               add_echo_byte(c, tty);
+       }
+
+       mutex_unlock(&tty->echo_lock);
+}
+
+/**
+ *     finish_erasing          -       complete erase
+ *     @tty: tty doing the erase
+ */
+
+static inline void finish_erasing(struct tty_struct *tty)
+{
+       if (tty->erasing) {
+               echo_char_raw('/', tty);
+               tty->erasing = 0;
+       }
+}
+
+/**
+ *     eraser          -       handle erase function
+ *     @c: character input
+ *     @tty: terminal device
+ *
+ *     Perform erase and necessary output when an erase character is
+ *     present in the stream from the driver layer. Handles the complexities
+ *     of UTF-8 multibyte symbols.
+ *
+ *     Locking: read_lock for tty buffers
+ */
+
+static void eraser(unsigned char c, struct tty_struct *tty)
+{
+       enum { ERASE, WERASE, KILL } kill_type;
+       int head, seen_alnums, cnt;
+       unsigned long flags;
+
+       /* FIXME: locking needed ? */
+       if (tty->read_head == tty->canon_head) {
+               /* process_output('\a', tty); */ /* what do you think? */
+               return;
+       }
+       if (c == ERASE_CHAR(tty))
+               kill_type = ERASE;
+       else if (c == WERASE_CHAR(tty))
+               kill_type = WERASE;
+       else {
+               if (!L_ECHO(tty)) {
+                       spin_lock_irqsave(&tty->read_lock, flags);
+                       tty->read_cnt -= ((tty->read_head - tty->canon_head) &
+                                         (N_TTY_BUF_SIZE - 1));
+                       tty->read_head = tty->canon_head;
+                       spin_unlock_irqrestore(&tty->read_lock, flags);
+                       return;
+               }
+               if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
+                       spin_lock_irqsave(&tty->read_lock, flags);
+                       tty->read_cnt -= ((tty->read_head - tty->canon_head) &
+                                         (N_TTY_BUF_SIZE - 1));
+                       tty->read_head = tty->canon_head;
+                       spin_unlock_irqrestore(&tty->read_lock, flags);
+                       finish_erasing(tty);
+                       echo_char(KILL_CHAR(tty), tty);
+                       /* Add a newline if ECHOK is on and ECHOKE is off. */
+                       if (L_ECHOK(tty))
+                               echo_char_raw('\n', tty);
+                       return;
+               }
+               kill_type = KILL;
+       }
+
+       seen_alnums = 0;
+       /* FIXME: Locking ?? */
+       while (tty->read_head != tty->canon_head) {
+               head = tty->read_head;
+
+               /* erase a single possibly multibyte character */
+               do {
+                       head = (head - 1) & (N_TTY_BUF_SIZE-1);
+                       c = tty->read_buf[head];
+               } while (is_continuation(c, tty) && head != tty->canon_head);
+
+               /* do not partially erase */
+               if (is_continuation(c, tty))
+                       break;
+
+               if (kill_type == WERASE) {
+                       /* Equivalent to BSD's ALTWERASE. */
+                       if (isalnum(c) || c == '_')
+                               seen_alnums++;
+                       else if (seen_alnums)
+                               break;
+               }
+               cnt = (tty->read_head - head) & (N_TTY_BUF_SIZE-1);
+               spin_lock_irqsave(&tty->read_lock, flags);
+               tty->read_head = head;
+               tty->read_cnt -= cnt;
+               spin_unlock_irqrestore(&tty->read_lock, flags);
+               if (L_ECHO(tty)) {
+                       if (L_ECHOPRT(tty)) {
+                               if (!tty->erasing) {
+                                       echo_char_raw('\\', tty);
+                                       tty->erasing = 1;
+                               }
+                               /* if cnt > 1, output a multi-byte character */
+                               echo_char(c, tty);
+                               while (--cnt > 0) {
+                                       head = (head+1) & (N_TTY_BUF_SIZE-1);
+                                       echo_char_raw(tty->read_buf[head], tty);
+                                       echo_move_back_col(tty);
+                               }
+                       } else if (kill_type == ERASE && !L_ECHOE(tty)) {
+                               echo_char(ERASE_CHAR(tty), tty);
+                       } else if (c == '\t') {
+                               unsigned int num_chars = 0;
+                               int after_tab = 0;
+                               unsigned long tail = tty->read_head;
+
+                               /*
+                                * Count the columns used for characters
+                                * since the start of input or after a
+                                * previous tab.
+                                * This info is used to go back the correct
+                                * number of columns.
+                                */
+                               while (tail != tty->canon_head) {
+                                       tail = (tail-1) & (N_TTY_BUF_SIZE-1);
+                                       c = tty->read_buf[tail];
+                                       if (c == '\t') {
+                                               after_tab = 1;
+                                               break;
+                                       } else if (iscntrl(c)) {
+                                               if (L_ECHOCTL(tty))
+                                                       num_chars += 2;
+                                       } else if (!is_continuation(c, tty)) {
+                                               num_chars++;
+                                       }
+                               }
+                               echo_erase_tab(num_chars, after_tab, tty);
+                       } else {
+                               if (iscntrl(c) && L_ECHOCTL(tty)) {
+                                       echo_char_raw('\b', tty);
+                                       echo_char_raw(' ', tty);
+                                       echo_char_raw('\b', tty);
+                               }
+                               if (!iscntrl(c) || L_ECHOCTL(tty)) {
+                                       echo_char_raw('\b', tty);
+                                       echo_char_raw(' ', tty);
+                                       echo_char_raw('\b', tty);
+                               }
+                       }
+               }
+               if (kill_type == ERASE)
+                       break;
+       }
+       if (tty->read_head == tty->canon_head && L_ECHO(tty))
+               finish_erasing(tty);
+}
+
+/**
+ *     isig            -       handle the ISIG optio
+ *     @sig: signal
+ *     @tty: terminal
+ *     @flush: force flush
+ *
+ *     Called when a signal is being sent due to terminal input. This
+ *     may caus terminal flushing to take place according to the termios
+ *     settings and character used. Called from the driver receive_buf
+ *     path so serialized.
+ *
+ *     Locking: ctrl_lock, read_lock (both via flush buffer)
+ */
+
+static inline void isig(int sig, struct tty_struct *tty, int flush)
+{
+       if (tty->pgrp)
+               kill_pgrp(tty->pgrp, sig, 1);
+       if (flush || !L_NOFLSH(tty)) {
+               n_tty_flush_buffer(tty);
+               tty_driver_flush_buffer(tty);
+       }
+}
+
+/**
+ *     n_tty_receive_break     -       handle break
+ *     @tty: terminal
+ *
+ *     An RS232 break event has been hit in the incoming bitstream. This
+ *     can cause a variety of events depending upon the termios settings.
+ *
+ *     Called from the receive_buf path so single threaded.
+ */
+
+static inline void n_tty_receive_break(struct tty_struct *tty)
+{
+       if (I_IGNBRK(tty))
+               return;
+       if (I_BRKINT(tty)) {
+               isig(SIGINT, tty, 1);
+               return;
+       }
+       if (I_PARMRK(tty)) {
+               put_tty_queue('\377', tty);
+               put_tty_queue('\0', tty);
+       }
+       put_tty_queue('\0', tty);
+       wake_up_interruptible(&tty->read_wait);
+}
+
+/**
+ *     n_tty_receive_overrun   -       handle overrun reporting
+ *     @tty: terminal
+ *
+ *     Data arrived faster than we could process it. While the tty
+ *     driver has flagged this the bits that were missed are gone
+ *     forever.
+ *
+ *     Called from the receive_buf path so single threaded. Does not
+ *     need locking as num_overrun and overrun_time are function
+ *     private.
+ */
+
+static inline void n_tty_receive_overrun(struct tty_struct *tty)
+{
+       char buf[64];
+
+       tty->num_overrun++;
+       if (time_before(tty->overrun_time, jiffies - HZ) ||
+                       time_after(tty->overrun_time, jiffies)) {
+               printk(KERN_WARNING "%s: %d input overrun(s)\n",
+                       tty_name(tty, buf),
+                       tty->num_overrun);
+               tty->overrun_time = jiffies;
+               tty->num_overrun = 0;
+       }
+}
+
+/**
+ *     n_tty_receive_parity_error      -       error notifier
+ *     @tty: terminal device
+ *     @c: character
+ *
+ *     Process a parity error and queue the right data to indicate
+ *     the error case if necessary. Locking as per n_tty_receive_buf.
+ */
+static inline void n_tty_receive_parity_error(struct tty_struct *tty,
+                                             unsigned char c)
+{
+       if (I_IGNPAR(tty))
+               return;
+       if (I_PARMRK(tty)) {
+               put_tty_queue('\377', tty);
+               put_tty_queue('\0', tty);
+               put_tty_queue(c, tty);
+       } else  if (I_INPCK(tty))
+               put_tty_queue('\0', tty);
+       else
+               put_tty_queue(c, tty);
+       wake_up_interruptible(&tty->read_wait);
+}
+
+/**
+ *     n_tty_receive_char      -       perform processing
+ *     @tty: terminal device
+ *     @c: character
+ *
+ *     Process an individual character of input received from the driver.
+ *     This is serialized with respect to itself by the rules for the
+ *     driver above.
+ */
+
+static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
+{
+       unsigned long flags;
+       int parmrk;
+
+       if (tty->raw) {
+               put_tty_queue(c, tty);
+               return;
+       }
+
+       if (I_ISTRIP(tty))
+               c &= 0x7f;
+       if (I_IUCLC(tty) && L_IEXTEN(tty))
+               c = tolower(c);
+
+       if (L_EXTPROC(tty)) {
+               put_tty_queue(c, tty);
+               return;
+       }
+
+       if (tty->stopped && !tty->flow_stopped && I_IXON(tty) &&
+           I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) &&
+           c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) {
+               start_tty(tty);
+               process_echoes(tty);
+       }
+
+       if (tty->closing) {
+               if (I_IXON(tty)) {
+                       if (c == START_CHAR(tty)) {
+                               start_tty(tty);
+                               process_echoes(tty);
+                       } else if (c == STOP_CHAR(tty))
+                               stop_tty(tty);
+               }
+               return;
+       }
+
+       /*
+        * If the previous character was LNEXT, or we know that this
+        * character is not one of the characters that we'll have to
+        * handle specially, do shortcut processing to speed things
+        * up.
+        */
+       if (!test_bit(c, tty->process_char_map) || tty->lnext) {
+               tty->lnext = 0;
+               parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
+               if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
+                       /* beep if no space */
+                       if (L_ECHO(tty))
+                               process_output('\a', tty);
+                       return;
+               }
+               if (L_ECHO(tty)) {
+                       finish_erasing(tty);
+                       /* Record the column of first canon char. */
+                       if (tty->canon_head == tty->read_head)
+                               echo_set_canon_col(tty);
+                       echo_char(c, tty);
+                       process_echoes(tty);
+               }
+               if (parmrk)
+                       put_tty_queue(c, tty);
+               put_tty_queue(c, tty);
+               return;
+       }
+
+       if (I_IXON(tty)) {
+               if (c == START_CHAR(tty)) {
+                       start_tty(tty);
+                       process_echoes(tty);
+                       return;
+               }
+               if (c == STOP_CHAR(tty)) {
+                       stop_tty(tty);
+                       return;
+               }
+       }
+
+       if (L_ISIG(tty)) {
+               int signal;
+               signal = SIGINT;
+               if (c == INTR_CHAR(tty))
+                       goto send_signal;
+               signal = SIGQUIT;
+               if (c == QUIT_CHAR(tty))
+                       goto send_signal;
+               signal = SIGTSTP;
+               if (c == SUSP_CHAR(tty)) {
+send_signal:
+                       /*
+                        * Note that we do not use isig() here because we want
+                        * the order to be:
+                        * 1) flush, 2) echo, 3) signal
+                        */
+                       if (!L_NOFLSH(tty)) {
+                               n_tty_flush_buffer(tty);
+                               tty_driver_flush_buffer(tty);
+                       }
+                       if (I_IXON(tty))
+                               start_tty(tty);
+                       if (L_ECHO(tty)) {
+                               echo_char(c, tty);
+                               process_echoes(tty);
+                       }
+                       if (tty->pgrp)
+                               kill_pgrp(tty->pgrp, signal, 1);
+                       return;
+               }
+       }
+
+       if (c == '\r') {
+               if (I_IGNCR(tty))
+                       return;
+               if (I_ICRNL(tty))
+                       c = '\n';
+       } else if (c == '\n' && I_INLCR(tty))
+               c = '\r';
+
+       if (tty->icanon) {
+               if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
+                   (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
+                       eraser(c, tty);
+                       process_echoes(tty);
+                       return;
+               }
+               if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
+                       tty->lnext = 1;
+                       if (L_ECHO(tty)) {
+                               finish_erasing(tty);
+                               if (L_ECHOCTL(tty)) {
+                                       echo_char_raw('^', tty);
+                                       echo_char_raw('\b', tty);
+                                       process_echoes(tty);
+                               }
+                       }
+                       return;
+               }
+               if (c == REPRINT_CHAR(tty) && L_ECHO(tty) &&
+                   L_IEXTEN(tty)) {
+                       unsigned long tail = tty->canon_head;
+
+                       finish_erasing(tty);
+                       echo_char(c, tty);
+                       echo_char_raw('\n', tty);
+                       while (tail != tty->read_head) {
+                               echo_char(tty->read_buf[tail], tty);
+                               tail = (tail+1) & (N_TTY_BUF_SIZE-1);
+                       }
+                       process_echoes(tty);
+                       return;
+               }
+               if (c == '\n') {
+                       if (tty->read_cnt >= N_TTY_BUF_SIZE) {
+                               if (L_ECHO(tty))
+                                       process_output('\a', tty);
+                               return;
+                       }
+                       if (L_ECHO(tty) || L_ECHONL(tty)) {
+                               echo_char_raw('\n', tty);
+                               process_echoes(tty);
+                       }
+                       goto handle_newline;
+               }
+               if (c == EOF_CHAR(tty)) {
+                       if (tty->read_cnt >= N_TTY_BUF_SIZE)
+                               return;
+                       if (tty->canon_head != tty->read_head)
+                               set_bit(TTY_PUSH, &tty->flags);
+                       c = __DISABLED_CHAR;
+                       goto handle_newline;
+               }
+               if ((c == EOL_CHAR(tty)) ||
+                   (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
+                       parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty))
+                                ? 1 : 0;
+                       if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) {
+                               if (L_ECHO(tty))
+                                       process_output('\a', tty);
+                               return;
+                       }
+                       /*
+                        * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
+                        */
+                       if (L_ECHO(tty)) {
+                               /* Record the column of first canon char. */
+                               if (tty->canon_head == tty->read_head)
+                                       echo_set_canon_col(tty);
+                               echo_char(c, tty);
+                               process_echoes(tty);
+                       }
+                       /*
+                        * XXX does PARMRK doubling happen for
+                        * EOL_CHAR and EOL2_CHAR?
+                        */
+                       if (parmrk)
+                               put_tty_queue(c, tty);
+
+handle_newline:
+                       spin_lock_irqsave(&tty->read_lock, flags);
+                       set_bit(tty->read_head, tty->read_flags);
+                       put_tty_queue_nolock(c, tty);
+                       tty->canon_head = tty->read_head;
+                       tty->canon_data++;
+                       spin_unlock_irqrestore(&tty->read_lock, flags);
+                       kill_fasync(&tty->fasync, SIGIO, POLL_IN);
+                       if (waitqueue_active(&tty->read_wait))
+                               wake_up_interruptible(&tty->read_wait);
+                       return;
+               }
+       }
+
+       parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
+       if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
+               /* beep if no space */
+               if (L_ECHO(tty))
+                       process_output('\a', tty);
+               return;
+       }
+       if (L_ECHO(tty)) {
+               finish_erasing(tty);
+               if (c == '\n')
+                       echo_char_raw('\n', tty);
+               else {
+                       /* Record the column of first canon char. */
+                       if (tty->canon_head == tty->read_head)
+                               echo_set_canon_col(tty);
+                       echo_char(c, tty);
+               }
+               process_echoes(tty);
+       }
+
+       if (parmrk)
+               put_tty_queue(c, tty);
+
+       put_tty_queue(c, tty);
+}
+
+
+/**
+ *     n_tty_write_wakeup      -       asynchronous I/O notifier
+ *     @tty: tty device
+ *
+ *     Required for the ptys, serial driver etc. since processes
+ *     that attach themselves to the master and rely on ASYNC
+ *     IO must be woken up
+ */
+
+static void n_tty_write_wakeup(struct tty_struct *tty)
+{
+       if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags))
+               kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
+}
+
+/**
+ *     n_tty_receive_buf       -       data receive
+ *     @tty: terminal device
+ *     @cp: buffer
+ *     @fp: flag buffer
+ *     @count: characters
+ *
+ *     Called by the terminal driver when a block of characters has
+ *     been received. This function must be called from soft contexts
+ *     not from interrupt context. The driver is responsible for making
+ *     calls one at a time and in order (or using flush_to_ldisc)
+ */
+
+static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+                             char *fp, int count)
+{
+       const unsigned char *p;
+       char *f, flags = TTY_NORMAL;
+       int     i;
+       char    buf[64];
+       unsigned long cpuflags;
+
+       if (!tty->read_buf)
+               return;
+
+       if (tty->real_raw) {
+               spin_lock_irqsave(&tty->read_lock, cpuflags);
+               i = min(N_TTY_BUF_SIZE - tty->read_cnt,
+                       N_TTY_BUF_SIZE - tty->read_head);
+               i = min(count, i);
+               memcpy(tty->read_buf + tty->read_head, cp, i);
+               tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
+               tty->read_cnt += i;
+               cp += i;
+               count -= i;
+
+               i = min(N_TTY_BUF_SIZE - tty->read_cnt,
+                       N_TTY_BUF_SIZE - tty->read_head);
+               i = min(count, i);
+               memcpy(tty->read_buf + tty->read_head, cp, i);
+               tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
+               tty->read_cnt += i;
+               spin_unlock_irqrestore(&tty->read_lock, cpuflags);
+       } else {
+               for (i = count, p = cp, f = fp; i; i--, p++) {
+                       if (f)
+                               flags = *f++;
+                       switch (flags) {
+                       case TTY_NORMAL:
+                               n_tty_receive_char(tty, *p);
+                               break;
+                       case TTY_BREAK:
+                               n_tty_receive_break(tty);
+                               break;
+                       case TTY_PARITY:
+                       case TTY_FRAME:
+                               n_tty_receive_parity_error(tty, *p);
+                               break;
+                       case TTY_OVERRUN:
+                               n_tty_receive_overrun(tty);
+                               break;
+                       default:
+                               printk(KERN_ERR "%s: unknown flag %d\n",
+                                      tty_name(tty, buf), flags);
+                               break;
+                       }
+               }
+               if (tty->ops->flush_chars)
+                       tty->ops->flush_chars(tty);
+       }
+
+       n_tty_set_room(tty);
+
+       if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
+               L_EXTPROC(tty)) {
+               kill_fasync(&tty->fasync, SIGIO, POLL_IN);
+               if (waitqueue_active(&tty->read_wait))
+                       wake_up_interruptible(&tty->read_wait);
+       }
+
+       /*
+        * Check the remaining room for the input canonicalization
+        * mode.  We don't want to throttle the driver if we're in
+        * canonical mode and don't have a newline yet!
+        */
+       if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
+               tty_throttle(tty);
+}
+
+int is_ignored(int sig)
+{
+       return (sigismember(&current->blocked, sig) ||
+               current->sighand->action[sig-1].sa.sa_handler == SIG_IGN);
+}
+
+/**
+ *     n_tty_set_termios       -       termios data changed
+ *     @tty: terminal
+ *     @old: previous data
+ *
+ *     Called by the tty layer when the user changes termios flags so
+ *     that the line discipline can plan ahead. This function cannot sleep
+ *     and is protected from re-entry by the tty layer. The user is
+ *     guaranteed that this function will not be re-entered or in progress
+ *     when the ldisc is closed.
+ *
+ *     Locking: Caller holds tty->termios_mutex
+ */
+
+static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
+{
+       int canon_change = 1;
+       BUG_ON(!tty);
+
+       if (old)
+               canon_change = (old->c_lflag ^ tty->termios->c_lflag) & ICANON;
+       if (canon_change) {
+               memset(&tty->read_flags, 0, sizeof tty->read_flags);
+               tty->canon_head = tty->read_tail;
+               tty->canon_data = 0;
+               tty->erasing = 0;
+       }
+
+       if (canon_change && !L_ICANON(tty) && tty->read_cnt)
+               wake_up_interruptible(&tty->read_wait);
+
+       tty->icanon = (L_ICANON(tty) != 0);
+       if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
+               tty->raw = 1;
+               tty->real_raw = 1;
+               n_tty_set_room(tty);
+               return;
+       }
+       if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
+           I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
+           I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
+           I_PARMRK(tty)) {
+               memset(tty->process_char_map, 0, 256/8);
+
+               if (I_IGNCR(tty) || I_ICRNL(tty))
+                       set_bit('\r', tty->process_char_map);
+               if (I_INLCR(tty))
+                       set_bit('\n', tty->process_char_map);
+
+               if (L_ICANON(tty)) {
+                       set_bit(ERASE_CHAR(tty), tty->process_char_map);
+                       set_bit(KILL_CHAR(tty), tty->process_char_map);
+                       set_bit(EOF_CHAR(tty), tty->process_char_map);
+                       set_bit('\n', tty->process_char_map);
+                       set_bit(EOL_CHAR(tty), tty->process_char_map);
+                       if (L_IEXTEN(tty)) {
+                               set_bit(WERASE_CHAR(tty),
+                                       tty->process_char_map);
+                               set_bit(LNEXT_CHAR(tty),
+                                       tty->process_char_map);
+                               set_bit(EOL2_CHAR(tty),
+                                       tty->process_char_map);
+                               if (L_ECHO(tty))
+                                       set_bit(REPRINT_CHAR(tty),
+                                               tty->process_char_map);
+                       }
+               }
+               if (I_IXON(tty)) {
+                       set_bit(START_CHAR(tty), tty->process_char_map);
+                       set_bit(STOP_CHAR(tty), tty->process_char_map);
+               }
+               if (L_ISIG(tty)) {
+                       set_bit(INTR_CHAR(tty), tty->process_char_map);
+                       set_bit(QUIT_CHAR(tty), tty->process_char_map);
+                       set_bit(SUSP_CHAR(tty), tty->process_char_map);
+               }
+               clear_bit(__DISABLED_CHAR, tty->process_char_map);
+               tty->raw = 0;
+               tty->real_raw = 0;
+       } else {
+               tty->raw = 1;
+               if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) &&
+                   (I_IGNPAR(tty) || !I_INPCK(tty)) &&
+                   (tty->driver->flags & TTY_DRIVER_REAL_RAW))
+                       tty->real_raw = 1;
+               else
+                       tty->real_raw = 0;
+       }
+       n_tty_set_room(tty);
+       /* The termios change make the tty ready for I/O */
+       wake_up_interruptible(&tty->write_wait);
+       wake_up_interruptible(&tty->read_wait);
+}
+
+/**
+ *     n_tty_close             -       close the ldisc for this tty
+ *     @tty: device
+ *
+ *     Called from the terminal layer when this line discipline is
+ *     being shut down, either because of a close or becsuse of a
+ *     discipline change. The function will not be called while other
+ *     ldisc methods are in progress.
+ */
+
+static void n_tty_close(struct tty_struct *tty)
+{
+       n_tty_flush_buffer(tty);
+       if (tty->read_buf) {
+               kfree(tty->read_buf);
+               tty->read_buf = NULL;
+       }
+       if (tty->echo_buf) {
+               kfree(tty->echo_buf);
+               tty->echo_buf = NULL;
+       }
+}
+
+/**
+ *     n_tty_open              -       open an ldisc
+ *     @tty: terminal to open
+ *
+ *     Called when this line discipline is being attached to the
+ *     terminal device. Can sleep. Called serialized so that no
+ *     other events will occur in parallel. No further open will occur
+ *     until a close.
+ */
+
+static int n_tty_open(struct tty_struct *tty)
+{
+       if (!tty)
+               return -EINVAL;
+
+       /* These are ugly. Currently a malloc failure here can panic */
+       if (!tty->read_buf) {
+               tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
+               if (!tty->read_buf)
+                       return -ENOMEM;
+       }
+       if (!tty->echo_buf) {
+               tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
+
+               if (!tty->echo_buf)
+                       return -ENOMEM;
+       }
+       reset_buffer_flags(tty);
+       tty->column = 0;
+       n_tty_set_termios(tty, NULL);
+       tty->minimum_to_wake = 1;
+       tty->closing = 0;
+       return 0;
+}
+
+static inline int input_available_p(struct tty_struct *tty, int amt)
+{
+       tty_flush_to_ldisc(tty);
+       if (tty->icanon && !L_EXTPROC(tty)) {
+               if (tty->canon_data)
+                       return 1;
+       } else if (tty->read_cnt >= (amt ? amt : 1))
+               return 1;
+
+       return 0;
+}
+
+/**
+ *     copy_from_read_buf      -       copy read data directly
+ *     @tty: terminal device
+ *     @b: user data
+ *     @nr: size of data
+ *
+ *     Helper function to speed up n_tty_read.  It is only called when
+ *     ICANON is off; it copies characters straight from the tty queue to
+ *     user space directly.  It can be profitably called twice; once to
+ *     drain the space from the tail pointer to the (physical) end of the
+ *     buffer, and once to drain the space from the (physical) beginning of
+ *     the buffer to head pointer.
+ *
+ *     Called under the tty->atomic_read_lock sem
+ *
+ */
+
+static int copy_from_read_buf(struct tty_struct *tty,
+                                     unsigned char __user **b,
+                                     size_t *nr)
+
+{
+       int retval;
+       size_t n;
+       unsigned long flags;
+
+       retval = 0;
+       spin_lock_irqsave(&tty->read_lock, flags);
+       n = min(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail);
+       n = min(*nr, n);
+       spin_unlock_irqrestore(&tty->read_lock, flags);
+       if (n) {
+               retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
+               n -= retval;
+               tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n);
+               spin_lock_irqsave(&tty->read_lock, flags);
+               tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
+               tty->read_cnt -= n;
+               /* Turn single EOF into zero-length read */
+               if (L_EXTPROC(tty) && tty->icanon && n == 1) {
+                       if (!tty->read_cnt && (*b)[n-1] == EOF_CHAR(tty))
+                               n--;
+               }
+               spin_unlock_irqrestore(&tty->read_lock, flags);
+               *b += n;
+               *nr -= n;
+       }
+       return retval;
+}
+
+extern ssize_t redirected_tty_write(struct file *, const char __user *,
+                                                       size_t, loff_t *);
+
+/**
+ *     job_control             -       check job control
+ *     @tty: tty
+ *     @file: file handle
+ *
+ *     Perform job control management checks on this file/tty descriptor
+ *     and if appropriate send any needed signals and return a negative
+ *     error code if action should be taken.
+ *
+ *     FIXME:
+ *     Locking: None - redirected write test is safe, testing
+ *     current->signal should possibly lock current->sighand
+ *     pgrp locking ?
+ */
+
+static int job_control(struct tty_struct *tty, struct file *file)
+{
+       /* Job control check -- must be done at start and after
+          every sleep (POSIX.1 7.1.1.4). */
+       /* NOTE: not yet done after every sleep pending a thorough
+          check of the logic of this change. -- jlc */
+       /* don't stop on /dev/console */
+       if (file->f_op->write != redirected_tty_write &&
+           current->signal->tty == tty) {
+               if (!tty->pgrp)
+                       printk(KERN_ERR "n_tty_read: no tty->pgrp!\n");
+               else if (task_pgrp(current) != tty->pgrp) {
+                       if (is_ignored(SIGTTIN) ||
+                           is_current_pgrp_orphaned())
+                               return -EIO;
+                       kill_pgrp(task_pgrp(current), SIGTTIN, 1);
+                       set_thread_flag(TIF_SIGPENDING);
+                       return -ERESTARTSYS;
+               }
+       }
+       return 0;
+}
+
+
+/**
+ *     n_tty_read              -       read function for tty
+ *     @tty: tty device
+ *     @file: file object
+ *     @buf: userspace buffer pointer
+ *     @nr: size of I/O
+ *
+ *     Perform reads for the line discipline. We are guaranteed that the
+ *     line discipline will not be closed under us but we may get multiple
+ *     parallel readers and must handle this ourselves. We may also get
+ *     a hangup. Always called in user context, may sleep.
+ *
+ *     This code must be sure never to sleep through a hangup.
+ */
+
+static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
+                        unsigned char __user *buf, size_t nr)
+{
+       unsigned char __user *b = buf;
+       DECLARE_WAITQUEUE(wait, current);
+       int c;
+       int minimum, time;
+       ssize_t retval = 0;
+       ssize_t size;
+       long timeout;
+       unsigned long flags;
+       int packet;
+
+do_it_again:
+
+       BUG_ON(!tty->read_buf);
+
+       c = job_control(tty, file);
+       if (c < 0)
+               return c;
+
+       minimum = time = 0;
+       timeout = MAX_SCHEDULE_TIMEOUT;
+       if (!tty->icanon) {
+               time = (HZ / 10) * TIME_CHAR(tty);
+               minimum = MIN_CHAR(tty);
+               if (minimum) {
+                       if (time)
+                               tty->minimum_to_wake = 1;
+                       else if (!waitqueue_active(&tty->read_wait) ||
+                                (tty->minimum_to_wake > minimum))
+                               tty->minimum_to_wake = minimum;
+               } else {
+                       timeout = 0;
+                       if (time) {
+                               timeout = time;
+                               time = 0;
+                       }
+                       tty->minimum_to_wake = minimum = 1;
+               }
+       }
+
+       /*
+        *      Internal serialization of reads.
+        */
+       if (file->f_flags & O_NONBLOCK) {
+               if (!mutex_trylock(&tty->atomic_read_lock))
+                       return -EAGAIN;
+       } else {
+               if (mutex_lock_interruptible(&tty->atomic_read_lock))
+                       return -ERESTARTSYS;
+       }
+       packet = tty->packet;
+
+       add_wait_queue(&tty->read_wait, &wait);
+       while (nr) {
+               /* First test for status change. */
+               if (packet && tty->link->ctrl_status) {
+                       unsigned char cs;
+                       if (b != buf)
+                               break;
+                       spin_lock_irqsave(&tty->link->ctrl_lock, flags);
+                       cs = tty->link->ctrl_status;
+                       tty->link->ctrl_status = 0;
+                       spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
+                       if (tty_put_user(tty, cs, b++)) {
+                               retval = -EFAULT;
+                               b--;
+                               break;
+                       }
+                       nr--;
+                       break;
+               }
+               /* This statement must be first before checking for input
+                  so that any interrupt will set the state back to
+                  TASK_RUNNING. */
+               set_current_state(TASK_INTERRUPTIBLE);
+
+               if (((minimum - (b - buf)) < tty->minimum_to_wake) &&
+                   ((minimum - (b - buf)) >= 1))
+                       tty->minimum_to_wake = (minimum - (b - buf));
+
+               if (!input_available_p(tty, 0)) {
+                       if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
+                               retval = -EIO;
+                               break;
+                       }
+                       if (tty_hung_up_p(file))
+                               break;
+                       if (!timeout)
+                               break;
+                       if (file->f_flags & O_NONBLOCK) {
+                               retval = -EAGAIN;
+                               break;
+                       }
+                       if (signal_pending(current)) {
+                               retval = -ERESTARTSYS;
+                               break;
+                       }
+                       /* FIXME: does n_tty_set_room need locking ? */
+                       n_tty_set_room(tty);
+                       timeout = schedule_timeout(timeout);
+                       continue;
+               }
+               __set_current_state(TASK_RUNNING);
+
+               /* Deal with packet mode. */
+               if (packet && b == buf) {
+                       if (tty_put_user(tty, TIOCPKT_DATA, b++)) {
+                               retval = -EFAULT;
+                               b--;
+                               break;
+                       }
+                       nr--;
+               }
+
+               if (tty->icanon && !L_EXTPROC(tty)) {
+                       /* N.B. avoid overrun if nr == 0 */
+                       while (nr && tty->read_cnt) {
+                               int eol;
+
+                               eol = test_and_clear_bit(tty->read_tail,
+                                               tty->read_flags);
+                               c = tty->read_buf[tty->read_tail];
+                               spin_lock_irqsave(&tty->read_lock, flags);
+                               tty->read_tail = ((tty->read_tail+1) &
+                                                 (N_TTY_BUF_SIZE-1));
+                               tty->read_cnt--;
+                               if (eol) {
+                                       /* this test should be redundant:
+                                        * we shouldn't be reading data if
+                                        * canon_data is 0
+                                        */
+                                       if (--tty->canon_data < 0)
+                                               tty->canon_data = 0;
+                               }
+                               spin_unlock_irqrestore(&tty->read_lock, flags);
+
+                               if (!eol || (c != __DISABLED_CHAR)) {
+                                       if (tty_put_user(tty, c, b++)) {
+                                               retval = -EFAULT;
+                                               b--;
+                                               break;
+                                       }
+                                       nr--;
+                               }
+                               if (eol) {
+                                       tty_audit_push(tty);
+                                       break;
+                               }
+                       }
+                       if (retval)
+                               break;
+               } else {
+                       int uncopied;
+                       /* The copy function takes the read lock and handles
+                          locking internally for this case */
+                       uncopied = copy_from_read_buf(tty, &b, &nr);
+                       uncopied += copy_from_read_buf(tty, &b, &nr);
+                       if (uncopied) {
+                               retval = -EFAULT;
+                               break;
+                       }
+               }
+
+               /* If there is enough space in the read buffer now, let the
+                * low-level driver know. We use n_tty_chars_in_buffer() to
+                * check the buffer, as it now knows about canonical mode.
+                * Otherwise, if the driver is throttled and the line is
+                * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
+                * we won't get any more characters.
+                */
+               if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) {
+                       n_tty_set_room(tty);
+                       check_unthrottle(tty);
+               }
+
+               if (b - buf >= minimum)
+                       break;
+               if (time)
+                       timeout = time;
+       }
+       mutex_unlock(&tty->atomic_read_lock);
+       remove_wait_queue(&tty->read_wait, &wait);
+
+       if (!waitqueue_active(&tty->read_wait))
+               tty->minimum_to_wake = minimum;
+
+       __set_current_state(TASK_RUNNING);
+       size = b - buf;
+       if (size) {
+               retval = size;
+               if (nr)
+                       clear_bit(TTY_PUSH, &tty->flags);
+       } else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
+                goto do_it_again;
+
+       n_tty_set_room(tty);
+       return retval;
+}
+
+/**
+ *     n_tty_write             -       write function for tty
+ *     @tty: tty device
+ *     @file: file object
+ *     @buf: userspace buffer pointer
+ *     @nr: size of I/O
+ *
+ *     Write function of the terminal device.  This is serialized with
+ *     respect to other write callers but not to termios changes, reads
+ *     and other such events.  Since the receive code will echo characters,
+ *     thus calling driver write methods, the output_lock is used in
+ *     the output processing functions called here as well as in the
+ *     echo processing function to protect the column state and space
+ *     left in the buffer.
+ *
+ *     This code must be sure never to sleep through a hangup.
+ *
+ *     Locking: output_lock to protect column state and space left
+ *              (note that the process_output*() functions take this
+ *               lock themselves)
+ */
+
+static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
+                          const unsigned char *buf, size_t nr)
+{
+       const unsigned char *b = buf;
+       DECLARE_WAITQUEUE(wait, current);
+       int c;
+       ssize_t retval = 0;
+
+       /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
+       if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) {
+               retval = tty_check_change(tty);
+               if (retval)
+                       return retval;
+       }
+
+       /* Write out any echoed characters that are still pending */
+       process_echoes(tty);
+
+       add_wait_queue(&tty->write_wait, &wait);
+       while (1) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (signal_pending(current)) {
+                       retval = -ERESTARTSYS;
+                       break;
+               }
+               if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
+                       retval = -EIO;
+                       break;
+               }
+               if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
+                       while (nr > 0) {
+                               ssize_t num = process_output_block(tty, b, nr);
+                               if (num < 0) {
+                                       if (num == -EAGAIN)
+                                               break;
+                                       retval = num;
+                                       goto break_out;
+                               }
+                               b += num;
+                               nr -= num;
+                               if (nr == 0)
+                                       break;
+                               c = *b;
+                               if (process_output(c, tty) < 0)
+                                       break;
+                               b++; nr--;
+                       }
+                       if (tty->ops->flush_chars)
+                               tty->ops->flush_chars(tty);
+               } else {
+                       while (nr > 0) {
+                               c = tty->ops->write(tty, b, nr);
+                               if (c < 0) {
+                                       retval = c;
+                                       goto break_out;
+                               }
+                               if (!c)
+                                       break;
+                               b += c;
+                               nr -= c;
+                       }
+               }
+               if (!nr)
+                       break;
+               if (file->f_flags & O_NONBLOCK) {
+                       retval = -EAGAIN;
+                       break;
+               }
+               schedule();
+       }
+break_out:
+       __set_current_state(TASK_RUNNING);
+       remove_wait_queue(&tty->write_wait, &wait);
+       if (b - buf != nr && tty->fasync)
+               set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+       return (b - buf) ? b - buf : retval;
+}
+
+/**
+ *     n_tty_poll              -       poll method for N_TTY
+ *     @tty: terminal device
+ *     @file: file accessing it
+ *     @wait: poll table
+ *
+ *     Called when the line discipline is asked to poll() for data or
+ *     for special events. This code is not serialized with respect to
+ *     other events save open/close.
+ *
+ *     This code must be sure never to sleep through a hangup.
+ *     Called without the kernel lock held - fine
+ */
+
+static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
+                                                       poll_table *wait)
+{
+       unsigned int mask = 0;
+
+       poll_wait(file, &tty->read_wait, wait);
+       poll_wait(file, &tty->write_wait, wait);
+       if (input_available_p(tty, TIME_CHAR(tty) ? 0 : MIN_CHAR(tty)))
+               mask |= POLLIN | POLLRDNORM;
+       if (tty->packet && tty->link->ctrl_status)
+               mask |= POLLPRI | POLLIN | POLLRDNORM;
+       if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
+               mask |= POLLHUP;
+       if (tty_hung_up_p(file))
+               mask |= POLLHUP;
+       if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) {
+               if (MIN_CHAR(tty) && !TIME_CHAR(tty))
+                       tty->minimum_to_wake = MIN_CHAR(tty);
+               else
+                       tty->minimum_to_wake = 1;
+       }
+       if (tty->ops->write && !tty_is_writelocked(tty) &&
+                       tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
+                       tty_write_room(tty) > 0)
+               mask |= POLLOUT | POLLWRNORM;
+       return mask;
+}
+
+static unsigned long inq_canon(struct tty_struct *tty)
+{
+       int nr, head, tail;
+
+       if (!tty->canon_data)
+               return 0;
+       head = tty->canon_head;
+       tail = tty->read_tail;
+       nr = (head - tail) & (N_TTY_BUF_SIZE-1);
+       /* Skip EOF-chars.. */
+       while (head != tail) {
+               if (test_bit(tail, tty->read_flags) &&
+                   tty->read_buf[tail] == __DISABLED_CHAR)
+                       nr--;
+               tail = (tail+1) & (N_TTY_BUF_SIZE-1);
+       }
+       return nr;
+}
+
+static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
+                      unsigned int cmd, unsigned long arg)
+{
+       int retval;
+
+       switch (cmd) {
+       case TIOCOUTQ:
+               return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
+       case TIOCINQ:
+               /* FIXME: Locking */
+               retval = tty->read_cnt;
+               if (L_ICANON(tty))
+                       retval = inq_canon(tty);
+               return put_user(retval, (unsigned int __user *) arg);
+       default:
+               return n_tty_ioctl_helper(tty, file, cmd, arg);
+       }
+}
+
+struct tty_ldisc_ops tty_ldisc_N_TTY = {
+       .magic           = TTY_LDISC_MAGIC,
+       .name            = "n_tty",
+       .open            = n_tty_open,
+       .close           = n_tty_close,
+       .flush_buffer    = n_tty_flush_buffer,
+       .chars_in_buffer = n_tty_chars_in_buffer,
+       .read            = n_tty_read,
+       .write           = n_tty_write,
+       .ioctl           = n_tty_ioctl,
+       .set_termios     = n_tty_set_termios,
+       .poll            = n_tty_poll,
+       .receive_buf     = n_tty_receive_buf,
+       .write_wakeup    = n_tty_write_wakeup
+};
+
+/**
+ *     n_tty_inherit_ops       -       inherit N_TTY methods
+ *     @ops: struct tty_ldisc_ops where to save N_TTY methods
+ *
+ *     Used by a generic struct tty_ldisc_ops to easily inherit N_TTY
+ *     methods.
+ */
+
+void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
+{
+       *ops = tty_ldisc_N_TTY;
+       ops->owner = NULL;
+       ops->refcount = ops->flags = 0;
+}
+EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
new file mode 100644 (file)
index 0000000..923a485
--- /dev/null
@@ -0,0 +1,777 @@
+/*
+ *  linux/drivers/char/pty.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  Added support for a Unix98-style ptmx device.
+ *    -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
+ *
+ *  When reading this code see also fs/devpts. In particular note that the
+ *  driver_data field is used by the devpts side as a binding to the devpts
+ *  inode.
+ */
+
+#include <linux/module.h>
+
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <linux/sysctl.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+#include <linux/bitops.h>
+#include <linux/devpts_fs.h>
+#include <linux/slab.h>
+
+#include <asm/system.h>
+
+#ifdef CONFIG_UNIX98_PTYS
+static struct tty_driver *ptm_driver;
+static struct tty_driver *pts_driver;
+#endif
+
+static void pty_close(struct tty_struct *tty, struct file *filp)
+{
+       BUG_ON(!tty);
+       if (tty->driver->subtype == PTY_TYPE_MASTER)
+               WARN_ON(tty->count > 1);
+       else {
+               if (tty->count > 2)
+                       return;
+       }
+       wake_up_interruptible(&tty->read_wait);
+       wake_up_interruptible(&tty->write_wait);
+       tty->packet = 0;
+       if (!tty->link)
+               return;
+       tty->link->packet = 0;
+       set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
+       wake_up_interruptible(&tty->link->read_wait);
+       wake_up_interruptible(&tty->link->write_wait);
+       if (tty->driver->subtype == PTY_TYPE_MASTER) {
+               set_bit(TTY_OTHER_CLOSED, &tty->flags);
+#ifdef CONFIG_UNIX98_PTYS
+               if (tty->driver == ptm_driver)
+                       devpts_pty_kill(tty->link);
+#endif
+               tty_unlock();
+               tty_vhangup(tty->link);
+               tty_lock();
+       }
+}
+
+/*
+ * The unthrottle routine is called by the line discipline to signal
+ * that it can receive more characters.  For PTY's, the TTY_THROTTLED
+ * flag is always set, to force the line discipline to always call the
+ * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE
+ * characters in the queue.  This is necessary since each time this
+ * happens, we need to wake up any sleeping processes that could be
+ * (1) trying to send data to the pty, or (2) waiting in wait_until_sent()
+ * for the pty buffer to be drained.
+ */
+static void pty_unthrottle(struct tty_struct *tty)
+{
+       tty_wakeup(tty->link);
+       set_bit(TTY_THROTTLED, &tty->flags);
+}
+
+/**
+ *     pty_space       -       report space left for writing
+ *     @to: tty we are writing into
+ *
+ *     The tty buffers allow 64K but we sneak a peak and clip at 8K this
+ *     allows a lot of overspill room for echo and other fun messes to
+ *     be handled properly
+ */
+
+static int pty_space(struct tty_struct *to)
+{
+       int n = 8192 - to->buf.memory_used;
+       if (n < 0)
+               return 0;
+       return n;
+}
+
+/**
+ *     pty_write               -       write to a pty
+ *     @tty: the tty we write from
+ *     @buf: kernel buffer of data
+ *     @count: bytes to write
+ *
+ *     Our "hardware" write method. Data is coming from the ldisc which
+ *     may be in a non sleeping state. We simply throw this at the other
+ *     end of the link as if we were an IRQ handler receiving stuff for
+ *     the other side of the pty/tty pair.
+ */
+
+static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
+{
+       struct tty_struct *to = tty->link;
+
+       if (tty->stopped)
+               return 0;
+
+       if (c > 0) {
+               /* Stuff the data into the input queue of the other end */
+               c = tty_insert_flip_string(to, buf, c);
+               /* And shovel */
+               if (c) {
+                       tty_flip_buffer_push(to);
+                       tty_wakeup(tty);
+               }
+       }
+       return c;
+}
+
+/**
+ *     pty_write_room  -       write space
+ *     @tty: tty we are writing from
+ *
+ *     Report how many bytes the ldisc can send into the queue for
+ *     the other device.
+ */
+
+static int pty_write_room(struct tty_struct *tty)
+{
+       if (tty->stopped)
+               return 0;
+       return pty_space(tty->link);
+}
+
+/**
+ *     pty_chars_in_buffer     -       characters currently in our tx queue
+ *     @tty: our tty
+ *
+ *     Report how much we have in the transmit queue. As everything is
+ *     instantly at the other end this is easy to implement.
+ */
+
+static int pty_chars_in_buffer(struct tty_struct *tty)
+{
+       return 0;
+}
+
+/* Set the lock flag on a pty */
+static int pty_set_lock(struct tty_struct *tty, int __user *arg)
+{
+       int val;
+       if (get_user(val, arg))
+               return -EFAULT;
+       if (val)
+               set_bit(TTY_PTY_LOCK, &tty->flags);
+       else
+               clear_bit(TTY_PTY_LOCK, &tty->flags);
+       return 0;
+}
+
+/* Send a signal to the slave */
+static int pty_signal(struct tty_struct *tty, int sig)
+{
+       unsigned long flags;
+       struct pid *pgrp;
+
+       if (tty->link) {
+               spin_lock_irqsave(&tty->link->ctrl_lock, flags);
+               pgrp = get_pid(tty->link->pgrp);
+               spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
+
+               kill_pgrp(pgrp, sig, 1);
+               put_pid(pgrp);
+       }
+       return 0;
+}
+
+static void pty_flush_buffer(struct tty_struct *tty)
+{
+       struct tty_struct *to = tty->link;
+       unsigned long flags;
+
+       if (!to)
+               return;
+       /* tty_buffer_flush(to); FIXME */
+       if (to->packet) {
+               spin_lock_irqsave(&tty->ctrl_lock, flags);
+               tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
+               wake_up_interruptible(&to->read_wait);
+               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+       }
+}
+
+static int pty_open(struct tty_struct *tty, struct file *filp)
+{
+       int     retval = -ENODEV;
+
+       if (!tty || !tty->link)
+               goto out;
+
+       retval = -EIO;
+       if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
+               goto out;
+       if (test_bit(TTY_PTY_LOCK, &tty->link->flags))
+               goto out;
+       if (tty->link->count != 1)
+               goto out;
+
+       clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
+       set_bit(TTY_THROTTLED, &tty->flags);
+       retval = 0;
+out:
+       return retval;
+}
+
+static void pty_set_termios(struct tty_struct *tty,
+                                       struct ktermios *old_termios)
+{
+       tty->termios->c_cflag &= ~(CSIZE | PARENB);
+       tty->termios->c_cflag |= (CS8 | CREAD);
+}
+
+/**
+ *     pty_do_resize           -       resize event
+ *     @tty: tty being resized
+ *     @ws: window size being set.
+ *
+ *     Update the termios variables and send the necessary signals to
+ *     peform a terminal resize correctly
+ */
+
+int pty_resize(struct tty_struct *tty,  struct winsize *ws)
+{
+       struct pid *pgrp, *rpgrp;
+       unsigned long flags;
+       struct tty_struct *pty = tty->link;
+
+       /* For a PTY we need to lock the tty side */
+       mutex_lock(&tty->termios_mutex);
+       if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
+               goto done;
+
+       /* Get the PID values and reference them so we can
+          avoid holding the tty ctrl lock while sending signals.
+          We need to lock these individually however. */
+
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+       pgrp = get_pid(tty->pgrp);
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+       spin_lock_irqsave(&pty->ctrl_lock, flags);
+       rpgrp = get_pid(pty->pgrp);
+       spin_unlock_irqrestore(&pty->ctrl_lock, flags);
+
+       if (pgrp)
+               kill_pgrp(pgrp, SIGWINCH, 1);
+       if (rpgrp != pgrp && rpgrp)
+               kill_pgrp(rpgrp, SIGWINCH, 1);
+
+       put_pid(pgrp);
+       put_pid(rpgrp);
+
+       tty->winsize = *ws;
+       pty->winsize = *ws;     /* Never used so will go away soon */
+done:
+       mutex_unlock(&tty->termios_mutex);
+       return 0;
+}
+
+/* Traditional BSD devices */
+#ifdef CONFIG_LEGACY_PTYS
+
+static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+       struct tty_struct *o_tty;
+       int idx = tty->index;
+       int retval;
+
+       o_tty = alloc_tty_struct();
+       if (!o_tty)
+               return -ENOMEM;
+       if (!try_module_get(driver->other->owner)) {
+               /* This cannot in fact currently happen */
+               free_tty_struct(o_tty);
+               return -ENOMEM;
+       }
+       initialize_tty_struct(o_tty, driver->other, idx);
+
+       /* We always use new tty termios data so we can do this
+          the easy way .. */
+       retval = tty_init_termios(tty);
+       if (retval)
+               goto free_mem_out;
+
+       retval = tty_init_termios(o_tty);
+       if (retval) {
+               tty_free_termios(tty);
+               goto free_mem_out;
+       }
+
+       /*
+        * Everything allocated ... set up the o_tty structure.
+        */
+       driver->other->ttys[idx] = o_tty;
+       tty_driver_kref_get(driver->other);
+       if (driver->subtype == PTY_TYPE_MASTER)
+               o_tty->count++;
+       /* Establish the links in both directions */
+       tty->link   = o_tty;
+       o_tty->link = tty;
+
+       tty_driver_kref_get(driver);
+       tty->count++;
+       driver->ttys[idx] = tty;
+       return 0;
+free_mem_out:
+       module_put(o_tty->driver->owner);
+       free_tty_struct(o_tty);
+       return -ENOMEM;
+}
+
+static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file,
+                        unsigned int cmd, unsigned long arg)
+{
+       switch (cmd) {
+       case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
+               return pty_set_lock(tty, (int __user *) arg);
+       case TIOCSIG:    /* Send signal to other side of pty */
+               return pty_signal(tty, (int) arg);
+       }
+       return -ENOIOCTLCMD;
+}
+
+static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
+module_param(legacy_count, int, 0);
+
+/*
+ * The master side of a pty can do TIOCSPTLCK and thus
+ * has pty_bsd_ioctl.
+ */
+static const struct tty_operations master_pty_ops_bsd = {
+       .install = pty_install,
+       .open = pty_open,
+       .close = pty_close,
+       .write = pty_write,
+       .write_room = pty_write_room,
+       .flush_buffer = pty_flush_buffer,
+       .chars_in_buffer = pty_chars_in_buffer,
+       .unthrottle = pty_unthrottle,
+       .set_termios = pty_set_termios,
+       .ioctl = pty_bsd_ioctl,
+       .resize = pty_resize
+};
+
+static const struct tty_operations slave_pty_ops_bsd = {
+       .install = pty_install,
+       .open = pty_open,
+       .close = pty_close,
+       .write = pty_write,
+       .write_room = pty_write_room,
+       .flush_buffer = pty_flush_buffer,
+       .chars_in_buffer = pty_chars_in_buffer,
+       .unthrottle = pty_unthrottle,
+       .set_termios = pty_set_termios,
+       .resize = pty_resize
+};
+
+static void __init legacy_pty_init(void)
+{
+       struct tty_driver *pty_driver, *pty_slave_driver;
+
+       if (legacy_count <= 0)
+               return;
+
+       pty_driver = alloc_tty_driver(legacy_count);
+       if (!pty_driver)
+               panic("Couldn't allocate pty driver");
+
+       pty_slave_driver = alloc_tty_driver(legacy_count);
+       if (!pty_slave_driver)
+               panic("Couldn't allocate pty slave driver");
+
+       pty_driver->owner = THIS_MODULE;
+       pty_driver->driver_name = "pty_master";
+       pty_driver->name = "pty";
+       pty_driver->major = PTY_MASTER_MAJOR;
+       pty_driver->minor_start = 0;
+       pty_driver->type = TTY_DRIVER_TYPE_PTY;
+       pty_driver->subtype = PTY_TYPE_MASTER;
+       pty_driver->init_termios = tty_std_termios;
+       pty_driver->init_termios.c_iflag = 0;
+       pty_driver->init_termios.c_oflag = 0;
+       pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
+       pty_driver->init_termios.c_lflag = 0;
+       pty_driver->init_termios.c_ispeed = 38400;
+       pty_driver->init_termios.c_ospeed = 38400;
+       pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW;
+       pty_driver->other = pty_slave_driver;
+       tty_set_operations(pty_driver, &master_pty_ops_bsd);
+
+       pty_slave_driver->owner = THIS_MODULE;
+       pty_slave_driver->driver_name = "pty_slave";
+       pty_slave_driver->name = "ttyp";
+       pty_slave_driver->major = PTY_SLAVE_MAJOR;
+       pty_slave_driver->minor_start = 0;
+       pty_slave_driver->type = TTY_DRIVER_TYPE_PTY;
+       pty_slave_driver->subtype = PTY_TYPE_SLAVE;
+       pty_slave_driver->init_termios = tty_std_termios;
+       pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
+       pty_slave_driver->init_termios.c_ispeed = 38400;
+       pty_slave_driver->init_termios.c_ospeed = 38400;
+       pty_slave_driver->flags = TTY_DRIVER_RESET_TERMIOS |
+                                       TTY_DRIVER_REAL_RAW;
+       pty_slave_driver->other = pty_driver;
+       tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd);
+
+       if (tty_register_driver(pty_driver))
+               panic("Couldn't register pty driver");
+       if (tty_register_driver(pty_slave_driver))
+               panic("Couldn't register pty slave driver");
+}
+#else
+static inline void legacy_pty_init(void) { }
+#endif
+
+/* Unix98 devices */
+#ifdef CONFIG_UNIX98_PTYS
+/*
+ * sysctl support for setting limits on the number of Unix98 ptys allocated.
+ * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
+ */
+int pty_limit = NR_UNIX98_PTY_DEFAULT;
+static int pty_limit_min;
+static int pty_limit_max = NR_UNIX98_PTY_MAX;
+static int pty_count;
+
+static struct cdev ptmx_cdev;
+
+static struct ctl_table pty_table[] = {
+       {
+               .procname       = "max",
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .data           = &pty_limit,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &pty_limit_min,
+               .extra2         = &pty_limit_max,
+       }, {
+               .procname       = "nr",
+               .maxlen         = sizeof(int),
+               .mode           = 0444,
+               .data           = &pty_count,
+               .proc_handler   = proc_dointvec,
+       }, 
+       {}
+};
+
+static struct ctl_table pty_kern_table[] = {
+       {
+               .procname       = "pty",
+               .mode           = 0555,
+               .child          = pty_table,
+       },
+       {}
+};
+
+static struct ctl_table pty_root_table[] = {
+       {
+               .procname       = "kernel",
+               .mode           = 0555,
+               .child          = pty_kern_table,
+       },
+       {}
+};
+
+
+static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
+                           unsigned int cmd, unsigned long arg)
+{
+       switch (cmd) {
+       case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
+               return pty_set_lock(tty, (int __user *)arg);
+       case TIOCGPTN: /* Get PT Number */
+               return put_user(tty->index, (unsigned int __user *)arg);
+       case TIOCSIG:    /* Send signal to other side of pty */
+               return pty_signal(tty, (int) arg);
+       }
+
+       return -ENOIOCTLCMD;
+}
+
+/**
+ *     ptm_unix98_lookup       -       find a pty master
+ *     @driver: ptm driver
+ *     @idx: tty index
+ *
+ *     Look up a pty master device. Called under the tty_mutex for now.
+ *     This provides our locking.
+ */
+
+static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver,
+               struct inode *ptm_inode, int idx)
+{
+       struct tty_struct *tty = devpts_get_tty(ptm_inode, idx);
+       if (tty)
+               tty = tty->link;
+       return tty;
+}
+
+/**
+ *     pts_unix98_lookup       -       find a pty slave
+ *     @driver: pts driver
+ *     @idx: tty index
+ *
+ *     Look up a pty master device. Called under the tty_mutex for now.
+ *     This provides our locking.
+ */
+
+static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
+               struct inode *pts_inode, int idx)
+{
+       struct tty_struct *tty = devpts_get_tty(pts_inode, idx);
+       /* Master must be open before slave */
+       if (!tty)
+               return ERR_PTR(-EIO);
+       return tty;
+}
+
+static void pty_unix98_shutdown(struct tty_struct *tty)
+{
+       /* We have our own method as we don't use the tty index */
+       kfree(tty->termios);
+}
+
+/* We have no need to install and remove our tty objects as devpts does all
+   the work for us */
+
+static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+       struct tty_struct *o_tty;
+       int idx = tty->index;
+
+       o_tty = alloc_tty_struct();
+       if (!o_tty)
+               return -ENOMEM;
+       if (!try_module_get(driver->other->owner)) {
+               /* This cannot in fact currently happen */
+               free_tty_struct(o_tty);
+               return -ENOMEM;
+       }
+       initialize_tty_struct(o_tty, driver->other, idx);
+
+       tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
+       if (tty->termios == NULL)
+               goto free_mem_out;
+       *tty->termios = driver->init_termios;
+       tty->termios_locked = tty->termios + 1;
+
+       o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
+       if (o_tty->termios == NULL)
+               goto free_mem_out;
+       *o_tty->termios = driver->other->init_termios;
+       o_tty->termios_locked = o_tty->termios + 1;
+
+       tty_driver_kref_get(driver->other);
+       if (driver->subtype == PTY_TYPE_MASTER)
+               o_tty->count++;
+       /* Establish the links in both directions */
+       tty->link   = o_tty;
+       o_tty->link = tty;
+       /*
+        * All structures have been allocated, so now we install them.
+        * Failures after this point use release_tty to clean up, so
+        * there's no need to null out the local pointers.
+        */
+       tty_driver_kref_get(driver);
+       tty->count++;
+       pty_count++;
+       return 0;
+free_mem_out:
+       kfree(o_tty->termios);
+       module_put(o_tty->driver->owner);
+       free_tty_struct(o_tty);
+       kfree(tty->termios);
+       return -ENOMEM;
+}
+
+static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
+{
+       pty_count--;
+}
+
+static const struct tty_operations ptm_unix98_ops = {
+       .lookup = ptm_unix98_lookup,
+       .install = pty_unix98_install,
+       .remove = pty_unix98_remove,
+       .open = pty_open,
+       .close = pty_close,
+       .write = pty_write,
+       .write_room = pty_write_room,
+       .flush_buffer = pty_flush_buffer,
+       .chars_in_buffer = pty_chars_in_buffer,
+       .unthrottle = pty_unthrottle,
+       .set_termios = pty_set_termios,
+       .ioctl = pty_unix98_ioctl,
+       .shutdown = pty_unix98_shutdown,
+       .resize = pty_resize
+};
+
+static const struct tty_operations pty_unix98_ops = {
+       .lookup = pts_unix98_lookup,
+       .install = pty_unix98_install,
+       .remove = pty_unix98_remove,
+       .open = pty_open,
+       .close = pty_close,
+       .write = pty_write,
+       .write_room = pty_write_room,
+       .flush_buffer = pty_flush_buffer,
+       .chars_in_buffer = pty_chars_in_buffer,
+       .unthrottle = pty_unthrottle,
+       .set_termios = pty_set_termios,
+       .shutdown = pty_unix98_shutdown
+};
+
+/**
+ *     ptmx_open               -       open a unix 98 pty master
+ *     @inode: inode of device file
+ *     @filp: file pointer to tty
+ *
+ *     Allocate a unix98 pty master device from the ptmx driver.
+ *
+ *     Locking: tty_mutex protects the init_dev work. tty->count should
+ *             protect the rest.
+ *             allocated_ptys_lock handles the list of free pty numbers
+ */
+
+static int ptmx_open(struct inode *inode, struct file *filp)
+{
+       struct tty_struct *tty;
+       int retval;
+       int index;
+
+       nonseekable_open(inode, filp);
+
+       /* find a device that is not in use. */
+       tty_lock();
+       index = devpts_new_index(inode);
+       tty_unlock();
+       if (index < 0)
+               return index;
+
+       mutex_lock(&tty_mutex);
+       tty_lock();
+       tty = tty_init_dev(ptm_driver, index, 1);
+       mutex_unlock(&tty_mutex);
+
+       if (IS_ERR(tty)) {
+               retval = PTR_ERR(tty);
+               goto out;
+       }
+
+       set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
+
+       retval = tty_add_file(tty, filp);
+       if (retval)
+               goto out;
+
+       retval = devpts_pty_new(inode, tty->link);
+       if (retval)
+               goto out1;
+
+       retval = ptm_driver->ops->open(tty, filp);
+       if (retval)
+               goto out2;
+out1:
+       tty_unlock();
+       return retval;
+out2:
+       tty_unlock();
+       tty_release(inode, filp);
+       return retval;
+out:
+       devpts_kill_index(inode, index);
+       tty_unlock();
+       return retval;
+}
+
+static struct file_operations ptmx_fops;
+
+static void __init unix98_pty_init(void)
+{
+       ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
+       if (!ptm_driver)
+               panic("Couldn't allocate Unix98 ptm driver");
+       pts_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
+       if (!pts_driver)
+               panic("Couldn't allocate Unix98 pts driver");
+
+       ptm_driver->owner = THIS_MODULE;
+       ptm_driver->driver_name = "pty_master";
+       ptm_driver->name = "ptm";
+       ptm_driver->major = UNIX98_PTY_MASTER_MAJOR;
+       ptm_driver->minor_start = 0;
+       ptm_driver->type = TTY_DRIVER_TYPE_PTY;
+       ptm_driver->subtype = PTY_TYPE_MASTER;
+       ptm_driver->init_termios = tty_std_termios;
+       ptm_driver->init_termios.c_iflag = 0;
+       ptm_driver->init_termios.c_oflag = 0;
+       ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
+       ptm_driver->init_termios.c_lflag = 0;
+       ptm_driver->init_termios.c_ispeed = 38400;
+       ptm_driver->init_termios.c_ospeed = 38400;
+       ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
+               TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
+       ptm_driver->other = pts_driver;
+       tty_set_operations(ptm_driver, &ptm_unix98_ops);
+
+       pts_driver->owner = THIS_MODULE;
+       pts_driver->driver_name = "pty_slave";
+       pts_driver->name = "pts";
+       pts_driver->major = UNIX98_PTY_SLAVE_MAJOR;
+       pts_driver->minor_start = 0;
+       pts_driver->type = TTY_DRIVER_TYPE_PTY;
+       pts_driver->subtype = PTY_TYPE_SLAVE;
+       pts_driver->init_termios = tty_std_termios;
+       pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
+       pts_driver->init_termios.c_ispeed = 38400;
+       pts_driver->init_termios.c_ospeed = 38400;
+       pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
+               TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
+       pts_driver->other = ptm_driver;
+       tty_set_operations(pts_driver, &pty_unix98_ops);
+
+       if (tty_register_driver(ptm_driver))
+               panic("Couldn't register Unix98 ptm driver");
+       if (tty_register_driver(pts_driver))
+               panic("Couldn't register Unix98 pts driver");
+
+       register_sysctl_table(pty_root_table);
+
+       /* Now create the /dev/ptmx special device */
+       tty_default_fops(&ptmx_fops);
+       ptmx_fops.open = ptmx_open;
+
+       cdev_init(&ptmx_cdev, &ptmx_fops);
+       if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
+           register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
+               panic("Couldn't register /dev/ptmx driver\n");
+       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
+}
+
+#else
+static inline void unix98_pty_init(void) { }
+#endif
+
+static int __init pty_init(void)
+{
+       legacy_pty_init();
+       unix98_pty_init();
+       return 0;
+}
+module_init(pty_init);
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
new file mode 100644 (file)
index 0000000..eaa5d3e
--- /dev/null
@@ -0,0 +1,811 @@
+/*
+ *     Linux Magic System Request Key Hacks
+ *
+ *     (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *     based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>
+ *
+ *     (c) 2000 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
+ *     overhauled to use key registration
+ *     based upon discusions in irc://irc.openprojects.net/#kernelnewbies
+ *
+ *     Copyright (c) 2010 Dmitry Torokhov
+ *     Input handler conversion
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/reboot.h>
+#include <linux/sysrq.h>
+#include <linux/kbd_kern.h>
+#include <linux/proc_fs.h>
+#include <linux/nmi.h>
+#include <linux/quotaops.h>
+#include <linux/perf_event.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/suspend.h>
+#include <linux/writeback.h>
+#include <linux/buffer_head.h>         /* for fsync_bdev() */
+#include <linux/swap.h>
+#include <linux/spinlock.h>
+#include <linux/vt_kern.h>
+#include <linux/workqueue.h>
+#include <linux/hrtimer.h>
+#include <linux/oom.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+
+#include <asm/ptrace.h>
+#include <asm/irq_regs.h>
+
+/* Whether we react on sysrq keys or just ignore them */
+static int __read_mostly sysrq_enabled = 1;
+static bool __read_mostly sysrq_always_enabled;
+
+static bool sysrq_on(void)
+{
+       return sysrq_enabled || sysrq_always_enabled;
+}
+
+/*
+ * A value of 1 means 'all', other nonzero values are an op mask:
+ */
+static bool sysrq_on_mask(int mask)
+{
+       return sysrq_always_enabled ||
+              sysrq_enabled == 1 ||
+              (sysrq_enabled & mask);
+}
+
+static int __init sysrq_always_enabled_setup(char *str)
+{
+       sysrq_always_enabled = true;
+       pr_info("sysrq always enabled.\n");
+
+       return 1;
+}
+
+__setup("sysrq_always_enabled", sysrq_always_enabled_setup);
+
+
+static void sysrq_handle_loglevel(int key)
+{
+       int i;
+
+       i = key - '0';
+       console_loglevel = 7;
+       printk("Loglevel set to %d\n", i);
+       console_loglevel = i;
+}
+static struct sysrq_key_op sysrq_loglevel_op = {
+       .handler        = sysrq_handle_loglevel,
+       .help_msg       = "loglevel(0-9)",
+       .action_msg     = "Changing Loglevel",
+       .enable_mask    = SYSRQ_ENABLE_LOG,
+};
+
+#ifdef CONFIG_VT
+static void sysrq_handle_SAK(int key)
+{
+       struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
+       schedule_work(SAK_work);
+}
+static struct sysrq_key_op sysrq_SAK_op = {
+       .handler        = sysrq_handle_SAK,
+       .help_msg       = "saK",
+       .action_msg     = "SAK",
+       .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
+};
+#else
+#define sysrq_SAK_op (*(struct sysrq_key_op *)NULL)
+#endif
+
+#ifdef CONFIG_VT
+static void sysrq_handle_unraw(int key)
+{
+       struct kbd_struct *kbd = &kbd_table[fg_console];
+
+       if (kbd)
+               kbd->kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
+}
+static struct sysrq_key_op sysrq_unraw_op = {
+       .handler        = sysrq_handle_unraw,
+       .help_msg       = "unRaw",
+       .action_msg     = "Keyboard mode set to system default",
+       .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
+};
+#else
+#define sysrq_unraw_op (*(struct sysrq_key_op *)NULL)
+#endif /* CONFIG_VT */
+
+static void sysrq_handle_crash(int key)
+{
+       char *killer = NULL;
+
+       panic_on_oops = 1;      /* force panic */
+       wmb();
+       *killer = 1;
+}
+static struct sysrq_key_op sysrq_crash_op = {
+       .handler        = sysrq_handle_crash,
+       .help_msg       = "Crash",
+       .action_msg     = "Trigger a crash",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+
+static void sysrq_handle_reboot(int key)
+{
+       lockdep_off();
+       local_irq_enable();
+       emergency_restart();
+}
+static struct sysrq_key_op sysrq_reboot_op = {
+       .handler        = sysrq_handle_reboot,
+       .help_msg       = "reBoot",
+       .action_msg     = "Resetting",
+       .enable_mask    = SYSRQ_ENABLE_BOOT,
+};
+
+static void sysrq_handle_sync(int key)
+{
+       emergency_sync();
+}
+static struct sysrq_key_op sysrq_sync_op = {
+       .handler        = sysrq_handle_sync,
+       .help_msg       = "Sync",
+       .action_msg     = "Emergency Sync",
+       .enable_mask    = SYSRQ_ENABLE_SYNC,
+};
+
+static void sysrq_handle_show_timers(int key)
+{
+       sysrq_timer_list_show();
+}
+
+static struct sysrq_key_op sysrq_show_timers_op = {
+       .handler        = sysrq_handle_show_timers,
+       .help_msg       = "show-all-timers(Q)",
+       .action_msg     = "Show clockevent devices & pending hrtimers (no others)",
+};
+
+static void sysrq_handle_mountro(int key)
+{
+       emergency_remount();
+}
+static struct sysrq_key_op sysrq_mountro_op = {
+       .handler        = sysrq_handle_mountro,
+       .help_msg       = "Unmount",
+       .action_msg     = "Emergency Remount R/O",
+       .enable_mask    = SYSRQ_ENABLE_REMOUNT,
+};
+
+#ifdef CONFIG_LOCKDEP
+static void sysrq_handle_showlocks(int key)
+{
+       debug_show_all_locks();
+}
+
+static struct sysrq_key_op sysrq_showlocks_op = {
+       .handler        = sysrq_handle_showlocks,
+       .help_msg       = "show-all-locks(D)",
+       .action_msg     = "Show Locks Held",
+};
+#else
+#define sysrq_showlocks_op (*(struct sysrq_key_op *)NULL)
+#endif
+
+#ifdef CONFIG_SMP
+static DEFINE_SPINLOCK(show_lock);
+
+static void showacpu(void *dummy)
+{
+       unsigned long flags;
+
+       /* Idle CPUs have no interesting backtrace. */
+       if (idle_cpu(smp_processor_id()))
+               return;
+
+       spin_lock_irqsave(&show_lock, flags);
+       printk(KERN_INFO "CPU%d:\n", smp_processor_id());
+       show_stack(NULL, NULL);
+       spin_unlock_irqrestore(&show_lock, flags);
+}
+
+static void sysrq_showregs_othercpus(struct work_struct *dummy)
+{
+       smp_call_function(showacpu, NULL, 0);
+}
+
+static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus);
+
+static void sysrq_handle_showallcpus(int key)
+{
+       /*
+        * Fall back to the workqueue based printing if the
+        * backtrace printing did not succeed or the
+        * architecture has no support for it:
+        */
+       if (!trigger_all_cpu_backtrace()) {
+               struct pt_regs *regs = get_irq_regs();
+
+               if (regs) {
+                       printk(KERN_INFO "CPU%d:\n", smp_processor_id());
+                       show_regs(regs);
+               }
+               schedule_work(&sysrq_showallcpus);
+       }
+}
+
+static struct sysrq_key_op sysrq_showallcpus_op = {
+       .handler        = sysrq_handle_showallcpus,
+       .help_msg       = "show-backtrace-all-active-cpus(L)",
+       .action_msg     = "Show backtrace of all active CPUs",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+#endif
+
+static void sysrq_handle_showregs(int key)
+{
+       struct pt_regs *regs = get_irq_regs();
+       if (regs)
+               show_regs(regs);
+       perf_event_print_debug();
+}
+static struct sysrq_key_op sysrq_showregs_op = {
+       .handler        = sysrq_handle_showregs,
+       .help_msg       = "show-registers(P)",
+       .action_msg     = "Show Regs",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+
+static void sysrq_handle_showstate(int key)
+{
+       show_state();
+}
+static struct sysrq_key_op sysrq_showstate_op = {
+       .handler        = sysrq_handle_showstate,
+       .help_msg       = "show-task-states(T)",
+       .action_msg     = "Show State",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+
+static void sysrq_handle_showstate_blocked(int key)
+{
+       show_state_filter(TASK_UNINTERRUPTIBLE);
+}
+static struct sysrq_key_op sysrq_showstate_blocked_op = {
+       .handler        = sysrq_handle_showstate_blocked,
+       .help_msg       = "show-blocked-tasks(W)",
+       .action_msg     = "Show Blocked State",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+
+#ifdef CONFIG_TRACING
+#include <linux/ftrace.h>
+
+static void sysrq_ftrace_dump(int key)
+{
+       ftrace_dump(DUMP_ALL);
+}
+static struct sysrq_key_op sysrq_ftrace_dump_op = {
+       .handler        = sysrq_ftrace_dump,
+       .help_msg       = "dump-ftrace-buffer(Z)",
+       .action_msg     = "Dump ftrace buffer",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+#else
+#define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL)
+#endif
+
+static void sysrq_handle_showmem(int key)
+{
+       show_mem();
+}
+static struct sysrq_key_op sysrq_showmem_op = {
+       .handler        = sysrq_handle_showmem,
+       .help_msg       = "show-memory-usage(M)",
+       .action_msg     = "Show Memory",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+
+/*
+ * Signal sysrq helper function.  Sends a signal to all user processes.
+ */
+static void send_sig_all(int sig)
+{
+       struct task_struct *p;
+
+       for_each_process(p) {
+               if (p->mm && !is_global_init(p))
+                       /* Not swapper, init nor kernel thread */
+                       force_sig(sig, p);
+       }
+}
+
+static void sysrq_handle_term(int key)
+{
+       send_sig_all(SIGTERM);
+       console_loglevel = 8;
+}
+static struct sysrq_key_op sysrq_term_op = {
+       .handler        = sysrq_handle_term,
+       .help_msg       = "terminate-all-tasks(E)",
+       .action_msg     = "Terminate All Tasks",
+       .enable_mask    = SYSRQ_ENABLE_SIGNAL,
+};
+
+static void moom_callback(struct work_struct *ignored)
+{
+       out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0, NULL);
+}
+
+static DECLARE_WORK(moom_work, moom_callback);
+
+static void sysrq_handle_moom(int key)
+{
+       schedule_work(&moom_work);
+}
+static struct sysrq_key_op sysrq_moom_op = {
+       .handler        = sysrq_handle_moom,
+       .help_msg       = "memory-full-oom-kill(F)",
+       .action_msg     = "Manual OOM execution",
+       .enable_mask    = SYSRQ_ENABLE_SIGNAL,
+};
+
+#ifdef CONFIG_BLOCK
+static void sysrq_handle_thaw(int key)
+{
+       emergency_thaw_all();
+}
+static struct sysrq_key_op sysrq_thaw_op = {
+       .handler        = sysrq_handle_thaw,
+       .help_msg       = "thaw-filesystems(J)",
+       .action_msg     = "Emergency Thaw of all frozen filesystems",
+       .enable_mask    = SYSRQ_ENABLE_SIGNAL,
+};
+#endif
+
+static void sysrq_handle_kill(int key)
+{
+       send_sig_all(SIGKILL);
+       console_loglevel = 8;
+}
+static struct sysrq_key_op sysrq_kill_op = {
+       .handler        = sysrq_handle_kill,
+       .help_msg       = "kill-all-tasks(I)",
+       .action_msg     = "Kill All Tasks",
+       .enable_mask    = SYSRQ_ENABLE_SIGNAL,
+};
+
+static void sysrq_handle_unrt(int key)
+{
+       normalize_rt_tasks();
+}
+static struct sysrq_key_op sysrq_unrt_op = {
+       .handler        = sysrq_handle_unrt,
+       .help_msg       = "nice-all-RT-tasks(N)",
+       .action_msg     = "Nice All RT Tasks",
+       .enable_mask    = SYSRQ_ENABLE_RTNICE,
+};
+
+/* Key Operations table and lock */
+static DEFINE_SPINLOCK(sysrq_key_table_lock);
+
+static struct sysrq_key_op *sysrq_key_table[36] = {
+       &sysrq_loglevel_op,             /* 0 */
+       &sysrq_loglevel_op,             /* 1 */
+       &sysrq_loglevel_op,             /* 2 */
+       &sysrq_loglevel_op,             /* 3 */
+       &sysrq_loglevel_op,             /* 4 */
+       &sysrq_loglevel_op,             /* 5 */
+       &sysrq_loglevel_op,             /* 6 */
+       &sysrq_loglevel_op,             /* 7 */
+       &sysrq_loglevel_op,             /* 8 */
+       &sysrq_loglevel_op,             /* 9 */
+
+       /*
+        * a: Don't use for system provided sysrqs, it is handled specially on
+        * sparc and will never arrive.
+        */
+       NULL,                           /* a */
+       &sysrq_reboot_op,               /* b */
+       &sysrq_crash_op,                /* c & ibm_emac driver debug */
+       &sysrq_showlocks_op,            /* d */
+       &sysrq_term_op,                 /* e */
+       &sysrq_moom_op,                 /* f */
+       /* g: May be registered for the kernel debugger */
+       NULL,                           /* g */
+       NULL,                           /* h - reserved for help */
+       &sysrq_kill_op,                 /* i */
+#ifdef CONFIG_BLOCK
+       &sysrq_thaw_op,                 /* j */
+#else
+       NULL,                           /* j */
+#endif
+       &sysrq_SAK_op,                  /* k */
+#ifdef CONFIG_SMP
+       &sysrq_showallcpus_op,          /* l */
+#else
+       NULL,                           /* l */
+#endif
+       &sysrq_showmem_op,              /* m */
+       &sysrq_unrt_op,                 /* n */
+       /* o: This will often be registered as 'Off' at init time */
+       NULL,                           /* o */
+       &sysrq_showregs_op,             /* p */
+       &sysrq_show_timers_op,          /* q */
+       &sysrq_unraw_op,                /* r */
+       &sysrq_sync_op,                 /* s */
+       &sysrq_showstate_op,            /* t */
+       &sysrq_mountro_op,              /* u */
+       /* v: May be registered for frame buffer console restore */
+       NULL,                           /* v */
+       &sysrq_showstate_blocked_op,    /* w */
+       /* x: May be registered on ppc/powerpc for xmon */
+       NULL,                           /* x */
+       /* y: May be registered on sparc64 for global register dump */
+       NULL,                           /* y */
+       &sysrq_ftrace_dump_op,          /* z */
+};
+
+/* key2index calculation, -1 on invalid index */
+static int sysrq_key_table_key2index(int key)
+{
+       int retval;
+
+       if ((key >= '0') && (key <= '9'))
+               retval = key - '0';
+       else if ((key >= 'a') && (key <= 'z'))
+               retval = key + 10 - 'a';
+       else
+               retval = -1;
+       return retval;
+}
+
+/*
+ * get and put functions for the table, exposed to modules.
+ */
+struct sysrq_key_op *__sysrq_get_key_op(int key)
+{
+        struct sysrq_key_op *op_p = NULL;
+        int i;
+
+       i = sysrq_key_table_key2index(key);
+       if (i != -1)
+               op_p = sysrq_key_table[i];
+
+        return op_p;
+}
+
+static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p)
+{
+        int i = sysrq_key_table_key2index(key);
+
+        if (i != -1)
+                sysrq_key_table[i] = op_p;
+}
+
+void __handle_sysrq(int key, bool check_mask)
+{
+       struct sysrq_key_op *op_p;
+       int orig_log_level;
+       int i;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sysrq_key_table_lock, flags);
+       /*
+        * Raise the apparent loglevel to maximum so that the sysrq header
+        * is shown to provide the user with positive feedback.  We do not
+        * simply emit this at KERN_EMERG as that would change message
+        * routing in the consumers of /proc/kmsg.
+        */
+       orig_log_level = console_loglevel;
+       console_loglevel = 7;
+       printk(KERN_INFO "SysRq : ");
+
+        op_p = __sysrq_get_key_op(key);
+        if (op_p) {
+               /*
+                * Should we check for enabled operations (/proc/sysrq-trigger
+                * should not) and is the invoked operation enabled?
+                */
+               if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
+                       printk("%s\n", op_p->action_msg);
+                       console_loglevel = orig_log_level;
+                       op_p->handler(key);
+               } else {
+                       printk("This sysrq operation is disabled.\n");
+               }
+       } else {
+               printk("HELP : ");
+               /* Only print the help msg once per handler */
+               for (i = 0; i < ARRAY_SIZE(sysrq_key_table); i++) {
+                       if (sysrq_key_table[i]) {
+                               int j;
+
+                               for (j = 0; sysrq_key_table[i] !=
+                                               sysrq_key_table[j]; j++)
+                                       ;
+                               if (j != i)
+                                       continue;
+                               printk("%s ", sysrq_key_table[i]->help_msg);
+                       }
+               }
+               printk("\n");
+               console_loglevel = orig_log_level;
+       }
+       spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
+}
+
+void handle_sysrq(int key)
+{
+       if (sysrq_on())
+               __handle_sysrq(key, true);
+}
+EXPORT_SYMBOL(handle_sysrq);
+
+#ifdef CONFIG_INPUT
+
+/* Simple translation table for the SysRq keys */
+static const unsigned char sysrq_xlate[KEY_MAX + 1] =
+        "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
+        "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
+        "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
+        "bnm,./\000*\000 \000\201\202\203\204\205"      /* 0x30 - 0x3f */
+        "\206\207\210\211\212\000\000789-456+1"         /* 0x40 - 0x4f */
+        "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
+        "\r\000/";                                      /* 0x60 - 0x6f */
+
+static bool sysrq_down;
+static int sysrq_alt_use;
+static int sysrq_alt;
+static DEFINE_SPINLOCK(sysrq_event_lock);
+
+static bool sysrq_filter(struct input_handle *handle, unsigned int type,
+                        unsigned int code, int value)
+{
+       bool suppress;
+
+       /* We are called with interrupts disabled, just take the lock */
+       spin_lock(&sysrq_event_lock);
+
+       if (type != EV_KEY)
+               goto out;
+
+       switch (code) {
+
+       case KEY_LEFTALT:
+       case KEY_RIGHTALT:
+               if (value)
+                       sysrq_alt = code;
+               else {
+                       if (sysrq_down && code == sysrq_alt_use)
+                               sysrq_down = false;
+
+                       sysrq_alt = 0;
+               }
+               break;
+
+       case KEY_SYSRQ:
+               if (value == 1 && sysrq_alt) {
+                       sysrq_down = true;
+                       sysrq_alt_use = sysrq_alt;
+               }
+               break;
+
+       default:
+               if (sysrq_down && value && value != 2)
+                       __handle_sysrq(sysrq_xlate[code], true);
+               break;
+       }
+
+out:
+       suppress = sysrq_down;
+       spin_unlock(&sysrq_event_lock);
+
+       return suppress;
+}
+
+static int sysrq_connect(struct input_handler *handler,
+                        struct input_dev *dev,
+                        const struct input_device_id *id)
+{
+       struct input_handle *handle;
+       int error;
+
+       sysrq_down = false;
+       sysrq_alt = 0;
+
+       handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+       if (!handle)
+               return -ENOMEM;
+
+       handle->dev = dev;
+       handle->handler = handler;
+       handle->name = "sysrq";
+
+       error = input_register_handle(handle);
+       if (error) {
+               pr_err("Failed to register input sysrq handler, error %d\n",
+                       error);
+               goto err_free;
+       }
+
+       error = input_open_device(handle);
+       if (error) {
+               pr_err("Failed to open input device, error %d\n", error);
+               goto err_unregister;
+       }
+
+       return 0;
+
+ err_unregister:
+       input_unregister_handle(handle);
+ err_free:
+       kfree(handle);
+       return error;
+}
+
+static void sysrq_disconnect(struct input_handle *handle)
+{
+       input_close_device(handle);
+       input_unregister_handle(handle);
+       kfree(handle);
+}
+
+/*
+ * We are matching on KEY_LEFTALT instead of KEY_SYSRQ because not all
+ * keyboards have SysRq key predefined and so user may add it to keymap
+ * later, but we expect all such keyboards to have left alt.
+ */
+static const struct input_device_id sysrq_ids[] = {
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                               INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { BIT_MASK(KEY_LEFTALT) },
+       },
+       { },
+};
+
+static struct input_handler sysrq_handler = {
+       .filter         = sysrq_filter,
+       .connect        = sysrq_connect,
+       .disconnect     = sysrq_disconnect,
+       .name           = "sysrq",
+       .id_table       = sysrq_ids,
+};
+
+static bool sysrq_handler_registered;
+
+static inline void sysrq_register_handler(void)
+{
+       int error;
+
+       error = input_register_handler(&sysrq_handler);
+       if (error)
+               pr_err("Failed to register input handler, error %d", error);
+       else
+               sysrq_handler_registered = true;
+}
+
+static inline void sysrq_unregister_handler(void)
+{
+       if (sysrq_handler_registered) {
+               input_unregister_handler(&sysrq_handler);
+               sysrq_handler_registered = false;
+       }
+}
+
+#else
+
+static inline void sysrq_register_handler(void)
+{
+}
+
+static inline void sysrq_unregister_handler(void)
+{
+}
+
+#endif /* CONFIG_INPUT */
+
+int sysrq_toggle_support(int enable_mask)
+{
+       bool was_enabled = sysrq_on();
+
+       sysrq_enabled = enable_mask;
+
+       if (was_enabled != sysrq_on()) {
+               if (sysrq_on())
+                       sysrq_register_handler();
+               else
+                       sysrq_unregister_handler();
+       }
+
+       return 0;
+}
+
+static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
+                                struct sysrq_key_op *remove_op_p)
+{
+       int retval;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sysrq_key_table_lock, flags);
+       if (__sysrq_get_key_op(key) == remove_op_p) {
+               __sysrq_put_key_op(key, insert_op_p);
+               retval = 0;
+       } else {
+               retval = -1;
+       }
+       spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
+       return retval;
+}
+
+int register_sysrq_key(int key, struct sysrq_key_op *op_p)
+{
+       return __sysrq_swap_key_ops(key, op_p, NULL);
+}
+EXPORT_SYMBOL(register_sysrq_key);
+
+int unregister_sysrq_key(int key, struct sysrq_key_op *op_p)
+{
+       return __sysrq_swap_key_ops(key, NULL, op_p);
+}
+EXPORT_SYMBOL(unregister_sysrq_key);
+
+#ifdef CONFIG_PROC_FS
+/*
+ * writing 'C' to /proc/sysrq-trigger is like sysrq-C
+ */
+static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
+                                  size_t count, loff_t *ppos)
+{
+       if (count) {
+               char c;
+
+               if (get_user(c, buf))
+                       return -EFAULT;
+               __handle_sysrq(c, false);
+       }
+
+       return count;
+}
+
+static const struct file_operations proc_sysrq_trigger_operations = {
+       .write          = write_sysrq_trigger,
+       .llseek         = noop_llseek,
+};
+
+static void sysrq_init_procfs(void)
+{
+       if (!proc_create("sysrq-trigger", S_IWUSR, NULL,
+                        &proc_sysrq_trigger_operations))
+               pr_err("Failed to register proc interface\n");
+}
+
+#else
+
+static inline void sysrq_init_procfs(void)
+{
+}
+
+#endif /* CONFIG_PROC_FS */
+
+static int __init sysrq_init(void)
+{
+       sysrq_init_procfs();
+
+       if (sysrq_on())
+               sysrq_register_handler();
+
+       return 0;
+}
+module_init(sysrq_init);
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c
new file mode 100644 (file)
index 0000000..f64582b
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * Creating audit events from TTY input.
+ *
+ * Copyright (C) 2007 Red Hat, Inc.  All rights reserved.  This copyrighted
+ * material is made available to anyone wishing to use, modify, copy, or
+ * redistribute it subject to the terms and conditions of the GNU General
+ * Public License v.2.
+ *
+ * Authors: Miloslav Trmac <mitr@redhat.com>
+ */
+
+#include <linux/audit.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+
+struct tty_audit_buf {
+       atomic_t count;
+       struct mutex mutex;     /* Protects all data below */
+       int major, minor;       /* The TTY which the data is from */
+       unsigned icanon:1;
+       size_t valid;
+       unsigned char *data;    /* Allocated size N_TTY_BUF_SIZE */
+};
+
+static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor,
+                                                int icanon)
+{
+       struct tty_audit_buf *buf;
+
+       buf = kmalloc(sizeof(*buf), GFP_KERNEL);
+       if (!buf)
+               goto err;
+       buf->data = kmalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
+       if (!buf->data)
+               goto err_buf;
+       atomic_set(&buf->count, 1);
+       mutex_init(&buf->mutex);
+       buf->major = major;
+       buf->minor = minor;
+       buf->icanon = icanon;
+       buf->valid = 0;
+       return buf;
+
+err_buf:
+       kfree(buf);
+err:
+       return NULL;
+}
+
+static void tty_audit_buf_free(struct tty_audit_buf *buf)
+{
+       WARN_ON(buf->valid != 0);
+       kfree(buf->data);
+       kfree(buf);
+}
+
+static void tty_audit_buf_put(struct tty_audit_buf *buf)
+{
+       if (atomic_dec_and_test(&buf->count))
+               tty_audit_buf_free(buf);
+}
+
+static void tty_audit_log(const char *description, struct task_struct *tsk,
+                         uid_t loginuid, unsigned sessionid, int major,
+                         int minor, unsigned char *data, size_t size)
+{
+       struct audit_buffer *ab;
+
+       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY);
+       if (ab) {
+               char name[sizeof(tsk->comm)];
+               uid_t uid = task_uid(tsk);
+
+               audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u "
+                                "major=%d minor=%d comm=", description,
+                                tsk->pid, uid, loginuid, sessionid,
+                                major, minor);
+               get_task_comm(name, tsk);
+               audit_log_untrustedstring(ab, name);
+               audit_log_format(ab, " data=");
+               audit_log_n_hex(ab, data, size);
+               audit_log_end(ab);
+       }
+}
+
+/**
+ *     tty_audit_buf_push      -       Push buffered data out
+ *
+ *     Generate an audit message from the contents of @buf, which is owned by
+ *     @tsk with @loginuid.  @buf->mutex must be locked.
+ */
+static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
+                              unsigned int sessionid,
+                              struct tty_audit_buf *buf)
+{
+       if (buf->valid == 0)
+               return;
+       if (audit_enabled == 0)
+               return;
+       tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor,
+                     buf->data, buf->valid);
+       buf->valid = 0;
+}
+
+/**
+ *     tty_audit_buf_push_current      -       Push buffered data out
+ *
+ *     Generate an audit message from the contents of @buf, which is owned by
+ *     the current task.  @buf->mutex must be locked.
+ */
+static void tty_audit_buf_push_current(struct tty_audit_buf *buf)
+{
+       uid_t auid = audit_get_loginuid(current);
+       unsigned int sessionid = audit_get_sessionid(current);
+       tty_audit_buf_push(current, auid, sessionid, buf);
+}
+
+/**
+ *     tty_audit_exit  -       Handle a task exit
+ *
+ *     Make sure all buffered data is written out and deallocate the buffer.
+ *     Only needs to be called if current->signal->tty_audit_buf != %NULL.
+ */
+void tty_audit_exit(void)
+{
+       struct tty_audit_buf *buf;
+
+       spin_lock_irq(&current->sighand->siglock);
+       buf = current->signal->tty_audit_buf;
+       current->signal->tty_audit_buf = NULL;
+       spin_unlock_irq(&current->sighand->siglock);
+       if (!buf)
+               return;
+
+       mutex_lock(&buf->mutex);
+       tty_audit_buf_push_current(buf);
+       mutex_unlock(&buf->mutex);
+
+       tty_audit_buf_put(buf);
+}
+
+/**
+ *     tty_audit_fork  -       Copy TTY audit state for a new task
+ *
+ *     Set up TTY audit state in @sig from current.  @sig needs no locking.
+ */
+void tty_audit_fork(struct signal_struct *sig)
+{
+       spin_lock_irq(&current->sighand->siglock);
+       sig->audit_tty = current->signal->audit_tty;
+       spin_unlock_irq(&current->sighand->siglock);
+}
+
+/**
+ *     tty_audit_tiocsti       -       Log TIOCSTI
+ */
+void tty_audit_tiocsti(struct tty_struct *tty, char ch)
+{
+       struct tty_audit_buf *buf;
+       int major, minor, should_audit;
+
+       spin_lock_irq(&current->sighand->siglock);
+       should_audit = current->signal->audit_tty;
+       buf = current->signal->tty_audit_buf;
+       if (buf)
+               atomic_inc(&buf->count);
+       spin_unlock_irq(&current->sighand->siglock);
+
+       major = tty->driver->major;
+       minor = tty->driver->minor_start + tty->index;
+       if (buf) {
+               mutex_lock(&buf->mutex);
+               if (buf->major == major && buf->minor == minor)
+                       tty_audit_buf_push_current(buf);
+               mutex_unlock(&buf->mutex);
+               tty_audit_buf_put(buf);
+       }
+
+       if (should_audit && audit_enabled) {
+               uid_t auid;
+               unsigned int sessionid;
+
+               auid = audit_get_loginuid(current);
+               sessionid = audit_get_sessionid(current);
+               tty_audit_log("ioctl=TIOCSTI", current, auid, sessionid, major,
+                             minor, &ch, 1);
+       }
+}
+
+/**
+ * tty_audit_push_task -       Flush task's pending audit data
+ * @tsk:               task pointer
+ * @loginuid:          sender login uid
+ * @sessionid:         sender session id
+ *
+ * Called with a ref on @tsk held. Try to lock sighand and get a
+ * reference to the tty audit buffer if available.
+ * Flush the buffer or return an appropriate error code.
+ */
+int tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
+{
+       struct tty_audit_buf *buf = ERR_PTR(-EPERM);
+       unsigned long flags;
+
+       if (!lock_task_sighand(tsk, &flags))
+               return -ESRCH;
+
+       if (tsk->signal->audit_tty) {
+               buf = tsk->signal->tty_audit_buf;
+               if (buf)
+                       atomic_inc(&buf->count);
+       }
+       unlock_task_sighand(tsk, &flags);
+
+       /*
+        * Return 0 when signal->audit_tty set
+        * but tsk->signal->tty_audit_buf == NULL.
+        */
+       if (!buf || IS_ERR(buf))
+               return PTR_ERR(buf);
+
+       mutex_lock(&buf->mutex);
+       tty_audit_buf_push(tsk, loginuid, sessionid, buf);
+       mutex_unlock(&buf->mutex);
+
+       tty_audit_buf_put(buf);
+       return 0;
+}
+
+/**
+ *     tty_audit_buf_get       -       Get an audit buffer.
+ *
+ *     Get an audit buffer for @tty, allocate it if necessary.  Return %NULL
+ *     if TTY auditing is disabled or out of memory.  Otherwise, return a new
+ *     reference to the buffer.
+ */
+static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty)
+{
+       struct tty_audit_buf *buf, *buf2;
+
+       buf = NULL;
+       buf2 = NULL;
+       spin_lock_irq(&current->sighand->siglock);
+       if (likely(!current->signal->audit_tty))
+               goto out;
+       buf = current->signal->tty_audit_buf;
+       if (buf) {
+               atomic_inc(&buf->count);
+               goto out;
+       }
+       spin_unlock_irq(&current->sighand->siglock);
+
+       buf2 = tty_audit_buf_alloc(tty->driver->major,
+                                  tty->driver->minor_start + tty->index,
+                                  tty->icanon);
+       if (buf2 == NULL) {
+               audit_log_lost("out of memory in TTY auditing");
+               return NULL;
+       }
+
+       spin_lock_irq(&current->sighand->siglock);
+       if (!current->signal->audit_tty)
+               goto out;
+       buf = current->signal->tty_audit_buf;
+       if (!buf) {
+               current->signal->tty_audit_buf = buf2;
+               buf = buf2;
+               buf2 = NULL;
+       }
+       atomic_inc(&buf->count);
+       /* Fall through */
+ out:
+       spin_unlock_irq(&current->sighand->siglock);
+       if (buf2)
+               tty_audit_buf_free(buf2);
+       return buf;
+}
+
+/**
+ *     tty_audit_add_data      -       Add data for TTY auditing.
+ *
+ *     Audit @data of @size from @tty, if necessary.
+ */
+void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
+                       size_t size)
+{
+       struct tty_audit_buf *buf;
+       int major, minor;
+
+       if (unlikely(size == 0))
+               return;
+
+       if (tty->driver->type == TTY_DRIVER_TYPE_PTY
+           && tty->driver->subtype == PTY_TYPE_MASTER)
+               return;
+
+       buf = tty_audit_buf_get(tty);
+       if (!buf)
+               return;
+
+       mutex_lock(&buf->mutex);
+       major = tty->driver->major;
+       minor = tty->driver->minor_start + tty->index;
+       if (buf->major != major || buf->minor != minor
+           || buf->icanon != tty->icanon) {
+               tty_audit_buf_push_current(buf);
+               buf->major = major;
+               buf->minor = minor;
+               buf->icanon = tty->icanon;
+       }
+       do {
+               size_t run;
+
+               run = N_TTY_BUF_SIZE - buf->valid;
+               if (run > size)
+                       run = size;
+               memcpy(buf->data + buf->valid, data, run);
+               buf->valid += run;
+               data += run;
+               size -= run;
+               if (buf->valid == N_TTY_BUF_SIZE)
+                       tty_audit_buf_push_current(buf);
+       } while (size != 0);
+       mutex_unlock(&buf->mutex);
+       tty_audit_buf_put(buf);
+}
+
+/**
+ *     tty_audit_push  -       Push buffered data out
+ *
+ *     Make sure no audit data is pending for @tty on the current process.
+ */
+void tty_audit_push(struct tty_struct *tty)
+{
+       struct tty_audit_buf *buf;
+
+       spin_lock_irq(&current->sighand->siglock);
+       if (likely(!current->signal->audit_tty)) {
+               spin_unlock_irq(&current->sighand->siglock);
+               return;
+       }
+       buf = current->signal->tty_audit_buf;
+       if (buf)
+               atomic_inc(&buf->count);
+       spin_unlock_irq(&current->sighand->siglock);
+
+       if (buf) {
+               int major, minor;
+
+               major = tty->driver->major;
+               minor = tty->driver->minor_start + tty->index;
+               mutex_lock(&buf->mutex);
+               if (buf->major == major && buf->minor == minor)
+                       tty_audit_buf_push_current(buf);
+               mutex_unlock(&buf->mutex);
+               tty_audit_buf_put(buf);
+       }
+}
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
new file mode 100644 (file)
index 0000000..d8210ca
--- /dev/null
@@ -0,0 +1,534 @@
+/*
+ * Tty buffer allocation management
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/timer.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+
+/**
+ *     tty_buffer_free_all             -       free buffers used by a tty
+ *     @tty: tty to free from
+ *
+ *     Remove all the buffers pending on a tty whether queued with data
+ *     or in the free ring. Must be called when the tty is no longer in use
+ *
+ *     Locking: none
+ */
+
+void tty_buffer_free_all(struct tty_struct *tty)
+{
+       struct tty_buffer *thead;
+       while ((thead = tty->buf.head) != NULL) {
+               tty->buf.head = thead->next;
+               kfree(thead);
+       }
+       while ((thead = tty->buf.free) != NULL) {
+               tty->buf.free = thead->next;
+               kfree(thead);
+       }
+       tty->buf.tail = NULL;
+       tty->buf.memory_used = 0;
+}
+
+/**
+ *     tty_buffer_alloc        -       allocate a tty buffer
+ *     @tty: tty device
+ *     @size: desired size (characters)
+ *
+ *     Allocate a new tty buffer to hold the desired number of characters.
+ *     Return NULL if out of memory or the allocation would exceed the
+ *     per device queue
+ *
+ *     Locking: Caller must hold tty->buf.lock
+ */
+
+static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
+{
+       struct tty_buffer *p;
+
+       if (tty->buf.memory_used + size > 65536)
+               return NULL;
+       p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC);
+       if (p == NULL)
+               return NULL;
+       p->used = 0;
+       p->size = size;
+       p->next = NULL;
+       p->commit = 0;
+       p->read = 0;
+       p->char_buf_ptr = (char *)(p->data);
+       p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
+       tty->buf.memory_used += size;
+       return p;
+}
+
+/**
+ *     tty_buffer_free         -       free a tty buffer
+ *     @tty: tty owning the buffer
+ *     @b: the buffer to free
+ *
+ *     Free a tty buffer, or add it to the free list according to our
+ *     internal strategy
+ *
+ *     Locking: Caller must hold tty->buf.lock
+ */
+
+static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
+{
+       /* Dumb strategy for now - should keep some stats */
+       tty->buf.memory_used -= b->size;
+       WARN_ON(tty->buf.memory_used < 0);
+
+       if (b->size >= 512)
+               kfree(b);
+       else {
+               b->next = tty->buf.free;
+               tty->buf.free = b;
+       }
+}
+
+/**
+ *     __tty_buffer_flush              -       flush full tty buffers
+ *     @tty: tty to flush
+ *
+ *     flush all the buffers containing receive data. Caller must
+ *     hold the buffer lock and must have ensured no parallel flush to
+ *     ldisc is running.
+ *
+ *     Locking: Caller must hold tty->buf.lock
+ */
+
+static void __tty_buffer_flush(struct tty_struct *tty)
+{
+       struct tty_buffer *thead;
+
+       while ((thead = tty->buf.head) != NULL) {
+               tty->buf.head = thead->next;
+               tty_buffer_free(tty, thead);
+       }
+       tty->buf.tail = NULL;
+}
+
+/**
+ *     tty_buffer_flush                -       flush full tty buffers
+ *     @tty: tty to flush
+ *
+ *     flush all the buffers containing receive data. If the buffer is
+ *     being processed by flush_to_ldisc then we defer the processing
+ *     to that function
+ *
+ *     Locking: none
+ */
+
+void tty_buffer_flush(struct tty_struct *tty)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&tty->buf.lock, flags);
+
+       /* If the data is being pushed to the tty layer then we can't
+          process it here. Instead set a flag and the flush_to_ldisc
+          path will process the flush request before it exits */
+       if (test_bit(TTY_FLUSHING, &tty->flags)) {
+               set_bit(TTY_FLUSHPENDING, &tty->flags);
+               spin_unlock_irqrestore(&tty->buf.lock, flags);
+               wait_event(tty->read_wait,
+                               test_bit(TTY_FLUSHPENDING, &tty->flags) == 0);
+               return;
+       } else
+               __tty_buffer_flush(tty);
+       spin_unlock_irqrestore(&tty->buf.lock, flags);
+}
+
+/**
+ *     tty_buffer_find         -       find a free tty buffer
+ *     @tty: tty owning the buffer
+ *     @size: characters wanted
+ *
+ *     Locate an existing suitable tty buffer or if we are lacking one then
+ *     allocate a new one. We round our buffers off in 256 character chunks
+ *     to get better allocation behaviour.
+ *
+ *     Locking: Caller must hold tty->buf.lock
+ */
+
+static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
+{
+       struct tty_buffer **tbh = &tty->buf.free;
+       while ((*tbh) != NULL) {
+               struct tty_buffer *t = *tbh;
+               if (t->size >= size) {
+                       *tbh = t->next;
+                       t->next = NULL;
+                       t->used = 0;
+                       t->commit = 0;
+                       t->read = 0;
+                       tty->buf.memory_used += t->size;
+                       return t;
+               }
+               tbh = &((*tbh)->next);
+       }
+       /* Round the buffer size out */
+       size = (size + 0xFF) & ~0xFF;
+       return tty_buffer_alloc(tty, size);
+       /* Should possibly check if this fails for the largest buffer we
+          have queued and recycle that ? */
+}
+
+/**
+ *     tty_buffer_request_room         -       grow tty buffer if needed
+ *     @tty: tty structure
+ *     @size: size desired
+ *
+ *     Make at least size bytes of linear space available for the tty
+ *     buffer. If we fail return the size we managed to find.
+ *
+ *     Locking: Takes tty->buf.lock
+ */
+int tty_buffer_request_room(struct tty_struct *tty, size_t size)
+{
+       struct tty_buffer *b, *n;
+       int left;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tty->buf.lock, flags);
+
+       /* OPTIMISATION: We could keep a per tty "zero" sized buffer to
+          remove this conditional if its worth it. This would be invisible
+          to the callers */
+       if ((b = tty->buf.tail) != NULL)
+               left = b->size - b->used;
+       else
+               left = 0;
+
+       if (left < size) {
+               /* This is the slow path - looking for new buffers to use */
+               if ((n = tty_buffer_find(tty, size)) != NULL) {
+                       if (b != NULL) {
+                               b->next = n;
+                               b->commit = b->used;
+                       } else
+                               tty->buf.head = n;
+                       tty->buf.tail = n;
+               } else
+                       size = left;
+       }
+
+       spin_unlock_irqrestore(&tty->buf.lock, flags);
+       return size;
+}
+EXPORT_SYMBOL_GPL(tty_buffer_request_room);
+
+/**
+ *     tty_insert_flip_string_fixed_flag - Add characters to the tty buffer
+ *     @tty: tty structure
+ *     @chars: characters
+ *     @flag: flag value for each character
+ *     @size: size
+ *
+ *     Queue a series of bytes to the tty buffering. All the characters
+ *     passed are marked with the supplied flag. Returns the number added.
+ *
+ *     Locking: Called functions may take tty->buf.lock
+ */
+
+int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
+               const unsigned char *chars, char flag, size_t size)
+{
+       int copied = 0;
+       do {
+               int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
+               int space = tty_buffer_request_room(tty, goal);
+               struct tty_buffer *tb = tty->buf.tail;
+               /* If there is no space then tb may be NULL */
+               if (unlikely(space == 0))
+                       break;
+               memcpy(tb->char_buf_ptr + tb->used, chars, space);
+               memset(tb->flag_buf_ptr + tb->used, flag, space);
+               tb->used += space;
+               copied += space;
+               chars += space;
+               /* There is a small chance that we need to split the data over
+                  several buffers. If this is the case we must loop */
+       } while (unlikely(size > copied));
+       return copied;
+}
+EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag);
+
+/**
+ *     tty_insert_flip_string_flags    -       Add characters to the tty buffer
+ *     @tty: tty structure
+ *     @chars: characters
+ *     @flags: flag bytes
+ *     @size: size
+ *
+ *     Queue a series of bytes to the tty buffering. For each character
+ *     the flags array indicates the status of the character. Returns the
+ *     number added.
+ *
+ *     Locking: Called functions may take tty->buf.lock
+ */
+
+int tty_insert_flip_string_flags(struct tty_struct *tty,
+               const unsigned char *chars, const char *flags, size_t size)
+{
+       int copied = 0;
+       do {
+               int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
+               int space = tty_buffer_request_room(tty, goal);
+               struct tty_buffer *tb = tty->buf.tail;
+               /* If there is no space then tb may be NULL */
+               if (unlikely(space == 0))
+                       break;
+               memcpy(tb->char_buf_ptr + tb->used, chars, space);
+               memcpy(tb->flag_buf_ptr + tb->used, flags, space);
+               tb->used += space;
+               copied += space;
+               chars += space;
+               flags += space;
+               /* There is a small chance that we need to split the data over
+                  several buffers. If this is the case we must loop */
+       } while (unlikely(size > copied));
+       return copied;
+}
+EXPORT_SYMBOL(tty_insert_flip_string_flags);
+
+/**
+ *     tty_schedule_flip       -       push characters to ldisc
+ *     @tty: tty to push from
+ *
+ *     Takes any pending buffers and transfers their ownership to the
+ *     ldisc side of the queue. It then schedules those characters for
+ *     processing by the line discipline.
+ *
+ *     Locking: Takes tty->buf.lock
+ */
+
+void tty_schedule_flip(struct tty_struct *tty)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&tty->buf.lock, flags);
+       if (tty->buf.tail != NULL)
+               tty->buf.tail->commit = tty->buf.tail->used;
+       spin_unlock_irqrestore(&tty->buf.lock, flags);
+       schedule_delayed_work(&tty->buf.work, 1);
+}
+EXPORT_SYMBOL(tty_schedule_flip);
+
+/**
+ *     tty_prepare_flip_string         -       make room for characters
+ *     @tty: tty
+ *     @chars: return pointer for character write area
+ *     @size: desired size
+ *
+ *     Prepare a block of space in the buffer for data. Returns the length
+ *     available and buffer pointer to the space which is now allocated and
+ *     accounted for as ready for normal characters. This is used for drivers
+ *     that need their own block copy routines into the buffer. There is no
+ *     guarantee the buffer is a DMA target!
+ *
+ *     Locking: May call functions taking tty->buf.lock
+ */
+
+int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars,
+                                                               size_t size)
+{
+       int space = tty_buffer_request_room(tty, size);
+       if (likely(space)) {
+               struct tty_buffer *tb = tty->buf.tail;
+               *chars = tb->char_buf_ptr + tb->used;
+               memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
+               tb->used += space;
+       }
+       return space;
+}
+EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
+
+/**
+ *     tty_prepare_flip_string_flags   -       make room for characters
+ *     @tty: tty
+ *     @chars: return pointer for character write area
+ *     @flags: return pointer for status flag write area
+ *     @size: desired size
+ *
+ *     Prepare a block of space in the buffer for data. Returns the length
+ *     available and buffer pointer to the space which is now allocated and
+ *     accounted for as ready for characters. This is used for drivers
+ *     that need their own block copy routines into the buffer. There is no
+ *     guarantee the buffer is a DMA target!
+ *
+ *     Locking: May call functions taking tty->buf.lock
+ */
+
+int tty_prepare_flip_string_flags(struct tty_struct *tty,
+                       unsigned char **chars, char **flags, size_t size)
+{
+       int space = tty_buffer_request_room(tty, size);
+       if (likely(space)) {
+               struct tty_buffer *tb = tty->buf.tail;
+               *chars = tb->char_buf_ptr + tb->used;
+               *flags = tb->flag_buf_ptr + tb->used;
+               tb->used += space;
+       }
+       return space;
+}
+EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
+
+
+
+/**
+ *     flush_to_ldisc
+ *     @work: tty structure passed from work queue.
+ *
+ *     This routine is called out of the software interrupt to flush data
+ *     from the buffer chain to the line discipline.
+ *
+ *     Locking: holds tty->buf.lock to guard buffer list. Drops the lock
+ *     while invoking the line discipline receive_buf method. The
+ *     receive_buf method is single threaded for each tty instance.
+ */
+
+static void flush_to_ldisc(struct work_struct *work)
+{
+       struct tty_struct *tty =
+               container_of(work, struct tty_struct, buf.work.work);
+       unsigned long   flags;
+       struct tty_ldisc *disc;
+
+       disc = tty_ldisc_ref(tty);
+       if (disc == NULL)       /*  !TTY_LDISC */
+               return;
+
+       spin_lock_irqsave(&tty->buf.lock, flags);
+
+       if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
+               struct tty_buffer *head, *tail = tty->buf.tail;
+               int seen_tail = 0;
+               while ((head = tty->buf.head) != NULL) {
+                       int count;
+                       char *char_buf;
+                       unsigned char *flag_buf;
+
+                       count = head->commit - head->read;
+                       if (!count) {
+                               if (head->next == NULL)
+                                       break;
+                               /*
+                                 There's a possibility tty might get new buffer
+                                 added during the unlock window below. We could
+                                 end up spinning in here forever hogging the CPU
+                                 completely. To avoid this let's have a rest each
+                                 time we processed the tail buffer.
+                               */
+                               if (tail == head)
+                                       seen_tail = 1;
+                               tty->buf.head = head->next;
+                               tty_buffer_free(tty, head);
+                               continue;
+                       }
+                       /* Ldisc or user is trying to flush the buffers
+                          we are feeding to the ldisc, stop feeding the
+                          line discipline as we want to empty the queue */
+                       if (test_bit(TTY_FLUSHPENDING, &tty->flags))
+                               break;
+                       if (!tty->receive_room || seen_tail) {
+                               schedule_delayed_work(&tty->buf.work, 1);
+                               break;
+                       }
+                       if (count > tty->receive_room)
+                               count = tty->receive_room;
+                       char_buf = head->char_buf_ptr + head->read;
+                       flag_buf = head->flag_buf_ptr + head->read;
+                       head->read += count;
+                       spin_unlock_irqrestore(&tty->buf.lock, flags);
+                       disc->ops->receive_buf(tty, char_buf,
+                                                       flag_buf, count);
+                       spin_lock_irqsave(&tty->buf.lock, flags);
+               }
+               clear_bit(TTY_FLUSHING, &tty->flags);
+       }
+
+       /* We may have a deferred request to flush the input buffer,
+          if so pull the chain under the lock and empty the queue */
+       if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
+               __tty_buffer_flush(tty);
+               clear_bit(TTY_FLUSHPENDING, &tty->flags);
+               wake_up(&tty->read_wait);
+       }
+       spin_unlock_irqrestore(&tty->buf.lock, flags);
+
+       tty_ldisc_deref(disc);
+}
+
+/**
+ *     tty_flush_to_ldisc
+ *     @tty: tty to push
+ *
+ *     Push the terminal flip buffers to the line discipline.
+ *
+ *     Must not be called from IRQ context.
+ */
+void tty_flush_to_ldisc(struct tty_struct *tty)
+{
+       flush_delayed_work(&tty->buf.work);
+}
+
+/**
+ *     tty_flip_buffer_push    -       terminal
+ *     @tty: tty to push
+ *
+ *     Queue a push of the terminal flip buffers to the line discipline. This
+ *     function must not be called from IRQ context if tty->low_latency is set.
+ *
+ *     In the event of the queue being busy for flipping the work will be
+ *     held off and retried later.
+ *
+ *     Locking: tty buffer lock. Driver locks in low latency mode.
+ */
+
+void tty_flip_buffer_push(struct tty_struct *tty)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&tty->buf.lock, flags);
+       if (tty->buf.tail != NULL)
+               tty->buf.tail->commit = tty->buf.tail->used;
+       spin_unlock_irqrestore(&tty->buf.lock, flags);
+
+       if (tty->low_latency)
+               flush_to_ldisc(&tty->buf.work.work);
+       else
+               schedule_delayed_work(&tty->buf.work, 1);
+}
+EXPORT_SYMBOL(tty_flip_buffer_push);
+
+/**
+ *     tty_buffer_init         -       prepare a tty buffer structure
+ *     @tty: tty to initialise
+ *
+ *     Set up the initial state of the buffer management for a tty device.
+ *     Must be called before the other tty buffer functions are used.
+ *
+ *     Locking: none
+ */
+
+void tty_buffer_init(struct tty_struct *tty)
+{
+       spin_lock_init(&tty->buf.lock);
+       tty->buf.head = NULL;
+       tty->buf.tail = NULL;
+       tty->buf.free = NULL;
+       tty->buf.memory_used = 0;
+       INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc);
+}
+
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
new file mode 100644 (file)
index 0000000..c05c5af
--- /dev/null
@@ -0,0 +1,3263 @@
+/*
+ *  linux/drivers/char/tty_io.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+/*
+ * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
+ * or rs-channels. It also implements echoing, cooked mode etc.
+ *
+ * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
+ *
+ * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the
+ * tty_struct and tty_queue structures.  Previously there was an array
+ * of 256 tty_struct's which was statically allocated, and the
+ * tty_queue structures were allocated at boot time.  Both are now
+ * dynamically allocated only when the tty is open.
+ *
+ * Also restructured routines so that there is more of a separation
+ * between the high-level tty routines (tty_io.c and tty_ioctl.c) and
+ * the low-level tty routines (serial.c, pty.c, console.c).  This
+ * makes for cleaner and more compact code.  -TYT, 9/17/92
+ *
+ * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
+ * which can be dynamically activated and de-activated by the line
+ * discipline handling modules (like SLIP).
+ *
+ * NOTE: pay no attention to the line discipline code (yet); its
+ * interface is still subject to change in this version...
+ * -- TYT, 1/31/92
+ *
+ * Added functionality to the OPOST tty handling.  No delays, but all
+ * other bits should be there.
+ *     -- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993.
+ *
+ * Rewrote canonical mode and added more termios flags.
+ *     -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94
+ *
+ * Reorganized FASYNC support so mouse code can share it.
+ *     -- ctm@ardi.com, 9Sep95
+ *
+ * New TIOCLINUX variants added.
+ *     -- mj@k332.feld.cvut.cz, 19-Nov-95
+ *
+ * Restrict vt switching via ioctl()
+ *      -- grif@cs.ucr.edu, 5-Dec-95
+ *
+ * Move console and virtual terminal code to more appropriate files,
+ * implement CONFIG_VT and generalize console device interface.
+ *     -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97
+ *
+ * Rewrote tty_init_dev and tty_release_dev to eliminate races.
+ *     -- Bill Hawes <whawes@star.net>, June 97
+ *
+ * Added devfs support.
+ *      -- C. Scott Ananian <cananian@alumni.princeton.edu>, 13-Jan-1998
+ *
+ * Added support for a Unix98-style ptmx device.
+ *      -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
+ *
+ * Reduced memory usage for older ARM systems
+ *      -- Russell King <rmk@arm.linux.org.uk>
+ *
+ * Move do_SAK() into process context.  Less stack use in devfs functions.
+ * alloc_tty_struct() always uses kmalloc()
+ *                      -- Andrew Morton <andrewm@uow.edu.eu> 17Mar01
+ */
+
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/devpts_fs.h>
+#include <linux/file.h>
+#include <linux/fdtable.h>
+#include <linux/console.h>
+#include <linux/timer.h>
+#include <linux/ctype.h>
+#include <linux/kd.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/serial.h>
+
+#include <linux/uaccess.h>
+#include <asm/system.h>
+
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+
+#include <linux/kmod.h>
+#include <linux/nsproxy.h>
+
+#undef TTY_DEBUG_HANGUP
+
+#define TTY_PARANOIA_CHECK 1
+#define CHECK_TTY_COUNT 1
+
+struct ktermios tty_std_termios = {    /* for the benefit of tty drivers  */
+       .c_iflag = ICRNL | IXON,
+       .c_oflag = OPOST | ONLCR,
+       .c_cflag = B38400 | CS8 | CREAD | HUPCL,
+       .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
+                  ECHOCTL | ECHOKE | IEXTEN,
+       .c_cc = INIT_C_CC,
+       .c_ispeed = 38400,
+       .c_ospeed = 38400
+};
+
+EXPORT_SYMBOL(tty_std_termios);
+
+/* This list gets poked at by procfs and various bits of boot up code. This
+   could do with some rationalisation such as pulling the tty proc function
+   into this file */
+
+LIST_HEAD(tty_drivers);                        /* linked list of tty drivers */
+
+/* Mutex to protect creating and releasing a tty. This is shared with
+   vt.c for deeply disgusting hack reasons */
+DEFINE_MUTEX(tty_mutex);
+EXPORT_SYMBOL(tty_mutex);
+
+/* Spinlock to protect the tty->tty_files list */
+DEFINE_SPINLOCK(tty_files_lock);
+
+static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
+ssize_t redirected_tty_write(struct file *, const char __user *,
+                                                       size_t, loff_t *);
+static unsigned int tty_poll(struct file *, poll_table *);
+static int tty_open(struct inode *, struct file *);
+long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+static long tty_compat_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg);
+#else
+#define tty_compat_ioctl NULL
+#endif
+static int __tty_fasync(int fd, struct file *filp, int on);
+static int tty_fasync(int fd, struct file *filp, int on);
+static void release_tty(struct tty_struct *tty, int idx);
+static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
+static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
+
+/**
+ *     alloc_tty_struct        -       allocate a tty object
+ *
+ *     Return a new empty tty structure. The data fields have not
+ *     been initialized in any way but has been zeroed
+ *
+ *     Locking: none
+ */
+
+struct tty_struct *alloc_tty_struct(void)
+{
+       return kzalloc(sizeof(struct tty_struct), GFP_KERNEL);
+}
+
+/**
+ *     free_tty_struct         -       free a disused tty
+ *     @tty: tty struct to free
+ *
+ *     Free the write buffers, tty queue and tty memory itself.
+ *
+ *     Locking: none. Must be called after tty is definitely unused
+ */
+
+void free_tty_struct(struct tty_struct *tty)
+{
+       if (tty->dev)
+               put_device(tty->dev);
+       kfree(tty->write_buf);
+       tty_buffer_free_all(tty);
+       kfree(tty);
+}
+
+static inline struct tty_struct *file_tty(struct file *file)
+{
+       return ((struct tty_file_private *)file->private_data)->tty;
+}
+
+/* Associate a new file with the tty structure */
+int tty_add_file(struct tty_struct *tty, struct file *file)
+{
+       struct tty_file_private *priv;
+
+       priv = kmalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->tty = tty;
+       priv->file = file;
+       file->private_data = priv;
+
+       spin_lock(&tty_files_lock);
+       list_add(&priv->list, &tty->tty_files);
+       spin_unlock(&tty_files_lock);
+
+       return 0;
+}
+
+/* Delete file from its tty */
+void tty_del_file(struct file *file)
+{
+       struct tty_file_private *priv = file->private_data;
+
+       spin_lock(&tty_files_lock);
+       list_del(&priv->list);
+       spin_unlock(&tty_files_lock);
+       file->private_data = NULL;
+       kfree(priv);
+}
+
+
+#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)
+
+/**
+ *     tty_name        -       return tty naming
+ *     @tty: tty structure
+ *     @buf: buffer for output
+ *
+ *     Convert a tty structure into a name. The name reflects the kernel
+ *     naming policy and if udev is in use may not reflect user space
+ *
+ *     Locking: none
+ */
+
+char *tty_name(struct tty_struct *tty, char *buf)
+{
+       if (!tty) /* Hmm.  NULL pointer.  That's fun. */
+               strcpy(buf, "NULL tty");
+       else
+               strcpy(buf, tty->name);
+       return buf;
+}
+
+EXPORT_SYMBOL(tty_name);
+
+int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
+                             const char *routine)
+{
+#ifdef TTY_PARANOIA_CHECK
+       if (!tty) {
+               printk(KERN_WARNING
+                       "null TTY for (%d:%d) in %s\n",
+                       imajor(inode), iminor(inode), routine);
+               return 1;
+       }
+       if (tty->magic != TTY_MAGIC) {
+               printk(KERN_WARNING
+                       "bad magic number for tty struct (%d:%d) in %s\n",
+                       imajor(inode), iminor(inode), routine);
+               return 1;
+       }
+#endif
+       return 0;
+}
+
+static int check_tty_count(struct tty_struct *tty, const char *routine)
+{
+#ifdef CHECK_TTY_COUNT
+       struct list_head *p;
+       int count = 0;
+
+       spin_lock(&tty_files_lock);
+       list_for_each(p, &tty->tty_files) {
+               count++;
+       }
+       spin_unlock(&tty_files_lock);
+       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
+           tty->driver->subtype == PTY_TYPE_SLAVE &&
+           tty->link && tty->link->count)
+               count++;
+       if (tty->count != count) {
+               printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) "
+                                   "!= #fd's(%d) in %s\n",
+                      tty->name, tty->count, count, routine);
+               return count;
+       }
+#endif
+       return 0;
+}
+
+/**
+ *     get_tty_driver          -       find device of a tty
+ *     @dev_t: device identifier
+ *     @index: returns the index of the tty
+ *
+ *     This routine returns a tty driver structure, given a device number
+ *     and also passes back the index number.
+ *
+ *     Locking: caller must hold tty_mutex
+ */
+
+static struct tty_driver *get_tty_driver(dev_t device, int *index)
+{
+       struct tty_driver *p;
+
+       list_for_each_entry(p, &tty_drivers, tty_drivers) {
+               dev_t base = MKDEV(p->major, p->minor_start);
+               if (device < base || device >= base + p->num)
+                       continue;
+               *index = device - base;
+               return tty_driver_kref_get(p);
+       }
+       return NULL;
+}
+
+#ifdef CONFIG_CONSOLE_POLL
+
+/**
+ *     tty_find_polling_driver -       find device of a polled tty
+ *     @name: name string to match
+ *     @line: pointer to resulting tty line nr
+ *
+ *     This routine returns a tty driver structure, given a name
+ *     and the condition that the tty driver is capable of polled
+ *     operation.
+ */
+struct tty_driver *tty_find_polling_driver(char *name, int *line)
+{
+       struct tty_driver *p, *res = NULL;
+       int tty_line = 0;
+       int len;
+       char *str, *stp;
+
+       for (str = name; *str; str++)
+               if ((*str >= '0' && *str <= '9') || *str == ',')
+                       break;
+       if (!*str)
+               return NULL;
+
+       len = str - name;
+       tty_line = simple_strtoul(str, &str, 10);
+
+       mutex_lock(&tty_mutex);
+       /* Search through the tty devices to look for a match */
+       list_for_each_entry(p, &tty_drivers, tty_drivers) {
+               if (strncmp(name, p->name, len) != 0)
+                       continue;
+               stp = str;
+               if (*stp == ',')
+                       stp++;
+               if (*stp == '\0')
+                       stp = NULL;
+
+               if (tty_line >= 0 && tty_line < p->num && p->ops &&
+                   p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
+                       res = tty_driver_kref_get(p);
+                       *line = tty_line;
+                       break;
+               }
+       }
+       mutex_unlock(&tty_mutex);
+
+       return res;
+}
+EXPORT_SYMBOL_GPL(tty_find_polling_driver);
+#endif
+
+/**
+ *     tty_check_change        -       check for POSIX terminal changes
+ *     @tty: tty to check
+ *
+ *     If we try to write to, or set the state of, a terminal and we're
+ *     not in the foreground, send a SIGTTOU.  If the signal is blocked or
+ *     ignored, go ahead and perform the operation.  (POSIX 7.2)
+ *
+ *     Locking: ctrl_lock
+ */
+
+int tty_check_change(struct tty_struct *tty)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       if (current->signal->tty != tty)
+               return 0;
+
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+
+       if (!tty->pgrp) {
+               printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
+               goto out_unlock;
+       }
+       if (task_pgrp(current) == tty->pgrp)
+               goto out_unlock;
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+       if (is_ignored(SIGTTOU))
+               goto out;
+       if (is_current_pgrp_orphaned()) {
+               ret = -EIO;
+               goto out;
+       }
+       kill_pgrp(task_pgrp(current), SIGTTOU, 1);
+       set_thread_flag(TIF_SIGPENDING);
+       ret = -ERESTARTSYS;
+out:
+       return ret;
+out_unlock:
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+       return ret;
+}
+
+EXPORT_SYMBOL(tty_check_change);
+
+static ssize_t hung_up_tty_read(struct file *file, char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       return 0;
+}
+
+static ssize_t hung_up_tty_write(struct file *file, const char __user *buf,
+                                size_t count, loff_t *ppos)
+{
+       return -EIO;
+}
+
+/* No kernel lock held - none needed ;) */
+static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait)
+{
+       return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
+}
+
+static long hung_up_tty_ioctl(struct file *file, unsigned int cmd,
+               unsigned long arg)
+{
+       return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
+}
+
+static long hung_up_tty_compat_ioctl(struct file *file,
+                                    unsigned int cmd, unsigned long arg)
+{
+       return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
+}
+
+static const struct file_operations tty_fops = {
+       .llseek         = no_llseek,
+       .read           = tty_read,
+       .write          = tty_write,
+       .poll           = tty_poll,
+       .unlocked_ioctl = tty_ioctl,
+       .compat_ioctl   = tty_compat_ioctl,
+       .open           = tty_open,
+       .release        = tty_release,
+       .fasync         = tty_fasync,
+};
+
+static const struct file_operations console_fops = {
+       .llseek         = no_llseek,
+       .read           = tty_read,
+       .write          = redirected_tty_write,
+       .poll           = tty_poll,
+       .unlocked_ioctl = tty_ioctl,
+       .compat_ioctl   = tty_compat_ioctl,
+       .open           = tty_open,
+       .release        = tty_release,
+       .fasync         = tty_fasync,
+};
+
+static const struct file_operations hung_up_tty_fops = {
+       .llseek         = no_llseek,
+       .read           = hung_up_tty_read,
+       .write          = hung_up_tty_write,
+       .poll           = hung_up_tty_poll,
+       .unlocked_ioctl = hung_up_tty_ioctl,
+       .compat_ioctl   = hung_up_tty_compat_ioctl,
+       .release        = tty_release,
+};
+
+static DEFINE_SPINLOCK(redirect_lock);
+static struct file *redirect;
+
+/**
+ *     tty_wakeup      -       request more data
+ *     @tty: terminal
+ *
+ *     Internal and external helper for wakeups of tty. This function
+ *     informs the line discipline if present that the driver is ready
+ *     to receive more output data.
+ */
+
+void tty_wakeup(struct tty_struct *tty)
+{
+       struct tty_ldisc *ld;
+
+       if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
+               ld = tty_ldisc_ref(tty);
+               if (ld) {
+                       if (ld->ops->write_wakeup)
+                               ld->ops->write_wakeup(tty);
+                       tty_ldisc_deref(ld);
+               }
+       }
+       wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+}
+
+EXPORT_SYMBOL_GPL(tty_wakeup);
+
+/**
+ *     __tty_hangup            -       actual handler for hangup events
+ *     @work: tty device
+ *
+ *     This can be called by the "eventd" kernel thread.  That is process
+ *     synchronous but doesn't hold any locks, so we need to make sure we
+ *     have the appropriate locks for what we're doing.
+ *
+ *     The hangup event clears any pending redirections onto the hung up
+ *     device. It ensures future writes will error and it does the needed
+ *     line discipline hangup and signal delivery. The tty object itself
+ *     remains intact.
+ *
+ *     Locking:
+ *             BTM
+ *               redirect lock for undoing redirection
+ *               file list lock for manipulating list of ttys
+ *               tty_ldisc_lock from called functions
+ *               termios_mutex resetting termios data
+ *               tasklist_lock to walk task list for hangup event
+ *                 ->siglock to protect ->signal/->sighand
+ */
+void __tty_hangup(struct tty_struct *tty)
+{
+       struct file *cons_filp = NULL;
+       struct file *filp, *f = NULL;
+       struct task_struct *p;
+       struct tty_file_private *priv;
+       int    closecount = 0, n;
+       unsigned long flags;
+       int refs = 0;
+
+       if (!tty)
+               return;
+
+
+       spin_lock(&redirect_lock);
+       if (redirect && file_tty(redirect) == tty) {
+               f = redirect;
+               redirect = NULL;
+       }
+       spin_unlock(&redirect_lock);
+
+       tty_lock();
+
+       /* inuse_filps is protected by the single tty lock,
+          this really needs to change if we want to flush the
+          workqueue with the lock held */
+       check_tty_count(tty, "tty_hangup");
+
+       spin_lock(&tty_files_lock);
+       /* This breaks for file handles being sent over AF_UNIX sockets ? */
+       list_for_each_entry(priv, &tty->tty_files, list) {
+               filp = priv->file;
+               if (filp->f_op->write == redirected_tty_write)
+                       cons_filp = filp;
+               if (filp->f_op->write != tty_write)
+                       continue;
+               closecount++;
+               __tty_fasync(-1, filp, 0);      /* can't block */
+               filp->f_op = &hung_up_tty_fops;
+       }
+       spin_unlock(&tty_files_lock);
+
+       tty_ldisc_hangup(tty);
+
+       read_lock(&tasklist_lock);
+       if (tty->session) {
+               do_each_pid_task(tty->session, PIDTYPE_SID, p) {
+                       spin_lock_irq(&p->sighand->siglock);
+                       if (p->signal->tty == tty) {
+                               p->signal->tty = NULL;
+                               /* We defer the dereferences outside fo
+                                  the tasklist lock */
+                               refs++;
+                       }
+                       if (!p->signal->leader) {
+                               spin_unlock_irq(&p->sighand->siglock);
+                               continue;
+                       }
+                       __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
+                       __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
+                       put_pid(p->signal->tty_old_pgrp);  /* A noop */
+                       spin_lock_irqsave(&tty->ctrl_lock, flags);
+                       if (tty->pgrp)
+                               p->signal->tty_old_pgrp = get_pid(tty->pgrp);
+                       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+                       spin_unlock_irq(&p->sighand->siglock);
+               } while_each_pid_task(tty->session, PIDTYPE_SID, p);
+       }
+       read_unlock(&tasklist_lock);
+
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+       clear_bit(TTY_THROTTLED, &tty->flags);
+       clear_bit(TTY_PUSH, &tty->flags);
+       clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+       put_pid(tty->session);
+       put_pid(tty->pgrp);
+       tty->session = NULL;
+       tty->pgrp = NULL;
+       tty->ctrl_status = 0;
+       set_bit(TTY_HUPPED, &tty->flags);
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+       /* Account for the p->signal references we killed */
+       while (refs--)
+               tty_kref_put(tty);
+
+       /*
+        * If one of the devices matches a console pointer, we
+        * cannot just call hangup() because that will cause
+        * tty->count and state->count to go out of sync.
+        * So we just call close() the right number of times.
+        */
+       if (cons_filp) {
+               if (tty->ops->close)
+                       for (n = 0; n < closecount; n++)
+                               tty->ops->close(tty, cons_filp);
+       } else if (tty->ops->hangup)
+               (tty->ops->hangup)(tty);
+       /*
+        * We don't want to have driver/ldisc interactions beyond
+        * the ones we did here. The driver layer expects no
+        * calls after ->hangup() from the ldisc side. However we
+        * can't yet guarantee all that.
+        */
+       set_bit(TTY_HUPPED, &tty->flags);
+       tty_ldisc_enable(tty);
+
+       tty_unlock();
+
+       if (f)
+               fput(f);
+}
+
+static void do_tty_hangup(struct work_struct *work)
+{
+       struct tty_struct *tty =
+               container_of(work, struct tty_struct, hangup_work);
+
+       __tty_hangup(tty);
+}
+
+/**
+ *     tty_hangup              -       trigger a hangup event
+ *     @tty: tty to hangup
+ *
+ *     A carrier loss (virtual or otherwise) has occurred on this like
+ *     schedule a hangup sequence to run after this event.
+ */
+
+void tty_hangup(struct tty_struct *tty)
+{
+#ifdef TTY_DEBUG_HANGUP
+       char    buf[64];
+       printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf));
+#endif
+       schedule_work(&tty->hangup_work);
+}
+
+EXPORT_SYMBOL(tty_hangup);
+
+/**
+ *     tty_vhangup             -       process vhangup
+ *     @tty: tty to hangup
+ *
+ *     The user has asked via system call for the terminal to be hung up.
+ *     We do this synchronously so that when the syscall returns the process
+ *     is complete. That guarantee is necessary for security reasons.
+ */
+
+void tty_vhangup(struct tty_struct *tty)
+{
+#ifdef TTY_DEBUG_HANGUP
+       char    buf[64];
+
+       printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
+#endif
+       __tty_hangup(tty);
+}
+
+EXPORT_SYMBOL(tty_vhangup);
+
+
+/**
+ *     tty_vhangup_self        -       process vhangup for own ctty
+ *
+ *     Perform a vhangup on the current controlling tty
+ */
+
+void tty_vhangup_self(void)
+{
+       struct tty_struct *tty;
+
+       tty = get_current_tty();
+       if (tty) {
+               tty_vhangup(tty);
+               tty_kref_put(tty);
+       }
+}
+
+/**
+ *     tty_hung_up_p           -       was tty hung up
+ *     @filp: file pointer of tty
+ *
+ *     Return true if the tty has been subject to a vhangup or a carrier
+ *     loss
+ */
+
+int tty_hung_up_p(struct file *filp)
+{
+       return (filp->f_op == &hung_up_tty_fops);
+}
+
+EXPORT_SYMBOL(tty_hung_up_p);
+
+static void session_clear_tty(struct pid *session)
+{
+       struct task_struct *p;
+       do_each_pid_task(session, PIDTYPE_SID, p) {
+               proc_clear_tty(p);
+       } while_each_pid_task(session, PIDTYPE_SID, p);
+}
+
+/**
+ *     disassociate_ctty       -       disconnect controlling tty
+ *     @on_exit: true if exiting so need to "hang up" the session
+ *
+ *     This function is typically called only by the session leader, when
+ *     it wants to disassociate itself from its controlling tty.
+ *
+ *     It performs the following functions:
+ *     (1)  Sends a SIGHUP and SIGCONT to the foreground process group
+ *     (2)  Clears the tty from being controlling the session
+ *     (3)  Clears the controlling tty for all processes in the
+ *             session group.
+ *
+ *     The argument on_exit is set to 1 if called when a process is
+ *     exiting; it is 0 if called by the ioctl TIOCNOTTY.
+ *
+ *     Locking:
+ *             BTM is taken for hysterical raisins, and held when
+ *               called from no_tty().
+ *               tty_mutex is taken to protect tty
+ *               ->siglock is taken to protect ->signal/->sighand
+ *               tasklist_lock is taken to walk process list for sessions
+ *                 ->siglock is taken to protect ->signal/->sighand
+ */
+
+void disassociate_ctty(int on_exit)
+{
+       struct tty_struct *tty;
+       struct pid *tty_pgrp = NULL;
+
+       if (!current->signal->leader)
+               return;
+
+       tty = get_current_tty();
+       if (tty) {
+               tty_pgrp = get_pid(tty->pgrp);
+               if (on_exit) {
+                       if (tty->driver->type != TTY_DRIVER_TYPE_PTY)
+                               tty_vhangup(tty);
+               }
+               tty_kref_put(tty);
+       } else if (on_exit) {
+               struct pid *old_pgrp;
+               spin_lock_irq(&current->sighand->siglock);
+               old_pgrp = current->signal->tty_old_pgrp;
+               current->signal->tty_old_pgrp = NULL;
+               spin_unlock_irq(&current->sighand->siglock);
+               if (old_pgrp) {
+                       kill_pgrp(old_pgrp, SIGHUP, on_exit);
+                       kill_pgrp(old_pgrp, SIGCONT, on_exit);
+                       put_pid(old_pgrp);
+               }
+               return;
+       }
+       if (tty_pgrp) {
+               kill_pgrp(tty_pgrp, SIGHUP, on_exit);
+               if (!on_exit)
+                       kill_pgrp(tty_pgrp, SIGCONT, on_exit);
+               put_pid(tty_pgrp);
+       }
+
+       spin_lock_irq(&current->sighand->siglock);
+       put_pid(current->signal->tty_old_pgrp);
+       current->signal->tty_old_pgrp = NULL;
+       spin_unlock_irq(&current->sighand->siglock);
+
+       tty = get_current_tty();
+       if (tty) {
+               unsigned long flags;
+               spin_lock_irqsave(&tty->ctrl_lock, flags);
+               put_pid(tty->session);
+               put_pid(tty->pgrp);
+               tty->session = NULL;
+               tty->pgrp = NULL;
+               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+               tty_kref_put(tty);
+       } else {
+#ifdef TTY_DEBUG_HANGUP
+               printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
+                      " = NULL", tty);
+#endif
+       }
+
+       /* Now clear signal->tty under the lock */
+       read_lock(&tasklist_lock);
+       session_clear_tty(task_session(current));
+       read_unlock(&tasklist_lock);
+}
+
+/**
+ *
+ *     no_tty  - Ensure the current process does not have a controlling tty
+ */
+void no_tty(void)
+{
+       struct task_struct *tsk = current;
+       tty_lock();
+       disassociate_ctty(0);
+       tty_unlock();
+       proc_clear_tty(tsk);
+}
+
+
+/**
+ *     stop_tty        -       propagate flow control
+ *     @tty: tty to stop
+ *
+ *     Perform flow control to the driver. For PTY/TTY pairs we
+ *     must also propagate the TIOCKPKT status. May be called
+ *     on an already stopped device and will not re-call the driver
+ *     method.
+ *
+ *     This functionality is used by both the line disciplines for
+ *     halting incoming flow and by the driver. It may therefore be
+ *     called from any context, may be under the tty atomic_write_lock
+ *     but not always.
+ *
+ *     Locking:
+ *             Uses the tty control lock internally
+ */
+
+void stop_tty(struct tty_struct *tty)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+       if (tty->stopped) {
+               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+               return;
+       }
+       tty->stopped = 1;
+       if (tty->link && tty->link->packet) {
+               tty->ctrl_status &= ~TIOCPKT_START;
+               tty->ctrl_status |= TIOCPKT_STOP;
+               wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
+       }
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+       if (tty->ops->stop)
+               (tty->ops->stop)(tty);
+}
+
+EXPORT_SYMBOL(stop_tty);
+
+/**
+ *     start_tty       -       propagate flow control
+ *     @tty: tty to start
+ *
+ *     Start a tty that has been stopped if at all possible. Perform
+ *     any necessary wakeups and propagate the TIOCPKT status. If this
+ *     is the tty was previous stopped and is being started then the
+ *     driver start method is invoked and the line discipline woken.
+ *
+ *     Locking:
+ *             ctrl_lock
+ */
+
+void start_tty(struct tty_struct *tty)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+       if (!tty->stopped || tty->flow_stopped) {
+               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+               return;
+       }
+       tty->stopped = 0;
+       if (tty->link && tty->link->packet) {
+               tty->ctrl_status &= ~TIOCPKT_STOP;
+               tty->ctrl_status |= TIOCPKT_START;
+               wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
+       }
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+       if (tty->ops->start)
+               (tty->ops->start)(tty);
+       /* If we have a running line discipline it may need kicking */
+       tty_wakeup(tty);
+}
+
+EXPORT_SYMBOL(start_tty);
+
+/**
+ *     tty_read        -       read method for tty device files
+ *     @file: pointer to tty file
+ *     @buf: user buffer
+ *     @count: size of user buffer
+ *     @ppos: unused
+ *
+ *     Perform the read system call function on this terminal device. Checks
+ *     for hung up devices before calling the line discipline method.
+ *
+ *     Locking:
+ *             Locks the line discipline internally while needed. Multiple
+ *     read calls may be outstanding in parallel.
+ */
+
+static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
+                       loff_t *ppos)
+{
+       int i;
+       struct inode *inode = file->f_path.dentry->d_inode;
+       struct tty_struct *tty = file_tty(file);
+       struct tty_ldisc *ld;
+
+       if (tty_paranoia_check(tty, inode, "tty_read"))
+               return -EIO;
+       if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
+               return -EIO;
+
+       /* We want to wait for the line discipline to sort out in this
+          situation */
+       ld = tty_ldisc_ref_wait(tty);
+       if (ld->ops->read)
+               i = (ld->ops->read)(tty, file, buf, count);
+       else
+               i = -EIO;
+       tty_ldisc_deref(ld);
+       if (i > 0)
+               inode->i_atime = current_fs_time(inode->i_sb);
+       return i;
+}
+
+void tty_write_unlock(struct tty_struct *tty)
+{
+       mutex_unlock(&tty->atomic_write_lock);
+       wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+}
+
+int tty_write_lock(struct tty_struct *tty, int ndelay)
+{
+       if (!mutex_trylock(&tty->atomic_write_lock)) {
+               if (ndelay)
+                       return -EAGAIN;
+               if (mutex_lock_interruptible(&tty->atomic_write_lock))
+                       return -ERESTARTSYS;
+       }
+       return 0;
+}
+
+/*
+ * Split writes up in sane blocksizes to avoid
+ * denial-of-service type attacks
+ */
+static inline ssize_t do_tty_write(
+       ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),
+       struct tty_struct *tty,
+       struct file *file,
+       const char __user *buf,
+       size_t count)
+{
+       ssize_t ret, written = 0;
+       unsigned int chunk;
+
+       ret = tty_write_lock(tty, file->f_flags & O_NDELAY);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * We chunk up writes into a temporary buffer. This
+        * simplifies low-level drivers immensely, since they
+        * don't have locking issues and user mode accesses.
+        *
+        * But if TTY_NO_WRITE_SPLIT is set, we should use a
+        * big chunk-size..
+        *
+        * The default chunk-size is 2kB, because the NTTY
+        * layer has problems with bigger chunks. It will
+        * claim to be able to handle more characters than
+        * it actually does.
+        *
+        * FIXME: This can probably go away now except that 64K chunks
+        * are too likely to fail unless switched to vmalloc...
+        */
+       chunk = 2048;
+       if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags))
+               chunk = 65536;
+       if (count < chunk)
+               chunk = count;
+
+       /* write_buf/write_cnt is protected by the atomic_write_lock mutex */
+       if (tty->write_cnt < chunk) {
+               unsigned char *buf_chunk;
+
+               if (chunk < 1024)
+                       chunk = 1024;
+
+               buf_chunk = kmalloc(chunk, GFP_KERNEL);
+               if (!buf_chunk) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               kfree(tty->write_buf);
+               tty->write_cnt = chunk;
+               tty->write_buf = buf_chunk;
+       }
+
+       /* Do the write .. */
+       for (;;) {
+               size_t size = count;
+               if (size > chunk)
+                       size = chunk;
+               ret = -EFAULT;
+               if (copy_from_user(tty->write_buf, buf, size))
+                       break;
+               ret = write(tty, file, tty->write_buf, size);
+               if (ret <= 0)
+                       break;
+               written += ret;
+               buf += ret;
+               count -= ret;
+               if (!count)
+                       break;
+               ret = -ERESTARTSYS;
+               if (signal_pending(current))
+                       break;
+               cond_resched();
+       }
+       if (written) {
+               struct inode *inode = file->f_path.dentry->d_inode;
+               inode->i_mtime = current_fs_time(inode->i_sb);
+               ret = written;
+       }
+out:
+       tty_write_unlock(tty);
+       return ret;
+}
+
+/**
+ * tty_write_message - write a message to a certain tty, not just the console.
+ * @tty: the destination tty_struct
+ * @msg: the message to write
+ *
+ * This is used for messages that need to be redirected to a specific tty.
+ * We don't put it into the syslog queue right now maybe in the future if
+ * really needed.
+ *
+ * We must still hold the BTM and test the CLOSING flag for the moment.
+ */
+
+void tty_write_message(struct tty_struct *tty, char *msg)
+{
+       if (tty) {
+               mutex_lock(&tty->atomic_write_lock);
+               tty_lock();
+               if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
+                       tty_unlock();
+                       tty->ops->write(tty, msg, strlen(msg));
+               } else
+                       tty_unlock();
+               tty_write_unlock(tty);
+       }
+       return;
+}
+
+
+/**
+ *     tty_write               -       write method for tty device file
+ *     @file: tty file pointer
+ *     @buf: user data to write
+ *     @count: bytes to write
+ *     @ppos: unused
+ *
+ *     Write data to a tty device via the line discipline.
+ *
+ *     Locking:
+ *             Locks the line discipline as required
+ *             Writes to the tty driver are serialized by the atomic_write_lock
+ *     and are then processed in chunks to the device. The line discipline
+ *     write method will not be invoked in parallel for each device.
+ */
+
+static ssize_t tty_write(struct file *file, const char __user *buf,
+                                               size_t count, loff_t *ppos)
+{
+       struct inode *inode = file->f_path.dentry->d_inode;
+       struct tty_struct *tty = file_tty(file);
+       struct tty_ldisc *ld;
+       ssize_t ret;
+
+       if (tty_paranoia_check(tty, inode, "tty_write"))
+               return -EIO;
+       if (!tty || !tty->ops->write ||
+               (test_bit(TTY_IO_ERROR, &tty->flags)))
+                       return -EIO;
+       /* Short term debug to catch buggy drivers */
+       if (tty->ops->write_room == NULL)
+               printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
+                       tty->driver->name);
+       ld = tty_ldisc_ref_wait(tty);
+       if (!ld->ops->write)
+               ret = -EIO;
+       else
+               ret = do_tty_write(ld->ops->write, tty, file, buf, count);
+       tty_ldisc_deref(ld);
+       return ret;
+}
+
+ssize_t redirected_tty_write(struct file *file, const char __user *buf,
+                                               size_t count, loff_t *ppos)
+{
+       struct file *p = NULL;
+
+       spin_lock(&redirect_lock);
+       if (redirect) {
+               get_file(redirect);
+               p = redirect;
+       }
+       spin_unlock(&redirect_lock);
+
+       if (p) {
+               ssize_t res;
+               res = vfs_write(p, buf, count, &p->f_pos);
+               fput(p);
+               return res;
+       }
+       return tty_write(file, buf, count, ppos);
+}
+
+static char ptychar[] = "pqrstuvwxyzabcde";
+
+/**
+ *     pty_line_name   -       generate name for a pty
+ *     @driver: the tty driver in use
+ *     @index: the minor number
+ *     @p: output buffer of at least 6 bytes
+ *
+ *     Generate a name from a driver reference and write it to the output
+ *     buffer.
+ *
+ *     Locking: None
+ */
+static void pty_line_name(struct tty_driver *driver, int index, char *p)
+{
+       int i = index + driver->name_base;
+       /* ->name is initialized to "ttyp", but "tty" is expected */
+       sprintf(p, "%s%c%x",
+               driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name,
+               ptychar[i >> 4 & 0xf], i & 0xf);
+}
+
+/**
+ *     tty_line_name   -       generate name for a tty
+ *     @driver: the tty driver in use
+ *     @index: the minor number
+ *     @p: output buffer of at least 7 bytes
+ *
+ *     Generate a name from a driver reference and write it to the output
+ *     buffer.
+ *
+ *     Locking: None
+ */
+static void tty_line_name(struct tty_driver *driver, int index, char *p)
+{
+       sprintf(p, "%s%d", driver->name, index + driver->name_base);
+}
+
+/**
+ *     tty_driver_lookup_tty() - find an existing tty, if any
+ *     @driver: the driver for the tty
+ *     @idx:    the minor number
+ *
+ *     Return the tty, if found or ERR_PTR() otherwise.
+ *
+ *     Locking: tty_mutex must be held. If tty is found, the mutex must
+ *     be held until the 'fast-open' is also done. Will change once we
+ *     have refcounting in the driver and per driver locking
+ */
+static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
+               struct inode *inode, int idx)
+{
+       struct tty_struct *tty;
+
+       if (driver->ops->lookup)
+               return driver->ops->lookup(driver, inode, idx);
+
+       tty = driver->ttys[idx];
+       return tty;
+}
+
+/**
+ *     tty_init_termios        -  helper for termios setup
+ *     @tty: the tty to set up
+ *
+ *     Initialise the termios structures for this tty. Thus runs under
+ *     the tty_mutex currently so we can be relaxed about ordering.
+ */
+
+int tty_init_termios(struct tty_struct *tty)
+{
+       struct ktermios *tp;
+       int idx = tty->index;
+
+       tp = tty->driver->termios[idx];
+       if (tp == NULL) {
+               tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
+               if (tp == NULL)
+                       return -ENOMEM;
+               memcpy(tp, &tty->driver->init_termios,
+                                               sizeof(struct ktermios));
+               tty->driver->termios[idx] = tp;
+       }
+       tty->termios = tp;
+       tty->termios_locked = tp + 1;
+
+       /* Compatibility until drivers always set this */
+       tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
+       tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tty_init_termios);
+
+/**
+ *     tty_driver_install_tty() - install a tty entry in the driver
+ *     @driver: the driver for the tty
+ *     @tty: the tty
+ *
+ *     Install a tty object into the driver tables. The tty->index field
+ *     will be set by the time this is called. This method is responsible
+ *     for ensuring any need additional structures are allocated and
+ *     configured.
+ *
+ *     Locking: tty_mutex for now
+ */
+static int tty_driver_install_tty(struct tty_driver *driver,
+                                               struct tty_struct *tty)
+{
+       int idx = tty->index;
+       int ret;
+
+       if (driver->ops->install) {
+               ret = driver->ops->install(driver, tty);
+               return ret;
+       }
+
+       if (tty_init_termios(tty) == 0) {
+               tty_driver_kref_get(driver);
+               tty->count++;
+               driver->ttys[idx] = tty;
+               return 0;
+       }
+       return -ENOMEM;
+}
+
+/**
+ *     tty_driver_remove_tty() - remove a tty from the driver tables
+ *     @driver: the driver for the tty
+ *     @idx:    the minor number
+ *
+ *     Remvoe a tty object from the driver tables. The tty->index field
+ *     will be set by the time this is called.
+ *
+ *     Locking: tty_mutex for now
+ */
+static void tty_driver_remove_tty(struct tty_driver *driver,
+                                               struct tty_struct *tty)
+{
+       if (driver->ops->remove)
+               driver->ops->remove(driver, tty);
+       else
+               driver->ttys[tty->index] = NULL;
+}
+
+/*
+ *     tty_reopen()    - fast re-open of an open tty
+ *     @tty    - the tty to open
+ *
+ *     Return 0 on success, -errno on error.
+ *
+ *     Locking: tty_mutex must be held from the time the tty was found
+ *              till this open completes.
+ */
+static int tty_reopen(struct tty_struct *tty)
+{
+       struct tty_driver *driver = tty->driver;
+
+       if (test_bit(TTY_CLOSING, &tty->flags))
+               return -EIO;
+
+       if (driver->type == TTY_DRIVER_TYPE_PTY &&
+           driver->subtype == PTY_TYPE_MASTER) {
+               /*
+                * special case for PTY masters: only one open permitted,
+                * and the slave side open count is incremented as well.
+                */
+               if (tty->count)
+                       return -EIO;
+
+               tty->link->count++;
+       }
+       tty->count++;
+       tty->driver = driver; /* N.B. why do this every time?? */
+
+       mutex_lock(&tty->ldisc_mutex);
+       WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
+       mutex_unlock(&tty->ldisc_mutex);
+
+       return 0;
+}
+
+/**
+ *     tty_init_dev            -       initialise a tty device
+ *     @driver: tty driver we are opening a device on
+ *     @idx: device index
+ *     @ret_tty: returned tty structure
+ *     @first_ok: ok to open a new device (used by ptmx)
+ *
+ *     Prepare a tty device. This may not be a "new" clean device but
+ *     could also be an active device. The pty drivers require special
+ *     handling because of this.
+ *
+ *     Locking:
+ *             The function is called under the tty_mutex, which
+ *     protects us from the tty struct or driver itself going away.
+ *
+ *     On exit the tty device has the line discipline attached and
+ *     a reference count of 1. If a pair was created for pty/tty use
+ *     and the other was a pty master then it too has a reference count of 1.
+ *
+ * WSH 06/09/97: Rewritten to remove races and properly clean up after a
+ * failed open.  The new code protects the open with a mutex, so it's
+ * really quite straightforward.  The mutex locking can probably be
+ * relaxed for the (most common) case of reopening a tty.
+ */
+
+struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
+                                                               int first_ok)
+{
+       struct tty_struct *tty;
+       int retval;
+
+       /* Check if pty master is being opened multiple times */
+       if (driver->subtype == PTY_TYPE_MASTER &&
+               (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
+               return ERR_PTR(-EIO);
+       }
+
+       /*
+        * First time open is complex, especially for PTY devices.
+        * This code guarantees that either everything succeeds and the
+        * TTY is ready for operation, or else the table slots are vacated
+        * and the allocated memory released.  (Except that the termios
+        * and locked termios may be retained.)
+        */
+
+       if (!try_module_get(driver->owner))
+               return ERR_PTR(-ENODEV);
+
+       tty = alloc_tty_struct();
+       if (!tty)
+               goto fail_no_mem;
+       initialize_tty_struct(tty, driver, idx);
+
+       retval = tty_driver_install_tty(driver, tty);
+       if (retval < 0) {
+               free_tty_struct(tty);
+               module_put(driver->owner);
+               return ERR_PTR(retval);
+       }
+
+       /*
+        * Structures all installed ... call the ldisc open routines.
+        * If we fail here just call release_tty to clean up.  No need
+        * to decrement the use counts, as release_tty doesn't care.
+        */
+       retval = tty_ldisc_setup(tty, tty->link);
+       if (retval)
+               goto release_mem_out;
+       return tty;
+
+fail_no_mem:
+       module_put(driver->owner);
+       return ERR_PTR(-ENOMEM);
+
+       /* call the tty release_tty routine to clean out this slot */
+release_mem_out:
+       if (printk_ratelimit())
+               printk(KERN_INFO "tty_init_dev: ldisc open failed, "
+                                "clearing slot %d\n", idx);
+       release_tty(tty, idx);
+       return ERR_PTR(retval);
+}
+
+void tty_free_termios(struct tty_struct *tty)
+{
+       struct ktermios *tp;
+       int idx = tty->index;
+       /* Kill this flag and push into drivers for locking etc */
+       if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
+               /* FIXME: Locking on ->termios array */
+               tp = tty->termios;
+               tty->driver->termios[idx] = NULL;
+               kfree(tp);
+       }
+}
+EXPORT_SYMBOL(tty_free_termios);
+
+void tty_shutdown(struct tty_struct *tty)
+{
+       tty_driver_remove_tty(tty->driver, tty);
+       tty_free_termios(tty);
+}
+EXPORT_SYMBOL(tty_shutdown);
+
+/**
+ *     release_one_tty         -       release tty structure memory
+ *     @kref: kref of tty we are obliterating
+ *
+ *     Releases memory associated with a tty structure, and clears out the
+ *     driver table slots. This function is called when a device is no longer
+ *     in use. It also gets called when setup of a device fails.
+ *
+ *     Locking:
+ *             tty_mutex - sometimes only
+ *             takes the file list lock internally when working on the list
+ *     of ttys that the driver keeps.
+ *
+ *     This method gets called from a work queue so that the driver private
+ *     cleanup ops can sleep (needed for USB at least)
+ */
+static void release_one_tty(struct work_struct *work)
+{
+       struct tty_struct *tty =
+               container_of(work, struct tty_struct, hangup_work);
+       struct tty_driver *driver = tty->driver;
+
+       if (tty->ops->cleanup)
+               tty->ops->cleanup(tty);
+
+       tty->magic = 0;
+       tty_driver_kref_put(driver);
+       module_put(driver->owner);
+
+       spin_lock(&tty_files_lock);
+       list_del_init(&tty->tty_files);
+       spin_unlock(&tty_files_lock);
+
+       put_pid(tty->pgrp);
+       put_pid(tty->session);
+       free_tty_struct(tty);
+}
+
+static void queue_release_one_tty(struct kref *kref)
+{
+       struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
+
+       if (tty->ops->shutdown)
+               tty->ops->shutdown(tty);
+       else
+               tty_shutdown(tty);
+
+       /* The hangup queue is now free so we can reuse it rather than
+          waste a chunk of memory for each port */
+       INIT_WORK(&tty->hangup_work, release_one_tty);
+       schedule_work(&tty->hangup_work);
+}
+
+/**
+ *     tty_kref_put            -       release a tty kref
+ *     @tty: tty device
+ *
+ *     Release a reference to a tty device and if need be let the kref
+ *     layer destruct the object for us
+ */
+
+void tty_kref_put(struct tty_struct *tty)
+{
+       if (tty)
+               kref_put(&tty->kref, queue_release_one_tty);
+}
+EXPORT_SYMBOL(tty_kref_put);
+
+/**
+ *     release_tty             -       release tty structure memory
+ *
+ *     Release both @tty and a possible linked partner (think pty pair),
+ *     and decrement the refcount of the backing module.
+ *
+ *     Locking:
+ *             tty_mutex - sometimes only
+ *             takes the file list lock internally when working on the list
+ *     of ttys that the driver keeps.
+ *             FIXME: should we require tty_mutex is held here ??
+ *
+ */
+static void release_tty(struct tty_struct *tty, int idx)
+{
+       /* This should always be true but check for the moment */
+       WARN_ON(tty->index != idx);
+
+       if (tty->link)
+               tty_kref_put(tty->link);
+       tty_kref_put(tty);
+}
+
+/**
+ *     tty_release             -       vfs callback for close
+ *     @inode: inode of tty
+ *     @filp: file pointer for handle to tty
+ *
+ *     Called the last time each file handle is closed that references
+ *     this tty. There may however be several such references.
+ *
+ *     Locking:
+ *             Takes bkl. See tty_release_dev
+ *
+ * Even releasing the tty structures is a tricky business.. We have
+ * to be very careful that the structures are all released at the
+ * same time, as interrupts might otherwise get the wrong pointers.
+ *
+ * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
+ * lead to double frees or releasing memory still in use.
+ */
+
+int tty_release(struct inode *inode, struct file *filp)
+{
+       struct tty_struct *tty = file_tty(filp);
+       struct tty_struct *o_tty;
+       int     pty_master, tty_closing, o_tty_closing, do_sleep;
+       int     devpts;
+       int     idx;
+       char    buf[64];
+
+       if (tty_paranoia_check(tty, inode, "tty_release_dev"))
+               return 0;
+
+       tty_lock();
+       check_tty_count(tty, "tty_release_dev");
+
+       __tty_fasync(-1, filp, 0);
+
+       idx = tty->index;
+       pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
+                     tty->driver->subtype == PTY_TYPE_MASTER);
+       devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
+       o_tty = tty->link;
+
+#ifdef TTY_PARANOIA_CHECK
+       if (idx < 0 || idx >= tty->driver->num) {
+               printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
+                                 "free (%s)\n", tty->name);
+               tty_unlock();
+               return 0;
+       }
+       if (!devpts) {
+               if (tty != tty->driver->ttys[idx]) {
+                       tty_unlock();
+                       printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
+                              "for (%s)\n", idx, tty->name);
+                       return 0;
+               }
+               if (tty->termios != tty->driver->termios[idx]) {
+                       tty_unlock();
+                       printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
+                              "for (%s)\n",
+                              idx, tty->name);
+                       return 0;
+               }
+       }
+#endif
+
+#ifdef TTY_DEBUG_HANGUP
+       printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...",
+              tty_name(tty, buf), tty->count);
+#endif
+
+#ifdef TTY_PARANOIA_CHECK
+       if (tty->driver->other &&
+            !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
+               if (o_tty != tty->driver->other->ttys[idx]) {
+                       tty_unlock();
+                       printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
+                                         "not o_tty for (%s)\n",
+                              idx, tty->name);
+                       return 0 ;
+               }
+               if (o_tty->termios != tty->driver->other->termios[idx]) {
+                       tty_unlock();
+                       printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
+                                         "not o_termios for (%s)\n",
+                              idx, tty->name);
+                       return 0;
+               }
+               if (o_tty->link != tty) {
+                       tty_unlock();
+                       printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
+                       return 0;
+               }
+       }
+#endif
+       if (tty->ops->close)
+               tty->ops->close(tty, filp);
+
+       tty_unlock();
+       /*
+        * Sanity check: if tty->count is going to zero, there shouldn't be
+        * any waiters on tty->read_wait or tty->write_wait.  We test the
+        * wait queues and kick everyone out _before_ actually starting to
+        * close.  This ensures that we won't block while releasing the tty
+        * structure.
+        *
+        * The test for the o_tty closing is necessary, since the master and
+        * slave sides may close in any order.  If the slave side closes out
+        * first, its count will be one, since the master side holds an open.
+        * Thus this test wouldn't be triggered at the time the slave closes,
+        * so we do it now.
+        *
+        * Note that it's possible for the tty to be opened again while we're
+        * flushing out waiters.  By recalculating the closing flags before
+        * each iteration we avoid any problems.
+        */
+       while (1) {
+               /* Guard against races with tty->count changes elsewhere and
+                  opens on /dev/tty */
+
+               mutex_lock(&tty_mutex);
+               tty_lock();
+               tty_closing = tty->count <= 1;
+               o_tty_closing = o_tty &&
+                       (o_tty->count <= (pty_master ? 1 : 0));
+               do_sleep = 0;
+
+               if (tty_closing) {
+                       if (waitqueue_active(&tty->read_wait)) {
+                               wake_up_poll(&tty->read_wait, POLLIN);
+                               do_sleep++;
+                       }
+                       if (waitqueue_active(&tty->write_wait)) {
+                               wake_up_poll(&tty->write_wait, POLLOUT);
+                               do_sleep++;
+                       }
+               }
+               if (o_tty_closing) {
+                       if (waitqueue_active(&o_tty->read_wait)) {
+                               wake_up_poll(&o_tty->read_wait, POLLIN);
+                               do_sleep++;
+                       }
+                       if (waitqueue_active(&o_tty->write_wait)) {
+                               wake_up_poll(&o_tty->write_wait, POLLOUT);
+                               do_sleep++;
+                       }
+               }
+               if (!do_sleep)
+                       break;
+
+               printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
+                                   "active!\n", tty_name(tty, buf));
+               tty_unlock();
+               mutex_unlock(&tty_mutex);
+               schedule();
+       }
+
+       /*
+        * The closing flags are now consistent with the open counts on
+        * both sides, and we've completed the last operation that could
+        * block, so it's safe to proceed with closing.
+        */
+       if (pty_master) {
+               if (--o_tty->count < 0) {
+                       printk(KERN_WARNING "tty_release_dev: bad pty slave count "
+                                           "(%d) for %s\n",
+                              o_tty->count, tty_name(o_tty, buf));
+                       o_tty->count = 0;
+               }
+       }
+       if (--tty->count < 0) {
+               printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n",
+                      tty->count, tty_name(tty, buf));
+               tty->count = 0;
+       }
+
+       /*
+        * We've decremented tty->count, so we need to remove this file
+        * descriptor off the tty->tty_files list; this serves two
+        * purposes:
+        *  - check_tty_count sees the correct number of file descriptors
+        *    associated with this tty.
+        *  - do_tty_hangup no longer sees this file descriptor as
+        *    something that needs to be handled for hangups.
+        */
+       tty_del_file(filp);
+
+       /*
+        * Perform some housekeeping before deciding whether to return.
+        *
+        * Set the TTY_CLOSING flag if this was the last open.  In the
+        * case of a pty we may have to wait around for the other side
+        * to close, and TTY_CLOSING makes sure we can't be reopened.
+        */
+       if (tty_closing)
+               set_bit(TTY_CLOSING, &tty->flags);
+       if (o_tty_closing)
+               set_bit(TTY_CLOSING, &o_tty->flags);
+
+       /*
+        * If _either_ side is closing, make sure there aren't any
+        * processes that still think tty or o_tty is their controlling
+        * tty.
+        */
+       if (tty_closing || o_tty_closing) {
+               read_lock(&tasklist_lock);
+               session_clear_tty(tty->session);
+               if (o_tty)
+                       session_clear_tty(o_tty->session);
+               read_unlock(&tasklist_lock);
+       }
+
+       mutex_unlock(&tty_mutex);
+
+       /* check whether both sides are closing ... */
+       if (!tty_closing || (o_tty && !o_tty_closing)) {
+               tty_unlock();
+               return 0;
+       }
+
+#ifdef TTY_DEBUG_HANGUP
+       printk(KERN_DEBUG "freeing tty structure...");
+#endif
+       /*
+        * Ask the line discipline code to release its structures
+        */
+       tty_ldisc_release(tty, o_tty);
+       /*
+        * The release_tty function takes care of the details of clearing
+        * the slots and preserving the termios structure.
+        */
+       release_tty(tty, idx);
+
+       /* Make this pty number available for reallocation */
+       if (devpts)
+               devpts_kill_index(inode, idx);
+       tty_unlock();
+       return 0;
+}
+
+/**
+ *     tty_open                -       open a tty device
+ *     @inode: inode of device file
+ *     @filp: file pointer to tty
+ *
+ *     tty_open and tty_release keep up the tty count that contains the
+ *     number of opens done on a tty. We cannot use the inode-count, as
+ *     different inodes might point to the same tty.
+ *
+ *     Open-counting is needed for pty masters, as well as for keeping
+ *     track of serial lines: DTR is dropped when the last close happens.
+ *     (This is not done solely through tty->count, now.  - Ted 1/27/92)
+ *
+ *     The termios state of a pty is reset on first open so that
+ *     settings don't persist across reuse.
+ *
+ *     Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work.
+ *              tty->count should protect the rest.
+ *              ->siglock protects ->signal/->sighand
+ */
+
+static int tty_open(struct inode *inode, struct file *filp)
+{
+       struct tty_struct *tty = NULL;
+       int noctty, retval;
+       struct tty_driver *driver;
+       int index;
+       dev_t device = inode->i_rdev;
+       unsigned saved_flags = filp->f_flags;
+
+       nonseekable_open(inode, filp);
+
+retry_open:
+       noctty = filp->f_flags & O_NOCTTY;
+       index  = -1;
+       retval = 0;
+
+       mutex_lock(&tty_mutex);
+       tty_lock();
+
+       if (device == MKDEV(TTYAUX_MAJOR, 0)) {
+               tty = get_current_tty();
+               if (!tty) {
+                       tty_unlock();
+                       mutex_unlock(&tty_mutex);
+                       return -ENXIO;
+               }
+               driver = tty_driver_kref_get(tty->driver);
+               index = tty->index;
+               filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
+               /* noctty = 1; */
+               /* FIXME: Should we take a driver reference ? */
+               tty_kref_put(tty);
+               goto got_driver;
+       }
+#ifdef CONFIG_VT
+       if (device == MKDEV(TTY_MAJOR, 0)) {
+               extern struct tty_driver *console_driver;
+               driver = tty_driver_kref_get(console_driver);
+               index = fg_console;
+               noctty = 1;
+               goto got_driver;
+       }
+#endif
+       if (device == MKDEV(TTYAUX_MAJOR, 1)) {
+               struct tty_driver *console_driver = console_device(&index);
+               if (console_driver) {
+                       driver = tty_driver_kref_get(console_driver);
+                       if (driver) {
+                               /* Don't let /dev/console block */
+                               filp->f_flags |= O_NONBLOCK;
+                               noctty = 1;
+                               goto got_driver;
+                       }
+               }
+               tty_unlock();
+               mutex_unlock(&tty_mutex);
+               return -ENODEV;
+       }
+
+       driver = get_tty_driver(device, &index);
+       if (!driver) {
+               tty_unlock();
+               mutex_unlock(&tty_mutex);
+               return -ENODEV;
+       }
+got_driver:
+       if (!tty) {
+               /* check whether we're reopening an existing tty */
+               tty = tty_driver_lookup_tty(driver, inode, index);
+
+               if (IS_ERR(tty)) {
+                       tty_unlock();
+                       mutex_unlock(&tty_mutex);
+                       return PTR_ERR(tty);
+               }
+       }
+
+       if (tty) {
+               retval = tty_reopen(tty);
+               if (retval)
+                       tty = ERR_PTR(retval);
+       } else
+               tty = tty_init_dev(driver, index, 0);
+
+       mutex_unlock(&tty_mutex);
+       tty_driver_kref_put(driver);
+       if (IS_ERR(tty)) {
+               tty_unlock();
+               return PTR_ERR(tty);
+       }
+
+       retval = tty_add_file(tty, filp);
+       if (retval) {
+               tty_unlock();
+               return retval;
+       }
+
+       check_tty_count(tty, "tty_open");
+       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
+           tty->driver->subtype == PTY_TYPE_MASTER)
+               noctty = 1;
+#ifdef TTY_DEBUG_HANGUP
+       printk(KERN_DEBUG "opening %s...", tty->name);
+#endif
+       if (!retval) {
+               if (tty->ops->open)
+                       retval = tty->ops->open(tty, filp);
+               else
+                       retval = -ENODEV;
+       }
+       filp->f_flags = saved_flags;
+
+       if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) &&
+                                               !capable(CAP_SYS_ADMIN))
+               retval = -EBUSY;
+
+       if (retval) {
+#ifdef TTY_DEBUG_HANGUP
+               printk(KERN_DEBUG "error %d in opening %s...", retval,
+                      tty->name);
+#endif
+               tty_unlock(); /* need to call tty_release without BTM */
+               tty_release(inode, filp);
+               if (retval != -ERESTARTSYS)
+                       return retval;
+
+               if (signal_pending(current))
+                       return retval;
+
+               schedule();
+               /*
+                * Need to reset f_op in case a hangup happened.
+                */
+               tty_lock();
+               if (filp->f_op == &hung_up_tty_fops)
+                       filp->f_op = &tty_fops;
+               tty_unlock();
+               goto retry_open;
+       }
+       tty_unlock();
+
+
+       mutex_lock(&tty_mutex);
+       tty_lock();
+       spin_lock_irq(&current->sighand->siglock);
+       if (!noctty &&
+           current->signal->leader &&
+           !current->signal->tty &&
+           tty->session == NULL)
+               __proc_set_tty(current, tty);
+       spin_unlock_irq(&current->sighand->siglock);
+       tty_unlock();
+       mutex_unlock(&tty_mutex);
+       return 0;
+}
+
+
+
+/**
+ *     tty_poll        -       check tty status
+ *     @filp: file being polled
+ *     @wait: poll wait structures to update
+ *
+ *     Call the line discipline polling method to obtain the poll
+ *     status of the device.
+ *
+ *     Locking: locks called line discipline but ldisc poll method
+ *     may be re-entered freely by other callers.
+ */
+
+static unsigned int tty_poll(struct file *filp, poll_table *wait)
+{
+       struct tty_struct *tty = file_tty(filp);
+       struct tty_ldisc *ld;
+       int ret = 0;
+
+       if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
+               return 0;
+
+       ld = tty_ldisc_ref_wait(tty);
+       if (ld->ops->poll)
+               ret = (ld->ops->poll)(tty, filp, wait);
+       tty_ldisc_deref(ld);
+       return ret;
+}
+
+static int __tty_fasync(int fd, struct file *filp, int on)
+{
+       struct tty_struct *tty = file_tty(filp);
+       unsigned long flags;
+       int retval = 0;
+
+       if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
+               goto out;
+
+       retval = fasync_helper(fd, filp, on, &tty->fasync);
+       if (retval <= 0)
+               goto out;
+
+       if (on) {
+               enum pid_type type;
+               struct pid *pid;
+               if (!waitqueue_active(&tty->read_wait))
+                       tty->minimum_to_wake = 1;
+               spin_lock_irqsave(&tty->ctrl_lock, flags);
+               if (tty->pgrp) {
+                       pid = tty->pgrp;
+                       type = PIDTYPE_PGID;
+               } else {
+                       pid = task_pid(current);
+                       type = PIDTYPE_PID;
+               }
+               get_pid(pid);
+               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+               retval = __f_setown(filp, pid, type, 0);
+               put_pid(pid);
+               if (retval)
+                       goto out;
+       } else {
+               if (!tty->fasync && !waitqueue_active(&tty->read_wait))
+                       tty->minimum_to_wake = N_TTY_BUF_SIZE;
+       }
+       retval = 0;
+out:
+       return retval;
+}
+
+static int tty_fasync(int fd, struct file *filp, int on)
+{
+       int retval;
+       tty_lock();
+       retval = __tty_fasync(fd, filp, on);
+       tty_unlock();
+       return retval;
+}
+
+/**
+ *     tiocsti                 -       fake input character
+ *     @tty: tty to fake input into
+ *     @p: pointer to character
+ *
+ *     Fake input to a tty device. Does the necessary locking and
+ *     input management.
+ *
+ *     FIXME: does not honour flow control ??
+ *
+ *     Locking:
+ *             Called functions take tty_ldisc_lock
+ *             current->signal->tty check is safe without locks
+ *
+ *     FIXME: may race normal receive processing
+ */
+
+static int tiocsti(struct tty_struct *tty, char __user *p)
+{
+       char ch, mbz = 0;
+       struct tty_ldisc *ld;
+
+       if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (get_user(ch, p))
+               return -EFAULT;
+       tty_audit_tiocsti(tty, ch);
+       ld = tty_ldisc_ref_wait(tty);
+       ld->ops->receive_buf(tty, &ch, &mbz, 1);
+       tty_ldisc_deref(ld);
+       return 0;
+}
+
+/**
+ *     tiocgwinsz              -       implement window query ioctl
+ *     @tty; tty
+ *     @arg: user buffer for result
+ *
+ *     Copies the kernel idea of the window size into the user buffer.
+ *
+ *     Locking: tty->termios_mutex is taken to ensure the winsize data
+ *             is consistent.
+ */
+
+static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
+{
+       int err;
+
+       mutex_lock(&tty->termios_mutex);
+       err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
+       mutex_unlock(&tty->termios_mutex);
+
+       return err ? -EFAULT: 0;
+}
+
+/**
+ *     tty_do_resize           -       resize event
+ *     @tty: tty being resized
+ *     @rows: rows (character)
+ *     @cols: cols (character)
+ *
+ *     Update the termios variables and send the necessary signals to
+ *     peform a terminal resize correctly
+ */
+
+int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
+{
+       struct pid *pgrp;
+       unsigned long flags;
+
+       /* Lock the tty */
+       mutex_lock(&tty->termios_mutex);
+       if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
+               goto done;
+       /* Get the PID values and reference them so we can
+          avoid holding the tty ctrl lock while sending signals */
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+       pgrp = get_pid(tty->pgrp);
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+       if (pgrp)
+               kill_pgrp(pgrp, SIGWINCH, 1);
+       put_pid(pgrp);
+
+       tty->winsize = *ws;
+done:
+       mutex_unlock(&tty->termios_mutex);
+       return 0;
+}
+
+/**
+ *     tiocswinsz              -       implement window size set ioctl
+ *     @tty; tty side of tty
+ *     @arg: user buffer for result
+ *
+ *     Copies the user idea of the window size to the kernel. Traditionally
+ *     this is just advisory information but for the Linux console it
+ *     actually has driver level meaning and triggers a VC resize.
+ *
+ *     Locking:
+ *             Driver dependant. The default do_resize method takes the
+ *     tty termios mutex and ctrl_lock. The console takes its own lock
+ *     then calls into the default method.
+ */
+
+static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg)
+{
+       struct winsize tmp_ws;
+       if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
+               return -EFAULT;
+
+       if (tty->ops->resize)
+               return tty->ops->resize(tty, &tmp_ws);
+       else
+               return tty_do_resize(tty, &tmp_ws);
+}
+
+/**
+ *     tioccons        -       allow admin to move logical console
+ *     @file: the file to become console
+ *
+ *     Allow the adminstrator to move the redirected console device
+ *
+ *     Locking: uses redirect_lock to guard the redirect information
+ */
+
+static int tioccons(struct file *file)
+{
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (file->f_op->write == redirected_tty_write) {
+               struct file *f;
+               spin_lock(&redirect_lock);
+               f = redirect;
+               redirect = NULL;
+               spin_unlock(&redirect_lock);
+               if (f)
+                       fput(f);
+               return 0;
+       }
+       spin_lock(&redirect_lock);
+       if (redirect) {
+               spin_unlock(&redirect_lock);
+               return -EBUSY;
+       }
+       get_file(file);
+       redirect = file;
+       spin_unlock(&redirect_lock);
+       return 0;
+}
+
+/**
+ *     fionbio         -       non blocking ioctl
+ *     @file: file to set blocking value
+ *     @p: user parameter
+ *
+ *     Historical tty interfaces had a blocking control ioctl before
+ *     the generic functionality existed. This piece of history is preserved
+ *     in the expected tty API of posix OS's.
+ *
+ *     Locking: none, the open file handle ensures it won't go away.
+ */
+
+static int fionbio(struct file *file, int __user *p)
+{
+       int nonblock;
+
+       if (get_user(nonblock, p))
+               return -EFAULT;
+
+       spin_lock(&file->f_lock);
+       if (nonblock)
+               file->f_flags |= O_NONBLOCK;
+       else
+               file->f_flags &= ~O_NONBLOCK;
+       spin_unlock(&file->f_lock);
+       return 0;
+}
+
+/**
+ *     tiocsctty       -       set controlling tty
+ *     @tty: tty structure
+ *     @arg: user argument
+ *
+ *     This ioctl is used to manage job control. It permits a session
+ *     leader to set this tty as the controlling tty for the session.
+ *
+ *     Locking:
+ *             Takes tty_mutex() to protect tty instance
+ *             Takes tasklist_lock internally to walk sessions
+ *             Takes ->siglock() when updating signal->tty
+ */
+
+static int tiocsctty(struct tty_struct *tty, int arg)
+{
+       int ret = 0;
+       if (current->signal->leader && (task_session(current) == tty->session))
+               return ret;
+
+       mutex_lock(&tty_mutex);
+       /*
+        * The process must be a session leader and
+        * not have a controlling tty already.
+        */
+       if (!current->signal->leader || current->signal->tty) {
+               ret = -EPERM;
+               goto unlock;
+       }
+
+       if (tty->session) {
+               /*
+                * This tty is already the controlling
+                * tty for another session group!
+                */
+               if (arg == 1 && capable(CAP_SYS_ADMIN)) {
+                       /*
+                        * Steal it away
+                        */
+                       read_lock(&tasklist_lock);
+                       session_clear_tty(tty->session);
+                       read_unlock(&tasklist_lock);
+               } else {
+                       ret = -EPERM;
+                       goto unlock;
+               }
+       }
+       proc_set_tty(current, tty);
+unlock:
+       mutex_unlock(&tty_mutex);
+       return ret;
+}
+
+/**
+ *     tty_get_pgrp    -       return a ref counted pgrp pid
+ *     @tty: tty to read
+ *
+ *     Returns a refcounted instance of the pid struct for the process
+ *     group controlling the tty.
+ */
+
+struct pid *tty_get_pgrp(struct tty_struct *tty)
+{
+       unsigned long flags;
+       struct pid *pgrp;
+
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+       pgrp = get_pid(tty->pgrp);
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+       return pgrp;
+}
+EXPORT_SYMBOL_GPL(tty_get_pgrp);
+
+/**
+ *     tiocgpgrp               -       get process group
+ *     @tty: tty passed by user
+ *     @real_tty: tty side of the tty pased by the user if a pty else the tty
+ *     @p: returned pid
+ *
+ *     Obtain the process group of the tty. If there is no process group
+ *     return an error.
+ *
+ *     Locking: none. Reference to current->signal->tty is safe.
+ */
+
+static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
+{
+       struct pid *pid;
+       int ret;
+       /*
+        * (tty == real_tty) is a cheap way of
+        * testing if the tty is NOT a master pty.
+        */
+       if (tty == real_tty && current->signal->tty != real_tty)
+               return -ENOTTY;
+       pid = tty_get_pgrp(real_tty);
+       ret =  put_user(pid_vnr(pid), p);
+       put_pid(pid);
+       return ret;
+}
+
+/**
+ *     tiocspgrp               -       attempt to set process group
+ *     @tty: tty passed by user
+ *     @real_tty: tty side device matching tty passed by user
+ *     @p: pid pointer
+ *
+ *     Set the process group of the tty to the session passed. Only
+ *     permitted where the tty session is our session.
+ *
+ *     Locking: RCU, ctrl lock
+ */
+
+static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
+{
+       struct pid *pgrp;
+       pid_t pgrp_nr;
+       int retval = tty_check_change(real_tty);
+       unsigned long flags;
+
+       if (retval == -EIO)
+               return -ENOTTY;
+       if (retval)
+               return retval;
+       if (!current->signal->tty ||
+           (current->signal->tty != real_tty) ||
+           (real_tty->session != task_session(current)))
+               return -ENOTTY;
+       if (get_user(pgrp_nr, p))
+               return -EFAULT;
+       if (pgrp_nr < 0)
+               return -EINVAL;
+       rcu_read_lock();
+       pgrp = find_vpid(pgrp_nr);
+       retval = -ESRCH;
+       if (!pgrp)
+               goto out_unlock;
+       retval = -EPERM;
+       if (session_of_pgrp(pgrp) != task_session(current))
+               goto out_unlock;
+       retval = 0;
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+       put_pid(real_tty->pgrp);
+       real_tty->pgrp = get_pid(pgrp);
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+out_unlock:
+       rcu_read_unlock();
+       return retval;
+}
+
+/**
+ *     tiocgsid                -       get session id
+ *     @tty: tty passed by user
+ *     @real_tty: tty side of the tty pased by the user if a pty else the tty
+ *     @p: pointer to returned session id
+ *
+ *     Obtain the session id of the tty. If there is no session
+ *     return an error.
+ *
+ *     Locking: none. Reference to current->signal->tty is safe.
+ */
+
+static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
+{
+       /*
+        * (tty == real_tty) is a cheap way of
+        * testing if the tty is NOT a master pty.
+       */
+       if (tty == real_tty && current->signal->tty != real_tty)
+               return -ENOTTY;
+       if (!real_tty->session)
+               return -ENOTTY;
+       return put_user(pid_vnr(real_tty->session), p);
+}
+
+/**
+ *     tiocsetd        -       set line discipline
+ *     @tty: tty device
+ *     @p: pointer to user data
+ *
+ *     Set the line discipline according to user request.
+ *
+ *     Locking: see tty_set_ldisc, this function is just a helper
+ */
+
+static int tiocsetd(struct tty_struct *tty, int __user *p)
+{
+       int ldisc;
+       int ret;
+
+       if (get_user(ldisc, p))
+               return -EFAULT;
+
+       ret = tty_set_ldisc(tty, ldisc);
+
+       return ret;
+}
+
+/**
+ *     send_break      -       performed time break
+ *     @tty: device to break on
+ *     @duration: timeout in mS
+ *
+ *     Perform a timed break on hardware that lacks its own driver level
+ *     timed break functionality.
+ *
+ *     Locking:
+ *             atomic_write_lock serializes
+ *
+ */
+
+static int send_break(struct tty_struct *tty, unsigned int duration)
+{
+       int retval;
+
+       if (tty->ops->break_ctl == NULL)
+               return 0;
+
+       if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
+               retval = tty->ops->break_ctl(tty, duration);
+       else {
+               /* Do the work ourselves */
+               if (tty_write_lock(tty, 0) < 0)
+                       return -EINTR;
+               retval = tty->ops->break_ctl(tty, -1);
+               if (retval)
+                       goto out;
+               if (!signal_pending(current))
+                       msleep_interruptible(duration);
+               retval = tty->ops->break_ctl(tty, 0);
+out:
+               tty_write_unlock(tty);
+               if (signal_pending(current))
+                       retval = -EINTR;
+       }
+       return retval;
+}
+
+/**
+ *     tty_tiocmget            -       get modem status
+ *     @tty: tty device
+ *     @file: user file pointer
+ *     @p: pointer to result
+ *
+ *     Obtain the modem status bits from the tty driver if the feature
+ *     is supported. Return -EINVAL if it is not available.
+ *
+ *     Locking: none (up to the driver)
+ */
+
+static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p)
+{
+       int retval = -EINVAL;
+
+       if (tty->ops->tiocmget) {
+               retval = tty->ops->tiocmget(tty, file);
+
+               if (retval >= 0)
+                       retval = put_user(retval, p);
+       }
+       return retval;
+}
+
+/**
+ *     tty_tiocmset            -       set modem status
+ *     @tty: tty device
+ *     @file: user file pointer
+ *     @cmd: command - clear bits, set bits or set all
+ *     @p: pointer to desired bits
+ *
+ *     Set the modem status bits from the tty driver if the feature
+ *     is supported. Return -EINVAL if it is not available.
+ *
+ *     Locking: none (up to the driver)
+ */
+
+static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd,
+            unsigned __user *p)
+{
+       int retval;
+       unsigned int set, clear, val;
+
+       if (tty->ops->tiocmset == NULL)
+               return -EINVAL;
+
+       retval = get_user(val, p);
+       if (retval)
+               return retval;
+       set = clear = 0;
+       switch (cmd) {
+       case TIOCMBIS:
+               set = val;
+               break;
+       case TIOCMBIC:
+               clear = val;
+               break;
+       case TIOCMSET:
+               set = val;
+               clear = ~val;
+               break;
+       }
+       set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
+       clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
+       return tty->ops->tiocmset(tty, file, set, clear);
+}
+
+static int tty_tiocgicount(struct tty_struct *tty, void __user *arg)
+{
+       int retval = -EINVAL;
+       struct serial_icounter_struct icount;
+       memset(&icount, 0, sizeof(icount));
+       if (tty->ops->get_icount)
+               retval = tty->ops->get_icount(tty, &icount);
+       if (retval != 0)
+               return retval;
+       if (copy_to_user(arg, &icount, sizeof(icount)))
+               return -EFAULT;
+       return 0;
+}
+
+struct tty_struct *tty_pair_get_tty(struct tty_struct *tty)
+{
+       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
+           tty->driver->subtype == PTY_TYPE_MASTER)
+               tty = tty->link;
+       return tty;
+}
+EXPORT_SYMBOL(tty_pair_get_tty);
+
+struct tty_struct *tty_pair_get_pty(struct tty_struct *tty)
+{
+       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
+           tty->driver->subtype == PTY_TYPE_MASTER)
+           return tty;
+       return tty->link;
+}
+EXPORT_SYMBOL(tty_pair_get_pty);
+
+/*
+ * Split this up, as gcc can choke on it otherwise..
+ */
+long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct tty_struct *tty = file_tty(file);
+       struct tty_struct *real_tty;
+       void __user *p = (void __user *)arg;
+       int retval;
+       struct tty_ldisc *ld;
+       struct inode *inode = file->f_dentry->d_inode;
+
+       if (tty_paranoia_check(tty, inode, "tty_ioctl"))
+               return -EINVAL;
+
+       real_tty = tty_pair_get_tty(tty);
+
+       /*
+        * Factor out some common prep work
+        */
+       switch (cmd) {
+       case TIOCSETD:
+       case TIOCSBRK:
+       case TIOCCBRK:
+       case TCSBRK:
+       case TCSBRKP:
+               retval = tty_check_change(tty);
+               if (retval)
+                       return retval;
+               if (cmd != TIOCCBRK) {
+                       tty_wait_until_sent(tty, 0);
+                       if (signal_pending(current))
+                               return -EINTR;
+               }
+               break;
+       }
+
+       /*
+        *      Now do the stuff.
+        */
+       switch (cmd) {
+       case TIOCSTI:
+               return tiocsti(tty, p);
+       case TIOCGWINSZ:
+               return tiocgwinsz(real_tty, p);
+       case TIOCSWINSZ:
+               return tiocswinsz(real_tty, p);
+       case TIOCCONS:
+               return real_tty != tty ? -EINVAL : tioccons(file);
+       case FIONBIO:
+               return fionbio(file, p);
+       case TIOCEXCL:
+               set_bit(TTY_EXCLUSIVE, &tty->flags);
+               return 0;
+       case TIOCNXCL:
+               clear_bit(TTY_EXCLUSIVE, &tty->flags);
+               return 0;
+       case TIOCNOTTY:
+               if (current->signal->tty != tty)
+                       return -ENOTTY;
+               no_tty();
+               return 0;
+       case TIOCSCTTY:
+               return tiocsctty(tty, arg);
+       case TIOCGPGRP:
+               return tiocgpgrp(tty, real_tty, p);
+       case TIOCSPGRP:
+               return tiocspgrp(tty, real_tty, p);
+       case TIOCGSID:
+               return tiocgsid(tty, real_tty, p);
+       case TIOCGETD:
+               return put_user(tty->ldisc->ops->num, (int __user *)p);
+       case TIOCSETD:
+               return tiocsetd(tty, p);
+       /*
+        * Break handling
+        */
+       case TIOCSBRK:  /* Turn break on, unconditionally */
+               if (tty->ops->break_ctl)
+                       return tty->ops->break_ctl(tty, -1);
+               return 0;
+       case TIOCCBRK:  /* Turn break off, unconditionally */
+               if (tty->ops->break_ctl)
+                       return tty->ops->break_ctl(tty, 0);
+               return 0;
+       case TCSBRK:   /* SVID version: non-zero arg --> no break */
+               /* non-zero arg means wait for all output data
+                * to be sent (performed above) but don't send break.
+                * This is used by the tcdrain() termios function.
+                */
+               if (!arg)
+                       return send_break(tty, 250);
+               return 0;
+       case TCSBRKP:   /* support for POSIX tcsendbreak() */
+               return send_break(tty, arg ? arg*100 : 250);
+
+       case TIOCMGET:
+               return tty_tiocmget(tty, file, p);
+       case TIOCMSET:
+       case TIOCMBIC:
+       case TIOCMBIS:
+               return tty_tiocmset(tty, file, cmd, p);
+       case TIOCGICOUNT:
+               retval = tty_tiocgicount(tty, p);
+               /* For the moment allow fall through to the old method */
+               if (retval != -EINVAL)
+                       return retval;
+               break;
+       case TCFLSH:
+               switch (arg) {
+               case TCIFLUSH:
+               case TCIOFLUSH:
+               /* flush tty buffer and allow ldisc to process ioctl */
+                       tty_buffer_flush(tty);
+                       break;
+               }
+               break;
+       }
+       if (tty->ops->ioctl) {
+               retval = (tty->ops->ioctl)(tty, file, cmd, arg);
+               if (retval != -ENOIOCTLCMD)
+                       return retval;
+       }
+       ld = tty_ldisc_ref_wait(tty);
+       retval = -EINVAL;
+       if (ld->ops->ioctl) {
+               retval = ld->ops->ioctl(tty, file, cmd, arg);
+               if (retval == -ENOIOCTLCMD)
+                       retval = -EINVAL;
+       }
+       tty_ldisc_deref(ld);
+       return retval;
+}
+
+#ifdef CONFIG_COMPAT
+static long tty_compat_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       struct tty_struct *tty = file_tty(file);
+       struct tty_ldisc *ld;
+       int retval = -ENOIOCTLCMD;
+
+       if (tty_paranoia_check(tty, inode, "tty_ioctl"))
+               return -EINVAL;
+
+       if (tty->ops->compat_ioctl) {
+               retval = (tty->ops->compat_ioctl)(tty, file, cmd, arg);
+               if (retval != -ENOIOCTLCMD)
+                       return retval;
+       }
+
+       ld = tty_ldisc_ref_wait(tty);
+       if (ld->ops->compat_ioctl)
+               retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
+       tty_ldisc_deref(ld);
+
+       return retval;
+}
+#endif
+
+/*
+ * This implements the "Secure Attention Key" ---  the idea is to
+ * prevent trojan horses by killing all processes associated with this
+ * tty when the user hits the "Secure Attention Key".  Required for
+ * super-paranoid applications --- see the Orange Book for more details.
+ *
+ * This code could be nicer; ideally it should send a HUP, wait a few
+ * seconds, then send a INT, and then a KILL signal.  But you then
+ * have to coordinate with the init process, since all processes associated
+ * with the current tty must be dead before the new getty is allowed
+ * to spawn.
+ *
+ * Now, if it would be correct ;-/ The current code has a nasty hole -
+ * it doesn't catch files in flight. We may send the descriptor to ourselves
+ * via AF_UNIX socket, close it and later fetch from socket. FIXME.
+ *
+ * Nasty bug: do_SAK is being called in interrupt context.  This can
+ * deadlock.  We punt it up to process context.  AKPM - 16Mar2001
+ */
+void __do_SAK(struct tty_struct *tty)
+{
+#ifdef TTY_SOFT_SAK
+       tty_hangup(tty);
+#else
+       struct task_struct *g, *p;
+       struct pid *session;
+       int             i;
+       struct file     *filp;
+       struct fdtable *fdt;
+
+       if (!tty)
+               return;
+       session = tty->session;
+
+       tty_ldisc_flush(tty);
+
+       tty_driver_flush_buffer(tty);
+
+       read_lock(&tasklist_lock);
+       /* Kill the entire session */
+       do_each_pid_task(session, PIDTYPE_SID, p) {
+               printk(KERN_NOTICE "SAK: killed process %d"
+                       " (%s): task_session(p)==tty->session\n",
+                       task_pid_nr(p), p->comm);
+               send_sig(SIGKILL, p, 1);
+       } while_each_pid_task(session, PIDTYPE_SID, p);
+       /* Now kill any processes that happen to have the
+        * tty open.
+        */
+       do_each_thread(g, p) {
+               if (p->signal->tty == tty) {
+                       printk(KERN_NOTICE "SAK: killed process %d"
+                           " (%s): task_session(p)==tty->session\n",
+                           task_pid_nr(p), p->comm);
+                       send_sig(SIGKILL, p, 1);
+                       continue;
+               }
+               task_lock(p);
+               if (p->files) {
+                       /*
+                        * We don't take a ref to the file, so we must
+                        * hold ->file_lock instead.
+                        */
+                       spin_lock(&p->files->file_lock);
+                       fdt = files_fdtable(p->files);
+                       for (i = 0; i < fdt->max_fds; i++) {
+                               filp = fcheck_files(p->files, i);
+                               if (!filp)
+                                       continue;
+                               if (filp->f_op->read == tty_read &&
+                                   file_tty(filp) == tty) {
+                                       printk(KERN_NOTICE "SAK: killed process %d"
+                                           " (%s): fd#%d opened to the tty\n",
+                                           task_pid_nr(p), p->comm, i);
+                                       force_sig(SIGKILL, p);
+                                       break;
+                               }
+                       }
+                       spin_unlock(&p->files->file_lock);
+               }
+               task_unlock(p);
+       } while_each_thread(g, p);
+       read_unlock(&tasklist_lock);
+#endif
+}
+
+static void do_SAK_work(struct work_struct *work)
+{
+       struct tty_struct *tty =
+               container_of(work, struct tty_struct, SAK_work);
+       __do_SAK(tty);
+}
+
+/*
+ * The tq handling here is a little racy - tty->SAK_work may already be queued.
+ * Fortunately we don't need to worry, because if ->SAK_work is already queued,
+ * the values which we write to it will be identical to the values which it
+ * already has. --akpm
+ */
+void do_SAK(struct tty_struct *tty)
+{
+       if (!tty)
+               return;
+       schedule_work(&tty->SAK_work);
+}
+
+EXPORT_SYMBOL(do_SAK);
+
+static int dev_match_devt(struct device *dev, void *data)
+{
+       dev_t *devt = data;
+       return dev->devt == *devt;
+}
+
+/* Must put_device() after it's unused! */
+static struct device *tty_get_device(struct tty_struct *tty)
+{
+       dev_t devt = tty_devnum(tty);
+       return class_find_device(tty_class, NULL, &devt, dev_match_devt);
+}
+
+
+/**
+ *     initialize_tty_struct
+ *     @tty: tty to initialize
+ *
+ *     This subroutine initializes a tty structure that has been newly
+ *     allocated.
+ *
+ *     Locking: none - tty in question must not be exposed at this point
+ */
+
+void initialize_tty_struct(struct tty_struct *tty,
+               struct tty_driver *driver, int idx)
+{
+       memset(tty, 0, sizeof(struct tty_struct));
+       kref_init(&tty->kref);
+       tty->magic = TTY_MAGIC;
+       tty_ldisc_init(tty);
+       tty->session = NULL;
+       tty->pgrp = NULL;
+       tty->overrun_time = jiffies;
+       tty->buf.head = tty->buf.tail = NULL;
+       tty_buffer_init(tty);
+       mutex_init(&tty->termios_mutex);
+       mutex_init(&tty->ldisc_mutex);
+       init_waitqueue_head(&tty->write_wait);
+       init_waitqueue_head(&tty->read_wait);
+       INIT_WORK(&tty->hangup_work, do_tty_hangup);
+       mutex_init(&tty->atomic_read_lock);
+       mutex_init(&tty->atomic_write_lock);
+       mutex_init(&tty->output_lock);
+       mutex_init(&tty->echo_lock);
+       spin_lock_init(&tty->read_lock);
+       spin_lock_init(&tty->ctrl_lock);
+       INIT_LIST_HEAD(&tty->tty_files);
+       INIT_WORK(&tty->SAK_work, do_SAK_work);
+
+       tty->driver = driver;
+       tty->ops = driver->ops;
+       tty->index = idx;
+       tty_line_name(driver, idx, tty->name);
+       tty->dev = tty_get_device(tty);
+}
+
+/**
+ *     tty_put_char    -       write one character to a tty
+ *     @tty: tty
+ *     @ch: character
+ *
+ *     Write one byte to the tty using the provided put_char method
+ *     if present. Returns the number of characters successfully output.
+ *
+ *     Note: the specific put_char operation in the driver layer may go
+ *     away soon. Don't call it directly, use this method
+ */
+
+int tty_put_char(struct tty_struct *tty, unsigned char ch)
+{
+       if (tty->ops->put_char)
+               return tty->ops->put_char(tty, ch);
+       return tty->ops->write(tty, &ch, 1);
+}
+EXPORT_SYMBOL_GPL(tty_put_char);
+
+struct class *tty_class;
+
+/**
+ *     tty_register_device - register a tty device
+ *     @driver: the tty driver that describes the tty device
+ *     @index: the index in the tty driver for this tty device
+ *     @device: a struct device that is associated with this tty device.
+ *             This field is optional, if there is no known struct device
+ *             for this tty device it can be set to NULL safely.
+ *
+ *     Returns a pointer to the struct device for this tty device
+ *     (or ERR_PTR(-EFOO) on error).
+ *
+ *     This call is required to be made to register an individual tty device
+ *     if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set.  If
+ *     that bit is not set, this function should not be called by a tty
+ *     driver.
+ *
+ *     Locking: ??
+ */
+
+struct device *tty_register_device(struct tty_driver *driver, unsigned index,
+                                  struct device *device)
+{
+       char name[64];
+       dev_t dev = MKDEV(driver->major, driver->minor_start) + index;
+
+       if (index >= driver->num) {
+               printk(KERN_ERR "Attempt to register invalid tty line number "
+                      " (%d).\n", index);
+               return ERR_PTR(-EINVAL);
+       }
+
+       if (driver->type == TTY_DRIVER_TYPE_PTY)
+               pty_line_name(driver, index, name);
+       else
+               tty_line_name(driver, index, name);
+
+       return device_create(tty_class, device, dev, NULL, name);
+}
+EXPORT_SYMBOL(tty_register_device);
+
+/**
+ *     tty_unregister_device - unregister a tty device
+ *     @driver: the tty driver that describes the tty device
+ *     @index: the index in the tty driver for this tty device
+ *
+ *     If a tty device is registered with a call to tty_register_device() then
+ *     this function must be called when the tty device is gone.
+ *
+ *     Locking: ??
+ */
+
+void tty_unregister_device(struct tty_driver *driver, unsigned index)
+{
+       device_destroy(tty_class,
+               MKDEV(driver->major, driver->minor_start) + index);
+}
+EXPORT_SYMBOL(tty_unregister_device);
+
+struct tty_driver *alloc_tty_driver(int lines)
+{
+       struct tty_driver *driver;
+
+       driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
+       if (driver) {
+               kref_init(&driver->kref);
+               driver->magic = TTY_DRIVER_MAGIC;
+               driver->num = lines;
+               /* later we'll move allocation of tables here */
+       }
+       return driver;
+}
+EXPORT_SYMBOL(alloc_tty_driver);
+
+static void destruct_tty_driver(struct kref *kref)
+{
+       struct tty_driver *driver = container_of(kref, struct tty_driver, kref);
+       int i;
+       struct ktermios *tp;
+       void *p;
+
+       if (driver->flags & TTY_DRIVER_INSTALLED) {
+               /*
+                * Free the termios and termios_locked structures because
+                * we don't want to get memory leaks when modular tty
+                * drivers are removed from the kernel.
+                */
+               for (i = 0; i < driver->num; i++) {
+                       tp = driver->termios[i];
+                       if (tp) {
+                               driver->termios[i] = NULL;
+                               kfree(tp);
+                       }
+                       if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
+                               tty_unregister_device(driver, i);
+               }
+               p = driver->ttys;
+               proc_tty_unregister_driver(driver);
+               driver->ttys = NULL;
+               driver->termios = NULL;
+               kfree(p);
+               cdev_del(&driver->cdev);
+       }
+       kfree(driver);
+}
+
+void tty_driver_kref_put(struct tty_driver *driver)
+{
+       kref_put(&driver->kref, destruct_tty_driver);
+}
+EXPORT_SYMBOL(tty_driver_kref_put);
+
+void tty_set_operations(struct tty_driver *driver,
+                       const struct tty_operations *op)
+{
+       driver->ops = op;
+};
+EXPORT_SYMBOL(tty_set_operations);
+
+void put_tty_driver(struct tty_driver *d)
+{
+       tty_driver_kref_put(d);
+}
+EXPORT_SYMBOL(put_tty_driver);
+
+/*
+ * Called by a tty driver to register itself.
+ */
+int tty_register_driver(struct tty_driver *driver)
+{
+       int error;
+       int i;
+       dev_t dev;
+       void **p = NULL;
+       struct device *d;
+
+       if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
+               p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
+               if (!p)
+                       return -ENOMEM;
+       }
+
+       if (!driver->major) {
+               error = alloc_chrdev_region(&dev, driver->minor_start,
+                                               driver->num, driver->name);
+               if (!error) {
+                       driver->major = MAJOR(dev);
+                       driver->minor_start = MINOR(dev);
+               }
+       } else {
+               dev = MKDEV(driver->major, driver->minor_start);
+               error = register_chrdev_region(dev, driver->num, driver->name);
+       }
+       if (error < 0) {
+               kfree(p);
+               return error;
+       }
+
+       if (p) {
+               driver->ttys = (struct tty_struct **)p;
+               driver->termios = (struct ktermios **)(p + driver->num);
+       } else {
+               driver->ttys = NULL;
+               driver->termios = NULL;
+       }
+
+       cdev_init(&driver->cdev, &tty_fops);
+       driver->cdev.owner = driver->owner;
+       error = cdev_add(&driver->cdev, dev, driver->num);
+       if (error) {
+               unregister_chrdev_region(dev, driver->num);
+               driver->ttys = NULL;
+               driver->termios = NULL;
+               kfree(p);
+               return error;
+       }
+
+       mutex_lock(&tty_mutex);
+       list_add(&driver->tty_drivers, &tty_drivers);
+       mutex_unlock(&tty_mutex);
+
+       if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
+               for (i = 0; i < driver->num; i++) {
+                       d = tty_register_device(driver, i, NULL);
+                       if (IS_ERR(d)) {
+                               error = PTR_ERR(d);
+                               goto err;
+                       }
+               }
+       }
+       proc_tty_register_driver(driver);
+       driver->flags |= TTY_DRIVER_INSTALLED;
+       return 0;
+
+err:
+       for (i--; i >= 0; i--)
+               tty_unregister_device(driver, i);
+
+       mutex_lock(&tty_mutex);
+       list_del(&driver->tty_drivers);
+       mutex_unlock(&tty_mutex);
+
+       unregister_chrdev_region(dev, driver->num);
+       driver->ttys = NULL;
+       driver->termios = NULL;
+       kfree(p);
+       return error;
+}
+
+EXPORT_SYMBOL(tty_register_driver);
+
+/*
+ * Called by a tty driver to unregister itself.
+ */
+int tty_unregister_driver(struct tty_driver *driver)
+{
+#if 0
+       /* FIXME */
+       if (driver->refcount)
+               return -EBUSY;
+#endif
+       unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
+                               driver->num);
+       mutex_lock(&tty_mutex);
+       list_del(&driver->tty_drivers);
+       mutex_unlock(&tty_mutex);
+       return 0;
+}
+
+EXPORT_SYMBOL(tty_unregister_driver);
+
+dev_t tty_devnum(struct tty_struct *tty)
+{
+       return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
+}
+EXPORT_SYMBOL(tty_devnum);
+
+void proc_clear_tty(struct task_struct *p)
+{
+       unsigned long flags;
+       struct tty_struct *tty;
+       spin_lock_irqsave(&p->sighand->siglock, flags);
+       tty = p->signal->tty;
+       p->signal->tty = NULL;
+       spin_unlock_irqrestore(&p->sighand->siglock, flags);
+       tty_kref_put(tty);
+}
+
+/* Called under the sighand lock */
+
+static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+{
+       if (tty) {
+               unsigned long flags;
+               /* We should not have a session or pgrp to put here but.... */
+               spin_lock_irqsave(&tty->ctrl_lock, flags);
+               put_pid(tty->session);
+               put_pid(tty->pgrp);
+               tty->pgrp = get_pid(task_pgrp(tsk));
+               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+               tty->session = get_pid(task_session(tsk));
+               if (tsk->signal->tty) {
+                       printk(KERN_DEBUG "tty not NULL!!\n");
+                       tty_kref_put(tsk->signal->tty);
+               }
+       }
+       put_pid(tsk->signal->tty_old_pgrp);
+       tsk->signal->tty = tty_kref_get(tty);
+       tsk->signal->tty_old_pgrp = NULL;
+}
+
+static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+{
+       spin_lock_irq(&tsk->sighand->siglock);
+       __proc_set_tty(tsk, tty);
+       spin_unlock_irq(&tsk->sighand->siglock);
+}
+
+struct tty_struct *get_current_tty(void)
+{
+       struct tty_struct *tty;
+       unsigned long flags;
+
+       spin_lock_irqsave(&current->sighand->siglock, flags);
+       tty = tty_kref_get(current->signal->tty);
+       spin_unlock_irqrestore(&current->sighand->siglock, flags);
+       return tty;
+}
+EXPORT_SYMBOL_GPL(get_current_tty);
+
+void tty_default_fops(struct file_operations *fops)
+{
+       *fops = tty_fops;
+}
+
+/*
+ * Initialize the console device. This is called *early*, so
+ * we can't necessarily depend on lots of kernel help here.
+ * Just do some early initializations, and do the complex setup
+ * later.
+ */
+void __init console_init(void)
+{
+       initcall_t *call;
+
+       /* Setup the default TTY line discipline. */
+       tty_ldisc_begin();
+
+       /*
+        * set up the console device so that later boot sequences can
+        * inform about problems etc..
+        */
+       call = __con_initcall_start;
+       while (call < __con_initcall_end) {
+               (*call)();
+               call++;
+       }
+}
+
+static char *tty_devnode(struct device *dev, mode_t *mode)
+{
+       if (!mode)
+               return NULL;
+       if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
+           dev->devt == MKDEV(TTYAUX_MAJOR, 2))
+               *mode = 0666;
+       return NULL;
+}
+
+static int __init tty_class_init(void)
+{
+       tty_class = class_create(THIS_MODULE, "tty");
+       if (IS_ERR(tty_class))
+               return PTR_ERR(tty_class);
+       tty_class->devnode = tty_devnode;
+       return 0;
+}
+
+postcore_initcall(tty_class_init);
+
+/* 3/2004 jmc: why do these devices exist? */
+
+static struct cdev tty_cdev, console_cdev;
+
+/*
+ * Ok, now we can initialize the rest of the tty devices and can count
+ * on memory allocations, interrupts etc..
+ */
+int __init tty_init(void)
+{
+       cdev_init(&tty_cdev, &tty_fops);
+       if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
+           register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
+               panic("Couldn't register /dev/tty driver\n");
+       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
+                             "tty");
+
+       cdev_init(&console_cdev, &console_fops);
+       if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
+           register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
+               panic("Couldn't register /dev/console driver\n");
+       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
+                             "console");
+
+#ifdef CONFIG_VT
+       vty_init(&console_fops);
+#endif
+       return 0;
+}
+
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
new file mode 100644 (file)
index 0000000..0c18899
--- /dev/null
@@ -0,0 +1,1179 @@
+/*
+ *  linux/drivers/char/tty_ioctl.c
+ *
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *
+ * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
+ * which can be dynamically activated and de-activated by the line
+ * discipline handling modules (like SLIP).
+ */
+
+#include <linux/types.h>
+#include <linux/termios.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/tty.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/mutex.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#undef TTY_DEBUG_WAIT_UNTIL_SENT
+
+#undef DEBUG
+
+/*
+ * Internal flag options for termios setting behavior
+ */
+#define TERMIOS_FLUSH  1
+#define TERMIOS_WAIT   2
+#define TERMIOS_TERMIO 4
+#define TERMIOS_OLD    8
+
+
+/**
+ *     tty_chars_in_buffer     -       characters pending
+ *     @tty: terminal
+ *
+ *     Return the number of bytes of data in the device private
+ *     output queue. If no private method is supplied there is assumed
+ *     to be no queue on the device.
+ */
+
+int tty_chars_in_buffer(struct tty_struct *tty)
+{
+       if (tty->ops->chars_in_buffer)
+               return tty->ops->chars_in_buffer(tty);
+       else
+               return 0;
+}
+EXPORT_SYMBOL(tty_chars_in_buffer);
+
+/**
+ *     tty_write_room          -       write queue space
+ *     @tty: terminal
+ *
+ *     Return the number of bytes that can be queued to this device
+ *     at the present time. The result should be treated as a guarantee
+ *     and the driver cannot offer a value it later shrinks by more than
+ *     the number of bytes written. If no method is provided 2K is always
+ *     returned and data may be lost as there will be no flow control.
+ */
+int tty_write_room(struct tty_struct *tty)
+{
+       if (tty->ops->write_room)
+               return tty->ops->write_room(tty);
+       return 2048;
+}
+EXPORT_SYMBOL(tty_write_room);
+
+/**
+ *     tty_driver_flush_buffer -       discard internal buffer
+ *     @tty: terminal
+ *
+ *     Discard the internal output buffer for this device. If no method
+ *     is provided then either the buffer cannot be hardware flushed or
+ *     there is no buffer driver side.
+ */
+void tty_driver_flush_buffer(struct tty_struct *tty)
+{
+       if (tty->ops->flush_buffer)
+               tty->ops->flush_buffer(tty);
+}
+EXPORT_SYMBOL(tty_driver_flush_buffer);
+
+/**
+ *     tty_throttle            -       flow control
+ *     @tty: terminal
+ *
+ *     Indicate that a tty should stop transmitting data down the stack.
+ *     Takes the termios mutex to protect against parallel throttle/unthrottle
+ *     and also to ensure the driver can consistently reference its own
+ *     termios data at this point when implementing software flow control.
+ */
+
+void tty_throttle(struct tty_struct *tty)
+{
+       mutex_lock(&tty->termios_mutex);
+       /* check TTY_THROTTLED first so it indicates our state */
+       if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
+           tty->ops->throttle)
+               tty->ops->throttle(tty);
+       mutex_unlock(&tty->termios_mutex);
+}
+EXPORT_SYMBOL(tty_throttle);
+
+/**
+ *     tty_unthrottle          -       flow control
+ *     @tty: terminal
+ *
+ *     Indicate that a tty may continue transmitting data down the stack.
+ *     Takes the termios mutex to protect against parallel throttle/unthrottle
+ *     and also to ensure the driver can consistently reference its own
+ *     termios data at this point when implementing software flow control.
+ *
+ *     Drivers should however remember that the stack can issue a throttle,
+ *     then change flow control method, then unthrottle.
+ */
+
+void tty_unthrottle(struct tty_struct *tty)
+{
+       mutex_lock(&tty->termios_mutex);
+       if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
+           tty->ops->unthrottle)
+               tty->ops->unthrottle(tty);
+       mutex_unlock(&tty->termios_mutex);
+}
+EXPORT_SYMBOL(tty_unthrottle);
+
+/**
+ *     tty_wait_until_sent     -       wait for I/O to finish
+ *     @tty: tty we are waiting for
+ *     @timeout: how long we will wait
+ *
+ *     Wait for characters pending in a tty driver to hit the wire, or
+ *     for a timeout to occur (eg due to flow control)
+ *
+ *     Locking: none
+ */
+
+void tty_wait_until_sent(struct tty_struct *tty, long timeout)
+{
+#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
+       char buf[64];
+
+       printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
+#endif
+       if (!timeout)
+               timeout = MAX_SCHEDULE_TIMEOUT;
+       if (wait_event_interruptible_timeout(tty->write_wait,
+                       !tty_chars_in_buffer(tty), timeout) >= 0) {
+               if (tty->ops->wait_until_sent)
+                       tty->ops->wait_until_sent(tty, timeout);
+       }
+}
+EXPORT_SYMBOL(tty_wait_until_sent);
+
+
+/*
+ *             Termios Helper Methods
+ */
+
+static void unset_locked_termios(struct ktermios *termios,
+                                struct ktermios *old,
+                                struct ktermios *locked)
+{
+       int     i;
+
+#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
+
+       if (!locked) {
+               printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
+               return;
+       }
+
+       NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
+       NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
+       NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
+       NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
+       termios->c_line = locked->c_line ? old->c_line : termios->c_line;
+       for (i = 0; i < NCCS; i++)
+               termios->c_cc[i] = locked->c_cc[i] ?
+                       old->c_cc[i] : termios->c_cc[i];
+       /* FIXME: What should we do for i/ospeed */
+}
+
+/*
+ * Routine which returns the baud rate of the tty
+ *
+ * Note that the baud_table needs to be kept in sync with the
+ * include/asm/termbits.h file.
+ */
+static const speed_t baud_table[] = {
+       0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+       9600, 19200, 38400, 57600, 115200, 230400, 460800,
+#ifdef __sparc__
+       76800, 153600, 307200, 614400, 921600
+#else
+       500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
+       2500000, 3000000, 3500000, 4000000
+#endif
+};
+
+#ifndef __sparc__
+static const tcflag_t baud_bits[] = {
+       B0, B50, B75, B110, B134, B150, B200, B300, B600,
+       B1200, B1800, B2400, B4800, B9600, B19200, B38400,
+       B57600, B115200, B230400, B460800, B500000, B576000,
+       B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
+       B3000000, B3500000, B4000000
+};
+#else
+static const tcflag_t baud_bits[] = {
+       B0, B50, B75, B110, B134, B150, B200, B300, B600,
+       B1200, B1800, B2400, B4800, B9600, B19200, B38400,
+       B57600, B115200, B230400, B460800, B76800, B153600,
+       B307200, B614400, B921600
+};
+#endif
+
+static int n_baud_table = ARRAY_SIZE(baud_table);
+
+/**
+ *     tty_termios_baud_rate
+ *     @termios: termios structure
+ *
+ *     Convert termios baud rate data into a speed. This should be called
+ *     with the termios lock held if this termios is a terminal termios
+ *     structure. May change the termios data. Device drivers can call this
+ *     function but should use ->c_[io]speed directly as they are updated.
+ *
+ *     Locking: none
+ */
+
+speed_t tty_termios_baud_rate(struct ktermios *termios)
+{
+       unsigned int cbaud;
+
+       cbaud = termios->c_cflag & CBAUD;
+
+#ifdef BOTHER
+       /* Magic token for arbitary speed via c_ispeed/c_ospeed */
+       if (cbaud == BOTHER)
+               return termios->c_ospeed;
+#endif
+       if (cbaud & CBAUDEX) {
+               cbaud &= ~CBAUDEX;
+
+               if (cbaud < 1 || cbaud + 15 > n_baud_table)
+                       termios->c_cflag &= ~CBAUDEX;
+               else
+                       cbaud += 15;
+       }
+       return baud_table[cbaud];
+}
+EXPORT_SYMBOL(tty_termios_baud_rate);
+
+/**
+ *     tty_termios_input_baud_rate
+ *     @termios: termios structure
+ *
+ *     Convert termios baud rate data into a speed. This should be called
+ *     with the termios lock held if this termios is a terminal termios
+ *     structure. May change the termios data. Device drivers can call this
+ *     function but should use ->c_[io]speed directly as they are updated.
+ *
+ *     Locking: none
+ */
+
+speed_t tty_termios_input_baud_rate(struct ktermios *termios)
+{
+#ifdef IBSHIFT
+       unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
+
+       if (cbaud == B0)
+               return tty_termios_baud_rate(termios);
+
+       /* Magic token for arbitary speed via c_ispeed*/
+       if (cbaud == BOTHER)
+               return termios->c_ispeed;
+
+       if (cbaud & CBAUDEX) {
+               cbaud &= ~CBAUDEX;
+
+               if (cbaud < 1 || cbaud + 15 > n_baud_table)
+                       termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
+               else
+                       cbaud += 15;
+       }
+       return baud_table[cbaud];
+#else
+       return tty_termios_baud_rate(termios);
+#endif
+}
+EXPORT_SYMBOL(tty_termios_input_baud_rate);
+
+/**
+ *     tty_termios_encode_baud_rate
+ *     @termios: ktermios structure holding user requested state
+ *     @ispeed: input speed
+ *     @ospeed: output speed
+ *
+ *     Encode the speeds set into the passed termios structure. This is
+ *     used as a library helper for drivers os that they can report back
+ *     the actual speed selected when it differs from the speed requested
+ *
+ *     For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
+ *     we need to carefully set the bits when the user does not get the
+ *     desired speed. We allow small margins and preserve as much of possible
+ *     of the input intent to keep compatibility.
+ *
+ *     Locking: Caller should hold termios lock. This is already held
+ *     when calling this function from the driver termios handler.
+ *
+ *     The ifdefs deal with platforms whose owners have yet to update them
+ *     and will all go away once this is done.
+ */
+
+void tty_termios_encode_baud_rate(struct ktermios *termios,
+                                 speed_t ibaud, speed_t obaud)
+{
+       int i = 0;
+       int ifound = -1, ofound = -1;
+       int iclose = ibaud/50, oclose = obaud/50;
+       int ibinput = 0;
+
+       if (obaud == 0)                 /* CD dropped             */
+               ibaud = 0;              /* Clear ibaud to be sure */
+
+       termios->c_ispeed = ibaud;
+       termios->c_ospeed = obaud;
+
+#ifdef BOTHER
+       /* If the user asked for a precise weird speed give a precise weird
+          answer. If they asked for a Bfoo speed they many have problems
+          digesting non-exact replies so fuzz a bit */
+
+       if ((termios->c_cflag & CBAUD) == BOTHER)
+               oclose = 0;
+       if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
+               iclose = 0;
+       if ((termios->c_cflag >> IBSHIFT) & CBAUD)
+               ibinput = 1;    /* An input speed was specified */
+#endif
+       termios->c_cflag &= ~CBAUD;
+
+       /*
+        *      Our goal is to find a close match to the standard baud rate
+        *      returned. Walk the baud rate table and if we get a very close
+        *      match then report back the speed as a POSIX Bxxxx value by
+        *      preference
+        */
+
+       do {
+               if (obaud - oclose <= baud_table[i] &&
+                   obaud + oclose >= baud_table[i]) {
+                       termios->c_cflag |= baud_bits[i];
+                       ofound = i;
+               }
+               if (ibaud - iclose <= baud_table[i] &&
+                   ibaud + iclose >= baud_table[i]) {
+                       /* For the case input == output don't set IBAUD bits
+                          if the user didn't do so */
+                       if (ofound == i && !ibinput)
+                               ifound  = i;
+#ifdef IBSHIFT
+                       else {
+                               ifound = i;
+                               termios->c_cflag |= (baud_bits[i] << IBSHIFT);
+                       }
+#endif
+               }
+       } while (++i < n_baud_table);
+
+       /*
+        *      If we found no match then use BOTHER if provided or warn
+        *      the user their platform maintainer needs to wake up if not.
+        */
+#ifdef BOTHER
+       if (ofound == -1)
+               termios->c_cflag |= BOTHER;
+       /* Set exact input bits only if the input and output differ or the
+          user already did */
+       if (ifound == -1 && (ibaud != obaud || ibinput))
+               termios->c_cflag |= (BOTHER << IBSHIFT);
+#else
+       if (ifound == -1 || ofound == -1) {
+               printk_once(KERN_WARNING "tty: Unable to return correct "
+                         "speed data as your architecture needs updating.\n");
+       }
+#endif
+}
+EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
+
+/**
+ *     tty_encode_baud_rate            -       set baud rate of the tty
+ *     @ibaud: input baud rate
+ *     @obad: output baud rate
+ *
+ *     Update the current termios data for the tty with the new speed
+ *     settings. The caller must hold the termios_mutex for the tty in
+ *     question.
+ */
+
+void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
+{
+       tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
+}
+EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
+
+/**
+ *     tty_get_baud_rate       -       get tty bit rates
+ *     @tty: tty to query
+ *
+ *     Returns the baud rate as an integer for this terminal. The
+ *     termios lock must be held by the caller and the terminal bit
+ *     flags may be updated.
+ *
+ *     Locking: none
+ */
+
+speed_t tty_get_baud_rate(struct tty_struct *tty)
+{
+       speed_t baud = tty_termios_baud_rate(tty->termios);
+
+       if (baud == 38400 && tty->alt_speed) {
+               if (!tty->warned) {
+                       printk(KERN_WARNING "Use of setserial/setrocket to "
+                                           "set SPD_* flags is deprecated\n");
+                       tty->warned = 1;
+               }
+               baud = tty->alt_speed;
+       }
+
+       return baud;
+}
+EXPORT_SYMBOL(tty_get_baud_rate);
+
+/**
+ *     tty_termios_copy_hw     -       copy hardware settings
+ *     @new: New termios
+ *     @old: Old termios
+ *
+ *     Propogate the hardware specific terminal setting bits from
+ *     the old termios structure to the new one. This is used in cases
+ *     where the hardware does not support reconfiguration or as a helper
+ *     in some cases where only minimal reconfiguration is supported
+ */
+
+void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
+{
+       /* The bits a dumb device handles in software. Smart devices need
+          to always provide a set_termios method */
+       new->c_cflag &= HUPCL | CREAD | CLOCAL;
+       new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
+       new->c_ispeed = old->c_ispeed;
+       new->c_ospeed = old->c_ospeed;
+}
+EXPORT_SYMBOL(tty_termios_copy_hw);
+
+/**
+ *     tty_termios_hw_change   -       check for setting change
+ *     @a: termios
+ *     @b: termios to compare
+ *
+ *     Check if any of the bits that affect a dumb device have changed
+ *     between the two termios structures, or a speed change is needed.
+ */
+
+int tty_termios_hw_change(struct ktermios *a, struct ktermios *b)
+{
+       if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
+               return 1;
+       if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
+               return 1;
+       return 0;
+}
+EXPORT_SYMBOL(tty_termios_hw_change);
+
+/**
+ *     change_termios          -       update termios values
+ *     @tty: tty to update
+ *     @new_termios: desired new value
+ *
+ *     Perform updates to the termios values set on this terminal. There
+ *     is a bit of layering violation here with n_tty in terms of the
+ *     internal knowledge of this function.
+ *
+ *     Locking: termios_mutex
+ */
+
+static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
+{
+       struct ktermios old_termios;
+       struct tty_ldisc *ld;
+       unsigned long flags;
+
+       /*
+        *      Perform the actual termios internal changes under lock.
+        */
+
+
+       /* FIXME: we need to decide on some locking/ordering semantics
+          for the set_termios notification eventually */
+       mutex_lock(&tty->termios_mutex);
+       old_termios = *tty->termios;
+       *tty->termios = *new_termios;
+       unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
+
+       /* See if packet mode change of state. */
+       if (tty->link && tty->link->packet) {
+               int extproc = (old_termios.c_lflag & EXTPROC) |
+                               (tty->termios->c_lflag & EXTPROC);
+               int old_flow = ((old_termios.c_iflag & IXON) &&
+                               (old_termios.c_cc[VSTOP] == '\023') &&
+                               (old_termios.c_cc[VSTART] == '\021'));
+               int new_flow = (I_IXON(tty) &&
+                               STOP_CHAR(tty) == '\023' &&
+                               START_CHAR(tty) == '\021');
+               if ((old_flow != new_flow) || extproc) {
+                       spin_lock_irqsave(&tty->ctrl_lock, flags);
+                       if (old_flow != new_flow) {
+                               tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
+                               if (new_flow)
+                                       tty->ctrl_status |= TIOCPKT_DOSTOP;
+                               else
+                                       tty->ctrl_status |= TIOCPKT_NOSTOP;
+                       }
+                       if (extproc)
+                               tty->ctrl_status |= TIOCPKT_IOCTL;
+                       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+                       wake_up_interruptible(&tty->link->read_wait);
+               }
+       }
+
+       if (tty->ops->set_termios)
+               (*tty->ops->set_termios)(tty, &old_termios);
+       else
+               tty_termios_copy_hw(tty->termios, &old_termios);
+
+       ld = tty_ldisc_ref(tty);
+       if (ld != NULL) {
+               if (ld->ops->set_termios)
+                       (ld->ops->set_termios)(tty, &old_termios);
+               tty_ldisc_deref(ld);
+       }
+       mutex_unlock(&tty->termios_mutex);
+}
+
+/**
+ *     set_termios             -       set termios values for a tty
+ *     @tty: terminal device
+ *     @arg: user data
+ *     @opt: option information
+ *
+ *     Helper function to prepare termios data and run necessary other
+ *     functions before using change_termios to do the actual changes.
+ *
+ *     Locking:
+ *             Called functions take ldisc and termios_mutex locks
+ */
+
+static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
+{
+       struct ktermios tmp_termios;
+       struct tty_ldisc *ld;
+       int retval = tty_check_change(tty);
+
+       if (retval)
+               return retval;
+
+       mutex_lock(&tty->termios_mutex);
+       memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
+       mutex_unlock(&tty->termios_mutex);
+
+       if (opt & TERMIOS_TERMIO) {
+               if (user_termio_to_kernel_termios(&tmp_termios,
+                                               (struct termio __user *)arg))
+                       return -EFAULT;
+#ifdef TCGETS2
+       } else if (opt & TERMIOS_OLD) {
+               if (user_termios_to_kernel_termios_1(&tmp_termios,
+                                               (struct termios __user *)arg))
+                       return -EFAULT;
+       } else {
+               if (user_termios_to_kernel_termios(&tmp_termios,
+                                               (struct termios2 __user *)arg))
+                       return -EFAULT;
+       }
+#else
+       } else if (user_termios_to_kernel_termios(&tmp_termios,
+                                       (struct termios __user *)arg))
+               return -EFAULT;
+#endif
+
+       /* If old style Bfoo values are used then load c_ispeed/c_ospeed
+        * with the real speed so its unconditionally usable */
+       tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
+       tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
+
+       ld = tty_ldisc_ref(tty);
+
+       if (ld != NULL) {
+               if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
+                       ld->ops->flush_buffer(tty);
+               tty_ldisc_deref(ld);
+       }
+
+       if (opt & TERMIOS_WAIT) {
+               tty_wait_until_sent(tty, 0);
+               if (signal_pending(current))
+                       return -EINTR;
+       }
+
+       change_termios(tty, &tmp_termios);
+
+       /* FIXME: Arguably if tmp_termios == tty->termios AND the
+          actual requested termios was not tmp_termios then we may
+          want to return an error as no user requested change has
+          succeeded */
+       return 0;
+}
+
+static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
+{
+       mutex_lock(&tty->termios_mutex);
+       memcpy(kterm, tty->termios, sizeof(struct ktermios));
+       mutex_unlock(&tty->termios_mutex);
+}
+
+static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
+{
+       mutex_lock(&tty->termios_mutex);
+       memcpy(kterm, tty->termios_locked, sizeof(struct ktermios));
+       mutex_unlock(&tty->termios_mutex);
+}
+
+static int get_termio(struct tty_struct *tty, struct termio __user *termio)
+{
+       struct ktermios kterm;
+       copy_termios(tty, &kterm);
+       if (kernel_termios_to_user_termio(termio, &kterm))
+               return -EFAULT;
+       return 0;
+}
+
+
+#ifdef TCGETX
+
+/**
+ *     set_termiox     -       set termiox fields if possible
+ *     @tty: terminal
+ *     @arg: termiox structure from user
+ *     @opt: option flags for ioctl type
+ *
+ *     Implement the device calling points for the SYS5 termiox ioctl
+ *     interface in Linux
+ */
+
+static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
+{
+       struct termiox tnew;
+       struct tty_ldisc *ld;
+
+       if (tty->termiox == NULL)
+               return -EINVAL;
+       if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
+               return -EFAULT;
+
+       ld = tty_ldisc_ref(tty);
+       if (ld != NULL) {
+               if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
+                       ld->ops->flush_buffer(tty);
+               tty_ldisc_deref(ld);
+       }
+       if (opt & TERMIOS_WAIT) {
+               tty_wait_until_sent(tty, 0);
+               if (signal_pending(current))
+                       return -EINTR;
+       }
+
+       mutex_lock(&tty->termios_mutex);
+       if (tty->ops->set_termiox)
+               tty->ops->set_termiox(tty, &tnew);
+       mutex_unlock(&tty->termios_mutex);
+       return 0;
+}
+
+#endif
+
+
+#ifdef TIOCGETP
+/*
+ * These are deprecated, but there is limited support..
+ *
+ * The "sg_flags" translation is a joke..
+ */
+static int get_sgflags(struct tty_struct *tty)
+{
+       int flags = 0;
+
+       if (!(tty->termios->c_lflag & ICANON)) {
+               if (tty->termios->c_lflag & ISIG)
+                       flags |= 0x02;          /* cbreak */
+               else
+                       flags |= 0x20;          /* raw */
+       }
+       if (tty->termios->c_lflag & ECHO)
+               flags |= 0x08;                  /* echo */
+       if (tty->termios->c_oflag & OPOST)
+               if (tty->termios->c_oflag & ONLCR)
+                       flags |= 0x10;          /* crmod */
+       return flags;
+}
+
+static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
+{
+       struct sgttyb tmp;
+
+       mutex_lock(&tty->termios_mutex);
+       tmp.sg_ispeed = tty->termios->c_ispeed;
+       tmp.sg_ospeed = tty->termios->c_ospeed;
+       tmp.sg_erase = tty->termios->c_cc[VERASE];
+       tmp.sg_kill = tty->termios->c_cc[VKILL];
+       tmp.sg_flags = get_sgflags(tty);
+       mutex_unlock(&tty->termios_mutex);
+
+       return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
+}
+
+static void set_sgflags(struct ktermios *termios, int flags)
+{
+       termios->c_iflag = ICRNL | IXON;
+       termios->c_oflag = 0;
+       termios->c_lflag = ISIG | ICANON;
+       if (flags & 0x02) {     /* cbreak */
+               termios->c_iflag = 0;
+               termios->c_lflag &= ~ICANON;
+       }
+       if (flags & 0x08) {             /* echo */
+               termios->c_lflag |= ECHO | ECHOE | ECHOK |
+                                   ECHOCTL | ECHOKE | IEXTEN;
+       }
+       if (flags & 0x10) {             /* crmod */
+               termios->c_oflag |= OPOST | ONLCR;
+       }
+       if (flags & 0x20) {     /* raw */
+               termios->c_iflag = 0;
+               termios->c_lflag &= ~(ISIG | ICANON);
+       }
+       if (!(termios->c_lflag & ICANON)) {
+               termios->c_cc[VMIN] = 1;
+               termios->c_cc[VTIME] = 0;
+       }
+}
+
+/**
+ *     set_sgttyb              -       set legacy terminal values
+ *     @tty: tty structure
+ *     @sgttyb: pointer to old style terminal structure
+ *
+ *     Updates a terminal from the legacy BSD style terminal information
+ *     structure.
+ *
+ *     Locking: termios_mutex
+ */
+
+static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
+{
+       int retval;
+       struct sgttyb tmp;
+       struct ktermios termios;
+
+       retval = tty_check_change(tty);
+       if (retval)
+               return retval;
+
+       if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
+               return -EFAULT;
+
+       mutex_lock(&tty->termios_mutex);
+       termios = *tty->termios;
+       termios.c_cc[VERASE] = tmp.sg_erase;
+       termios.c_cc[VKILL] = tmp.sg_kill;
+       set_sgflags(&termios, tmp.sg_flags);
+       /* Try and encode into Bfoo format */
+#ifdef BOTHER
+       tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
+                                               termios.c_ospeed);
+#endif
+       mutex_unlock(&tty->termios_mutex);
+       change_termios(tty, &termios);
+       return 0;
+}
+#endif
+
+#ifdef TIOCGETC
+static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
+{
+       struct tchars tmp;
+
+       mutex_lock(&tty->termios_mutex);
+       tmp.t_intrc = tty->termios->c_cc[VINTR];
+       tmp.t_quitc = tty->termios->c_cc[VQUIT];
+       tmp.t_startc = tty->termios->c_cc[VSTART];
+       tmp.t_stopc = tty->termios->c_cc[VSTOP];
+       tmp.t_eofc = tty->termios->c_cc[VEOF];
+       tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
+       mutex_unlock(&tty->termios_mutex);
+       return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
+}
+
+static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
+{
+       struct tchars tmp;
+
+       if (copy_from_user(&tmp, tchars, sizeof(tmp)))
+               return -EFAULT;
+       mutex_lock(&tty->termios_mutex);
+       tty->termios->c_cc[VINTR] = tmp.t_intrc;
+       tty->termios->c_cc[VQUIT] = tmp.t_quitc;
+       tty->termios->c_cc[VSTART] = tmp.t_startc;
+       tty->termios->c_cc[VSTOP] = tmp.t_stopc;
+       tty->termios->c_cc[VEOF] = tmp.t_eofc;
+       tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
+       mutex_unlock(&tty->termios_mutex);
+       return 0;
+}
+#endif
+
+#ifdef TIOCGLTC
+static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
+{
+       struct ltchars tmp;
+
+       mutex_lock(&tty->termios_mutex);
+       tmp.t_suspc = tty->termios->c_cc[VSUSP];
+       /* what is dsuspc anyway? */
+       tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
+       tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
+       /* what is flushc anyway? */
+       tmp.t_flushc = tty->termios->c_cc[VEOL2];
+       tmp.t_werasc = tty->termios->c_cc[VWERASE];
+       tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
+       mutex_unlock(&tty->termios_mutex);
+       return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
+}
+
+static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
+{
+       struct ltchars tmp;
+
+       if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
+               return -EFAULT;
+
+       mutex_lock(&tty->termios_mutex);
+       tty->termios->c_cc[VSUSP] = tmp.t_suspc;
+       /* what is dsuspc anyway? */
+       tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
+       tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
+       /* what is flushc anyway? */
+       tty->termios->c_cc[VEOL2] = tmp.t_flushc;
+       tty->termios->c_cc[VWERASE] = tmp.t_werasc;
+       tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
+       mutex_unlock(&tty->termios_mutex);
+       return 0;
+}
+#endif
+
+/**
+ *     send_prio_char          -       send priority character
+ *
+ *     Send a high priority character to the tty even if stopped
+ *
+ *     Locking: none for xchar method, write ordering for write method.
+ */
+
+static int send_prio_char(struct tty_struct *tty, char ch)
+{
+       int     was_stopped = tty->stopped;
+
+       if (tty->ops->send_xchar) {
+               tty->ops->send_xchar(tty, ch);
+               return 0;
+       }
+
+       if (tty_write_lock(tty, 0) < 0)
+               return -ERESTARTSYS;
+
+       if (was_stopped)
+               start_tty(tty);
+       tty->ops->write(tty, &ch, 1);
+       if (was_stopped)
+               stop_tty(tty);
+       tty_write_unlock(tty);
+       return 0;
+}
+
+/**
+ *     tty_change_softcar      -       carrier change ioctl helper
+ *     @tty: tty to update
+ *     @arg: enable/disable CLOCAL
+ *
+ *     Perform a change to the CLOCAL state and call into the driver
+ *     layer to make it visible. All done with the termios mutex
+ */
+
+static int tty_change_softcar(struct tty_struct *tty, int arg)
+{
+       int ret = 0;
+       int bit = arg ? CLOCAL : 0;
+       struct ktermios old;
+
+       mutex_lock(&tty->termios_mutex);
+       old = *tty->termios;
+       tty->termios->c_cflag &= ~CLOCAL;
+       tty->termios->c_cflag |= bit;
+       if (tty->ops->set_termios)
+               tty->ops->set_termios(tty, &old);
+       if ((tty->termios->c_cflag & CLOCAL) != bit)
+               ret = -EINVAL;
+       mutex_unlock(&tty->termios_mutex);
+       return ret;
+}
+
+/**
+ *     tty_mode_ioctl          -       mode related ioctls
+ *     @tty: tty for the ioctl
+ *     @file: file pointer for the tty
+ *     @cmd: command
+ *     @arg: ioctl argument
+ *
+ *     Perform non line discipline specific mode control ioctls. This
+ *     is designed to be called by line disciplines to ensure they provide
+ *     consistent mode setting.
+ */
+
+int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+{
+       struct tty_struct *real_tty;
+       void __user *p = (void __user *)arg;
+       int ret = 0;
+       struct ktermios kterm;
+
+       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
+           tty->driver->subtype == PTY_TYPE_MASTER)
+               real_tty = tty->link;
+       else
+               real_tty = tty;
+
+       switch (cmd) {
+#ifdef TIOCGETP
+       case TIOCGETP:
+               return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
+       case TIOCSETP:
+       case TIOCSETN:
+               return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
+#endif
+#ifdef TIOCGETC
+       case TIOCGETC:
+               return get_tchars(real_tty, p);
+       case TIOCSETC:
+               return set_tchars(real_tty, p);
+#endif
+#ifdef TIOCGLTC
+       case TIOCGLTC:
+               return get_ltchars(real_tty, p);
+       case TIOCSLTC:
+               return set_ltchars(real_tty, p);
+#endif
+       case TCSETSF:
+               return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
+       case TCSETSW:
+               return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
+       case TCSETS:
+               return set_termios(real_tty, p, TERMIOS_OLD);
+#ifndef TCGETS2
+       case TCGETS:
+               copy_termios(real_tty, &kterm);
+               if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
+                       ret = -EFAULT;
+               return ret;
+#else
+       case TCGETS:
+               copy_termios(real_tty, &kterm);
+               if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
+                       ret = -EFAULT;
+               return ret;
+       case TCGETS2:
+               copy_termios(real_tty, &kterm);
+               if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm))
+                       ret = -EFAULT;
+               return ret;
+       case TCSETSF2:
+               return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
+       case TCSETSW2:
+               return set_termios(real_tty, p, TERMIOS_WAIT);
+       case TCSETS2:
+               return set_termios(real_tty, p, 0);
+#endif
+       case TCGETA:
+               return get_termio(real_tty, p);
+       case TCSETAF:
+               return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
+       case TCSETAW:
+               return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
+       case TCSETA:
+               return set_termios(real_tty, p, TERMIOS_TERMIO);
+#ifndef TCGETS2
+       case TIOCGLCKTRMIOS:
+               copy_termios_locked(real_tty, &kterm);
+               if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
+                       ret = -EFAULT;
+               return ret;
+       case TIOCSLCKTRMIOS:
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               copy_termios_locked(real_tty, &kterm);
+               if (user_termios_to_kernel_termios(&kterm,
+                                              (struct termios __user *) arg))
+                       return -EFAULT;
+               mutex_lock(&real_tty->termios_mutex);
+               memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
+               mutex_unlock(&real_tty->termios_mutex);
+               return 0;
+#else
+       case TIOCGLCKTRMIOS:
+               copy_termios_locked(real_tty, &kterm);
+               if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
+                       ret = -EFAULT;
+               return ret;
+       case TIOCSLCKTRMIOS:
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               copy_termios_locked(real_tty, &kterm);
+               if (user_termios_to_kernel_termios_1(&kterm,
+                                              (struct termios __user *) arg))
+                       return -EFAULT;
+               mutex_lock(&real_tty->termios_mutex);
+               memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
+               mutex_unlock(&real_tty->termios_mutex);
+               return ret;
+#endif
+#ifdef TCGETX
+       case TCGETX: {
+               struct termiox ktermx;
+               if (real_tty->termiox == NULL)
+                       return -EINVAL;
+               mutex_lock(&real_tty->termios_mutex);
+               memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
+               mutex_unlock(&real_tty->termios_mutex);
+               if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
+                       ret = -EFAULT;
+               return ret;
+       }
+       case TCSETX:
+               return set_termiox(real_tty, p, 0);
+       case TCSETXW:
+               return set_termiox(real_tty, p, TERMIOS_WAIT);
+       case TCSETXF:
+               return set_termiox(real_tty, p, TERMIOS_FLUSH);
+#endif         
+       case TIOCGSOFTCAR:
+               copy_termios(real_tty, &kterm);
+               ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
+                                               (int __user *)arg);
+               return ret;
+       case TIOCSSOFTCAR:
+               if (get_user(arg, (unsigned int __user *) arg))
+                       return -EFAULT;
+               return tty_change_softcar(real_tty, arg);
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+EXPORT_SYMBOL_GPL(tty_mode_ioctl);
+
+int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
+{
+       struct tty_ldisc *ld;
+       int retval = tty_check_change(tty);
+       if (retval)
+               return retval;
+
+       ld = tty_ldisc_ref_wait(tty);
+       switch (arg) {
+       case TCIFLUSH:
+               if (ld && ld->ops->flush_buffer)
+                       ld->ops->flush_buffer(tty);
+               break;
+       case TCIOFLUSH:
+               if (ld && ld->ops->flush_buffer)
+                       ld->ops->flush_buffer(tty);
+               /* fall through */
+       case TCOFLUSH:
+               tty_driver_flush_buffer(tty);
+               break;
+       default:
+               tty_ldisc_deref(ld);
+               return -EINVAL;
+       }
+       tty_ldisc_deref(ld);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tty_perform_flush);
+
+int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
+                      unsigned int cmd, unsigned long arg)
+{
+       unsigned long flags;
+       int retval;
+
+       switch (cmd) {
+       case TCXONC:
+               retval = tty_check_change(tty);
+               if (retval)
+                       return retval;
+               switch (arg) {
+               case TCOOFF:
+                       if (!tty->flow_stopped) {
+                               tty->flow_stopped = 1;
+                               stop_tty(tty);
+                       }
+                       break;
+               case TCOON:
+                       if (tty->flow_stopped) {
+                               tty->flow_stopped = 0;
+                               start_tty(tty);
+                       }
+                       break;
+               case TCIOFF:
+                       if (STOP_CHAR(tty) != __DISABLED_CHAR)
+                               return send_prio_char(tty, STOP_CHAR(tty));
+                       break;
+               case TCION:
+                       if (START_CHAR(tty) != __DISABLED_CHAR)
+                               return send_prio_char(tty, START_CHAR(tty));
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               return 0;
+       case TCFLSH:
+               return tty_perform_flush(tty, arg);
+       case TIOCPKT:
+       {
+               int pktmode;
+
+               if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
+                   tty->driver->subtype != PTY_TYPE_MASTER)
+                       return -ENOTTY;
+               if (get_user(pktmode, (int __user *) arg))
+                       return -EFAULT;
+               spin_lock_irqsave(&tty->ctrl_lock, flags);
+               if (pktmode) {
+                       if (!tty->packet) {
+                               tty->packet = 1;
+                               tty->link->ctrl_status = 0;
+                       }
+               } else
+                       tty->packet = 0;
+               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+               return 0;
+       }
+       default:
+               /* Try the mode commands */
+               return tty_mode_ioctl(tty, file, cmd, arg);
+       }
+}
+EXPORT_SYMBOL(n_tty_ioctl_helper);
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
new file mode 100644 (file)
index 0000000..d8e96b0
--- /dev/null
@@ -0,0 +1,950 @@
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/devpts_fs.h>
+#include <linux/file.h>
+#include <linux/console.h>
+#include <linux/timer.h>
+#include <linux/ctype.h>
+#include <linux/kd.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+
+#include <linux/uaccess.h>
+#include <asm/system.h>
+
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+
+#include <linux/smp_lock.h>    /* For the moment */
+
+#include <linux/kmod.h>
+#include <linux/nsproxy.h>
+
+/*
+ *     This guards the refcounted line discipline lists. The lock
+ *     must be taken with irqs off because there are hangup path
+ *     callers who will do ldisc lookups and cannot sleep.
+ */
+
+static DEFINE_SPINLOCK(tty_ldisc_lock);
+static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
+static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_idle);
+/* Line disc dispatch table */
+static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
+
+static inline struct tty_ldisc *get_ldisc(struct tty_ldisc *ld)
+{
+       if (ld)
+               atomic_inc(&ld->users);
+       return ld;
+}
+
+static void put_ldisc(struct tty_ldisc *ld)
+{
+       unsigned long flags;
+
+       if (WARN_ON_ONCE(!ld))
+               return;
+
+       /*
+        * If this is the last user, free the ldisc, and
+        * release the ldisc ops.
+        *
+        * We really want an "atomic_dec_and_lock_irqsave()",
+        * but we don't have it, so this does it by hand.
+        */
+       local_irq_save(flags);
+       if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) {
+               struct tty_ldisc_ops *ldo = ld->ops;
+
+               ldo->refcount--;
+               module_put(ldo->owner);
+               spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+               kfree(ld);
+               return;
+       }
+       local_irq_restore(flags);
+       wake_up(&tty_ldisc_idle);
+}
+
+/**
+ *     tty_register_ldisc      -       install a line discipline
+ *     @disc: ldisc number
+ *     @new_ldisc: pointer to the ldisc object
+ *
+ *     Installs a new line discipline into the kernel. The discipline
+ *     is set up as unreferenced and then made available to the kernel
+ *     from this point onwards.
+ *
+ *     Locking:
+ *             takes tty_ldisc_lock to guard against ldisc races
+ */
+
+int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       if (disc < N_TTY || disc >= NR_LDISCS)
+               return -EINVAL;
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       tty_ldiscs[disc] = new_ldisc;
+       new_ldisc->num = disc;
+       new_ldisc->refcount = 0;
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(tty_register_ldisc);
+
+/**
+ *     tty_unregister_ldisc    -       unload a line discipline
+ *     @disc: ldisc number
+ *     @new_ldisc: pointer to the ldisc object
+ *
+ *     Remove a line discipline from the kernel providing it is not
+ *     currently in use.
+ *
+ *     Locking:
+ *             takes tty_ldisc_lock to guard against ldisc races
+ */
+
+int tty_unregister_ldisc(int disc)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       if (disc < N_TTY || disc >= NR_LDISCS)
+               return -EINVAL;
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       if (tty_ldiscs[disc]->refcount)
+               ret = -EBUSY;
+       else
+               tty_ldiscs[disc] = NULL;
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(tty_unregister_ldisc);
+
+static struct tty_ldisc_ops *get_ldops(int disc)
+{
+       unsigned long flags;
+       struct tty_ldisc_ops *ldops, *ret;
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       ret = ERR_PTR(-EINVAL);
+       ldops = tty_ldiscs[disc];
+       if (ldops) {
+               ret = ERR_PTR(-EAGAIN);
+               if (try_module_get(ldops->owner)) {
+                       ldops->refcount++;
+                       ret = ldops;
+               }
+       }
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+       return ret;
+}
+
+static void put_ldops(struct tty_ldisc_ops *ldops)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       ldops->refcount--;
+       module_put(ldops->owner);
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+}
+
+/**
+ *     tty_ldisc_get           -       take a reference to an ldisc
+ *     @disc: ldisc number
+ *
+ *     Takes a reference to a line discipline. Deals with refcounts and
+ *     module locking counts. Returns NULL if the discipline is not available.
+ *     Returns a pointer to the discipline and bumps the ref count if it is
+ *     available
+ *
+ *     Locking:
+ *             takes tty_ldisc_lock to guard against ldisc races
+ */
+
+static struct tty_ldisc *tty_ldisc_get(int disc)
+{
+       struct tty_ldisc *ld;
+       struct tty_ldisc_ops *ldops;
+
+       if (disc < N_TTY || disc >= NR_LDISCS)
+               return ERR_PTR(-EINVAL);
+
+       /*
+        * Get the ldisc ops - we may need to request them to be loaded
+        * dynamically and try again.
+        */
+       ldops = get_ldops(disc);
+       if (IS_ERR(ldops)) {
+               request_module("tty-ldisc-%d", disc);
+               ldops = get_ldops(disc);
+               if (IS_ERR(ldops))
+                       return ERR_CAST(ldops);
+       }
+
+       ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
+       if (ld == NULL) {
+               put_ldops(ldops);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       ld->ops = ldops;
+       atomic_set(&ld->users, 1);
+       return ld;
+}
+
+static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
+{
+       return (*pos < NR_LDISCS) ? pos : NULL;
+}
+
+static void *tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+       (*pos)++;
+       return (*pos < NR_LDISCS) ? pos : NULL;
+}
+
+static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
+{
+}
+
+static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
+{
+       int i = *(loff_t *)v;
+       struct tty_ldisc_ops *ldops;
+
+       ldops = get_ldops(i);
+       if (IS_ERR(ldops))
+               return 0;
+       seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
+       put_ldops(ldops);
+       return 0;
+}
+
+static const struct seq_operations tty_ldiscs_seq_ops = {
+       .start  = tty_ldiscs_seq_start,
+       .next   = tty_ldiscs_seq_next,
+       .stop   = tty_ldiscs_seq_stop,
+       .show   = tty_ldiscs_seq_show,
+};
+
+static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &tty_ldiscs_seq_ops);
+}
+
+const struct file_operations tty_ldiscs_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = proc_tty_ldiscs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+/**
+ *     tty_ldisc_assign        -       set ldisc on a tty
+ *     @tty: tty to assign
+ *     @ld: line discipline
+ *
+ *     Install an instance of a line discipline into a tty structure. The
+ *     ldisc must have a reference count above zero to ensure it remains.
+ *     The tty instance refcount starts at zero.
+ *
+ *     Locking:
+ *             Caller must hold references
+ */
+
+static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
+{
+       tty->ldisc = ld;
+}
+
+/**
+ *     tty_ldisc_try           -       internal helper
+ *     @tty: the tty
+ *
+ *     Make a single attempt to grab and bump the refcount on
+ *     the tty ldisc. Return 0 on failure or 1 on success. This is
+ *     used to implement both the waiting and non waiting versions
+ *     of tty_ldisc_ref
+ *
+ *     Locking: takes tty_ldisc_lock
+ */
+
+static struct tty_ldisc *tty_ldisc_try(struct tty_struct *tty)
+{
+       unsigned long flags;
+       struct tty_ldisc *ld;
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       ld = NULL;
+       if (test_bit(TTY_LDISC, &tty->flags))
+               ld = get_ldisc(tty->ldisc);
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+       return ld;
+}
+
+/**
+ *     tty_ldisc_ref_wait      -       wait for the tty ldisc
+ *     @tty: tty device
+ *
+ *     Dereference the line discipline for the terminal and take a
+ *     reference to it. If the line discipline is in flux then
+ *     wait patiently until it changes.
+ *
+ *     Note: Must not be called from an IRQ/timer context. The caller
+ *     must also be careful not to hold other locks that will deadlock
+ *     against a discipline change, such as an existing ldisc reference
+ *     (which we check for)
+ *
+ *     Locking: call functions take tty_ldisc_lock
+ */
+
+struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
+{
+       struct tty_ldisc *ld;
+
+       /* wait_event is a macro */
+       wait_event(tty_ldisc_wait, (ld = tty_ldisc_try(tty)) != NULL);
+       return ld;
+}
+EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
+
+/**
+ *     tty_ldisc_ref           -       get the tty ldisc
+ *     @tty: tty device
+ *
+ *     Dereference the line discipline for the terminal and take a
+ *     reference to it. If the line discipline is in flux then
+ *     return NULL. Can be called from IRQ and timer functions.
+ *
+ *     Locking: called functions take tty_ldisc_lock
+ */
+
+struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
+{
+       return tty_ldisc_try(tty);
+}
+EXPORT_SYMBOL_GPL(tty_ldisc_ref);
+
+/**
+ *     tty_ldisc_deref         -       free a tty ldisc reference
+ *     @ld: reference to free up
+ *
+ *     Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May
+ *     be called in IRQ context.
+ *
+ *     Locking: takes tty_ldisc_lock
+ */
+
+void tty_ldisc_deref(struct tty_ldisc *ld)
+{
+       put_ldisc(ld);
+}
+EXPORT_SYMBOL_GPL(tty_ldisc_deref);
+
+static inline void tty_ldisc_put(struct tty_ldisc *ld)
+{
+       put_ldisc(ld);
+}
+
+/**
+ *     tty_ldisc_enable        -       allow ldisc use
+ *     @tty: terminal to activate ldisc on
+ *
+ *     Set the TTY_LDISC flag when the line discipline can be called
+ *     again. Do necessary wakeups for existing sleepers. Clear the LDISC
+ *     changing flag to indicate any ldisc change is now over.
+ *
+ *     Note: nobody should set the TTY_LDISC bit except via this function.
+ *     Clearing directly is allowed.
+ */
+
+void tty_ldisc_enable(struct tty_struct *tty)
+{
+       set_bit(TTY_LDISC, &tty->flags);
+       clear_bit(TTY_LDISC_CHANGING, &tty->flags);
+       wake_up(&tty_ldisc_wait);
+}
+
+/**
+ *     tty_ldisc_flush -       flush line discipline queue
+ *     @tty: tty
+ *
+ *     Flush the line discipline queue (if any) for this tty. If there
+ *     is no line discipline active this is a no-op.
+ */
+
+void tty_ldisc_flush(struct tty_struct *tty)
+{
+       struct tty_ldisc *ld = tty_ldisc_ref(tty);
+       if (ld) {
+               if (ld->ops->flush_buffer)
+                       ld->ops->flush_buffer(tty);
+               tty_ldisc_deref(ld);
+       }
+       tty_buffer_flush(tty);
+}
+EXPORT_SYMBOL_GPL(tty_ldisc_flush);
+
+/**
+ *     tty_set_termios_ldisc           -       set ldisc field
+ *     @tty: tty structure
+ *     @num: line discipline number
+ *
+ *     This is probably overkill for real world processors but
+ *     they are not on hot paths so a little discipline won't do
+ *     any harm.
+ *
+ *     Locking: takes termios_mutex
+ */
+
+static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
+{
+       mutex_lock(&tty->termios_mutex);
+       tty->termios->c_line = num;
+       mutex_unlock(&tty->termios_mutex);
+}
+
+/**
+ *     tty_ldisc_open          -       open a line discipline
+ *     @tty: tty we are opening the ldisc on
+ *     @ld: discipline to open
+ *
+ *     A helper opening method. Also a convenient debugging and check
+ *     point.
+ *
+ *     Locking: always called with BTM already held.
+ */
+
+static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
+{
+       WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
+       if (ld->ops->open) {
+               int ret;
+                /* BTM here locks versus a hangup event */
+               WARN_ON(!tty_locked());
+               ret = ld->ops->open(tty);
+               return ret;
+       }
+       return 0;
+}
+
+/**
+ *     tty_ldisc_close         -       close a line discipline
+ *     @tty: tty we are opening the ldisc on
+ *     @ld: discipline to close
+ *
+ *     A helper close method. Also a convenient debugging and check
+ *     point.
+ */
+
+static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
+{
+       WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags));
+       clear_bit(TTY_LDISC_OPEN, &tty->flags);
+       if (ld->ops->close)
+               ld->ops->close(tty);
+}
+
+/**
+ *     tty_ldisc_restore       -       helper for tty ldisc change
+ *     @tty: tty to recover
+ *     @old: previous ldisc
+ *
+ *     Restore the previous line discipline or N_TTY when a line discipline
+ *     change fails due to an open error
+ */
+
+static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
+{
+       char buf[64];
+       struct tty_ldisc *new_ldisc;
+       int r;
+
+       /* There is an outstanding reference here so this is safe */
+       old = tty_ldisc_get(old->ops->num);
+       WARN_ON(IS_ERR(old));
+       tty_ldisc_assign(tty, old);
+       tty_set_termios_ldisc(tty, old->ops->num);
+       if (tty_ldisc_open(tty, old) < 0) {
+               tty_ldisc_put(old);
+               /* This driver is always present */
+               new_ldisc = tty_ldisc_get(N_TTY);
+               if (IS_ERR(new_ldisc))
+                       panic("n_tty: get");
+               tty_ldisc_assign(tty, new_ldisc);
+               tty_set_termios_ldisc(tty, N_TTY);
+               r = tty_ldisc_open(tty, new_ldisc);
+               if (r < 0)
+                       panic("Couldn't open N_TTY ldisc for "
+                             "%s --- error %d.",
+                             tty_name(tty, buf), r);
+       }
+}
+
+/**
+ *     tty_ldisc_halt          -       shut down the line discipline
+ *     @tty: tty device
+ *
+ *     Shut down the line discipline and work queue for this tty device.
+ *     The TTY_LDISC flag being cleared ensures no further references can
+ *     be obtained while the delayed work queue halt ensures that no more
+ *     data is fed to the ldisc.
+ *
+ *     You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex)
+ *     in order to make sure any currently executing ldisc work is also
+ *     flushed.
+ */
+
+static int tty_ldisc_halt(struct tty_struct *tty)
+{
+       clear_bit(TTY_LDISC, &tty->flags);
+       return cancel_delayed_work_sync(&tty->buf.work);
+}
+
+/**
+ *     tty_ldisc_wait_idle     -       wait for the ldisc to become idle
+ *     @tty: tty to wait for
+ *
+ *     Wait for the line discipline to become idle. The discipline must
+ *     have been halted for this to guarantee it remains idle.
+ */
+static int tty_ldisc_wait_idle(struct tty_struct *tty)
+{
+       int ret;
+       ret = wait_event_interruptible_timeout(tty_ldisc_idle,
+                       atomic_read(&tty->ldisc->users) == 1, 5 * HZ);
+       if (ret < 0)
+               return ret;
+       return ret > 0 ? 0 : -EBUSY;
+}
+
+/**
+ *     tty_set_ldisc           -       set line discipline
+ *     @tty: the terminal to set
+ *     @ldisc: the line discipline
+ *
+ *     Set the discipline of a tty line. Must be called from a process
+ *     context. The ldisc change logic has to protect itself against any
+ *     overlapping ldisc change (including on the other end of pty pairs),
+ *     the close of one side of a tty/pty pair, and eventually hangup.
+ *
+ *     Locking: takes tty_ldisc_lock, termios_mutex
+ */
+
+int tty_set_ldisc(struct tty_struct *tty, int ldisc)
+{
+       int retval;
+       struct tty_ldisc *o_ldisc, *new_ldisc;
+       int work, o_work = 0;
+       struct tty_struct *o_tty;
+
+       new_ldisc = tty_ldisc_get(ldisc);
+       if (IS_ERR(new_ldisc))
+               return PTR_ERR(new_ldisc);
+
+       tty_lock();
+       /*
+        *      We need to look at the tty locking here for pty/tty pairs
+        *      when both sides try to change in parallel.
+        */
+
+       o_tty = tty->link;      /* o_tty is the pty side or NULL */
+
+
+       /*
+        *      Check the no-op case
+        */
+
+       if (tty->ldisc->ops->num == ldisc) {
+               tty_unlock();
+               tty_ldisc_put(new_ldisc);
+               return 0;
+       }
+
+       tty_unlock();
+       /*
+        *      Problem: What do we do if this blocks ?
+        *      We could deadlock here
+        */
+
+       tty_wait_until_sent(tty, 0);
+
+       tty_lock();
+       mutex_lock(&tty->ldisc_mutex);
+
+       /*
+        *      We could be midstream of another ldisc change which has
+        *      dropped the lock during processing. If so we need to wait.
+        */
+
+       while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) {
+               mutex_unlock(&tty->ldisc_mutex);
+               tty_unlock();
+               wait_event(tty_ldisc_wait,
+                       test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
+               tty_lock();
+               mutex_lock(&tty->ldisc_mutex);
+       }
+
+       set_bit(TTY_LDISC_CHANGING, &tty->flags);
+
+       /*
+        *      No more input please, we are switching. The new ldisc
+        *      will update this value in the ldisc open function
+        */
+
+       tty->receive_room = 0;
+
+       o_ldisc = tty->ldisc;
+
+       tty_unlock();
+       /*
+        *      Make sure we don't change while someone holds a
+        *      reference to the line discipline. The TTY_LDISC bit
+        *      prevents anyone taking a reference once it is clear.
+        *      We need the lock to avoid racing reference takers.
+        *
+        *      We must clear the TTY_LDISC bit here to avoid a livelock
+        *      with a userspace app continually trying to use the tty in
+        *      parallel to the change and re-referencing the tty.
+        */
+
+       work = tty_ldisc_halt(tty);
+       if (o_tty)
+               o_work = tty_ldisc_halt(o_tty);
+
+       /*
+        * Wait for ->hangup_work and ->buf.work handlers to terminate.
+        * We must drop the mutex here in case a hangup is also in process.
+        */
+
+       mutex_unlock(&tty->ldisc_mutex);
+
+       flush_scheduled_work();
+
+       retval = tty_ldisc_wait_idle(tty);
+
+       tty_lock();
+       mutex_lock(&tty->ldisc_mutex);
+
+       /* handle wait idle failure locked */
+       if (retval) {
+               tty_ldisc_put(new_ldisc);
+               goto enable;
+       }
+
+       if (test_bit(TTY_HUPPED, &tty->flags)) {
+               /* We were raced by the hangup method. It will have stomped
+                  the ldisc data and closed the ldisc down */
+               clear_bit(TTY_LDISC_CHANGING, &tty->flags);
+               mutex_unlock(&tty->ldisc_mutex);
+               tty_ldisc_put(new_ldisc);
+               tty_unlock();
+               return -EIO;
+       }
+
+       /* Shutdown the current discipline. */
+       tty_ldisc_close(tty, o_ldisc);
+
+       /* Now set up the new line discipline. */
+       tty_ldisc_assign(tty, new_ldisc);
+       tty_set_termios_ldisc(tty, ldisc);
+
+       retval = tty_ldisc_open(tty, new_ldisc);
+       if (retval < 0) {
+               /* Back to the old one or N_TTY if we can't */
+               tty_ldisc_put(new_ldisc);
+               tty_ldisc_restore(tty, o_ldisc);
+       }
+
+       /* At this point we hold a reference to the new ldisc and a
+          a reference to the old ldisc. If we ended up flipping back
+          to the existing ldisc we have two references to it */
+
+       if (tty->ldisc->ops->num != o_ldisc->ops->num && tty->ops->set_ldisc)
+               tty->ops->set_ldisc(tty);
+
+       tty_ldisc_put(o_ldisc);
+
+enable:
+       /*
+        *      Allow ldisc referencing to occur again
+        */
+
+       tty_ldisc_enable(tty);
+       if (o_tty)
+               tty_ldisc_enable(o_tty);
+
+       /* Restart the work queue in case no characters kick it off. Safe if
+          already running */
+       if (work)
+               schedule_delayed_work(&tty->buf.work, 1);
+       if (o_work)
+               schedule_delayed_work(&o_tty->buf.work, 1);
+       mutex_unlock(&tty->ldisc_mutex);
+       tty_unlock();
+       return retval;
+}
+
+/**
+ *     tty_reset_termios       -       reset terminal state
+ *     @tty: tty to reset
+ *
+ *     Restore a terminal to the driver default state.
+ */
+
+static void tty_reset_termios(struct tty_struct *tty)
+{
+       mutex_lock(&tty->termios_mutex);
+       *tty->termios = tty->driver->init_termios;
+       tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
+       tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
+       mutex_unlock(&tty->termios_mutex);
+}
+
+
+/**
+ *     tty_ldisc_reinit        -       reinitialise the tty ldisc
+ *     @tty: tty to reinit
+ *     @ldisc: line discipline to reinitialize
+ *
+ *     Switch the tty to a line discipline and leave the ldisc
+ *     state closed
+ */
+
+static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
+{
+       struct tty_ldisc *ld = tty_ldisc_get(ldisc);
+
+       if (IS_ERR(ld))
+               return -1;
+
+       tty_ldisc_close(tty, tty->ldisc);
+       tty_ldisc_put(tty->ldisc);
+       tty->ldisc = NULL;
+       /*
+        *      Switch the line discipline back
+        */
+       tty_ldisc_assign(tty, ld);
+       tty_set_termios_ldisc(tty, ldisc);
+
+       return 0;
+}
+
+/**
+ *     tty_ldisc_hangup                -       hangup ldisc reset
+ *     @tty: tty being hung up
+ *
+ *     Some tty devices reset their termios when they receive a hangup
+ *     event. In that situation we must also switch back to N_TTY properly
+ *     before we reset the termios data.
+ *
+ *     Locking: We can take the ldisc mutex as the rest of the code is
+ *     careful to allow for this.
+ *
+ *     In the pty pair case this occurs in the close() path of the
+ *     tty itself so we must be careful about locking rules.
+ */
+
+void tty_ldisc_hangup(struct tty_struct *tty)
+{
+       struct tty_ldisc *ld;
+       int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS;
+       int err = 0;
+
+       /*
+        * FIXME! What are the locking issues here? This may me overdoing
+        * things... This question is especially important now that we've
+        * removed the irqlock.
+        */
+       ld = tty_ldisc_ref(tty);
+       if (ld != NULL) {
+               /* We may have no line discipline at this point */
+               if (ld->ops->flush_buffer)
+                       ld->ops->flush_buffer(tty);
+               tty_driver_flush_buffer(tty);
+               if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
+                   ld->ops->write_wakeup)
+                       ld->ops->write_wakeup(tty);
+               if (ld->ops->hangup)
+                       ld->ops->hangup(tty);
+               tty_ldisc_deref(ld);
+       }
+       /*
+        * FIXME: Once we trust the LDISC code better we can wait here for
+        * ldisc completion and fix the driver call race
+        */
+       wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+       wake_up_interruptible_poll(&tty->read_wait, POLLIN);
+       /*
+        * Shutdown the current line discipline, and reset it to
+        * N_TTY if need be.
+        *
+        * Avoid racing set_ldisc or tty_ldisc_release
+        */
+       mutex_lock(&tty->ldisc_mutex);
+
+       /*
+        * this is like tty_ldisc_halt, but we need to give up
+        * the BTM before calling cancel_delayed_work_sync,
+        * which may need to wait for another function taking the BTM
+        */
+       clear_bit(TTY_LDISC, &tty->flags);
+       tty_unlock();
+       cancel_delayed_work_sync(&tty->buf.work);
+       mutex_unlock(&tty->ldisc_mutex);
+
+       tty_lock();
+       mutex_lock(&tty->ldisc_mutex);
+
+       /* At this point we have a closed ldisc and we want to
+          reopen it. We could defer this to the next open but
+          it means auditing a lot of other paths so this is
+          a FIXME */
+       if (tty->ldisc) {       /* Not yet closed */
+               if (reset == 0) {
+
+                       if (!tty_ldisc_reinit(tty, tty->termios->c_line))
+                               err = tty_ldisc_open(tty, tty->ldisc);
+                       else
+                               err = 1;
+               }
+               /* If the re-open fails or we reset then go to N_TTY. The
+                  N_TTY open cannot fail */
+               if (reset || err) {
+                       BUG_ON(tty_ldisc_reinit(tty, N_TTY));
+                       WARN_ON(tty_ldisc_open(tty, tty->ldisc));
+               }
+               tty_ldisc_enable(tty);
+       }
+       mutex_unlock(&tty->ldisc_mutex);
+       if (reset)
+               tty_reset_termios(tty);
+}
+
+/**
+ *     tty_ldisc_setup                 -       open line discipline
+ *     @tty: tty being shut down
+ *     @o_tty: pair tty for pty/tty pairs
+ *
+ *     Called during the initial open of a tty/pty pair in order to set up the
+ *     line disciplines and bind them to the tty. This has no locking issues
+ *     as the device isn't yet active.
+ */
+
+int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
+{
+       struct tty_ldisc *ld = tty->ldisc;
+       int retval;
+
+       retval = tty_ldisc_open(tty, ld);
+       if (retval)
+               return retval;
+
+       if (o_tty) {
+               retval = tty_ldisc_open(o_tty, o_tty->ldisc);
+               if (retval) {
+                       tty_ldisc_close(tty, ld);
+                       return retval;
+               }
+               tty_ldisc_enable(o_tty);
+       }
+       tty_ldisc_enable(tty);
+       return 0;
+}
+/**
+ *     tty_ldisc_release               -       release line discipline
+ *     @tty: tty being shut down
+ *     @o_tty: pair tty for pty/tty pairs
+ *
+ *     Called during the final close of a tty/pty pair in order to shut down
+ *     the line discpline layer. On exit the ldisc assigned is N_TTY and the
+ *     ldisc has not been opened.
+ */
+
+void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
+{
+       /*
+        * Prevent flush_to_ldisc() from rescheduling the work for later.  Then
+        * kill any delayed work. As this is the final close it does not
+        * race with the set_ldisc code path.
+        */
+
+       tty_unlock();
+       tty_ldisc_halt(tty);
+       flush_scheduled_work();
+       tty_lock();
+
+       mutex_lock(&tty->ldisc_mutex);
+       /*
+        * Now kill off the ldisc
+        */
+       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);
+       mutex_unlock(&tty->ldisc_mutex);
+
+       /* 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 */
+}
+
+/**
+ *     tty_ldisc_init          -       ldisc setup for new tty
+ *     @tty: tty being allocated
+ *
+ *     Set up the line discipline objects for a newly allocated tty. Note that
+ *     the tty structure is not completely set up when this call is made.
+ */
+
+void tty_ldisc_init(struct tty_struct *tty)
+{
+       struct tty_ldisc *ld = tty_ldisc_get(N_TTY);
+       if (IS_ERR(ld))
+               panic("n_tty: init_tty");
+       tty_ldisc_assign(tty, ld);
+}
+
+void tty_ldisc_begin(void)
+{
+       /* Setup the default TTY line discipline. */
+       (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
+}
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c
new file mode 100644 (file)
index 0000000..1336975
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * drivers/char/tty_lock.c
+ */
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/semaphore.h>
+#include <linux/sched.h>
+
+/*
+ * The 'big tty mutex'
+ *
+ * This mutex is taken and released by tty_lock() and tty_unlock(),
+ * replacing the older big kernel lock.
+ * It can no longer be taken recursively, and does not get
+ * released implicitly while sleeping.
+ *
+ * Don't use in new code.
+ */
+static DEFINE_MUTEX(big_tty_mutex);
+struct task_struct *__big_tty_mutex_owner;
+EXPORT_SYMBOL_GPL(__big_tty_mutex_owner);
+
+/*
+ * Getting the big tty mutex.
+ */
+void __lockfunc tty_lock(void)
+{
+       struct task_struct *task = current;
+
+       WARN_ON(__big_tty_mutex_owner == task);
+
+       mutex_lock(&big_tty_mutex);
+       __big_tty_mutex_owner = task;
+}
+EXPORT_SYMBOL(tty_lock);
+
+void __lockfunc tty_unlock(void)
+{
+       struct task_struct *task = current;
+
+       WARN_ON(__big_tty_mutex_owner != task);
+       __big_tty_mutex_owner = NULL;
+
+       mutex_unlock(&big_tty_mutex);
+}
+EXPORT_SYMBOL(tty_unlock);
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
new file mode 100644 (file)
index 0000000..33d37d2
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+ * Tty port functions
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/timer.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+
+void tty_port_init(struct tty_port *port)
+{
+       memset(port, 0, sizeof(*port));
+       init_waitqueue_head(&port->open_wait);
+       init_waitqueue_head(&port->close_wait);
+       init_waitqueue_head(&port->delta_msr_wait);
+       mutex_init(&port->mutex);
+       mutex_init(&port->buf_mutex);
+       spin_lock_init(&port->lock);
+       port->close_delay = (50 * HZ) / 100;
+       port->closing_wait = (3000 * HZ) / 100;
+       kref_init(&port->kref);
+}
+EXPORT_SYMBOL(tty_port_init);
+
+int tty_port_alloc_xmit_buf(struct tty_port *port)
+{
+       /* We may sleep in get_zeroed_page() */
+       mutex_lock(&port->buf_mutex);
+       if (port->xmit_buf == NULL)
+               port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
+       mutex_unlock(&port->buf_mutex);
+       if (port->xmit_buf == NULL)
+               return -ENOMEM;
+       return 0;
+}
+EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
+
+void tty_port_free_xmit_buf(struct tty_port *port)
+{
+       mutex_lock(&port->buf_mutex);
+       if (port->xmit_buf != NULL) {
+               free_page((unsigned long)port->xmit_buf);
+               port->xmit_buf = NULL;
+       }
+       mutex_unlock(&port->buf_mutex);
+}
+EXPORT_SYMBOL(tty_port_free_xmit_buf);
+
+static void tty_port_destructor(struct kref *kref)
+{
+       struct tty_port *port = container_of(kref, struct tty_port, kref);
+       if (port->xmit_buf)
+               free_page((unsigned long)port->xmit_buf);
+       if (port->ops->destruct)
+               port->ops->destruct(port);
+       else
+               kfree(port);
+}
+
+void tty_port_put(struct tty_port *port)
+{
+       if (port)
+               kref_put(&port->kref, tty_port_destructor);
+}
+EXPORT_SYMBOL(tty_port_put);
+
+/**
+ *     tty_port_tty_get        -       get a tty reference
+ *     @port: tty port
+ *
+ *     Return a refcount protected tty instance or NULL if the port is not
+ *     associated with a tty (eg due to close or hangup)
+ */
+
+struct tty_struct *tty_port_tty_get(struct tty_port *port)
+{
+       unsigned long flags;
+       struct tty_struct *tty;
+
+       spin_lock_irqsave(&port->lock, flags);
+       tty = tty_kref_get(port->tty);
+       spin_unlock_irqrestore(&port->lock, flags);
+       return tty;
+}
+EXPORT_SYMBOL(tty_port_tty_get);
+
+/**
+ *     tty_port_tty_set        -       set the tty of a port
+ *     @port: tty port
+ *     @tty: the tty
+ *
+ *     Associate the port and tty pair. Manages any internal refcounts.
+ *     Pass NULL to deassociate a port
+ */
+
+void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       if (port->tty)
+               tty_kref_put(port->tty);
+       port->tty = tty_kref_get(tty);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+EXPORT_SYMBOL(tty_port_tty_set);
+
+static void tty_port_shutdown(struct tty_port *port)
+{
+       mutex_lock(&port->mutex);
+       if (port->ops->shutdown && !port->console &&
+               test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
+                       port->ops->shutdown(port);
+       mutex_unlock(&port->mutex);
+}
+
+/**
+ *     tty_port_hangup         -       hangup helper
+ *     @port: tty port
+ *
+ *     Perform port level tty hangup flag and count changes. Drop the tty
+ *     reference.
+ */
+
+void tty_port_hangup(struct tty_port *port)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       port->count = 0;
+       port->flags &= ~ASYNC_NORMAL_ACTIVE;
+       if (port->tty) {
+               set_bit(TTY_IO_ERROR, &port->tty->flags);
+               tty_kref_put(port->tty);
+       }
+       port->tty = NULL;
+       spin_unlock_irqrestore(&port->lock, flags);
+       wake_up_interruptible(&port->open_wait);
+       wake_up_interruptible(&port->delta_msr_wait);
+       tty_port_shutdown(port);
+}
+EXPORT_SYMBOL(tty_port_hangup);
+
+/**
+ *     tty_port_carrier_raised -       carrier raised check
+ *     @port: tty port
+ *
+ *     Wrapper for the carrier detect logic. For the moment this is used
+ *     to hide some internal details. This will eventually become entirely
+ *     internal to the tty port.
+ */
+
+int tty_port_carrier_raised(struct tty_port *port)
+{
+       if (port->ops->carrier_raised == NULL)
+               return 1;
+       return port->ops->carrier_raised(port);
+}
+EXPORT_SYMBOL(tty_port_carrier_raised);
+
+/**
+ *     tty_port_raise_dtr_rts  -       Raise DTR/RTS
+ *     @port: tty port
+ *
+ *     Wrapper for the DTR/RTS raise logic. For the moment this is used
+ *     to hide some internal details. This will eventually become entirely
+ *     internal to the tty port.
+ */
+
+void tty_port_raise_dtr_rts(struct tty_port *port)
+{
+       if (port->ops->dtr_rts)
+               port->ops->dtr_rts(port, 1);
+}
+EXPORT_SYMBOL(tty_port_raise_dtr_rts);
+
+/**
+ *     tty_port_lower_dtr_rts  -       Lower DTR/RTS
+ *     @port: tty port
+ *
+ *     Wrapper for the DTR/RTS raise logic. For the moment this is used
+ *     to hide some internal details. This will eventually become entirely
+ *     internal to the tty port.
+ */
+
+void tty_port_lower_dtr_rts(struct tty_port *port)
+{
+       if (port->ops->dtr_rts)
+               port->ops->dtr_rts(port, 0);
+}
+EXPORT_SYMBOL(tty_port_lower_dtr_rts);
+
+/**
+ *     tty_port_block_til_ready        -       Waiting logic for tty open
+ *     @port: the tty port being opened
+ *     @tty: the tty device being bound
+ *     @filp: the file pointer of the opener
+ *
+ *     Implement the core POSIX/SuS tty behaviour when opening a tty device.
+ *     Handles:
+ *             - hangup (both before and during)
+ *             - non blocking open
+ *             - rts/dtr/dcd
+ *             - signals
+ *             - port flags and counts
+ *
+ *     The passed tty_port must implement the carrier_raised method if it can
+ *     do carrier detect and the dtr_rts method if it supports software
+ *     management of these lines. Note that the dtr/rts raise is done each
+ *     iteration as a hangup may have previously dropped them while we wait.
+ */
+
+int tty_port_block_til_ready(struct tty_port *port,
+                               struct tty_struct *tty, struct file *filp)
+{
+       int do_clocal = 0, retval;
+       unsigned long flags;
+       DEFINE_WAIT(wait);
+       int cd;
+
+       /* block if port is in the process of being closed */
+       if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
+               wait_event_interruptible_tty(port->close_wait,
+                               !(port->flags & ASYNC_CLOSING));
+               if (port->flags & ASYNC_HUP_NOTIFY)
+                       return -EAGAIN;
+               else
+                       return -ERESTARTSYS;
+       }
+
+       /* if non-blocking mode is set we can pass directly to open unless
+          the port has just hung up or is in another error state */
+       if (tty->flags & (1 << TTY_IO_ERROR)) {
+               port->flags |= ASYNC_NORMAL_ACTIVE;
+               return 0;
+       }
+       if (filp->f_flags & O_NONBLOCK) {
+               /* Indicate we are open */
+               if (tty->termios->c_cflag & CBAUD)
+                       tty_port_raise_dtr_rts(port);
+               port->flags |= ASYNC_NORMAL_ACTIVE;
+               return 0;
+       }
+
+       if (C_CLOCAL(tty))
+               do_clocal = 1;
+
+       /* Block waiting until we can proceed. We may need to wait for the
+          carrier, but we must also wait for any close that is in progress
+          before the next open may complete */
+
+       retval = 0;
+
+       /* The port lock protects the port counts */
+       spin_lock_irqsave(&port->lock, flags);
+       if (!tty_hung_up_p(filp))
+               port->count--;
+       port->blocked_open++;
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       while (1) {
+               /* Indicate we are open */
+               if (tty->termios->c_cflag & CBAUD)
+                       tty_port_raise_dtr_rts(port);
+
+               prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
+               /* Check for a hangup or uninitialised port.
+                                                       Return accordingly */
+               if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
+                       if (port->flags & ASYNC_HUP_NOTIFY)
+                               retval = -EAGAIN;
+                       else
+                               retval = -ERESTARTSYS;
+                       break;
+               }
+               /* Probe the carrier. For devices with no carrier detect this
+                  will always return true */
+               cd = tty_port_carrier_raised(port);
+               if (!(port->flags & ASYNC_CLOSING) &&
+                               (do_clocal || cd))
+                       break;
+               if (signal_pending(current)) {
+                       retval = -ERESTARTSYS;
+                       break;
+               }
+               tty_unlock();
+               schedule();
+               tty_lock();
+       }
+       finish_wait(&port->open_wait, &wait);
+
+       /* Update counts. A parallel hangup will have set count to zero and
+          we must not mess that up further */
+       spin_lock_irqsave(&port->lock, flags);
+       if (!tty_hung_up_p(filp))
+               port->count++;
+       port->blocked_open--;
+       if (retval == 0)
+               port->flags |= ASYNC_NORMAL_ACTIVE;
+       spin_unlock_irqrestore(&port->lock, flags);
+       return retval;
+}
+EXPORT_SYMBOL(tty_port_block_til_ready);
+
+int tty_port_close_start(struct tty_port *port,
+                               struct tty_struct *tty, struct file *filp)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       if (tty_hung_up_p(filp)) {
+               spin_unlock_irqrestore(&port->lock, flags);
+               return 0;
+       }
+
+       if (tty->count == 1 && port->count != 1) {
+               printk(KERN_WARNING
+                   "tty_port_close_start: tty->count = 1 port count = %d.\n",
+                                                               port->count);
+               port->count = 1;
+       }
+       if (--port->count < 0) {
+               printk(KERN_WARNING "tty_port_close_start: count = %d\n",
+                                                               port->count);
+               port->count = 0;
+       }
+
+       if (port->count) {
+               spin_unlock_irqrestore(&port->lock, flags);
+               if (port->ops->drop)
+                       port->ops->drop(port);
+               return 0;
+       }
+       set_bit(ASYNCB_CLOSING, &port->flags);
+       tty->closing = 1;
+       spin_unlock_irqrestore(&port->lock, flags);
+       /* Don't block on a stalled port, just pull the chain */
+       if (tty->flow_stopped)
+               tty_driver_flush_buffer(tty);
+       if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
+                       port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+               tty_wait_until_sent(tty, port->closing_wait);
+       if (port->drain_delay) {
+               unsigned int bps = tty_get_baud_rate(tty);
+               long timeout;
+
+               if (bps > 1200)
+                       timeout = max_t(long,
+                               (HZ * 10 * port->drain_delay) / bps, HZ / 10);
+               else
+                       timeout = 2 * HZ;
+               schedule_timeout_interruptible(timeout);
+       }
+       /* Flush the ldisc buffering */
+       tty_ldisc_flush(tty);
+
+       /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
+          hang up the line */
+       if (tty->termios->c_cflag & HUPCL)
+               tty_port_lower_dtr_rts(port);
+
+       /* Don't call port->drop for the last reference. Callers will want
+          to drop the last active reference in ->shutdown() or the tty
+          shutdown path */
+       return 1;
+}
+EXPORT_SYMBOL(tty_port_close_start);
+
+void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       tty->closing = 0;
+
+       if (port->blocked_open) {
+               spin_unlock_irqrestore(&port->lock, flags);
+               if (port->close_delay) {
+                       msleep_interruptible(
+                               jiffies_to_msecs(port->close_delay));
+               }
+               spin_lock_irqsave(&port->lock, flags);
+               wake_up_interruptible(&port->open_wait);
+       }
+       port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+       wake_up_interruptible(&port->close_wait);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+EXPORT_SYMBOL(tty_port_close_end);
+
+void tty_port_close(struct tty_port *port, struct tty_struct *tty,
+                                                       struct file *filp)
+{
+       if (tty_port_close_start(port, tty, filp) == 0)
+               return;
+       tty_port_shutdown(port);
+       set_bit(TTY_IO_ERROR, &tty->flags);
+       tty_port_close_end(port, tty);
+       tty_port_tty_set(port, NULL);
+}
+EXPORT_SYMBOL(tty_port_close);
+
+int tty_port_open(struct tty_port *port, struct tty_struct *tty,
+                                                       struct file *filp)
+{
+       spin_lock_irq(&port->lock);
+       if (!tty_hung_up_p(filp))
+               ++port->count;
+       spin_unlock_irq(&port->lock);
+       tty_port_tty_set(port, tty);
+
+       /*
+        * Do the device-specific open only if the hardware isn't
+        * already initialized. Serialize open and shutdown using the
+        * port mutex.
+        */
+
+       mutex_lock(&port->mutex);
+
+       if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+               clear_bit(TTY_IO_ERROR, &tty->flags);
+               if (port->ops->activate) {
+                       int retval = port->ops->activate(port, tty);
+                       if (retval) {
+                               mutex_unlock(&port->mutex);
+                               return retval;
+                       }
+               }
+               set_bit(ASYNCB_INITIALIZED, &port->flags);
+       }
+       mutex_unlock(&port->mutex);
+       return tty_port_block_til_ready(port, tty, filp);
+}
+
+EXPORT_SYMBOL(tty_port_open);
diff --git a/drivers/tty/vt/.gitignore b/drivers/tty/vt/.gitignore
new file mode 100644 (file)
index 0000000..83683a2
--- /dev/null
@@ -0,0 +1,2 @@
+consolemap_deftbl.c
+defkeymap.c
diff --git a/drivers/tty/vt/Makefile b/drivers/tty/vt/Makefile
new file mode 100644 (file)
index 0000000..14a51c9
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# This file contains the font map for the default (hardware) font
+#
+FONTMAPFILE = cp437.uni
+
+obj-$(CONFIG_VT)                       += vt_ioctl.o vc_screen.o \
+                                          selection.o keyboard.o
+obj-$(CONFIG_CONSOLE_TRANSLATIONS)     += consolemap.o consolemap_deftbl.o
+obj-$(CONFIG_HW_CONSOLE)               += vt.o defkeymap.o
+
+# Files generated that shall be removed upon make clean
+clean-files := consolemap_deftbl.c defkeymap.c
+
+quiet_cmd_conmk = CONMK   $@
+      cmd_conmk = scripts/conmakehash $< > $@
+
+$(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE)
+       $(call cmd,conmk)
+
+$(obj)/defkeymap.o:  $(obj)/defkeymap.c
+
+# Uncomment if you're changing the keymap and have an appropriate
+# loadkeys version for the map. By default, we'll use the shipped
+# versions.
+# GENERATE_KEYMAP := 1
+
+ifdef GENERATE_KEYMAP
+
+$(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map
+       loadkeys --mktable $< > $@.tmp
+       sed -e 's/^static *//' $@.tmp > $@
+       rm $@.tmp
+
+endif
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c
new file mode 100644 (file)
index 0000000..45d3e80
--- /dev/null
@@ -0,0 +1,745 @@
+/*
+ * consolemap.c
+ *
+ * Mapping from internal code (such as Latin-1 or Unicode or IBM PC code)
+ * to font positions.
+ *
+ * aeb, 950210
+ *
+ * Support for multiple unimaps by Jakub Jelinek <jj@ultra.linux.cz>, July 1998
+ *
+ * Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998
+ */
+
+#include <linux/module.h>
+#include <linux/kd.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <asm/uaccess.h>
+#include <linux/consolemap.h>
+#include <linux/vt_kern.h>
+
+static unsigned short translations[][256] = {
+  /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
+  {
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+    0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+    0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+    0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+    0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+    0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+    0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+    0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+  }, 
+  /* VT100 graphics mapped to Unicode */
+  {
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+    0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+    0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+    0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
+    0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
+    0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
+    0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
+    0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
+    0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+    0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+    0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+  },
+  /* IBM Codepage 437 mapped to Unicode */
+  {
+    0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 
+    0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
+    0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
+    0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+    0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+    0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+    0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
+    0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
+    0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
+    0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
+    0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
+    0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
+    0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
+    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+    0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
+    0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
+    0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
+    0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
+    0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
+    0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
+    0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
+    0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
+    0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
+  }, 
+  /* User mapping -- default to codes for direct font mapping */
+  {
+    0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
+    0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
+    0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
+    0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
+    0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
+    0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f,
+    0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
+    0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f,
+    0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047,
+    0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f,
+    0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057,
+    0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f,
+    0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067,
+    0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f,
+    0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077,
+    0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f,
+    0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
+    0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
+    0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
+    0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
+    0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7,
+    0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af,
+    0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7,
+    0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf,
+    0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7,
+    0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf,
+    0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7,
+    0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df,
+    0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
+    0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
+    0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
+    0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
+  }
+};
+
+/* The standard kernel character-to-font mappings are not invertible
+   -- this is just a best effort. */
+
+#define MAX_GLYPH 512          /* Max possible glyph value */
+
+static int inv_translate[MAX_NR_CONSOLES];
+
+struct uni_pagedir {
+       u16             **uni_pgdir[32];
+       unsigned long   refcount;
+       unsigned long   sum;
+       unsigned char   *inverse_translations[4];
+       u16             *inverse_trans_unicode;
+       int             readonly;
+};
+
+static struct uni_pagedir *dflt;
+
+static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int i)
+{
+       int j, glyph;
+       unsigned short *t = translations[i];
+       unsigned char *q;
+       
+       if (!p) return;
+       q = p->inverse_translations[i];
+
+       if (!q) {
+               q = p->inverse_translations[i] = (unsigned char *) 
+                       kmalloc(MAX_GLYPH, GFP_KERNEL);
+               if (!q) return;
+       }
+       memset(q, 0, MAX_GLYPH);
+
+       for (j = 0; j < E_TABSZ; j++) {
+               glyph = conv_uni_to_pc(conp, t[j]);
+               if (glyph >= 0 && glyph < MAX_GLYPH && q[glyph] < 32) {
+                       /* prefer '-' above SHY etc. */
+                       q[glyph] = j;
+               }
+       }
+}
+
+static void set_inverse_trans_unicode(struct vc_data *conp,
+                                     struct uni_pagedir *p)
+{
+       int i, j, k, glyph;
+       u16 **p1, *p2;
+       u16 *q;
+
+       if (!p) return;
+       q = p->inverse_trans_unicode;
+       if (!q) {
+               q = p->inverse_trans_unicode =
+                       kmalloc(MAX_GLYPH * sizeof(u16), GFP_KERNEL);
+               if (!q)
+                       return;
+       }
+       memset(q, 0, MAX_GLYPH * sizeof(u16));
+
+       for (i = 0; i < 32; i++) {
+               p1 = p->uni_pgdir[i];
+               if (!p1)
+                       continue;
+               for (j = 0; j < 32; j++) {
+                       p2 = p1[j];
+                       if (!p2)
+                               continue;
+                       for (k = 0; k < 64; k++) {
+                               glyph = p2[k];
+                               if (glyph >= 0 && glyph < MAX_GLYPH
+                                              && q[glyph] < 32)
+                                       q[glyph] = (i << 11) + (j << 6) + k;
+                       }
+               }
+       }
+}
+
+unsigned short *set_translate(int m, struct vc_data *vc)
+{
+       inv_translate[vc->vc_num] = m;
+       return translations[m];
+}
+
+/*
+ * Inverse translation is impossible for several reasons:
+ * 1. The font<->character maps are not 1-1.
+ * 2. The text may have been written while a different translation map
+ *    was active.
+ * Still, it is now possible to a certain extent to cut and paste non-ASCII.
+ */
+u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
+{
+       struct uni_pagedir *p;
+       int m;
+       if (glyph < 0 || glyph >= MAX_GLYPH)
+               return 0;
+       else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc))
+               return glyph;
+       else if (use_unicode) {
+               if (!p->inverse_trans_unicode)
+                       return glyph;
+               else
+                       return p->inverse_trans_unicode[glyph];
+       } else {
+               m = inv_translate[conp->vc_num];
+               if (!p->inverse_translations[m])
+                       return glyph;
+               else
+                       return p->inverse_translations[m][glyph];
+       }
+}
+EXPORT_SYMBOL_GPL(inverse_translate);
+
+static void update_user_maps(void)
+{
+       int i;
+       struct uni_pagedir *p, *q = NULL;
+       
+       for (i = 0; i < MAX_NR_CONSOLES; i++) {
+               if (!vc_cons_allocated(i))
+                       continue;
+               p = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc;
+               if (p && p != q) {
+                       set_inverse_transl(vc_cons[i].d, p, USER_MAP);
+                       set_inverse_trans_unicode(vc_cons[i].d, p);
+                       q = p;
+               }
+       }
+}
+
+/*
+ * Load customizable translation table
+ * arg points to a 256 byte translation table.
+ *
+ * The "old" variants are for translation directly to font (using the
+ * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
+ * Unicodes explicitly.
+ */
+int con_set_trans_old(unsigned char __user * arg)
+{
+       int i;
+       unsigned short *p = translations[USER_MAP];
+
+       if (!access_ok(VERIFY_READ, arg, E_TABSZ))
+               return -EFAULT;
+
+       for (i=0; i<E_TABSZ ; i++) {
+               unsigned char uc;
+               __get_user(uc, arg+i);
+               p[i] = UNI_DIRECT_BASE | uc;
+       }
+
+       update_user_maps();
+       return 0;
+}
+
+int con_get_trans_old(unsigned char __user * arg)
+{
+       int i, ch;
+       unsigned short *p = translations[USER_MAP];
+
+       if (!access_ok(VERIFY_WRITE, arg, E_TABSZ))
+               return -EFAULT;
+
+       for (i=0; i<E_TABSZ ; i++)
+         {
+           ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
+           __put_user((ch & ~0xff) ? 0 : ch, arg+i);
+         }
+       return 0;
+}
+
+int con_set_trans_new(ushort __user * arg)
+{
+       int i;
+       unsigned short *p = translations[USER_MAP];
+
+       if (!access_ok(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short)))
+               return -EFAULT;
+
+       for (i=0; i<E_TABSZ ; i++) {
+               unsigned short us;
+               __get_user(us, arg+i);
+               p[i] = us;
+       }
+
+       update_user_maps();
+       return 0;
+}
+
+int con_get_trans_new(ushort __user * arg)
+{
+       int i;
+       unsigned short *p = translations[USER_MAP];
+
+       if (!access_ok(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short)))
+               return -EFAULT;
+
+       for (i=0; i<E_TABSZ ; i++)
+         __put_user(p[i], arg+i);
+       
+       return 0;
+}
+
+/*
+ * Unicode -> current font conversion 
+ *
+ * A font has at most 512 chars, usually 256.
+ * But one font position may represent several Unicode chars.
+ * A hashtable is somewhat of a pain to deal with, so use a
+ * "paged table" instead.  Simulation has shown the memory cost of
+ * this 3-level paged table scheme to be comparable to a hash table.
+ */
+
+extern u8 dfont_unicount[];    /* Defined in console_defmap.c */
+extern u16 dfont_unitable[];
+
+static void con_release_unimap(struct uni_pagedir *p)
+{
+       u16 **p1;
+       int i, j;
+
+       if (p == dflt) dflt = NULL;  
+       for (i = 0; i < 32; i++) {
+               if ((p1 = p->uni_pgdir[i]) != NULL) {
+                       for (j = 0; j < 32; j++)
+                               kfree(p1[j]);
+                       kfree(p1);
+               }
+               p->uni_pgdir[i] = NULL;
+       }
+       for (i = 0; i < 4; i++) {
+               kfree(p->inverse_translations[i]);
+               p->inverse_translations[i] = NULL;
+       }
+       if (p->inverse_trans_unicode) {
+               kfree(p->inverse_trans_unicode);
+               p->inverse_trans_unicode = NULL;
+       }
+}
+
+void con_free_unimap(struct vc_data *vc)
+{
+       struct uni_pagedir *p;
+
+       p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
+       if (!p)
+               return;
+       *vc->vc_uni_pagedir_loc = 0;
+       if (--p->refcount)
+               return;
+       con_release_unimap(p);
+       kfree(p);
+}
+  
+static int con_unify_unimap(struct vc_data *conp, struct uni_pagedir *p)
+{
+       int i, j, k;
+       struct uni_pagedir *q;
+       
+       for (i = 0; i < MAX_NR_CONSOLES; i++) {
+               if (!vc_cons_allocated(i))
+                       continue;
+               q = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc;
+               if (!q || q == p || q->sum != p->sum)
+                       continue;
+               for (j = 0; j < 32; j++) {
+                       u16 **p1, **q1;
+                       p1 = p->uni_pgdir[j]; q1 = q->uni_pgdir[j];
+                       if (!p1 && !q1)
+                               continue;
+                       if (!p1 || !q1)
+                               break;
+                       for (k = 0; k < 32; k++) {
+                               if (!p1[k] && !q1[k])
+                                       continue;
+                               if (!p1[k] || !q1[k])
+                                       break;
+                               if (memcmp(p1[k], q1[k], 64*sizeof(u16)))
+                                       break;
+                       }
+                       if (k < 32)
+                               break;
+               }
+               if (j == 32) {
+                       q->refcount++;
+                       *conp->vc_uni_pagedir_loc = (unsigned long)q;
+                       con_release_unimap(p);
+                       kfree(p);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int
+con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
+{
+       int i, n;
+       u16 **p1, *p2;
+
+       if (!(p1 = p->uni_pgdir[n = unicode >> 11])) {
+               p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL);
+               if (!p1) return -ENOMEM;
+               for (i = 0; i < 32; i++)
+                       p1[i] = NULL;
+       }
+
+       if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) {
+               p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL);
+               if (!p2) return -ENOMEM;
+               memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */
+       }
+
+       p2[unicode & 0x3f] = fontpos;
+       
+       p->sum += (fontpos << 20) + unicode;
+
+       return 0;
+}
+
+/* ui is a leftover from using a hashtable, but might be used again */
+int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
+{
+       struct uni_pagedir *p, *q;
+  
+       p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
+       if (p && p->readonly) return -EIO;
+       if (!p || --p->refcount) {
+               q = kzalloc(sizeof(*p), GFP_KERNEL);
+               if (!q) {
+                       if (p) p->refcount++;
+                       return -ENOMEM;
+               }
+               q->refcount=1;
+               *vc->vc_uni_pagedir_loc = (unsigned long)q;
+       } else {
+               if (p == dflt) dflt = NULL;
+               p->refcount++;
+               p->sum = 0;
+               con_release_unimap(p);
+       }
+       return 0;
+}
+
+int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
+{
+       int err = 0, err1, i;
+       struct uni_pagedir *p, *q;
+
+       p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
+       if (p->readonly) return -EIO;
+       
+       if (!ct) return 0;
+       
+       if (p->refcount > 1) {
+               int j, k;
+               u16 **p1, *p2, l;
+               
+               err1 = con_clear_unimap(vc, NULL);
+               if (err1) return err1;
+               
+               q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
+               for (i = 0, l = 0; i < 32; i++)
+               if ((p1 = p->uni_pgdir[i]))
+                       for (j = 0; j < 32; j++)
+                       if ((p2 = p1[j]))
+                               for (k = 0; k < 64; k++, l++)
+                               if (p2[k] != 0xffff) {
+                                       err1 = con_insert_unipair(q, l, p2[k]);
+                                       if (err1) {
+                                               p->refcount++;
+                                               *vc->vc_uni_pagedir_loc = (unsigned long)p;
+                                               con_release_unimap(q);
+                                               kfree(q);
+                                               return err1; 
+                                       }
+                               }
+               p = q;
+       } else if (p == dflt)
+               dflt = NULL;
+       
+       while (ct--) {
+               unsigned short unicode, fontpos;
+               __get_user(unicode, &list->unicode);
+               __get_user(fontpos, &list->fontpos);
+               if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0)
+                       err = err1;
+               list++;
+       }
+       
+       if (con_unify_unimap(vc, p))
+               return err;
+
+       for (i = 0; i <= 3; i++)
+               set_inverse_transl(vc, p, i); /* Update all inverse translations */
+       set_inverse_trans_unicode(vc, p);
+  
+       return err;
+}
+
+/* Loads the unimap for the hardware font, as defined in uni_hash.tbl.
+   The representation used was the most compact I could come up
+   with.  This routine is executed at sys_setup time, and when the
+   PIO_FONTRESET ioctl is called. */
+
+int con_set_default_unimap(struct vc_data *vc)
+{
+       int i, j, err = 0, err1;
+       u16 *q;
+       struct uni_pagedir *p;
+
+       if (dflt) {
+               p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
+               if (p == dflt)
+                       return 0;
+               dflt->refcount++;
+               *vc->vc_uni_pagedir_loc = (unsigned long)dflt;
+               if (p && --p->refcount) {
+                       con_release_unimap(p);
+                       kfree(p);
+               }
+               return 0;
+       }
+       
+       /* The default font is always 256 characters */
+
+       err = con_clear_unimap(vc, NULL);
+       if (err) return err;
+    
+       p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
+       q = dfont_unitable;
+       
+       for (i = 0; i < 256; i++)
+               for (j = dfont_unicount[i]; j; j--) {
+                       err1 = con_insert_unipair(p, *(q++), i);
+                       if (err1)
+                               err = err1;
+               }
+                       
+       if (con_unify_unimap(vc, p)) {
+               dflt = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
+               return err;
+       }
+
+       for (i = 0; i <= 3; i++)
+               set_inverse_transl(vc, p, i);   /* Update all inverse translations */
+       set_inverse_trans_unicode(vc, p);
+       dflt = p;
+       return err;
+}
+EXPORT_SYMBOL(con_set_default_unimap);
+
+int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
+{
+       struct uni_pagedir *q;
+
+       if (!*src_vc->vc_uni_pagedir_loc)
+               return -EINVAL;
+       if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc)
+               return 0;
+       con_free_unimap(dst_vc);
+       q = (struct uni_pagedir *)*src_vc->vc_uni_pagedir_loc;
+       q->refcount++;
+       *dst_vc->vc_uni_pagedir_loc = (long)q;
+       return 0;
+}
+
+int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list)
+{
+       int i, j, k, ect;
+       u16 **p1, *p2;
+       struct uni_pagedir *p;
+
+       ect = 0;
+       if (*vc->vc_uni_pagedir_loc) {
+               p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
+               for (i = 0; i < 32; i++)
+               if ((p1 = p->uni_pgdir[i]))
+                       for (j = 0; j < 32; j++)
+                       if ((p2 = *(p1++)))
+                               for (k = 0; k < 64; k++) {
+                                       if (*p2 < MAX_GLYPH && ect++ < ct) {
+                                               __put_user((u_short)((i<<11)+(j<<6)+k),
+                                                          &list->unicode);
+                                               __put_user((u_short) *p2, 
+                                                          &list->fontpos);
+                                               list++;
+                                       }
+                                       p2++;
+                               }
+       }
+       __put_user(ect, uct);
+       return ((ect <= ct) ? 0 : -ENOMEM);
+}
+
+void con_protect_unimap(struct vc_data *vc, int rdonly)
+{
+       struct uni_pagedir *p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
+       
+       if (p)
+               p->readonly = rdonly;
+}
+
+/*
+ * Always use USER_MAP. These functions are used by the keyboard,
+ * which shouldn't be affected by G0/G1 switching, etc.
+ * If the user map still contains default values, i.e. the
+ * direct-to-font mapping, then assume user is using Latin1.
+ */
+/* may be called during an interrupt */
+u32 conv_8bit_to_uni(unsigned char c)
+{
+       unsigned short uni = translations[USER_MAP][c];
+       return uni == (0xf000 | c) ? c : uni;
+}
+
+int conv_uni_to_8bit(u32 uni)
+{
+       int c;
+       for (c = 0; c < 0x100; c++)
+               if (translations[USER_MAP][c] == uni ||
+                  (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
+                       return c;
+       return -1;
+}
+
+int
+conv_uni_to_pc(struct vc_data *conp, long ucs) 
+{
+       int h;
+       u16 **p1, *p2;
+       struct uni_pagedir *p;
+  
+       /* Only 16-bit codes supported at this time */
+       if (ucs > 0xffff)
+               return -4;              /* Not found */
+       else if (ucs < 0x20)
+               return -1;              /* Not a printable character */
+       else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
+               return -2;                      /* Zero-width space */
+       /*
+        * UNI_DIRECT_BASE indicates the start of the region in the User Zone
+        * which always has a 1:1 mapping to the currently loaded font.  The
+        * UNI_DIRECT_MASK indicates the bit span of the region.
+        */
+       else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
+               return ucs & UNI_DIRECT_MASK;
+  
+       if (!*conp->vc_uni_pagedir_loc)
+               return -3;
+
+       p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;  
+       if ((p1 = p->uni_pgdir[ucs >> 11]) &&
+           (p2 = p1[(ucs >> 6) & 0x1f]) &&
+           (h = p2[ucs & 0x3f]) < MAX_GLYPH)
+               return h;
+
+       return -4;              /* not found */
+}
+
+/*
+ * This is called at sys_setup time, after memory and the console are
+ * initialized.  It must be possible to call kmalloc(..., GFP_KERNEL)
+ * from this function, hence the call from sys_setup.
+ */
+void __init 
+console_map_init(void)
+{
+       int i;
+       
+       for (i = 0; i < MAX_NR_CONSOLES; i++)
+               if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
+                       con_set_default_unimap(vc_cons[i].d);
+}
+
+EXPORT_SYMBOL(con_copy_unimap);
diff --git a/drivers/tty/vt/cp437.uni b/drivers/tty/vt/cp437.uni
new file mode 100644 (file)
index 0000000..bc61634
--- /dev/null
@@ -0,0 +1,291 @@
+#
+# Unicode table for IBM Codepage 437.  Note that there are many more
+# substitutions that could be conceived (for example, thick-line
+# graphs probably should be replaced with double-line ones, accented
+# Latin characters should replaced with their nonaccented versions,
+# and some upper case Greek characters could be replaced by Latin), however,
+# I have limited myself to the Unicodes used by the kernel ISO 8859-1,
+# DEC VT, and IBM CP 437 tables.
+#
+# --------------------------------
+#
+# Basic IBM dingbats, some of which will never have a purpose clear
+# to mankind
+#
+0x00   U+0000
+0x01   U+263a
+0x02   U+263b
+0x03   U+2665
+0x04   U+2666 U+25c6
+0x05   U+2663
+0x06   U+2660
+0x07   U+2022
+0x08   U+25d8
+0x09   U+25cb
+0x0a   U+25d9
+0x0b   U+2642
+0x0c   U+2640
+0x0d   U+266a
+0x0e   U+266b
+0x0f   U+263c U+00a4
+0x10   U+25b6 U+25ba
+0x11   U+25c0 U+25c4
+0x12   U+2195
+0x13   U+203c
+0x14   U+00b6
+0x15   U+00a7
+0x16   U+25ac
+0x17   U+21a8
+0x18   U+2191
+0x19   U+2193
+0x1a   U+2192
+0x1b   U+2190
+0x1c   U+221f
+0x1d   U+2194
+0x1e   U+25b2
+0x1f   U+25bc
+#
+# The ASCII range is identity-mapped, but some of the characters also
+# have to act as substitutes, especially the upper-case characters.
+#
+0x20   U+0020
+0x21   U+0021
+0x22   U+0022 U+00a8
+0x23   U+0023
+0x24   U+0024
+0x25   U+0025
+0x26   U+0026
+0x27   U+0027 U+00b4
+0x28   U+0028
+0x29   U+0029
+0x2a   U+002a
+0x2b   U+002b
+0x2c   U+002c U+00b8
+0x2d   U+002d U+00ad
+0x2e   U+002e
+0x2f   U+002f
+0x30   U+0030
+0x31   U+0031
+0x32   U+0032
+0x33   U+0033
+0x34   U+0034
+0x35   U+0035
+0x36   U+0036
+0x37   U+0037
+0x38   U+0038
+0x39   U+0039
+0x3a   U+003a
+0x3b   U+003b
+0x3c   U+003c
+0x3d   U+003d
+0x3e   U+003e
+0x3f   U+003f
+0x40   U+0040
+0x41   U+0041 U+00c0 U+00c1 U+00c2 U+00c3
+0x42   U+0042
+0x43   U+0043 U+00a9
+0x44   U+0044 U+00d0
+0x45   U+0045 U+00c8 U+00ca U+00cb
+0x46   U+0046
+0x47   U+0047
+0x48   U+0048
+0x49   U+0049 U+00cc U+00cd U+00ce U+00cf
+0x4a   U+004a
+0x4b   U+004b U+212a
+0x4c   U+004c
+0x4d   U+004d
+0x4e   U+004e
+0x4f   U+004f U+00d2 U+00d3 U+00d4 U+00d5
+0x50   U+0050
+0x51   U+0051
+0x52   U+0052 U+00ae
+0x53   U+0053
+0x54   U+0054
+0x55   U+0055 U+00d9 U+00da U+00db
+0x56   U+0056
+0x57   U+0057
+0x58   U+0058
+0x59   U+0059 U+00dd
+0x5a   U+005a
+0x5b   U+005b
+0x5c   U+005c
+0x5d   U+005d
+0x5e   U+005e
+0x5f   U+005f U+23bd U+f804
+0x60   U+0060
+0x61   U+0061 U+00e3
+0x62   U+0062
+0x63   U+0063
+0x64   U+0064
+0x65   U+0065
+0x66   U+0066
+0x67   U+0067
+0x68   U+0068
+0x69   U+0069
+0x6a   U+006a
+0x6b   U+006b
+0x6c   U+006c
+0x6d   U+006d
+0x6e   U+006e
+0x6f   U+006f U+00f5
+0x70   U+0070
+0x71   U+0071
+0x72   U+0072
+0x73   U+0073
+0x74   U+0074
+0x75   U+0075
+0x76   U+0076
+0x77   U+0077
+0x78   U+0078 U+00d7
+0x79   U+0079 U+00fd
+0x7a   U+007a
+0x7b   U+007b
+0x7c   U+007c U+00a6
+0x7d   U+007d
+0x7e   U+007e
+#
+# Okay, what on Earth is this one supposed to be used for?
+#
+0x7f   U+2302
+#
+# Non-English characters, mostly lower case letters...
+#
+0x80   U+00c7
+0x81   U+00fc
+0x82   U+00e9
+0x83   U+00e2
+0x84   U+00e4
+0x85   U+00e0
+0x86   U+00e5
+0x87   U+00e7
+0x88   U+00ea
+0x89   U+00eb
+0x8a   U+00e8
+0x8b   U+00ef
+0x8c   U+00ee
+0x8d   U+00ec
+0x8e   U+00c4
+0x8f   U+00c5 U+212b
+0x90   U+00c9
+0x91   U+00e6
+0x92   U+00c6
+0x93   U+00f4
+0x94   U+00f6
+0x95   U+00f2
+0x96   U+00fb
+0x97   U+00f9
+0x98   U+00ff
+0x99   U+00d6
+0x9a   U+00dc
+0x9b   U+00a2
+0x9c   U+00a3
+0x9d   U+00a5
+0x9e   U+20a7
+0x9f   U+0192
+0xa0   U+00e1
+0xa1   U+00ed
+0xa2   U+00f3
+0xa3   U+00fa
+0xa4   U+00f1
+0xa5   U+00d1
+0xa6   U+00aa
+0xa7   U+00ba
+0xa8   U+00bf
+0xa9   U+2310
+0xaa   U+00ac
+0xab   U+00bd
+0xac   U+00bc
+0xad   U+00a1
+0xae   U+00ab
+0xaf   U+00bb
+#
+# Block graphics
+#
+0xb0   U+2591
+0xb1   U+2592
+0xb2   U+2593
+0xb3   U+2502
+0xb4   U+2524
+0xb5   U+2561
+0xb6   U+2562
+0xb7   U+2556
+0xb8   U+2555
+0xb9   U+2563
+0xba   U+2551
+0xbb   U+2557
+0xbc   U+255d
+0xbd   U+255c
+0xbe   U+255b
+0xbf   U+2510
+0xc0   U+2514
+0xc1   U+2534
+0xc2   U+252c
+0xc3   U+251c
+0xc4   U+2500
+0xc5   U+253c
+0xc6   U+255e
+0xc7   U+255f
+0xc8   U+255a
+0xc9   U+2554
+0xca   U+2569
+0xcb   U+2566
+0xcc   U+2560
+0xcd   U+2550
+0xce   U+256c
+0xcf   U+2567
+0xd0   U+2568
+0xd1   U+2564
+0xd2   U+2565
+0xd3   U+2559
+0xd4   U+2558
+0xd5   U+2552
+0xd6   U+2553
+0xd7   U+256b
+0xd8   U+256a
+0xd9   U+2518
+0xda   U+250c
+0xdb   U+2588
+0xdc   U+2584
+0xdd   U+258c
+0xde   U+2590
+0xdf   U+2580
+#
+# Greek letters and mathematical symbols
+#
+0xe0   U+03b1
+0xe1   U+03b2 U+00df
+0xe2   U+0393
+0xe3   U+03c0
+0xe4   U+03a3
+0xe5   U+03c3
+0xe6   U+00b5 U+03bc
+0xe7   U+03c4
+0xe8   U+03a6 U+00d8
+0xe9   U+0398
+0xea   U+03a9 U+2126
+0xeb   U+03b4 U+00f0
+0xec   U+221e
+0xed   U+03c6 U+00f8
+0xee   U+03b5 U+2208
+0xef   U+2229
+0xf0   U+2261
+0xf1   U+00b1
+0xf2   U+2265
+0xf3   U+2264
+0xf4   U+2320
+0xf5   U+2321
+0xf6   U+00f7
+0xf7   U+2248
+0xf8   U+00b0
+0xf9   U+2219
+0xfa   U+00b7
+0xfb   U+221a
+0xfc   U+207f
+0xfd   U+00b2
+#
+# Square bullet, non-spacing blank
+# Mapping U+fffd to the square bullet means it is the substitution
+# character
+# 
+0xfe   U+25a0 U+fffd
+0xff   U+00a0
diff --git a/drivers/tty/vt/defkeymap.c_shipped b/drivers/tty/vt/defkeymap.c_shipped
new file mode 100644 (file)
index 0000000..d2208df
--- /dev/null
@@ -0,0 +1,262 @@
+/* Do not edit this file! It was automatically generated by   */
+/*    loadkeys --mktable defkeymap.map > defkeymap.c          */
+
+#include <linux/types.h>
+#include <linux/keyboard.h>
+#include <linux/kd.h>
+
+u_short plain_map[NR_KEYS] = {
+       0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
+       0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
+       0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
+       0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
+       0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
+       0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
+       0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
+       0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
+       0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
+       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+       0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
+       0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
+       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short shift_map[NR_KEYS] = {
+       0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
+       0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
+       0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
+       0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
+       0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
+       0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
+       0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
+       0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
+       0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
+       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+       0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
+       0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+       0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
+       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short altgr_map[NR_KEYS] = {
+       0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
+       0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
+       0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
+       0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
+       0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
+       0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
+       0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
+       0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
+       0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
+       0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
+       0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
+       0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short ctrl_map[NR_KEYS] = {
+       0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
+       0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
+       0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
+       0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
+       0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
+       0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
+       0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
+       0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
+       0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
+       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+       0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
+       0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
+       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short shift_ctrl_map[NR_KEYS] = {
+       0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
+       0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
+       0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
+       0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
+       0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
+       0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
+       0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
+       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+       0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short alt_map[NR_KEYS] = {
+       0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
+       0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
+       0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
+       0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
+       0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
+       0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
+       0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
+       0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
+       0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
+       0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
+       0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
+       0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
+       0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short ctrl_alt_map[NR_KEYS] = {
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
+       0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
+       0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
+       0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
+       0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
+       0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
+       0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
+       0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+       0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
+       0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+       0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+       0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
+       0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+       0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+ushort *key_maps[MAX_NR_KEYMAPS] = {
+       plain_map, shift_map, altgr_map, NULL,
+       ctrl_map, shift_ctrl_map, NULL, NULL,
+       alt_map, NULL, NULL, NULL,
+       ctrl_alt_map, NULL
+};
+
+unsigned int keymap_count = 7;
+
+/*
+ * Philosophy: most people do not define more strings, but they who do
+ * often want quite a lot of string space. So, we statically allocate
+ * the default and allocate dynamically in chunks of 512 bytes.
+ */
+
+char func_buf[] = {
+       '\033', '[', '[', 'A', 0, 
+       '\033', '[', '[', 'B', 0, 
+       '\033', '[', '[', 'C', 0, 
+       '\033', '[', '[', 'D', 0, 
+       '\033', '[', '[', 'E', 0, 
+       '\033', '[', '1', '7', '~', 0, 
+       '\033', '[', '1', '8', '~', 0, 
+       '\033', '[', '1', '9', '~', 0, 
+       '\033', '[', '2', '0', '~', 0, 
+       '\033', '[', '2', '1', '~', 0, 
+       '\033', '[', '2', '3', '~', 0, 
+       '\033', '[', '2', '4', '~', 0, 
+       '\033', '[', '2', '5', '~', 0, 
+       '\033', '[', '2', '6', '~', 0, 
+       '\033', '[', '2', '8', '~', 0, 
+       '\033', '[', '2', '9', '~', 0, 
+       '\033', '[', '3', '1', '~', 0, 
+       '\033', '[', '3', '2', '~', 0, 
+       '\033', '[', '3', '3', '~', 0, 
+       '\033', '[', '3', '4', '~', 0, 
+       '\033', '[', '1', '~', 0, 
+       '\033', '[', '2', '~', 0, 
+       '\033', '[', '3', '~', 0, 
+       '\033', '[', '4', '~', 0, 
+       '\033', '[', '5', '~', 0, 
+       '\033', '[', '6', '~', 0, 
+       '\033', '[', 'M', 0, 
+       '\033', '[', 'P', 0, 
+};
+
+char *funcbufptr = func_buf;
+int funcbufsize = sizeof(func_buf);
+int funcbufleft = 0;          /* space left */
+
+char *func_table[MAX_NR_FUNC] = {
+       func_buf + 0,
+       func_buf + 5,
+       func_buf + 10,
+       func_buf + 15,
+       func_buf + 20,
+       func_buf + 25,
+       func_buf + 31,
+       func_buf + 37,
+       func_buf + 43,
+       func_buf + 49,
+       func_buf + 55,
+       func_buf + 61,
+       func_buf + 67,
+       func_buf + 73,
+       func_buf + 79,
+       func_buf + 85,
+       func_buf + 91,
+       func_buf + 97,
+       func_buf + 103,
+       func_buf + 109,
+       func_buf + 115,
+       func_buf + 120,
+       func_buf + 125,
+       func_buf + 130,
+       func_buf + 135,
+       func_buf + 140,
+       func_buf + 145,
+       NULL,
+       NULL,
+       func_buf + 149,
+       NULL,
+};
+
+struct kbdiacruc accent_table[MAX_DIACR] = {
+       {'`', 'A', 0300},       {'`', 'a', 0340},
+       {'\'', 'A', 0301},      {'\'', 'a', 0341},
+       {'^', 'A', 0302},       {'^', 'a', 0342},
+       {'~', 'A', 0303},       {'~', 'a', 0343},
+       {'"', 'A', 0304},       {'"', 'a', 0344},
+       {'O', 'A', 0305},       {'o', 'a', 0345},
+       {'0', 'A', 0305},       {'0', 'a', 0345},
+       {'A', 'A', 0305},       {'a', 'a', 0345},
+       {'A', 'E', 0306},       {'a', 'e', 0346},
+       {',', 'C', 0307},       {',', 'c', 0347},
+       {'`', 'E', 0310},       {'`', 'e', 0350},
+       {'\'', 'E', 0311},      {'\'', 'e', 0351},
+       {'^', 'E', 0312},       {'^', 'e', 0352},
+       {'"', 'E', 0313},       {'"', 'e', 0353},
+       {'`', 'I', 0314},       {'`', 'i', 0354},
+       {'\'', 'I', 0315},      {'\'', 'i', 0355},
+       {'^', 'I', 0316},       {'^', 'i', 0356},
+       {'"', 'I', 0317},       {'"', 'i', 0357},
+       {'-', 'D', 0320},       {'-', 'd', 0360},
+       {'~', 'N', 0321},       {'~', 'n', 0361},
+       {'`', 'O', 0322},       {'`', 'o', 0362},
+       {'\'', 'O', 0323},      {'\'', 'o', 0363},
+       {'^', 'O', 0324},       {'^', 'o', 0364},
+       {'~', 'O', 0325},       {'~', 'o', 0365},
+       {'"', 'O', 0326},       {'"', 'o', 0366},
+       {'/', 'O', 0330},       {'/', 'o', 0370},
+       {'`', 'U', 0331},       {'`', 'u', 0371},
+       {'\'', 'U', 0332},      {'\'', 'u', 0372},
+       {'^', 'U', 0333},       {'^', 'u', 0373},
+       {'"', 'U', 0334},       {'"', 'u', 0374},
+       {'\'', 'Y', 0335},      {'\'', 'y', 0375},
+       {'T', 'H', 0336},       {'t', 'h', 0376},
+       {'s', 's', 0337},       {'"', 'y', 0377},
+       {'s', 'z', 0337},       {'i', 'j', 0377},
+};
+
+unsigned int accent_table_size = 68;
diff --git a/drivers/tty/vt/defkeymap.map b/drivers/tty/vt/defkeymap.map
new file mode 100644 (file)
index 0000000..50b30ca
--- /dev/null
@@ -0,0 +1,357 @@
+# Default kernel keymap. This uses 7 modifier combinations.
+keymaps 0-2,4-5,8,12
+# Change the above line into
+#      keymaps 0-2,4-6,8,12
+# in case you want the entries
+#      altgr   control keycode  83 = Boot            
+#      altgr   control keycode 111 = Boot            
+# below.
+#
+# In fact AltGr is used very little, and one more keymap can
+# be saved by mapping AltGr to Alt (and adapting a few entries):
+# keycode 100 = Alt
+#
+keycode   1 = Escape           Escape          
+       alt     keycode   1 = Meta_Escape     
+keycode   2 = one              exclam          
+       alt     keycode   2 = Meta_one        
+keycode   3 = two              at               at              
+       control keycode   3 = nul             
+       shift   control keycode   3 = nul             
+       alt     keycode   3 = Meta_two        
+keycode   4 = three            numbersign      
+       control keycode   4 = Escape          
+       alt     keycode   4 = Meta_three      
+keycode   5 = four             dollar           dollar          
+       control keycode   5 = Control_backslash
+       alt     keycode   5 = Meta_four       
+keycode   6 = five             percent         
+       control keycode   6 = Control_bracketright
+       alt     keycode   6 = Meta_five       
+keycode   7 = six              asciicircum     
+       control keycode   7 = Control_asciicircum
+       alt     keycode   7 = Meta_six        
+keycode   8 = seven            ampersand        braceleft       
+       control keycode   8 = Control_underscore
+       alt     keycode   8 = Meta_seven      
+keycode   9 = eight            asterisk         bracketleft     
+       control keycode   9 = Delete          
+       alt     keycode   9 = Meta_eight      
+keycode  10 = nine             parenleft        bracketright    
+       alt     keycode  10 = Meta_nine       
+keycode  11 = zero             parenright       braceright      
+       alt     keycode  11 = Meta_zero       
+keycode  12 = minus            underscore       backslash       
+       control keycode  12 = Control_underscore
+       shift   control keycode  12 = Control_underscore
+       alt     keycode  12 = Meta_minus      
+keycode  13 = equal            plus            
+       alt     keycode  13 = Meta_equal      
+keycode  14 = Delete           Delete          
+       control keycode  14 = BackSpace
+       alt     keycode  14 = Meta_Delete     
+keycode  15 = Tab              Tab             
+       alt     keycode  15 = Meta_Tab        
+keycode  16 = q               
+keycode  17 = w               
+keycode  18 = e
+       altgr   keycode  18 = Hex_E   
+keycode  19 = r               
+keycode  20 = t               
+keycode  21 = y               
+keycode  22 = u               
+keycode  23 = i               
+keycode  24 = o               
+keycode  25 = p               
+keycode  26 = bracketleft      braceleft       
+       control keycode  26 = Escape          
+       alt     keycode  26 = Meta_bracketleft
+keycode  27 = bracketright     braceright       asciitilde      
+       control keycode  27 = Control_bracketright
+       alt     keycode  27 = Meta_bracketright
+keycode  28 = Return          
+       alt     keycode  28 = Meta_Control_m  
+keycode  29 = Control         
+keycode  30 = a
+       altgr   keycode  30 = Hex_A
+keycode  31 = s               
+keycode  32 = d
+       altgr   keycode  32 = Hex_D   
+keycode  33 = f
+       altgr   keycode  33 = Hex_F               
+keycode  34 = g               
+keycode  35 = h               
+keycode  36 = j               
+keycode  37 = k               
+keycode  38 = l               
+keycode  39 = semicolon        colon           
+       alt     keycode  39 = Meta_semicolon  
+keycode  40 = apostrophe       quotedbl        
+       control keycode  40 = Control_g       
+       alt     keycode  40 = Meta_apostrophe 
+keycode  41 = grave            asciitilde      
+       control keycode  41 = nul             
+       alt     keycode  41 = Meta_grave      
+keycode  42 = Shift           
+keycode  43 = backslash        bar             
+       control keycode  43 = Control_backslash
+       alt     keycode  43 = Meta_backslash  
+keycode  44 = z               
+keycode  45 = x               
+keycode  46 = c
+       altgr   keycode  46 = Hex_C   
+keycode  47 = v               
+keycode  48 = b
+       altgr   keycode  48 = Hex_B
+keycode  49 = n               
+keycode  50 = m               
+keycode  51 = comma            less            
+       alt     keycode  51 = Meta_comma      
+keycode  52 = period           greater         
+       control keycode  52 = Compose         
+       alt     keycode  52 = Meta_period     
+keycode  53 = slash            question        
+       control keycode  53 = Delete          
+       alt     keycode  53 = Meta_slash      
+keycode  54 = Shift           
+keycode  55 = KP_Multiply     
+keycode  56 = Alt             
+keycode  57 = space            space           
+       control keycode  57 = nul             
+       alt     keycode  57 = Meta_space      
+keycode  58 = Caps_Lock       
+keycode  59 = F1               F11              Console_13      
+       control keycode  59 = F1              
+       alt     keycode  59 = Console_1       
+       control alt     keycode  59 = Console_1       
+keycode  60 = F2               F12              Console_14      
+       control keycode  60 = F2              
+       alt     keycode  60 = Console_2       
+       control alt     keycode  60 = Console_2       
+keycode  61 = F3               F13              Console_15      
+       control keycode  61 = F3              
+       alt     keycode  61 = Console_3       
+       control alt     keycode  61 = Console_3       
+keycode  62 = F4               F14              Console_16      
+       control keycode  62 = F4              
+       alt     keycode  62 = Console_4       
+       control alt     keycode  62 = Console_4       
+keycode  63 = F5               F15              Console_17      
+       control keycode  63 = F5              
+       alt     keycode  63 = Console_5       
+       control alt     keycode  63 = Console_5       
+keycode  64 = F6               F16              Console_18      
+       control keycode  64 = F6              
+       alt     keycode  64 = Console_6       
+       control alt     keycode  64 = Console_6       
+keycode  65 = F7               F17              Console_19      
+       control keycode  65 = F7              
+       alt     keycode  65 = Console_7       
+       control alt     keycode  65 = Console_7       
+keycode  66 = F8               F18              Console_20      
+       control keycode  66 = F8              
+       alt     keycode  66 = Console_8       
+       control alt     keycode  66 = Console_8       
+keycode  67 = F9               F19              Console_21      
+       control keycode  67 = F9              
+       alt     keycode  67 = Console_9       
+       control alt     keycode  67 = Console_9       
+keycode  68 = F10              F20              Console_22      
+       control keycode  68 = F10             
+       alt     keycode  68 = Console_10      
+       control alt     keycode  68 = Console_10      
+keycode  69 = Num_Lock
+       shift   keycode  69 = Bare_Num_Lock
+keycode  70 = Scroll_Lock      Show_Memory      Show_Registers  
+       control keycode  70 = Show_State      
+       alt     keycode  70 = Scroll_Lock     
+keycode  71 = KP_7            
+       alt     keycode  71 = Ascii_7         
+       altgr   keycode  71 = Hex_7         
+keycode  72 = KP_8            
+       alt     keycode  72 = Ascii_8         
+       altgr   keycode  72 = Hex_8         
+keycode  73 = KP_9            
+       alt     keycode  73 = Ascii_9         
+       altgr   keycode  73 = Hex_9         
+keycode  74 = KP_Subtract     
+keycode  75 = KP_4            
+       alt     keycode  75 = Ascii_4         
+       altgr   keycode  75 = Hex_4         
+keycode  76 = KP_5            
+       alt     keycode  76 = Ascii_5         
+       altgr   keycode  76 = Hex_5         
+keycode  77 = KP_6            
+       alt     keycode  77 = Ascii_6         
+       altgr   keycode  77 = Hex_6         
+keycode  78 = KP_Add          
+keycode  79 = KP_1            
+       alt     keycode  79 = Ascii_1         
+       altgr   keycode  79 = Hex_1         
+keycode  80 = KP_2            
+       alt     keycode  80 = Ascii_2         
+       altgr   keycode  80 = Hex_2         
+keycode  81 = KP_3            
+       alt     keycode  81 = Ascii_3         
+       altgr   keycode  81 = Hex_3         
+keycode  82 = KP_0            
+       alt     keycode  82 = Ascii_0         
+       altgr   keycode  82 = Hex_0         
+keycode  83 = KP_Period       
+#      altgr   control keycode  83 = Boot            
+       control alt     keycode  83 = Boot            
+keycode  84 = Last_Console    
+keycode  85 =
+keycode  86 = less             greater          bar             
+       alt     keycode  86 = Meta_less       
+keycode  87 = F11              F11              Console_23      
+       control keycode  87 = F11             
+       alt     keycode  87 = Console_11      
+       control alt     keycode  87 = Console_11      
+keycode  88 = F12              F12              Console_24      
+       control keycode  88 = F12             
+       alt     keycode  88 = Console_12      
+       control alt     keycode  88 = Console_12      
+keycode  89 =
+keycode  90 =
+keycode  91 =
+keycode  92 =
+keycode  93 =
+keycode  94 =
+keycode  95 =
+keycode  96 = KP_Enter        
+keycode  97 = Control         
+keycode  98 = KP_Divide       
+keycode  99 = Control_backslash
+       control keycode  99 = Control_backslash
+       alt     keycode  99 = Control_backslash
+keycode 100 = AltGr           
+keycode 101 = Break           
+keycode 102 = Find            
+keycode 103 = Up              
+keycode 104 = Prior           
+       shift   keycode 104 = Scroll_Backward 
+keycode 105 = Left            
+       alt     keycode 105 = Decr_Console
+keycode 106 = Right           
+       alt     keycode 106 = Incr_Console
+keycode 107 = Select          
+keycode 108 = Down            
+keycode 109 = Next            
+       shift   keycode 109 = Scroll_Forward  
+keycode 110 = Insert          
+keycode 111 = Remove          
+#      altgr   control keycode 111 = Boot            
+       control alt     keycode 111 = Boot            
+keycode 112 = Macro           
+keycode 113 = F13             
+keycode 114 = F14             
+keycode 115 = Help            
+keycode 116 = Do              
+keycode 117 = F17             
+keycode 118 = KP_MinPlus      
+keycode 119 = Pause           
+keycode 120 =
+keycode 121 =
+keycode 122 =
+keycode 123 =
+keycode 124 =
+keycode 125 =
+keycode 126 =
+keycode 127 =
+string F1 = "\033[[A"
+string F2 = "\033[[B"
+string F3 = "\033[[C"
+string F4 = "\033[[D"
+string F5 = "\033[[E"
+string F6 = "\033[17~"
+string F7 = "\033[18~"
+string F8 = "\033[19~"
+string F9 = "\033[20~"
+string F10 = "\033[21~"
+string F11 = "\033[23~"
+string F12 = "\033[24~"
+string F13 = "\033[25~"
+string F14 = "\033[26~"
+string F15 = "\033[28~"
+string F16 = "\033[29~"
+string F17 = "\033[31~"
+string F18 = "\033[32~"
+string F19 = "\033[33~"
+string F20 = "\033[34~"
+string Find = "\033[1~"
+string Insert = "\033[2~"
+string Remove = "\033[3~"
+string Select = "\033[4~"
+string Prior = "\033[5~"
+string Next = "\033[6~"
+string Macro = "\033[M"
+string Pause = "\033[P"
+compose '`' 'A' to 'À'
+compose '`' 'a' to 'à'
+compose '\'' 'A' to 'Á'
+compose '\'' 'a' to 'á'
+compose '^' 'A' to 'Â'
+compose '^' 'a' to 'â'
+compose '~' 'A' to 'Ã'
+compose '~' 'a' to 'ã'
+compose '"' 'A' to 'Ä'
+compose '"' 'a' to 'ä'
+compose 'O' 'A' to 'Å'
+compose 'o' 'a' to 'å'
+compose '0' 'A' to 'Å'
+compose '0' 'a' to 'å'
+compose 'A' 'A' to 'Å'
+compose 'a' 'a' to 'å'
+compose 'A' 'E' to 'Æ'
+compose 'a' 'e' to 'æ'
+compose ',' 'C' to 'Ç'
+compose ',' 'c' to 'ç'
+compose '`' 'E' to 'È'
+compose '`' 'e' to 'è'
+compose '\'' 'E' to 'É'
+compose '\'' 'e' to 'é'
+compose '^' 'E' to 'Ê'
+compose '^' 'e' to 'ê'
+compose '"' 'E' to 'Ë'
+compose '"' 'e' to 'ë'
+compose '`' 'I' to 'Ì'
+compose '`' 'i' to 'ì'
+compose '\'' 'I' to 'Í'
+compose '\'' 'i' to 'í'
+compose '^' 'I' to 'Î'
+compose '^' 'i' to 'î'
+compose '"' 'I' to 'Ï'
+compose '"' 'i' to 'ï'
+compose '-' 'D' to 'Ð'
+compose '-' 'd' to 'ð'
+compose '~' 'N' to 'Ñ'
+compose '~' 'n' to 'ñ'
+compose '`' 'O' to 'Ò'
+compose '`' 'o' to 'ò'
+compose '\'' 'O' to 'Ó'
+compose '\'' 'o' to 'ó'
+compose '^' 'O' to 'Ô'
+compose '^' 'o' to 'ô'
+compose '~' 'O' to 'Õ'
+compose '~' 'o' to 'õ'
+compose '"' 'O' to 'Ö'
+compose '"' 'o' to 'ö'
+compose '/' 'O' to 'Ø'
+compose '/' 'o' to 'ø'
+compose '`' 'U' to 'Ù'
+compose '`' 'u' to 'ù'
+compose '\'' 'U' to 'Ú'
+compose '\'' 'u' to 'ú'
+compose '^' 'U' to 'Û'
+compose '^' 'u' to 'û'
+compose '"' 'U' to 'Ü'
+compose '"' 'u' to 'ü'
+compose '\'' 'Y' to 'Ý'
+compose '\'' 'y' to 'ý'
+compose 'T' 'H' to 'Þ'
+compose 't' 'h' to 'þ'
+compose 's' 's' to 'ß'
+compose '"' 'y' to 'ÿ'
+compose 's' 'z' to 'ß'
+compose 'i' 'j' to 'ÿ'
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
new file mode 100644 (file)
index 0000000..e95d787
--- /dev/null
@@ -0,0 +1,1454 @@
+/*
+ * linux/drivers/char/keyboard.c
+ *
+ * Written for linux by Johan Myreen as a translation from
+ * the assembly version by Linus (with diacriticals added)
+ *
+ * Some additional features added by Christoph Niemann (ChN), March 1993
+ *
+ * Loadable keymaps by Risto Kankkunen, May 1993
+ *
+ * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
+ * Added decr/incr_console, dynamic keymaps, Unicode support,
+ * dynamic function/string keys, led setting,  Sept 1994
+ * `Sticky' modifier keys, 951006.
+ *
+ * 11-11-96: SAK should now work in the raw mode (Martin Mares)
+ *
+ * Modified to provide 'generic' keyboard support by Hamish Macdonald
+ * Merge with the m68k keyboard driver and split-off of the PC low-level
+ * parts by Geert Uytterhoeven, May 1997
+ *
+ * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
+ * 30-07-98: Dead keys redone, aeb@cwi.nl.
+ * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/consolemap.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+
+#include <linux/kbd_kern.h>
+#include <linux/kbd_diacr.h>
+#include <linux/vt_kern.h>
+#include <linux/input.h>
+#include <linux/reboot.h>
+#include <linux/notifier.h>
+#include <linux/jiffies.h>
+
+extern void ctrl_alt_del(void);
+
+/*
+ * Exported functions/variables
+ */
+
+#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
+
+/*
+ * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
+ * This seems a good reason to start with NumLock off. On HIL keyboards
+ * of PARISC machines however there is no NumLock key and everyone expects the keypad
+ * to be used for numbers.
+ */
+
+#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
+#define KBD_DEFLEDS (1 << VC_NUMLOCK)
+#else
+#define KBD_DEFLEDS 0
+#endif
+
+#define KBD_DEFLOCK 0
+
+void compute_shiftstate(void);
+
+/*
+ * Handler Tables.
+ */
+
+#define K_HANDLERS\
+       k_self,         k_fn,           k_spec,         k_pad,\
+       k_dead,         k_cons,         k_cur,          k_shift,\
+       k_meta,         k_ascii,        k_lock,         k_lowercase,\
+       k_slock,        k_dead2,        k_brl,          k_ignore
+
+typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
+                           char up_flag);
+static k_handler_fn K_HANDLERS;
+static k_handler_fn *k_handler[16] = { K_HANDLERS };
+
+#define FN_HANDLERS\
+       fn_null,        fn_enter,       fn_show_ptregs, fn_show_mem,\
+       fn_show_state,  fn_send_intr,   fn_lastcons,    fn_caps_toggle,\
+       fn_num,         fn_hold,        fn_scroll_forw, fn_scroll_back,\
+       fn_boot_it,     fn_caps_on,     fn_compose,     fn_SAK,\
+       fn_dec_console, fn_inc_console, fn_spawn_con,   fn_bare_num
+
+typedef void (fn_handler_fn)(struct vc_data *vc);
+static fn_handler_fn FN_HANDLERS;
+static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
+
+/*
+ * Variables exported for vt_ioctl.c
+ */
+
+/* maximum values each key_handler can handle */
+const int max_vals[] = {
+       255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
+       NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
+       255, NR_LOCK - 1, 255, NR_BRL - 1
+};
+
+const int NR_TYPES = ARRAY_SIZE(max_vals);
+
+struct kbd_struct kbd_table[MAX_NR_CONSOLES];
+EXPORT_SYMBOL_GPL(kbd_table);
+static struct kbd_struct *kbd = kbd_table;
+
+struct vt_spawn_console vt_spawn_con = {
+       .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
+       .pid  = NULL,
+       .sig  = 0,
+};
+
+/*
+ * Variables exported for vt.c
+ */
+
+int shift_state = 0;
+
+/*
+ * Internal Data.
+ */
+
+static struct input_handler kbd_handler;
+static DEFINE_SPINLOCK(kbd_event_lock);
+static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
+static unsigned char shift_down[NR_SHIFT];             /* shift state counters.. */
+static bool dead_key_next;
+static int npadch = -1;                                        /* -1 or number assembled on pad */
+static unsigned int diacr;
+static char rep;                                       /* flag telling character repeat */
+
+static unsigned char ledstate = 0xff;                  /* undefined */
+static unsigned char ledioctl;
+
+static struct ledptr {
+       unsigned int *addr;
+       unsigned int mask;
+       unsigned char valid:1;
+} ledptrs[3];
+
+/*
+ * Notifier list for console keyboard events
+ */
+static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
+
+int register_keyboard_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_keyboard_notifier);
+
+int unregister_keyboard_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
+
+/*
+ * Translation of scancodes to keycodes. We set them on only the first
+ * keyboard in the list that accepts the scancode and keycode.
+ * Explanation for not choosing the first attached keyboard anymore:
+ *  USB keyboards for example have two event devices: one for all "normal"
+ *  keys and one for extra function keys (like "volume up", "make coffee",
+ *  etc.). So this means that scancodes for the extra function keys won't
+ *  be valid for the first event device, but will be for the second.
+ */
+
+struct getset_keycode_data {
+       struct input_keymap_entry ke;
+       int error;
+};
+
+static int getkeycode_helper(struct input_handle *handle, void *data)
+{
+       struct getset_keycode_data *d = data;
+
+       d->error = input_get_keycode(handle->dev, &d->ke);
+
+       return d->error == 0; /* stop as soon as we successfully get one */
+}
+
+int getkeycode(unsigned int scancode)
+{
+       struct getset_keycode_data d = {
+               .ke     = {
+                       .flags          = 0,
+                       .len            = sizeof(scancode),
+                       .keycode        = 0,
+               },
+               .error  = -ENODEV,
+       };
+
+       memcpy(d.ke.scancode, &scancode, sizeof(scancode));
+
+       input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
+
+       return d.error ?: d.ke.keycode;
+}
+
+static int setkeycode_helper(struct input_handle *handle, void *data)
+{
+       struct getset_keycode_data *d = data;
+
+       d->error = input_set_keycode(handle->dev, &d->ke);
+
+       return d->error == 0; /* stop as soon as we successfully set one */
+}
+
+int setkeycode(unsigned int scancode, unsigned int keycode)
+{
+       struct getset_keycode_data d = {
+               .ke     = {
+                       .flags          = 0,
+                       .len            = sizeof(scancode),
+                       .keycode        = keycode,
+               },
+               .error  = -ENODEV,
+       };
+
+       memcpy(d.ke.scancode, &scancode, sizeof(scancode));
+
+       input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
+
+       return d.error;
+}
+
+/*
+ * Making beeps and bells. Note that we prefer beeps to bells, but when
+ * shutting the sound off we do both.
+ */
+
+static int kd_sound_helper(struct input_handle *handle, void *data)
+{
+       unsigned int *hz = data;
+       struct input_dev *dev = handle->dev;
+
+       if (test_bit(EV_SND, dev->evbit)) {
+               if (test_bit(SND_TONE, dev->sndbit)) {
+                       input_inject_event(handle, EV_SND, SND_TONE, *hz);
+                       if (*hz)
+                               return 0;
+               }
+               if (test_bit(SND_BELL, dev->sndbit))
+                       input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
+       }
+
+       return 0;
+}
+
+static void kd_nosound(unsigned long ignored)
+{
+       static unsigned int zero;
+
+       input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
+}
+
+static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
+
+void kd_mksound(unsigned int hz, unsigned int ticks)
+{
+       del_timer_sync(&kd_mksound_timer);
+
+       input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
+
+       if (hz && ticks)
+               mod_timer(&kd_mksound_timer, jiffies + ticks);
+}
+EXPORT_SYMBOL(kd_mksound);
+
+/*
+ * Setting the keyboard rate.
+ */
+
+static int kbd_rate_helper(struct input_handle *handle, void *data)
+{
+       struct input_dev *dev = handle->dev;
+       struct kbd_repeat *rep = data;
+
+       if (test_bit(EV_REP, dev->evbit)) {
+
+               if (rep[0].delay > 0)
+                       input_inject_event(handle,
+                                          EV_REP, REP_DELAY, rep[0].delay);
+               if (rep[0].period > 0)
+                       input_inject_event(handle,
+                                          EV_REP, REP_PERIOD, rep[0].period);
+
+               rep[1].delay = dev->rep[REP_DELAY];
+               rep[1].period = dev->rep[REP_PERIOD];
+       }
+
+       return 0;
+}
+
+int kbd_rate(struct kbd_repeat *rep)
+{
+       struct kbd_repeat data[2] = { *rep };
+
+       input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
+       *rep = data[1]; /* Copy currently used settings */
+
+       return 0;
+}
+
+/*
+ * Helper Functions.
+ */
+static void put_queue(struct vc_data *vc, int ch)
+{
+       struct tty_struct *tty = vc->port.tty;
+
+       if (tty) {
+               tty_insert_flip_char(tty, ch, 0);
+               con_schedule_flip(tty);
+       }
+}
+
+static void puts_queue(struct vc_data *vc, char *cp)
+{
+       struct tty_struct *tty = vc->port.tty;
+
+       if (!tty)
+               return;
+
+       while (*cp) {
+               tty_insert_flip_char(tty, *cp, 0);
+               cp++;
+       }
+       con_schedule_flip(tty);
+}
+
+static void applkey(struct vc_data *vc, int key, char mode)
+{
+       static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
+
+       buf[1] = (mode ? 'O' : '[');
+       buf[2] = key;
+       puts_queue(vc, buf);
+}
+
+/*
+ * Many other routines do put_queue, but I think either
+ * they produce ASCII, or they produce some user-assigned
+ * string, and in both cases we might assume that it is
+ * in utf-8 already.
+ */
+static void to_utf8(struct vc_data *vc, uint c)
+{
+       if (c < 0x80)
+               /*  0******* */
+               put_queue(vc, c);
+       else if (c < 0x800) {
+               /* 110***** 10****** */
+               put_queue(vc, 0xc0 | (c >> 6));
+               put_queue(vc, 0x80 | (c & 0x3f));
+       } else if (c < 0x10000) {
+               if (c >= 0xD800 && c < 0xE000)
+                       return;
+               if (c == 0xFFFF)
+                       return;
+               /* 1110**** 10****** 10****** */
+               put_queue(vc, 0xe0 | (c >> 12));
+               put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
+               put_queue(vc, 0x80 | (c & 0x3f));
+       } else if (c < 0x110000) {
+               /* 11110*** 10****** 10****** 10****** */
+               put_queue(vc, 0xf0 | (c >> 18));
+               put_queue(vc, 0x80 | ((c >> 12) & 0x3f));
+               put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
+               put_queue(vc, 0x80 | (c & 0x3f));
+       }
+}
+
+/*
+ * Called after returning from RAW mode or when changing consoles - recompute
+ * shift_down[] and shift_state from key_down[] maybe called when keymap is
+ * undefined, so that shiftkey release is seen
+ */
+void compute_shiftstate(void)
+{
+       unsigned int i, j, k, sym, val;
+
+       shift_state = 0;
+       memset(shift_down, 0, sizeof(shift_down));
+
+       for (i = 0; i < ARRAY_SIZE(key_down); i++) {
+
+               if (!key_down[i])
+                       continue;
+
+               k = i * BITS_PER_LONG;
+
+               for (j = 0; j < BITS_PER_LONG; j++, k++) {
+
+                       if (!test_bit(k, key_down))
+                               continue;
+
+                       sym = U(key_maps[0][k]);
+                       if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
+                               continue;
+
+                       val = KVAL(sym);
+                       if (val == KVAL(K_CAPSSHIFT))
+                               val = KVAL(K_SHIFT);
+
+                       shift_down[val]++;
+                       shift_state |= (1 << val);
+               }
+       }
+}
+
+/*
+ * We have a combining character DIACR here, followed by the character CH.
+ * If the combination occurs in the table, return the corresponding value.
+ * Otherwise, if CH is a space or equals DIACR, return DIACR.
+ * Otherwise, conclude that DIACR was not combining after all,
+ * queue it and return CH.
+ */
+static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
+{
+       unsigned int d = diacr;
+       unsigned int i;
+
+       diacr = 0;
+
+       if ((d & ~0xff) == BRL_UC_ROW) {
+               if ((ch & ~0xff) == BRL_UC_ROW)
+                       return d | ch;
+       } else {
+               for (i = 0; i < accent_table_size; i++)
+                       if (accent_table[i].diacr == d && accent_table[i].base == ch)
+                               return accent_table[i].result;
+       }
+
+       if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
+               return d;
+
+       if (kbd->kbdmode == VC_UNICODE)
+               to_utf8(vc, d);
+       else {
+               int c = conv_uni_to_8bit(d);
+               if (c != -1)
+                       put_queue(vc, c);
+       }
+
+       return ch;
+}
+
+/*
+ * Special function handlers
+ */
+static void fn_enter(struct vc_data *vc)
+{
+       if (diacr) {
+               if (kbd->kbdmode == VC_UNICODE)
+                       to_utf8(vc, diacr);
+               else {
+                       int c = conv_uni_to_8bit(diacr);
+                       if (c != -1)
+                               put_queue(vc, c);
+               }
+               diacr = 0;
+       }
+
+       put_queue(vc, 13);
+       if (vc_kbd_mode(kbd, VC_CRLF))
+               put_queue(vc, 10);
+}
+
+static void fn_caps_toggle(struct vc_data *vc)
+{
+       if (rep)
+               return;
+
+       chg_vc_kbd_led(kbd, VC_CAPSLOCK);
+}
+
+static void fn_caps_on(struct vc_data *vc)
+{
+       if (rep)
+               return;
+
+       set_vc_kbd_led(kbd, VC_CAPSLOCK);
+}
+
+static void fn_show_ptregs(struct vc_data *vc)
+{
+       struct pt_regs *regs = get_irq_regs();
+
+       if (regs)
+               show_regs(regs);
+}
+
+static void fn_hold(struct vc_data *vc)
+{
+       struct tty_struct *tty = vc->port.tty;
+
+       if (rep || !tty)
+               return;
+
+       /*
+        * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
+        * these routines are also activated by ^S/^Q.
+        * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
+        */
+       if (tty->stopped)
+               start_tty(tty);
+       else
+               stop_tty(tty);
+}
+
+static void fn_num(struct vc_data *vc)
+{
+       if (vc_kbd_mode(kbd, VC_APPLIC))
+               applkey(vc, 'P', 1);
+       else
+               fn_bare_num(vc);
+}
+
+/*
+ * Bind this to Shift-NumLock if you work in application keypad mode
+ * but want to be able to change the NumLock flag.
+ * Bind this to NumLock if you prefer that the NumLock key always
+ * changes the NumLock flag.
+ */
+static void fn_bare_num(struct vc_data *vc)
+{
+       if (!rep)
+               chg_vc_kbd_led(kbd, VC_NUMLOCK);
+}
+
+static void fn_lastcons(struct vc_data *vc)
+{
+       /* switch to the last used console, ChN */
+       set_console(last_console);
+}
+
+static void fn_dec_console(struct vc_data *vc)
+{
+       int i, cur = fg_console;
+
+       /* Currently switching?  Queue this next switch relative to that. */
+       if (want_console != -1)
+               cur = want_console;
+
+       for (i = cur - 1; i != cur; i--) {
+               if (i == -1)
+                       i = MAX_NR_CONSOLES - 1;
+               if (vc_cons_allocated(i))
+                       break;
+       }
+       set_console(i);
+}
+
+static void fn_inc_console(struct vc_data *vc)
+{
+       int i, cur = fg_console;
+
+       /* Currently switching?  Queue this next switch relative to that. */
+       if (want_console != -1)
+               cur = want_console;
+
+       for (i = cur+1; i != cur; i++) {
+               if (i == MAX_NR_CONSOLES)
+                       i = 0;
+               if (vc_cons_allocated(i))
+                       break;
+       }
+       set_console(i);
+}
+
+static void fn_send_intr(struct vc_data *vc)
+{
+       struct tty_struct *tty = vc->port.tty;
+
+       if (!tty)
+               return;
+       tty_insert_flip_char(tty, 0, TTY_BREAK);
+       con_schedule_flip(tty);
+}
+
+static void fn_scroll_forw(struct vc_data *vc)
+{
+       scrollfront(vc, 0);
+}
+
+static void fn_scroll_back(struct vc_data *vc)
+{
+       scrollback(vc, 0);
+}
+
+static void fn_show_mem(struct vc_data *vc)
+{
+       show_mem();
+}
+
+static void fn_show_state(struct vc_data *vc)
+{
+       show_state();
+}
+
+static void fn_boot_it(struct vc_data *vc)
+{
+       ctrl_alt_del();
+}
+
+static void fn_compose(struct vc_data *vc)
+{
+       dead_key_next = true;
+}
+
+static void fn_spawn_con(struct vc_data *vc)
+{
+       spin_lock(&vt_spawn_con.lock);
+       if (vt_spawn_con.pid)
+               if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
+                       put_pid(vt_spawn_con.pid);
+                       vt_spawn_con.pid = NULL;
+               }
+       spin_unlock(&vt_spawn_con.lock);
+}
+
+static void fn_SAK(struct vc_data *vc)
+{
+       struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
+       schedule_work(SAK_work);
+}
+
+static void fn_null(struct vc_data *vc)
+{
+       compute_shiftstate();
+}
+
+/*
+ * Special key handlers
+ */
+static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag)
+{
+}
+
+static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       if (up_flag)
+               return;
+       if (value >= ARRAY_SIZE(fn_handler))
+               return;
+       if ((kbd->kbdmode == VC_RAW ||
+            kbd->kbdmode == VC_MEDIUMRAW) &&
+            value != KVAL(K_SAK))
+               return;         /* SAK is allowed even in raw mode */
+       fn_handler[value](vc);
+}
+
+static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       pr_err("k_lowercase was called - impossible\n");
+}
+
+static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
+{
+       if (up_flag)
+               return;         /* no action, if this is a key release */
+
+       if (diacr)
+               value = handle_diacr(vc, value);
+
+       if (dead_key_next) {
+               dead_key_next = false;
+               diacr = value;
+               return;
+       }
+       if (kbd->kbdmode == VC_UNICODE)
+               to_utf8(vc, value);
+       else {
+               int c = conv_uni_to_8bit(value);
+               if (c != -1)
+                       put_queue(vc, c);
+       }
+}
+
+/*
+ * Handle dead key. Note that we now may have several
+ * dead keys modifying the same character. Very useful
+ * for Vietnamese.
+ */
+static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
+{
+       if (up_flag)
+               return;
+
+       diacr = (diacr ? handle_diacr(vc, value) : value);
+}
+
+static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       k_unicode(vc, conv_8bit_to_uni(value), up_flag);
+}
+
+static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       k_deadunicode(vc, value, up_flag);
+}
+
+/*
+ * Obsolete - for backwards compatibility only
+ */
+static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
+
+       k_deadunicode(vc, ret_diacr[value], up_flag);
+}
+
+static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       if (up_flag)
+               return;
+
+       set_console(value);
+}
+
+static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       if (up_flag)
+               return;
+
+       if ((unsigned)value < ARRAY_SIZE(func_table)) {
+               if (func_table[value])
+                       puts_queue(vc, func_table[value]);
+       } else
+               pr_err("k_fn called with value=%d\n", value);
+}
+
+static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       static const char cur_chars[] = "BDCA";
+
+       if (up_flag)
+               return;
+
+       applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
+}
+
+static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       static const char pad_chars[] = "0123456789+-*/\015,.?()#";
+       static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
+
+       if (up_flag)
+               return;         /* no action, if this is a key release */
+
+       /* kludge... shift forces cursor/number keys */
+       if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) {
+               applkey(vc, app_map[value], 1);
+               return;
+       }
+
+       if (!vc_kbd_led(kbd, VC_NUMLOCK)) {
+
+               switch (value) {
+               case KVAL(K_PCOMMA):
+               case KVAL(K_PDOT):
+                       k_fn(vc, KVAL(K_REMOVE), 0);
+                       return;
+               case KVAL(K_P0):
+                       k_fn(vc, KVAL(K_INSERT), 0);
+                       return;
+               case KVAL(K_P1):
+                       k_fn(vc, KVAL(K_SELECT), 0);
+                       return;
+               case KVAL(K_P2):
+                       k_cur(vc, KVAL(K_DOWN), 0);
+                       return;
+               case KVAL(K_P3):
+                       k_fn(vc, KVAL(K_PGDN), 0);
+                       return;
+               case KVAL(K_P4):
+                       k_cur(vc, KVAL(K_LEFT), 0);
+                       return;
+               case KVAL(K_P6):
+                       k_cur(vc, KVAL(K_RIGHT), 0);
+                       return;
+               case KVAL(K_P7):
+                       k_fn(vc, KVAL(K_FIND), 0);
+                       return;
+               case KVAL(K_P8):
+                       k_cur(vc, KVAL(K_UP), 0);
+                       return;
+               case KVAL(K_P9):
+                       k_fn(vc, KVAL(K_PGUP), 0);
+                       return;
+               case KVAL(K_P5):
+                       applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
+                       return;
+               }
+       }
+
+       put_queue(vc, pad_chars[value]);
+       if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
+               put_queue(vc, 10);
+}
+
+static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       int old_state = shift_state;
+
+       if (rep)
+               return;
+       /*
+        * Mimic typewriter:
+        * a CapsShift key acts like Shift but undoes CapsLock
+        */
+       if (value == KVAL(K_CAPSSHIFT)) {
+               value = KVAL(K_SHIFT);
+               if (!up_flag)
+                       clr_vc_kbd_led(kbd, VC_CAPSLOCK);
+       }
+
+       if (up_flag) {
+               /*
+                * handle the case that two shift or control
+                * keys are depressed simultaneously
+                */
+               if (shift_down[value])
+                       shift_down[value]--;
+       } else
+               shift_down[value]++;
+
+       if (shift_down[value])
+               shift_state |= (1 << value);
+       else
+               shift_state &= ~(1 << value);
+
+       /* kludge */
+       if (up_flag && shift_state != old_state && npadch != -1) {
+               if (kbd->kbdmode == VC_UNICODE)
+                       to_utf8(vc, npadch);
+               else
+                       put_queue(vc, npadch & 0xff);
+               npadch = -1;
+       }
+}
+
+static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       if (up_flag)
+               return;
+
+       if (vc_kbd_mode(kbd, VC_META)) {
+               put_queue(vc, '\033');
+               put_queue(vc, value);
+       } else
+               put_queue(vc, value | 0x80);
+}
+
+static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       int base;
+
+       if (up_flag)
+               return;
+
+       if (value < 10) {
+               /* decimal input of code, while Alt depressed */
+               base = 10;
+       } else {
+               /* hexadecimal input of code, while AltGr depressed */
+               value -= 10;
+               base = 16;
+       }
+
+       if (npadch == -1)
+               npadch = value;
+       else
+               npadch = npadch * base + value;
+}
+
+static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       if (up_flag || rep)
+               return;
+
+       chg_vc_kbd_lock(kbd, value);
+}
+
+static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       k_shift(vc, value, up_flag);
+       if (up_flag || rep)
+               return;
+
+       chg_vc_kbd_slock(kbd, value);
+       /* try to make Alt, oops, AltGr and such work */
+       if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
+               kbd->slockstate = 0;
+               chg_vc_kbd_slock(kbd, value);
+       }
+}
+
+/* by default, 300ms interval for combination release */
+static unsigned brl_timeout = 300;
+MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");
+module_param(brl_timeout, uint, 0644);
+
+static unsigned brl_nbchords = 1;
+MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
+module_param(brl_nbchords, uint, 0644);
+
+static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag)
+{
+       static unsigned long chords;
+       static unsigned committed;
+
+       if (!brl_nbchords)
+               k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag);
+       else {
+               committed |= pattern;
+               chords++;
+               if (chords == brl_nbchords) {
+                       k_unicode(vc, BRL_UC_ROW | committed, up_flag);
+                       chords = 0;
+                       committed = 0;
+               }
+       }
+}
+
+static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
+{
+       static unsigned pressed, committing;
+       static unsigned long releasestart;
+
+       if (kbd->kbdmode != VC_UNICODE) {
+               if (!up_flag)
+                       pr_warning("keyboard mode must be unicode for braille patterns\n");
+               return;
+       }
+
+       if (!value) {
+               k_unicode(vc, BRL_UC_ROW, up_flag);
+               return;
+       }
+
+       if (value > 8)
+               return;
+
+       if (!up_flag) {
+               pressed |= 1 << (value - 1);
+               if (!brl_timeout)
+                       committing = pressed;
+       } else if (brl_timeout) {
+               if (!committing ||
+                   time_after(jiffies,
+                              releasestart + msecs_to_jiffies(brl_timeout))) {
+                       committing = pressed;
+                       releasestart = jiffies;
+               }
+               pressed &= ~(1 << (value - 1));
+               if (!pressed && committing) {
+                       k_brlcommit(vc, committing, 0);
+                       committing = 0;
+               }
+       } else {
+               if (committing) {
+                       k_brlcommit(vc, committing, 0);
+                       committing = 0;
+               }
+               pressed &= ~(1 << (value - 1));
+       }
+}
+
+/*
+ * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
+ * or (ii) whatever pattern of lights people want to show using KDSETLED,
+ * or (iii) specified bits of specified words in kernel memory.
+ */
+unsigned char getledstate(void)
+{
+       return ledstate;
+}
+
+void setledstate(struct kbd_struct *kbd, unsigned int led)
+{
+       if (!(led & ~7)) {
+               ledioctl = led;
+               kbd->ledmode = LED_SHOW_IOCTL;
+       } else
+               kbd->ledmode = LED_SHOW_FLAGS;
+
+       set_leds();
+}
+
+static inline unsigned char getleds(void)
+{
+       struct kbd_struct *kbd = kbd_table + fg_console;
+       unsigned char leds;
+       int i;
+
+       if (kbd->ledmode == LED_SHOW_IOCTL)
+               return ledioctl;
+
+       leds = kbd->ledflagstate;
+
+       if (kbd->ledmode == LED_SHOW_MEM) {
+               for (i = 0; i < 3; i++)
+                       if (ledptrs[i].valid) {
+                               if (*ledptrs[i].addr & ledptrs[i].mask)
+                                       leds |= (1 << i);
+                               else
+                                       leds &= ~(1 << i);
+                       }
+       }
+       return leds;
+}
+
+static int kbd_update_leds_helper(struct input_handle *handle, void *data)
+{
+       unsigned char leds = *(unsigned char *)data;
+
+       if (test_bit(EV_LED, handle->dev->evbit)) {
+               input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
+               input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
+               input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
+               input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
+       }
+
+       return 0;
+}
+
+/*
+ * This is the tasklet that updates LED state on all keyboards
+ * attached to the box. The reason we use tasklet is that we
+ * need to handle the scenario when keyboard handler is not
+ * registered yet but we already getting updates form VT to
+ * update led state.
+ */
+static void kbd_bh(unsigned long dummy)
+{
+       unsigned char leds = getleds();
+
+       if (leds != ledstate) {
+               input_handler_for_each_handle(&kbd_handler, &leds,
+                                             kbd_update_leds_helper);
+               ledstate = leds;
+       }
+}
+
+DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
+
+#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
+    defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
+    defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
+    (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) ||\
+    defined(CONFIG_AVR32)
+
+#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
+                       ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
+
+static const unsigned short x86_keycodes[256] =
+       { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+        64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+        80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92,
+       284,285,309,  0,312, 91,327,328,329,331,333,335,336,337,338,339,
+       367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
+       360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
+       103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
+       291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
+       264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
+       377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
+       308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
+       332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
+
+#ifdef CONFIG_SPARC
+static int sparc_l1_a_state;
+extern void sun_do_break(void);
+#endif
+
+static int emulate_raw(struct vc_data *vc, unsigned int keycode,
+                      unsigned char up_flag)
+{
+       int code;
+
+       switch (keycode) {
+
+       case KEY_PAUSE:
+               put_queue(vc, 0xe1);
+               put_queue(vc, 0x1d | up_flag);
+               put_queue(vc, 0x45 | up_flag);
+               break;
+
+       case KEY_HANGEUL:
+               if (!up_flag)
+                       put_queue(vc, 0xf2);
+               break;
+
+       case KEY_HANJA:
+               if (!up_flag)
+                       put_queue(vc, 0xf1);
+               break;
+
+       case KEY_SYSRQ:
+               /*
+                * Real AT keyboards (that's what we're trying
+                * to emulate here emit 0xe0 0x2a 0xe0 0x37 when
+                * pressing PrtSc/SysRq alone, but simply 0x54
+                * when pressing Alt+PrtSc/SysRq.
+                */
+               if (test_bit(KEY_LEFTALT, key_down) ||
+                   test_bit(KEY_RIGHTALT, key_down)) {
+                       put_queue(vc, 0x54 | up_flag);
+               } else {
+                       put_queue(vc, 0xe0);
+                       put_queue(vc, 0x2a | up_flag);
+                       put_queue(vc, 0xe0);
+                       put_queue(vc, 0x37 | up_flag);
+               }
+               break;
+
+       default:
+               if (keycode > 255)
+                       return -1;
+
+               code = x86_keycodes[keycode];
+               if (!code)
+                       return -1;
+
+               if (code & 0x100)
+                       put_queue(vc, 0xe0);
+               put_queue(vc, (code & 0x7f) | up_flag);
+
+               break;
+       }
+
+       return 0;
+}
+
+#else
+
+#define HW_RAW(dev)    0
+
+static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
+{
+       if (keycode > 127)
+               return -1;
+
+       put_queue(vc, keycode | up_flag);
+       return 0;
+}
+#endif
+
+static void kbd_rawcode(unsigned char data)
+{
+       struct vc_data *vc = vc_cons[fg_console].d;
+
+       kbd = kbd_table + vc->vc_num;
+       if (kbd->kbdmode == VC_RAW)
+               put_queue(vc, data);
+}
+
+static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
+{
+       struct vc_data *vc = vc_cons[fg_console].d;
+       unsigned short keysym, *key_map;
+       unsigned char type;
+       bool raw_mode;
+       struct tty_struct *tty;
+       int shift_final;
+       struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
+       int rc;
+
+       tty = vc->port.tty;
+
+       if (tty && (!tty->driver_data)) {
+               /* No driver data? Strange. Okay we fix it then. */
+               tty->driver_data = vc;
+       }
+
+       kbd = kbd_table + vc->vc_num;
+
+#ifdef CONFIG_SPARC
+       if (keycode == KEY_STOP)
+               sparc_l1_a_state = down;
+#endif
+
+       rep = (down == 2);
+
+       raw_mode = (kbd->kbdmode == VC_RAW);
+       if (raw_mode && !hw_raw)
+               if (emulate_raw(vc, keycode, !down << 7))
+                       if (keycode < BTN_MISC && printk_ratelimit())
+                               pr_warning("can't emulate rawmode for keycode %d\n",
+                                          keycode);
+
+#ifdef CONFIG_SPARC
+       if (keycode == KEY_A && sparc_l1_a_state) {
+               sparc_l1_a_state = false;
+               sun_do_break();
+       }
+#endif
+
+       if (kbd->kbdmode == VC_MEDIUMRAW) {
+               /*
+                * This is extended medium raw mode, with keys above 127
+                * encoded as 0, high 7 bits, low 7 bits, with the 0 bearing
+                * the 'up' flag if needed. 0 is reserved, so this shouldn't
+                * interfere with anything else. The two bytes after 0 will
+                * always have the up flag set not to interfere with older
+                * applications. This allows for 16384 different keycodes,
+                * which should be enough.
+                */
+               if (keycode < 128) {
+                       put_queue(vc, keycode | (!down << 7));
+               } else {
+                       put_queue(vc, !down << 7);
+                       put_queue(vc, (keycode >> 7) | 0x80);
+                       put_queue(vc, keycode | 0x80);
+               }
+               raw_mode = true;
+       }
+
+       if (down)
+               set_bit(keycode, key_down);
+       else
+               clear_bit(keycode, key_down);
+
+       if (rep &&
+           (!vc_kbd_mode(kbd, VC_REPEAT) ||
+            (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) {
+               /*
+                * Don't repeat a key if the input buffers are not empty and the
+                * characters get aren't echoed locally. This makes key repeat
+                * usable with slow applications and under heavy loads.
+                */
+               return;
+       }
+
+       param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
+       param.ledstate = kbd->ledflagstate;
+       key_map = key_maps[shift_final];
+
+       rc = atomic_notifier_call_chain(&keyboard_notifier_list,
+                                       KBD_KEYCODE, &param);
+       if (rc == NOTIFY_STOP || !key_map) {
+               atomic_notifier_call_chain(&keyboard_notifier_list,
+                                          KBD_UNBOUND_KEYCODE, &param);
+               compute_shiftstate();
+               kbd->slockstate = 0;
+               return;
+       }
+
+       if (keycode < NR_KEYS)
+               keysym = key_map[keycode];
+       else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
+               keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
+       else
+               return;
+
+       type = KTYP(keysym);
+
+       if (type < 0xf0) {
+               param.value = keysym;
+               rc = atomic_notifier_call_chain(&keyboard_notifier_list,
+                                               KBD_UNICODE, &param);
+               if (rc != NOTIFY_STOP)
+                       if (down && !raw_mode)
+                               to_utf8(vc, keysym);
+               return;
+       }
+
+       type -= 0xf0;
+
+       if (type == KT_LETTER) {
+               type = KT_LATIN;
+               if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
+                       key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
+                       if (key_map)
+                               keysym = key_map[keycode];
+               }
+       }
+
+       param.value = keysym;
+       rc = atomic_notifier_call_chain(&keyboard_notifier_list,
+                                       KBD_KEYSYM, &param);
+       if (rc == NOTIFY_STOP)
+               return;
+
+       if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
+               return;
+
+       (*k_handler[type])(vc, keysym & 0xff, !down);
+
+       param.ledstate = kbd->ledflagstate;
+       atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, &param);
+
+       if (type != KT_SLOCK)
+               kbd->slockstate = 0;
+}
+
+static void kbd_event(struct input_handle *handle, unsigned int event_type,
+                     unsigned int event_code, int value)
+{
+       /* We are called with interrupts disabled, just take the lock */
+       spin_lock(&kbd_event_lock);
+
+       if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
+               kbd_rawcode(value);
+       if (event_type == EV_KEY)
+               kbd_keycode(event_code, value, HW_RAW(handle->dev));
+
+       spin_unlock(&kbd_event_lock);
+
+       tasklet_schedule(&keyboard_tasklet);
+       do_poke_blanked_console = 1;
+       schedule_console_callback();
+}
+
+static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
+{
+       int i;
+
+       if (test_bit(EV_SND, dev->evbit))
+               return true;
+
+       if (test_bit(EV_KEY, dev->evbit)) {
+               for (i = KEY_RESERVED; i < BTN_MISC; i++)
+                       if (test_bit(i, dev->keybit))
+                               return true;
+               for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
+                       if (test_bit(i, dev->keybit))
+                               return true;
+       }
+
+       return false;
+}
+
+/*
+ * When a keyboard (or other input device) is found, the kbd_connect
+ * function is called. The function then looks at the device, and if it
+ * likes it, it can open it and get events from it. In this (kbd_connect)
+ * function, we should decide which VT to bind that keyboard to initially.
+ */
+static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
+                       const struct input_device_id *id)
+{
+       struct input_handle *handle;
+       int error;
+
+       handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+       if (!handle)
+               return -ENOMEM;
+
+       handle->dev = dev;
+       handle->handler = handler;
+       handle->name = "kbd";
+
+       error = input_register_handle(handle);
+       if (error)
+               goto err_free_handle;
+
+       error = input_open_device(handle);
+       if (error)
+               goto err_unregister_handle;
+
+       return 0;
+
+ err_unregister_handle:
+       input_unregister_handle(handle);
+ err_free_handle:
+       kfree(handle);
+       return error;
+}
+
+static void kbd_disconnect(struct input_handle *handle)
+{
+       input_close_device(handle);
+       input_unregister_handle(handle);
+       kfree(handle);
+}
+
+/*
+ * Start keyboard handler on the new keyboard by refreshing LED state to
+ * match the rest of the system.
+ */
+static void kbd_start(struct input_handle *handle)
+{
+       tasklet_disable(&keyboard_tasklet);
+
+       if (ledstate != 0xff)
+               kbd_update_leds_helper(handle, &ledstate);
+
+       tasklet_enable(&keyboard_tasklet);
+}
+
+static const struct input_device_id kbd_ids[] = {
+       {
+                .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+                .evbit = { BIT_MASK(EV_KEY) },
+        },
+
+       {
+                .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+                .evbit = { BIT_MASK(EV_SND) },
+        },
+
+       { },    /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(input, kbd_ids);
+
+static struct input_handler kbd_handler = {
+       .event          = kbd_event,
+       .match          = kbd_match,
+       .connect        = kbd_connect,
+       .disconnect     = kbd_disconnect,
+       .start          = kbd_start,
+       .name           = "kbd",
+       .id_table       = kbd_ids,
+};
+
+int __init kbd_init(void)
+{
+       int i;
+       int error;
+
+        for (i = 0; i < MAX_NR_CONSOLES; i++) {
+               kbd_table[i].ledflagstate = KBD_DEFLEDS;
+               kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
+               kbd_table[i].ledmode = LED_SHOW_FLAGS;
+               kbd_table[i].lockstate = KBD_DEFLOCK;
+               kbd_table[i].slockstate = 0;
+               kbd_table[i].modeflags = KBD_DEFMODE;
+               kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
+       }
+
+       error = input_register_handler(&kbd_handler);
+       if (error)
+               return error;
+
+       tasklet_enable(&keyboard_tasklet);
+       tasklet_schedule(&keyboard_tasklet);
+
+       return 0;
+}
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
new file mode 100644 (file)
index 0000000..ebae344
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * linux/drivers/char/selection.c
+ *
+ * This module exports the functions:
+ *
+ *     'int set_selection(struct tiocl_selection __user *, struct tty_struct *)'
+ *     'void clear_selection(void)'
+ *     'int paste_selection(struct tty_struct *)'
+ *     'int sel_loadlut(char __user *)'
+ *
+ * Now that /dev/vcs exists, most of this can disappear again.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <asm/uaccess.h>
+
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
+#include <linux/selection.h>
+#include <linux/tiocl.h>
+#include <linux/console.h>
+#include <linux/smp_lock.h>
+
+/* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */
+#define isspace(c)     ((c) == ' ')
+
+extern void poke_blanked_console(void);
+
+/* Variables for selection control. */
+/* Use a dynamic buffer, instead of static (Dec 1994) */
+struct vc_data *sel_cons;              /* must not be deallocated */
+static int use_unicode;
+static volatile int sel_start = -1;    /* cleared by clear_selection */
+static int sel_end;
+static int sel_buffer_lth;
+static char *sel_buffer;
+
+/* clear_selection, highlight and highlight_pointer can be called
+   from interrupt (via scrollback/front) */
+
+/* set reverse video on characters s-e of console with selection. */
+static inline void highlight(const int s, const int e)
+{
+       invert_screen(sel_cons, s, e-s+2, 1);
+}
+
+/* use complementary color to show the pointer */
+static inline void highlight_pointer(const int where)
+{
+       complement_pos(sel_cons, where);
+}
+
+static u16
+sel_pos(int n)
+{
+       return inverse_translate(sel_cons, screen_glyph(sel_cons, n),
+                               use_unicode);
+}
+
+/* remove the current selection highlight, if any,
+   from the console holding the selection. */
+void
+clear_selection(void) {
+       highlight_pointer(-1); /* hide the pointer */
+       if (sel_start != -1) {
+               highlight(sel_start, sel_end);
+               sel_start = -1;
+       }
+}
+
+/*
+ * User settable table: what characters are to be considered alphabetic?
+ * 256 bits
+ */
+static u32 inwordLut[8]={
+  0x00000000, /* control chars     */
+  0x03FF0000, /* digits            */
+  0x87FFFFFE, /* uppercase and '_' */
+  0x07FFFFFE, /* lowercase         */
+  0x00000000,
+  0x00000000,
+  0xFF7FFFFF, /* latin-1 accented letters, not multiplication sign */
+  0xFF7FFFFF  /* latin-1 accented letters, not division sign */
+};
+
+static inline int inword(const u16 c) {
+       return c > 0xff || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1);
+}
+
+/* set inwordLut contents. Invoked by ioctl(). */
+int sel_loadlut(char __user *p)
+{
+       return copy_from_user(inwordLut, (u32 __user *)(p+4), 32) ? -EFAULT : 0;
+}
+
+/* does screen address p correspond to character at LH/RH edge of screen? */
+static inline int atedge(const int p, int size_row)
+{
+       return (!(p % size_row) || !((p + 2) % size_row));
+}
+
+/* constrain v such that v <= u */
+static inline unsigned short limit(const unsigned short v, const unsigned short u)
+{
+       return (v > u) ? u : v;
+}
+
+/* stores the char in UTF8 and returns the number of bytes used (1-3) */
+static int store_utf8(u16 c, char *p)
+{
+       if (c < 0x80) {
+               /*  0******* */
+               p[0] = c;
+               return 1;
+       } else if (c < 0x800) {
+               /* 110***** 10****** */
+               p[0] = 0xc0 | (c >> 6);
+               p[1] = 0x80 | (c & 0x3f);
+               return 2;
+       } else {
+               /* 1110**** 10****** 10****** */
+               p[0] = 0xe0 | (c >> 12);
+               p[1] = 0x80 | ((c >> 6) & 0x3f);
+               p[2] = 0x80 | (c & 0x3f);
+               return 3;
+       }
+}
+
+/* set the current selection. Invoked by ioctl() or by kernel code. */
+int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
+{
+       struct vc_data *vc = vc_cons[fg_console].d;
+       int sel_mode, new_sel_start, new_sel_end, spc;
+       char *bp, *obp;
+       int i, ps, pe, multiplier;
+       u16 c;
+       struct kbd_struct *kbd = kbd_table + fg_console;
+
+       poke_blanked_console();
+
+       { unsigned short xs, ys, xe, ye;
+
+         if (!access_ok(VERIFY_READ, sel, sizeof(*sel)))
+               return -EFAULT;
+         __get_user(xs, &sel->xs);
+         __get_user(ys, &sel->ys);
+         __get_user(xe, &sel->xe);
+         __get_user(ye, &sel->ye);
+         __get_user(sel_mode, &sel->sel_mode);
+         xs--; ys--; xe--; ye--;
+         xs = limit(xs, vc->vc_cols - 1);
+         ys = limit(ys, vc->vc_rows - 1);
+         xe = limit(xe, vc->vc_cols - 1);
+         ye = limit(ye, vc->vc_rows - 1);
+         ps = ys * vc->vc_size_row + (xs << 1);
+         pe = ye * vc->vc_size_row + (xe << 1);
+
+         if (sel_mode == TIOCL_SELCLEAR) {
+             /* useful for screendump without selection highlights */
+             clear_selection();
+             return 0;
+         }
+
+         if (mouse_reporting() && (sel_mode & TIOCL_SELMOUSEREPORT)) {
+             mouse_report(tty, sel_mode & TIOCL_SELBUTTONMASK, xs, ys);
+             return 0;
+         }
+        }
+
+       if (ps > pe)    /* make sel_start <= sel_end */
+       {
+               int tmp = ps;
+               ps = pe;
+               pe = tmp;
+       }
+
+       if (sel_cons != vc_cons[fg_console].d) {
+               clear_selection();
+               sel_cons = vc_cons[fg_console].d;
+       }
+       use_unicode = kbd && kbd->kbdmode == VC_UNICODE;
+
+       switch (sel_mode)
+       {
+               case TIOCL_SELCHAR:     /* character-by-character selection */
+                       new_sel_start = ps;
+                       new_sel_end = pe;
+                       break;
+               case TIOCL_SELWORD:     /* word-by-word selection */
+                       spc = isspace(sel_pos(ps));
+                       for (new_sel_start = ps; ; ps -= 2)
+                       {
+                               if ((spc && !isspace(sel_pos(ps))) ||
+                                   (!spc && !inword(sel_pos(ps))))
+                                       break;
+                               new_sel_start = ps;
+                               if (!(ps % vc->vc_size_row))
+                                       break;
+                       }
+                       spc = isspace(sel_pos(pe));
+                       for (new_sel_end = pe; ; pe += 2)
+                       {
+                               if ((spc && !isspace(sel_pos(pe))) ||
+                                   (!spc && !inword(sel_pos(pe))))
+                                       break;
+                               new_sel_end = pe;
+                               if (!((pe + 2) % vc->vc_size_row))
+                                       break;
+                       }
+                       break;
+               case TIOCL_SELLINE:     /* line-by-line selection */
+                       new_sel_start = ps - ps % vc->vc_size_row;
+                       new_sel_end = pe + vc->vc_size_row
+                                   - pe % vc->vc_size_row - 2;
+                       break;
+               case TIOCL_SELPOINTER:
+                       highlight_pointer(pe);
+                       return 0;
+               default:
+                       return -EINVAL;
+       }
+
+       /* remove the pointer */
+       highlight_pointer(-1);
+
+       /* select to end of line if on trailing space */
+       if (new_sel_end > new_sel_start &&
+               !atedge(new_sel_end, vc->vc_size_row) &&
+               isspace(sel_pos(new_sel_end))) {
+               for (pe = new_sel_end + 2; ; pe += 2)
+                       if (!isspace(sel_pos(pe)) ||
+                           atedge(pe, vc->vc_size_row))
+                               break;
+               if (isspace(sel_pos(pe)))
+                       new_sel_end = pe;
+       }
+       if (sel_start == -1)    /* no current selection */
+               highlight(new_sel_start, new_sel_end);
+       else if (new_sel_start == sel_start)
+       {
+               if (new_sel_end == sel_end)     /* no action required */
+                       return 0;
+               else if (new_sel_end > sel_end) /* extend to right */
+                       highlight(sel_end + 2, new_sel_end);
+               else                            /* contract from right */
+                       highlight(new_sel_end + 2, sel_end);
+       }
+       else if (new_sel_end == sel_end)
+       {
+               if (new_sel_start < sel_start)  /* extend to left */
+                       highlight(new_sel_start, sel_start - 2);
+               else                            /* contract from left */
+                       highlight(sel_start, new_sel_start - 2);
+       }
+       else    /* some other case; start selection from scratch */
+       {
+               clear_selection();
+               highlight(new_sel_start, new_sel_end);
+       }
+       sel_start = new_sel_start;
+       sel_end = new_sel_end;
+
+       /* Allocate a new buffer before freeing the old one ... */
+       multiplier = use_unicode ? 3 : 1;  /* chars can take up to 3 bytes */
+       bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL);
+       if (!bp) {
+               printk(KERN_WARNING "selection: kmalloc() failed\n");
+               clear_selection();
+               return -ENOMEM;
+       }
+       kfree(sel_buffer);
+       sel_buffer = bp;
+
+       obp = bp;
+       for (i = sel_start; i <= sel_end; i += 2) {
+               c = sel_pos(i);
+               if (use_unicode)
+                       bp += store_utf8(c, bp);
+               else
+                       *bp++ = c;
+               if (!isspace(c))
+                       obp = bp;
+               if (! ((i + 2) % vc->vc_size_row)) {
+                       /* strip trailing blanks from line and add newline,
+                          unless non-space at end of line. */
+                       if (obp != bp) {
+                               bp = obp;
+                               *bp++ = '\r';
+                       }
+                       obp = bp;
+               }
+       }
+       sel_buffer_lth = bp - sel_buffer;
+       return 0;
+}
+
+/* Insert the contents of the selection buffer into the
+ * queue of the tty associated with the current console.
+ * Invoked by ioctl().
+ */
+int paste_selection(struct tty_struct *tty)
+{
+       struct vc_data *vc = tty->driver_data;
+       int     pasted = 0;
+       unsigned int count;
+       struct  tty_ldisc *ld;
+       DECLARE_WAITQUEUE(wait, current);
+
+       /* always called with BTM from vt_ioctl */
+       WARN_ON(!tty_locked());
+
+       acquire_console_sem();
+       poke_blanked_console();
+       release_console_sem();
+
+       ld = tty_ldisc_ref(tty);
+       if (!ld) {
+               tty_unlock();
+               ld = tty_ldisc_ref_wait(tty);
+               tty_lock();
+       }
+
+       add_wait_queue(&vc->paste_wait, &wait);
+       while (sel_buffer && sel_buffer_lth > pasted) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (test_bit(TTY_THROTTLED, &tty->flags)) {
+                       schedule();
+                       continue;
+               }
+               count = sel_buffer_lth - pasted;
+               count = min(count, tty->receive_room);
+               tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
+                                                               NULL, count);
+               pasted += count;
+       }
+       remove_wait_queue(&vc->paste_wait, &wait);
+       __set_current_state(TASK_RUNNING);
+
+       tty_ldisc_deref(ld);
+       return 0;
+}
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
new file mode 100644 (file)
index 0000000..eab3a1f
--- /dev/null
@@ -0,0 +1,644 @@
+/*
+ * linux/drivers/char/vc_screen.c
+ *
+ * Provide access to virtual console memory.
+ * /dev/vcs0: the screen as it is being viewed right now (possibly scrolled)
+ * /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63)
+ *            [minor: N]
+ *
+ * /dev/vcsaN: idem, but including attributes, and prefixed with
+ *     the 4 bytes lines,columns,x,y (as screendump used to give).
+ *     Attribute/character pair is in native endianity.
+ *            [minor: N+128]
+ *
+ * This replaces screendump and part of selection, so that the system
+ * administrator can control access using file system permissions.
+ *
+ * aeb@cwi.nl - efter Friedas begravelse - 950211
+ *
+ * machek@k332.feld.cvut.cz - modified not to send characters to wrong console
+ *      - fixed some fatal off-by-one bugs (0-- no longer == -1 -> looping and looping and looping...)
+ *      - making it shorter - scr_readw are macros which expand in PRETTY long code
+ */
+
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/kbd_kern.h>
+#include <linux/console.h>
+#include <linux/device.h>
+#include <linux/smp_lock.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/notifier.h>
+
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
+
+#undef attr
+#undef org
+#undef addr
+#define HEADER_SIZE    4
+
+struct vcs_poll_data {
+       struct notifier_block notifier;
+       unsigned int cons_num;
+       bool seen_last_update;
+       wait_queue_head_t waitq;
+       struct fasync_struct *fasync;
+};
+
+static int
+vcs_notifier(struct notifier_block *nb, unsigned long code, void *_param)
+{
+       struct vt_notifier_param *param = _param;
+       struct vc_data *vc = param->vc;
+       struct vcs_poll_data *poll =
+               container_of(nb, struct vcs_poll_data, notifier);
+       int currcons = poll->cons_num;
+
+       if (code != VT_UPDATE)
+               return NOTIFY_DONE;
+
+       if (currcons == 0)
+               currcons = fg_console;
+       else
+               currcons--;
+       if (currcons != vc->vc_num)
+               return NOTIFY_DONE;
+
+       poll->seen_last_update = false;
+       wake_up_interruptible(&poll->waitq);
+       kill_fasync(&poll->fasync, SIGIO, POLL_IN);
+       return NOTIFY_OK;
+}
+
+static void
+vcs_poll_data_free(struct vcs_poll_data *poll)
+{
+       unregister_vt_notifier(&poll->notifier);
+       kfree(poll);
+}
+
+static struct vcs_poll_data *
+vcs_poll_data_get(struct file *file)
+{
+       struct vcs_poll_data *poll = file->private_data;
+
+       if (poll)
+               return poll;
+
+       poll = kzalloc(sizeof(*poll), GFP_KERNEL);
+       if (!poll)
+               return NULL;
+       poll->cons_num = iminor(file->f_path.dentry->d_inode) & 127;
+       init_waitqueue_head(&poll->waitq);
+       poll->notifier.notifier_call = vcs_notifier;
+       if (register_vt_notifier(&poll->notifier) != 0) {
+               kfree(poll);
+               return NULL;
+       }
+
+       /*
+        * This code may be called either through ->poll() or ->fasync().
+        * If we have two threads using the same file descriptor, they could
+        * both enter this function, both notice that the structure hasn't
+        * been allocated yet and go ahead allocating it in parallel, but
+        * only one of them must survive and be shared otherwise we'd leak
+        * memory with a dangling notifier callback.
+        */
+       spin_lock(&file->f_lock);
+       if (!file->private_data) {
+               file->private_data = poll;
+       } else {
+               /* someone else raced ahead of us */
+               vcs_poll_data_free(poll);
+               poll = file->private_data;
+       }
+       spin_unlock(&file->f_lock);
+
+       return poll;
+}
+
+static int
+vcs_size(struct inode *inode)
+{
+       int size;
+       int minor = iminor(inode);
+       int currcons = minor & 127;
+       struct vc_data *vc;
+
+       if (currcons == 0)
+               currcons = fg_console;
+       else
+               currcons--;
+       if (!vc_cons_allocated(currcons))
+               return -ENXIO;
+       vc = vc_cons[currcons].d;
+
+       size = vc->vc_rows * vc->vc_cols;
+
+       if (minor & 128)
+               size = 2*size + HEADER_SIZE;
+       return size;
+}
+
+static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
+{
+       int size;
+
+       mutex_lock(&con_buf_mtx);
+       size = vcs_size(file->f_path.dentry->d_inode);
+       switch (orig) {
+               default:
+                       mutex_unlock(&con_buf_mtx);
+                       return -EINVAL;
+               case 2:
+                       offset += size;
+                       break;
+               case 1:
+                       offset += file->f_pos;
+               case 0:
+                       break;
+       }
+       if (offset < 0 || offset > size) {
+               mutex_unlock(&con_buf_mtx);
+               return -EINVAL;
+       }
+       file->f_pos = offset;
+       mutex_unlock(&con_buf_mtx);
+       return file->f_pos;
+}
+
+
+static ssize_t
+vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+       struct inode *inode = file->f_path.dentry->d_inode;
+       unsigned int currcons = iminor(inode);
+       struct vc_data *vc;
+       struct vcs_poll_data *poll;
+       long pos;
+       long viewed, attr, read;
+       int col, maxcol;
+       unsigned short *org = NULL;
+       ssize_t ret;
+
+       mutex_lock(&con_buf_mtx);
+
+       pos = *ppos;
+
+       /* Select the proper current console and verify
+        * sanity of the situation under the console lock.
+        */
+       acquire_console_sem();
+
+       attr = (currcons & 128);
+       currcons = (currcons & 127);
+       if (currcons == 0) {
+               currcons = fg_console;
+               viewed = 1;
+       } else {
+               currcons--;
+               viewed = 0;
+       }
+       ret = -ENXIO;
+       if (!vc_cons_allocated(currcons))
+               goto unlock_out;
+       vc = vc_cons[currcons].d;
+
+       ret = -EINVAL;
+       if (pos < 0)
+               goto unlock_out;
+       poll = file->private_data;
+       if (count && poll)
+               poll->seen_last_update = true;
+       read = 0;
+       ret = 0;
+       while (count) {
+               char *con_buf0, *con_buf_start;
+               long this_round, size;
+               ssize_t orig_count;
+               long p = pos;
+
+               /* Check whether we are above size each round,
+                * as copy_to_user at the end of this loop
+                * could sleep.
+                */
+               size = vcs_size(inode);
+               if (pos >= size)
+                       break;
+               if (count > size - pos)
+                       count = size - pos;
+
+               this_round = count;
+               if (this_round > CON_BUF_SIZE)
+                       this_round = CON_BUF_SIZE;
+
+               /* Perform the whole read into the local con_buf.
+                * Then we can drop the console spinlock and safely
+                * attempt to move it to userspace.
+                */
+
+               con_buf_start = con_buf0 = con_buf;
+               orig_count = this_round;
+               maxcol = vc->vc_cols;
+               if (!attr) {
+                       org = screen_pos(vc, p, viewed);
+                       col = p % maxcol;
+                       p += maxcol - col;
+                       while (this_round-- > 0) {
+                               *con_buf0++ = (vcs_scr_readw(vc, org++) & 0xff);
+                               if (++col == maxcol) {
+                                       org = screen_pos(vc, p, viewed);
+                                       col = 0;
+                                       p += maxcol;
+                               }
+                       }
+               } else {
+                       if (p < HEADER_SIZE) {
+                               size_t tmp_count;
+
+                               con_buf0[0] = (char)vc->vc_rows;
+                               con_buf0[1] = (char)vc->vc_cols;
+                               getconsxy(vc, con_buf0 + 2);
+
+                               con_buf_start += p;
+                               this_round += p;
+                               if (this_round > CON_BUF_SIZE) {
+                                       this_round = CON_BUF_SIZE;
+                                       orig_count = this_round - p;
+                               }
+
+                               tmp_count = HEADER_SIZE;
+                               if (tmp_count > this_round)
+                                       tmp_count = this_round;
+
+                               /* Advance state pointers and move on. */
+                               this_round -= tmp_count;
+                               p = HEADER_SIZE;
+                               con_buf0 = con_buf + HEADER_SIZE;
+                               /* If this_round >= 0, then p is even... */
+                       } else if (p & 1) {
+                               /* Skip first byte for output if start address is odd
+                                * Update region sizes up/down depending on free
+                                * space in buffer.
+                                */
+                               con_buf_start++;
+                               if (this_round < CON_BUF_SIZE)
+                                       this_round++;
+                               else
+                                       orig_count--;
+                       }
+                       if (this_round > 0) {
+                               unsigned short *tmp_buf = (unsigned short *)con_buf0;
+
+                               p -= HEADER_SIZE;
+                               p /= 2;
+                               col = p % maxcol;
+
+                               org = screen_pos(vc, p, viewed);
+                               p += maxcol - col;
+
+                               /* Buffer has even length, so we can always copy
+                                * character + attribute. We do not copy last byte
+                                * to userspace if this_round is odd.
+                                */
+                               this_round = (this_round + 1) >> 1;
+
+                               while (this_round) {
+                                       *tmp_buf++ = vcs_scr_readw(vc, org++);
+                                       this_round --;
+                                       if (++col == maxcol) {
+                                               org = screen_pos(vc, p, viewed);
+                                               col = 0;
+                                               p += maxcol;
+                                       }
+                               }
+                       }
+               }
+
+               /* Finally, release the console semaphore while we push
+                * all the data to userspace from our temporary buffer.
+                *
+                * AKPM: Even though it's a semaphore, we should drop it because
+                * the pagefault handling code may want to call printk().
+                */
+
+               release_console_sem();
+               ret = copy_to_user(buf, con_buf_start, orig_count);
+               acquire_console_sem();
+
+               if (ret) {
+                       read += (orig_count - ret);
+                       ret = -EFAULT;
+                       break;
+               }
+               buf += orig_count;
+               pos += orig_count;
+               read += orig_count;
+               count -= orig_count;
+       }
+       *ppos += read;
+       if (read)
+               ret = read;
+unlock_out:
+       release_console_sem();
+       mutex_unlock(&con_buf_mtx);
+       return ret;
+}
+
+static ssize_t
+vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{
+       struct inode *inode = file->f_path.dentry->d_inode;
+       unsigned int currcons = iminor(inode);
+       struct vc_data *vc;
+       long pos;
+       long viewed, attr, size, written;
+       char *con_buf0;
+       int col, maxcol;
+       u16 *org0 = NULL, *org = NULL;
+       size_t ret;
+
+       mutex_lock(&con_buf_mtx);
+
+       pos = *ppos;
+
+       /* Select the proper current console and verify
+        * sanity of the situation under the console lock.
+        */
+       acquire_console_sem();
+
+       attr = (currcons & 128);
+       currcons = (currcons & 127);
+
+       if (currcons == 0) {
+               currcons = fg_console;
+               viewed = 1;
+       } else {
+               currcons--;
+               viewed = 0;
+       }
+       ret = -ENXIO;
+       if (!vc_cons_allocated(currcons))
+               goto unlock_out;
+       vc = vc_cons[currcons].d;
+
+       size = vcs_size(inode);
+       ret = -EINVAL;
+       if (pos < 0 || pos > size)
+               goto unlock_out;
+       if (count > size - pos)
+               count = size - pos;
+       written = 0;
+       while (count) {
+               long this_round = count;
+               size_t orig_count;
+               long p;
+
+               if (this_round > CON_BUF_SIZE)
+                       this_round = CON_BUF_SIZE;
+
+               /* Temporarily drop the console lock so that we can read
+                * in the write data from userspace safely.
+                */
+               release_console_sem();
+               ret = copy_from_user(con_buf, buf, this_round);
+               acquire_console_sem();
+
+               if (ret) {
+                       this_round -= ret;
+                       if (!this_round) {
+                               /* Abort loop if no data were copied. Otherwise
+                                * fail with -EFAULT.
+                                */
+                               if (written)
+                                       break;
+                               ret = -EFAULT;
+                               goto unlock_out;
+                       }
+               }
+
+               /* The vcs_size might have changed while we slept to grab
+                * the user buffer, so recheck.
+                * Return data written up to now on failure.
+                */
+               size = vcs_size(inode);
+               if (pos >= size)
+                       break;
+               if (this_round > size - pos)
+                       this_round = size - pos;
+
+               /* OK, now actually push the write to the console
+                * under the lock using the local kernel buffer.
+                */
+
+               con_buf0 = con_buf;
+               orig_count = this_round;
+               maxcol = vc->vc_cols;
+               p = pos;
+               if (!attr) {
+                       org0 = org = screen_pos(vc, p, viewed);
+                       col = p % maxcol;
+                       p += maxcol - col;
+
+                       while (this_round > 0) {
+                               unsigned char c = *con_buf0++;
+
+                               this_round--;
+                               vcs_scr_writew(vc,
+                                              (vcs_scr_readw(vc, org) & 0xff00) | c, org);
+                               org++;
+                               if (++col == maxcol) {
+                                       org = screen_pos(vc, p, viewed);
+                                       col = 0;
+                                       p += maxcol;
+                               }
+                       }
+               } else {
+                       if (p < HEADER_SIZE) {
+                               char header[HEADER_SIZE];
+
+                               getconsxy(vc, header + 2);
+                               while (p < HEADER_SIZE && this_round > 0) {
+                                       this_round--;
+                                       header[p++] = *con_buf0++;
+                               }
+                               if (!viewed)
+                                       putconsxy(vc, header + 2);
+                       }
+                       p -= HEADER_SIZE;
+                       col = (p/2) % maxcol;
+                       if (this_round > 0) {
+                               org0 = org = screen_pos(vc, p/2, viewed);
+                               if ((p & 1) && this_round > 0) {
+                                       char c;
+
+                                       this_round--;
+                                       c = *con_buf0++;
+#ifdef __BIG_ENDIAN
+                                       vcs_scr_writew(vc, c |
+                                            (vcs_scr_readw(vc, org) & 0xff00), org);
+#else
+                                       vcs_scr_writew(vc, (c << 8) |
+                                            (vcs_scr_readw(vc, org) & 0xff), org);
+#endif
+                                       org++;
+                                       p++;
+                                       if (++col == maxcol) {
+                                               org = screen_pos(vc, p/2, viewed);
+                                               col = 0;
+                                       }
+                               }
+                               p /= 2;
+                               p += maxcol - col;
+                       }
+                       while (this_round > 1) {
+                               unsigned short w;
+
+                               w = get_unaligned(((unsigned short *)con_buf0));
+                               vcs_scr_writew(vc, w, org++);
+                               con_buf0 += 2;
+                               this_round -= 2;
+                               if (++col == maxcol) {
+                                       org = screen_pos(vc, p, viewed);
+                                       col = 0;
+                                       p += maxcol;
+                               }
+                       }
+                       if (this_round > 0) {
+                               unsigned char c;
+
+                               c = *con_buf0++;
+#ifdef __BIG_ENDIAN
+                               vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org);
+#else
+                               vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org);
+#endif
+                       }
+               }
+               count -= orig_count;
+               written += orig_count;
+               buf += orig_count;
+               pos += orig_count;
+               if (org0)
+                       update_region(vc, (unsigned long)(org0), org - org0);
+       }
+       *ppos += written;
+       ret = written;
+       if (written)
+               vcs_scr_updated(vc);
+
+unlock_out:
+       release_console_sem();
+
+       mutex_unlock(&con_buf_mtx);
+
+       return ret;
+}
+
+static unsigned int
+vcs_poll(struct file *file, poll_table *wait)
+{
+       struct vcs_poll_data *poll = vcs_poll_data_get(file);
+       int ret = DEFAULT_POLLMASK|POLLERR|POLLPRI;
+
+       if (poll) {
+               poll_wait(file, &poll->waitq, wait);
+               if (poll->seen_last_update)
+                       ret = DEFAULT_POLLMASK;
+       }
+       return ret;
+}
+
+static int
+vcs_fasync(int fd, struct file *file, int on)
+{
+       struct vcs_poll_data *poll = file->private_data;
+
+       if (!poll) {
+               /* don't allocate anything if all we want is disable fasync */
+               if (!on)
+                       return 0;
+               poll = vcs_poll_data_get(file);
+               if (!poll)
+                       return -ENOMEM;
+       }
+
+       return fasync_helper(fd, file, on, &poll->fasync);
+}
+
+static int
+vcs_open(struct inode *inode, struct file *filp)
+{
+       unsigned int currcons = iminor(inode) & 127;
+       int ret = 0;
+       
+       tty_lock();
+       if(currcons && !vc_cons_allocated(currcons-1))
+               ret = -ENXIO;
+       tty_unlock();
+       return ret;
+}
+
+static int vcs_release(struct inode *inode, struct file *file)
+{
+       struct vcs_poll_data *poll = file->private_data;
+
+       if (poll)
+               vcs_poll_data_free(poll);
+       return 0;
+}
+
+static const struct file_operations vcs_fops = {
+       .llseek         = vcs_lseek,
+       .read           = vcs_read,
+       .write          = vcs_write,
+       .poll           = vcs_poll,
+       .fasync         = vcs_fasync,
+       .open           = vcs_open,
+       .release        = vcs_release,
+};
+
+static struct class *vc_class;
+
+void vcs_make_sysfs(int index)
+{
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL,
+                     "vcs%u", index + 1);
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL,
+                     "vcsa%u", index + 1);
+}
+
+void vcs_remove_sysfs(int index)
+{
+       device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1));
+       device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129));
+}
+
+int __init vcs_init(void)
+{
+       unsigned int i;
+
+       if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
+               panic("unable to get major %d for vcs device", VCS_MAJOR);
+       vc_class = class_create(THIS_MODULE, "vc");
+
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+       for (i = 0; i < MIN_NR_CONSOLES; i++)
+               vcs_make_sysfs(i);
+       return 0;
+}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
new file mode 100644 (file)
index 0000000..a8ec48e
--- /dev/null
@@ -0,0 +1,4209 @@
+/*
+ *  linux/drivers/char/vt.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+/*
+ * Hopefully this will be a rather complete VT102 implementation.
+ *
+ * Beeping thanks to John T Kohl.
+ *
+ * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
+ *   Chars, and VT100 enhancements by Peter MacDonald.
+ *
+ * Copy and paste function by Andrew Haylett,
+ *   some enhancements by Alessandro Rubini.
+ *
+ * Code to check for different video-cards mostly by Galen Hunt,
+ * <g-hunt@ee.utah.edu>
+ *
+ * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
+ * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
+ *
+ * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
+ * Resizing of consoles, aeb, 940926
+ *
+ * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
+ * <poe@daimi.aau.dk>
+ *
+ * User-defined bell sound, new setterm control sequences and printk
+ * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
+ *
+ * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp>
+ *
+ * Merge with the abstract console driver by Geert Uytterhoeven
+ * <geert@linux-m68k.org>, Jan 1997.
+ *
+ *   Original m68k console driver modifications by
+ *
+ *     - Arno Griffioen <arno@usn.nl>
+ *     - David Carter <carter@cs.bris.ac.uk>
+ * 
+ *   The abstract console driver provides a generic interface for a text
+ *   console. It supports VGA text mode, frame buffer based graphical consoles
+ *   and special graphics processors that are only accessible through some
+ *   registers (e.g. a TMS340x0 GSP).
+ *
+ *   The interface to the hardware is specified using a special structure
+ *   (struct consw) which contains function pointers to console operations
+ *   (see <linux/console.h> for more information).
+ *
+ * Support for changeable cursor shape
+ * by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>, August 1997
+ *
+ * Ported to i386 and con_scrolldelta fixed
+ * by Emmanuel Marty <core@ggi-project.org>, April 1998
+ *
+ * Resurrected character buffers in videoram plus lots of other trickery
+ * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998
+ *
+ * Removed old-style timers, introduced console_timer, made timer
+ * deletion SMP-safe.  17Jun00, Andrew Morton
+ *
+ * Removed console_lock, enabled interrupts across all console operations
+ * 13 March 2001, Andrew Morton
+ *
+ * Fixed UTF-8 mode so alternate charset modes always work according
+ * to control sequences interpreted in do_con_trol function
+ * preserving backward VT100 semigraphics compatibility,
+ * malformed UTF sequences represented as sequences of replacement glyphs,
+ * original codes or '?' as a last resort if replacement glyph is undefined
+ * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kd.h>
+#include <linux/slab.h>
+#include <linux/major.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/smp_lock.h>
+#include <linux/tiocl.h>
+#include <linux/kbd_kern.h>
+#include <linux/consolemap.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/pm.h>
+#include <linux/font.h>
+#include <linux/bitops.h>
+#include <linux/notifier.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <linux/uaccess.h>
+#include <linux/kdb.h>
+#include <linux/ctype.h>
+
+#define MAX_NR_CON_DRIVER 16
+
+#define CON_DRIVER_FLAG_MODULE 1
+#define CON_DRIVER_FLAG_INIT   2
+#define CON_DRIVER_FLAG_ATTR   4
+
+struct con_driver {
+       const struct consw *con;
+       const char *desc;
+       struct device *dev;
+       int node;
+       int first;
+       int last;
+       int flag;
+};
+
+static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
+const struct consw *conswitchp;
+
+/* A bitmap for codes <32. A bit of 1 indicates that the code
+ * corresponding to that bit number invokes some special action
+ * (such as cursor movement) and should not be displayed as a
+ * glyph unless the disp_ctrl mode is explicitly enabled.
+ */
+#define CTRL_ACTION 0x0d00ff81
+#define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */
+
+/*
+ * Here is the default bell parameters: 750HZ, 1/8th of a second
+ */
+#define DEFAULT_BELL_PITCH     750
+#define DEFAULT_BELL_DURATION  (HZ/8)
+
+struct vc vc_cons [MAX_NR_CONSOLES];
+
+#ifndef VT_SINGLE_DRIVER
+static const struct consw *con_driver_map[MAX_NR_CONSOLES];
+#endif
+
+static int con_open(struct tty_struct *, struct file *);
+static void vc_init(struct vc_data *vc, unsigned int rows,
+                   unsigned int cols, int do_clear);
+static void gotoxy(struct vc_data *vc, int new_x, int new_y);
+static void save_cur(struct vc_data *vc);
+static void reset_terminal(struct vc_data *vc, int do_clear);
+static void con_flush_chars(struct tty_struct *tty);
+static int set_vesa_blanking(char __user *p);
+static void set_cursor(struct vc_data *vc);
+static void hide_cursor(struct vc_data *vc);
+static void console_callback(struct work_struct *ignored);
+static void blank_screen_t(unsigned long dummy);
+static void set_palette(struct vc_data *vc);
+
+static int printable;          /* Is console ready for printing? */
+int default_utf8 = true;
+module_param(default_utf8, int, S_IRUGO | S_IWUSR);
+int global_cursor_default = -1;
+module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
+
+static int cur_default = CUR_DEFAULT;
+module_param(cur_default, int, S_IRUGO | S_IWUSR);
+
+/*
+ * ignore_poke: don't unblank the screen when things are typed.  This is
+ * mainly for the privacy of braille terminal users.
+ */
+static int ignore_poke;
+
+int do_poke_blanked_console;
+int console_blanked;
+
+static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
+static int vesa_off_interval;
+static int blankinterval = 10*60;
+core_param(consoleblank, blankinterval, int, 0444);
+
+static DECLARE_WORK(console_work, console_callback);
+
+/*
+ * fg_console is the current virtual console,
+ * last_console is the last used one,
+ * want_console is the console we want to switch to,
+ * saved_* variants are for save/restore around kernel debugger enter/leave
+ */
+int fg_console;
+int last_console;
+int want_console = -1;
+static int saved_fg_console;
+static int saved_last_console;
+static int saved_want_console;
+static int saved_vc_mode;
+static int saved_console_blanked;
+
+/*
+ * For each existing display, we have a pointer to console currently visible
+ * on that display, allowing consoles other than fg_console to be refreshed
+ * appropriately. Unless the low-level driver supplies its own display_fg
+ * variable, we use this one for the "master display".
+ */
+static struct vc_data *master_display_fg;
+
+/*
+ * Unfortunately, we need to delay tty echo when we're currently writing to the
+ * console since the code is (and always was) not re-entrant, so we schedule
+ * all flip requests to process context with schedule-task() and run it from
+ * console_callback().
+ */
+
+/*
+ * For the same reason, we defer scrollback to the console callback.
+ */
+static int scrollback_delta;
+
+/*
+ * Hook so that the power management routines can (un)blank
+ * the console on our behalf.
+ */
+int (*console_blank_hook)(int);
+
+static DEFINE_TIMER(console_timer, blank_screen_t, 0, 0);
+static int blank_state;
+static int blank_timer_expired;
+enum {
+       blank_off = 0,
+       blank_normal_wait,
+       blank_vesa_wait,
+};
+
+/*
+ * Notifier list for console events.
+ */
+static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
+
+int register_vt_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_register(&vt_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_vt_notifier);
+
+int unregister_vt_notifier(struct notifier_block *nb)
+{
+       return atomic_notifier_chain_unregister(&vt_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_vt_notifier);
+
+static void notify_write(struct vc_data *vc, unsigned int unicode)
+{
+       struct vt_notifier_param param = { .vc = vc, unicode = unicode };
+       atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
+}
+
+static void notify_update(struct vc_data *vc)
+{
+       struct vt_notifier_param param = { .vc = vc };
+       atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
+}
+/*
+ *     Low-Level Functions
+ */
+
+#define IS_FG(vc)      ((vc)->vc_num == fg_console)
+
+#ifdef VT_BUF_VRAM_ONLY
+#define DO_UPDATE(vc)  0
+#else
+#define DO_UPDATE(vc)  (CON_IS_VISIBLE(vc) && !console_blanked)
+#endif
+
+static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
+{
+       unsigned short *p;
+       
+       if (!viewed)
+               p = (unsigned short *)(vc->vc_origin + offset);
+       else if (!vc->vc_sw->con_screen_pos)
+               p = (unsigned short *)(vc->vc_visible_origin + offset);
+       else
+               p = vc->vc_sw->con_screen_pos(vc, offset);
+       return p;
+}
+
+/* Called  from the keyboard irq path.. */
+static inline void scrolldelta(int lines)
+{
+       /* FIXME */
+       /* scrolldelta needs some kind of consistency lock, but the BKL was
+          and still is not protecting versus the scheduled back end */
+       scrollback_delta += lines;
+       schedule_console_callback();
+}
+
+void schedule_console_callback(void)
+{
+       schedule_work(&console_work);
+}
+
+static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
+{
+       unsigned short *d, *s;
+
+       if (t+nr >= b)
+               nr = b - t - 1;
+       if (b > vc->vc_rows || t >= b || nr < 1)
+               return;
+       if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr))
+               return;
+       d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
+       s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr));
+       scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);
+       scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char,
+                   vc->vc_size_row * nr);
+}
+
+static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
+{
+       unsigned short *s;
+       unsigned int step;
+
+       if (t+nr >= b)
+               nr = b - t - 1;
+       if (b > vc->vc_rows || t >= b || nr < 1)
+               return;
+       if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr))
+               return;
+       s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
+       step = vc->vc_cols * nr;
+       scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row);
+       scr_memsetw(s, vc->vc_video_erase_char, 2 * step);
+}
+
+static void do_update_region(struct vc_data *vc, unsigned long start, int count)
+{
+#ifndef VT_BUF_VRAM_ONLY
+       unsigned int xx, yy, offset;
+       u16 *p;
+
+       p = (u16 *) start;
+       if (!vc->vc_sw->con_getxy) {
+               offset = (start - vc->vc_origin) / 2;
+               xx = offset % vc->vc_cols;
+               yy = offset / vc->vc_cols;
+       } else {
+               int nxx, nyy;
+               start = vc->vc_sw->con_getxy(vc, start, &nxx, &nyy);
+               xx = nxx; yy = nyy;
+       }
+       for(;;) {
+               u16 attrib = scr_readw(p) & 0xff00;
+               int startx = xx;
+               u16 *q = p;
+               while (xx < vc->vc_cols && count) {
+                       if (attrib != (scr_readw(p) & 0xff00)) {
+                               if (p > q)
+                                       vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
+                               startx = xx;
+                               q = p;
+                               attrib = scr_readw(p) & 0xff00;
+                       }
+                       p++;
+                       xx++;
+                       count--;
+               }
+               if (p > q)
+                       vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
+               if (!count)
+                       break;
+               xx = 0;
+               yy++;
+               if (vc->vc_sw->con_getxy) {
+                       p = (u16 *)start;
+                       start = vc->vc_sw->con_getxy(vc, start, NULL, NULL);
+               }
+       }
+#endif
+}
+
+void update_region(struct vc_data *vc, unsigned long start, int count)
+{
+       WARN_CONSOLE_UNLOCKED();
+
+       if (DO_UPDATE(vc)) {
+               hide_cursor(vc);
+               do_update_region(vc, start, count);
+               set_cursor(vc);
+       }
+}
+
+/* Structure of attributes is hardware-dependent */
+
+static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
+    u8 _underline, u8 _reverse, u8 _italic)
+{
+       if (vc->vc_sw->con_build_attr)
+               return vc->vc_sw->con_build_attr(vc, _color, _intensity,
+                      _blink, _underline, _reverse, _italic);
+
+#ifndef VT_BUF_VRAM_ONLY
+/*
+ * ++roman: I completely changed the attribute format for monochrome
+ * mode (!can_do_color). The formerly used MDA (monochrome display
+ * adapter) format didn't allow the combination of certain effects.
+ * Now the attribute is just a bit vector:
+ *  Bit 0..1: intensity (0..2)
+ *  Bit 2   : underline
+ *  Bit 3   : reverse
+ *  Bit 7   : blink
+ */
+       {
+       u8 a = _color;
+       if (!vc->vc_can_do_color)
+               return _intensity |
+                      (_italic ? 2 : 0) |
+                      (_underline ? 4 : 0) |
+                      (_reverse ? 8 : 0) |
+                      (_blink ? 0x80 : 0);
+       if (_italic)
+               a = (a & 0xF0) | vc->vc_itcolor;
+       else if (_underline)
+               a = (a & 0xf0) | vc->vc_ulcolor;
+       else if (_intensity == 0)
+               a = (a & 0xf0) | vc->vc_ulcolor;
+       if (_reverse)
+               a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77);
+       if (_blink)
+               a ^= 0x80;
+       if (_intensity == 2)
+               a ^= 0x08;
+       if (vc->vc_hi_font_mask == 0x100)
+               a <<= 1;
+       return a;
+       }
+#else
+       return 0;
+#endif
+}
+
+static void update_attr(struct vc_data *vc)
+{
+       vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
+                     vc->vc_blink, vc->vc_underline,
+                     vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
+       vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
+}
+
+/* Note: inverting the screen twice should revert to the original state */
+void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
+{
+       unsigned short *p;
+
+       WARN_CONSOLE_UNLOCKED();
+
+       count /= 2;
+       p = screenpos(vc, offset, viewed);
+       if (vc->vc_sw->con_invert_region)
+               vc->vc_sw->con_invert_region(vc, p, count);
+#ifndef VT_BUF_VRAM_ONLY
+       else {
+               u16 *q = p;
+               int cnt = count;
+               u16 a;
+
+               if (!vc->vc_can_do_color) {
+                       while (cnt--) {
+                           a = scr_readw(q);
+                           a ^= 0x0800;
+                           scr_writew(a, q);
+                           q++;
+                       }
+               } else if (vc->vc_hi_font_mask == 0x100) {
+                       while (cnt--) {
+                               a = scr_readw(q);
+                               a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
+                               scr_writew(a, q);
+                               q++;
+                       }
+               } else {
+                       while (cnt--) {
+                               a = scr_readw(q);
+                               a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
+                               scr_writew(a, q);
+                               q++;
+                       }
+               }
+       }
+#endif
+       if (DO_UPDATE(vc))
+               do_update_region(vc, (unsigned long) p, count);
+}
+
+/* used by selection: complement pointer position */
+void complement_pos(struct vc_data *vc, int offset)
+{
+       static int old_offset = -1;
+       static unsigned short old;
+       static unsigned short oldx, oldy;
+
+       WARN_CONSOLE_UNLOCKED();
+
+       if (old_offset != -1 && old_offset >= 0 &&
+           old_offset < vc->vc_screenbuf_size) {
+               scr_writew(old, screenpos(vc, old_offset, 1));
+               if (DO_UPDATE(vc))
+                       vc->vc_sw->con_putc(vc, old, oldy, oldx);
+       }
+
+       old_offset = offset;
+
+       if (offset != -1 && offset >= 0 &&
+           offset < vc->vc_screenbuf_size) {
+               unsigned short new;
+               unsigned short *p;
+               p = screenpos(vc, offset, 1);
+               old = scr_readw(p);
+               new = old ^ vc->vc_complement_mask;
+               scr_writew(new, p);
+               if (DO_UPDATE(vc)) {
+                       oldx = (offset >> 1) % vc->vc_cols;
+                       oldy = (offset >> 1) / vc->vc_cols;
+                       vc->vc_sw->con_putc(vc, new, oldy, oldx);
+               }
+       }
+
+}
+
+static void insert_char(struct vc_data *vc, unsigned int nr)
+{
+       unsigned short *p, *q = (unsigned short *)vc->vc_pos;
+
+       p = q + vc->vc_cols - nr - vc->vc_x;
+       while (--p >= q)
+               scr_writew(scr_readw(p), p + nr);
+       scr_memsetw(q, vc->vc_video_erase_char, nr * 2);
+       vc->vc_need_wrap = 0;
+       if (DO_UPDATE(vc)) {
+               unsigned short oldattr = vc->vc_attr;
+               vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1,
+                                    vc->vc_cols - vc->vc_x - nr);
+               vc->vc_attr = vc->vc_video_erase_char >> 8;
+               while (nr--)
+                       vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr);
+               vc->vc_attr = oldattr;
+       }
+}
+
+static void delete_char(struct vc_data *vc, unsigned int nr)
+{
+       unsigned int i = vc->vc_x;
+       unsigned short *p = (unsigned short *)vc->vc_pos;
+
+       while (++i <= vc->vc_cols - nr) {
+               scr_writew(scr_readw(p+nr), p);
+               p++;
+       }
+       scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
+       vc->vc_need_wrap = 0;
+       if (DO_UPDATE(vc)) {
+               unsigned short oldattr = vc->vc_attr;
+               vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1,
+                                    vc->vc_cols - vc->vc_x - nr);
+               vc->vc_attr = vc->vc_video_erase_char >> 8;
+               while (nr--)
+                       vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y,
+                                    vc->vc_cols - 1 - nr);
+               vc->vc_attr = oldattr;
+       }
+}
+
+static int softcursor_original;
+
+static void add_softcursor(struct vc_data *vc)
+{
+       int i = scr_readw((u16 *) vc->vc_pos);
+       u32 type = vc->vc_cursor_type;
+
+       if (! (type & 0x10)) return;
+       if (softcursor_original != -1) return;
+       softcursor_original = i;
+       i |= ((type >> 8) & 0xff00 );
+       i ^= ((type) & 0xff00 );
+       if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
+       if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
+       scr_writew(i, (u16 *) vc->vc_pos);
+       if (DO_UPDATE(vc))
+               vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
+}
+
+static void hide_softcursor(struct vc_data *vc)
+{
+       if (softcursor_original != -1) {
+               scr_writew(softcursor_original, (u16 *)vc->vc_pos);
+               if (DO_UPDATE(vc))
+                       vc->vc_sw->con_putc(vc, softcursor_original,
+                                       vc->vc_y, vc->vc_x);
+               softcursor_original = -1;
+       }
+}
+
+static void hide_cursor(struct vc_data *vc)
+{
+       if (vc == sel_cons)
+               clear_selection();
+       vc->vc_sw->con_cursor(vc, CM_ERASE);
+       hide_softcursor(vc);
+}
+
+static void set_cursor(struct vc_data *vc)
+{
+       if (!IS_FG(vc) || console_blanked ||
+           vc->vc_mode == KD_GRAPHICS)
+               return;
+       if (vc->vc_deccm) {
+               if (vc == sel_cons)
+                       clear_selection();
+               add_softcursor(vc);
+               if ((vc->vc_cursor_type & 0x0f) != 1)
+                       vc->vc_sw->con_cursor(vc, CM_DRAW);
+       } else
+               hide_cursor(vc);
+}
+
+static void set_origin(struct vc_data *vc)
+{
+       WARN_CONSOLE_UNLOCKED();
+
+       if (!CON_IS_VISIBLE(vc) ||
+           !vc->vc_sw->con_set_origin ||
+           !vc->vc_sw->con_set_origin(vc))
+               vc->vc_origin = (unsigned long)vc->vc_screenbuf;
+       vc->vc_visible_origin = vc->vc_origin;
+       vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
+       vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
+}
+
+static inline void save_screen(struct vc_data *vc)
+{
+       WARN_CONSOLE_UNLOCKED();
+
+       if (vc->vc_sw->con_save_screen)
+               vc->vc_sw->con_save_screen(vc);
+}
+
+/*
+ *     Redrawing of screen
+ */
+
+static void clear_buffer_attributes(struct vc_data *vc)
+{
+       unsigned short *p = (unsigned short *)vc->vc_origin;
+       int count = vc->vc_screenbuf_size / 2;
+       int mask = vc->vc_hi_font_mask | 0xff;
+
+       for (; count > 0; count--, p++) {
+               scr_writew((scr_readw(p)&mask) | (vc->vc_video_erase_char & ~mask), p);
+       }
+}
+
+void redraw_screen(struct vc_data *vc, int is_switch)
+{
+       int redraw = 0;
+
+       WARN_CONSOLE_UNLOCKED();
+
+       if (!vc) {
+               /* strange ... */
+               /* printk("redraw_screen: tty %d not allocated ??\n", new_console+1); */
+               return;
+       }
+
+       if (is_switch) {
+               struct vc_data *old_vc = vc_cons[fg_console].d;
+               if (old_vc == vc)
+                       return;
+               if (!CON_IS_VISIBLE(vc))
+                       redraw = 1;
+               *vc->vc_display_fg = vc;
+               fg_console = vc->vc_num;
+               hide_cursor(old_vc);
+               if (!CON_IS_VISIBLE(old_vc)) {
+                       save_screen(old_vc);
+                       set_origin(old_vc);
+               }
+       } else {
+               hide_cursor(vc);
+               redraw = 1;
+       }
+
+       if (redraw) {
+               int update;
+               int old_was_color = vc->vc_can_do_color;
+
+               set_origin(vc);
+               update = vc->vc_sw->con_switch(vc);
+               set_palette(vc);
+               /*
+                * If console changed from mono<->color, the best we can do
+                * is to clear the buffer attributes. As it currently stands,
+                * rebuilding new attributes from the old buffer is not doable
+                * without overly complex code.
+                */
+               if (old_was_color != vc->vc_can_do_color) {
+                       update_attr(vc);
+                       clear_buffer_attributes(vc);
+               }
+
+               /* Forcibly update if we're panicing */
+               if ((update && vc->vc_mode != KD_GRAPHICS) ||
+                   vt_force_oops_output(vc))
+                       do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
+       }
+       set_cursor(vc);
+       if (is_switch) {
+               set_leds();
+               compute_shiftstate();
+               notify_update(vc);
+       }
+}
+
+/*
+ *     Allocation, freeing and resizing of VTs.
+ */
+
+int vc_cons_allocated(unsigned int i)
+{
+       return (i < MAX_NR_CONSOLES && vc_cons[i].d);
+}
+
+static void visual_init(struct vc_data *vc, int num, int init)
+{
+       /* ++Geert: vc->vc_sw->con_init determines console size */
+       if (vc->vc_sw)
+               module_put(vc->vc_sw->owner);
+       vc->vc_sw = conswitchp;
+#ifndef VT_SINGLE_DRIVER
+       if (con_driver_map[num])
+               vc->vc_sw = con_driver_map[num];
+#endif
+       __module_get(vc->vc_sw->owner);
+       vc->vc_num = num;
+       vc->vc_display_fg = &master_display_fg;
+       vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;
+       vc->vc_uni_pagedir = 0;
+       vc->vc_hi_font_mask = 0;
+       vc->vc_complement_mask = 0;
+       vc->vc_can_do_color = 0;
+       vc->vc_panic_force_write = false;
+       vc->vc_sw->con_init(vc, init);
+       if (!vc->vc_complement_mask)
+               vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+       vc->vc_s_complement_mask = vc->vc_complement_mask;
+       vc->vc_size_row = vc->vc_cols << 1;
+       vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
+}
+
+int vc_allocate(unsigned int currcons) /* return 0 on success */
+{
+       WARN_CONSOLE_UNLOCKED();
+
+       if (currcons >= MAX_NR_CONSOLES)
+               return -ENXIO;
+       if (!vc_cons[currcons].d) {
+           struct vc_data *vc;
+           struct vt_notifier_param param;
+
+           /* prevent users from taking too much memory */
+           if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
+             return -EPERM;
+
+           /* due to the granularity of kmalloc, we waste some memory here */
+           /* the alloc is done in two steps, to optimize the common situation
+              of a 25x80 console (structsize=216, screenbuf_size=4000) */
+           /* although the numbers above are not valid since long ago, the
+              point is still up-to-date and the comment still has its value
+              even if only as a historical artifact.  --mj, July 1998 */
+           param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
+           if (!vc)
+               return -ENOMEM;
+           vc_cons[currcons].d = vc;
+           tty_port_init(&vc->port);
+           INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
+           visual_init(vc, currcons, 1);
+           if (!*vc->vc_uni_pagedir_loc)
+               con_set_default_unimap(vc);
+           vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
+           if (!vc->vc_screenbuf) {
+               kfree(vc);
+               vc_cons[currcons].d = NULL;
+               return -ENOMEM;
+           }
+
+           /* If no drivers have overridden us and the user didn't pass a
+              boot option, default to displaying the cursor */
+           if (global_cursor_default == -1)
+                   global_cursor_default = 1;
+
+           vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+           vcs_make_sysfs(currcons);
+           atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
+       }
+       return 0;
+}
+
+static inline int resize_screen(struct vc_data *vc, int width, int height,
+                               int user)
+{
+       /* Resizes the resolution of the display adapater */
+       int err = 0;
+
+       if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
+               err = vc->vc_sw->con_resize(vc, width, height, user);
+
+       return err;
+}
+
+/*
+ * Change # of rows and columns (0 means unchanged/the size of fg_console)
+ * [this is to be used together with some user program
+ * like resize that changes the hardware videomode]
+ */
+#define VC_RESIZE_MAXCOL (32767)
+#define VC_RESIZE_MAXROW (32767)
+
+/**
+ *     vc_do_resize    -       resizing method for the tty
+ *     @tty: tty being resized
+ *     @real_tty: real tty (different to tty if a pty/tty pair)
+ *     @vc: virtual console private data
+ *     @cols: columns
+ *     @lines: lines
+ *
+ *     Resize a virtual console, clipping according to the actual constraints.
+ *     If the caller passes a tty structure then update the termios winsize
+ *     information and perform any necessary signal handling.
+ *
+ *     Caller must hold the console semaphore. Takes the termios mutex and
+ *     ctrl_lock of the tty IFF a tty is passed.
+ */
+
+static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
+                               unsigned int cols, unsigned int lines)
+{
+       unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
+       unsigned long end;
+       unsigned int old_cols, old_rows, old_row_size, old_screen_size;
+       unsigned int new_cols, new_rows, new_row_size, new_screen_size;
+       unsigned int user;
+       unsigned short *newscreen;
+
+       WARN_CONSOLE_UNLOCKED();
+
+       if (!vc)
+               return -ENXIO;
+
+       user = vc->vc_resize_user;
+       vc->vc_resize_user = 0;
+
+       if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
+               return -EINVAL;
+
+       new_cols = (cols ? cols : vc->vc_cols);
+       new_rows = (lines ? lines : vc->vc_rows);
+       new_row_size = new_cols << 1;
+       new_screen_size = new_row_size * new_rows;
+
+       if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
+               return 0;
+
+       newscreen = kmalloc(new_screen_size, GFP_USER);
+       if (!newscreen)
+               return -ENOMEM;
+
+       old_rows = vc->vc_rows;
+       old_cols = vc->vc_cols;
+       old_row_size = vc->vc_size_row;
+       old_screen_size = vc->vc_screenbuf_size;
+
+       err = resize_screen(vc, new_cols, new_rows, user);
+       if (err) {
+               kfree(newscreen);
+               return err;
+       }
+
+       vc->vc_rows = new_rows;
+       vc->vc_cols = new_cols;
+       vc->vc_size_row = new_row_size;
+       vc->vc_screenbuf_size = new_screen_size;
+
+       rlth = min(old_row_size, new_row_size);
+       rrem = new_row_size - rlth;
+       old_origin = vc->vc_origin;
+       new_origin = (long) newscreen;
+       new_scr_end = new_origin + new_screen_size;
+
+       if (vc->vc_y > new_rows) {
+               if (old_rows - vc->vc_y < new_rows) {
+                       /*
+                        * Cursor near the bottom, copy contents from the
+                        * bottom of buffer
+                        */
+                       old_origin += (old_rows - new_rows) * old_row_size;
+               } else {
+                       /*
+                        * Cursor is in no man's land, copy 1/2 screenful
+                        * from the top and bottom of cursor position
+                        */
+                       old_origin += (vc->vc_y - new_rows/2) * old_row_size;
+               }
+       }
+
+       end = old_origin + old_row_size * min(old_rows, new_rows);
+
+       update_attr(vc);
+
+       while (old_origin < end) {
+               scr_memcpyw((unsigned short *) new_origin,
+                           (unsigned short *) old_origin, rlth);
+               if (rrem)
+                       scr_memsetw((void *)(new_origin + rlth),
+                                   vc->vc_video_erase_char, rrem);
+               old_origin += old_row_size;
+               new_origin += new_row_size;
+       }
+       if (new_scr_end > new_origin)
+               scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
+                           new_scr_end - new_origin);
+       kfree(vc->vc_screenbuf);
+       vc->vc_screenbuf = newscreen;
+       vc->vc_screenbuf_size = new_screen_size;
+       set_origin(vc);
+
+       /* do part of a reset_terminal() */
+       vc->vc_top = 0;
+       vc->vc_bottom = vc->vc_rows;
+       gotoxy(vc, vc->vc_x, vc->vc_y);
+       save_cur(vc);
+
+       if (tty) {
+               /* Rewrite the requested winsize data with the actual
+                  resulting sizes */
+               struct winsize ws;
+               memset(&ws, 0, sizeof(ws));
+               ws.ws_row = vc->vc_rows;
+               ws.ws_col = vc->vc_cols;
+               ws.ws_ypixel = vc->vc_scan_lines;
+               tty_do_resize(tty, &ws);
+       }
+
+       if (CON_IS_VISIBLE(vc))
+               update_screen(vc);
+       vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
+       return err;
+}
+
+/**
+ *     vc_resize               -       resize a VT
+ *     @vc: virtual console
+ *     @cols: columns
+ *     @rows: rows
+ *
+ *     Resize a virtual console as seen from the console end of things. We
+ *     use the common vc_do_resize methods to update the structures. The
+ *     caller must hold the console sem to protect console internals and
+ *     vc->port.tty
+ */
+
+int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
+{
+       return vc_do_resize(vc->port.tty, vc, cols, rows);
+}
+
+/**
+ *     vt_resize               -       resize a VT
+ *     @tty: tty to resize
+ *     @ws: winsize attributes
+ *
+ *     Resize a virtual terminal. This is called by the tty layer as we
+ *     register our own handler for resizing. The mutual helper does all
+ *     the actual work.
+ *
+ *     Takes the console sem and the called methods then take the tty
+ *     termios_mutex and the tty ctrl_lock in that order.
+ */
+static int vt_resize(struct tty_struct *tty, struct winsize *ws)
+{
+       struct vc_data *vc = tty->driver_data;
+       int ret;
+
+       acquire_console_sem();
+       ret = vc_do_resize(tty, vc, ws->ws_col, ws->ws_row);
+       release_console_sem();
+       return ret;
+}
+
+void vc_deallocate(unsigned int currcons)
+{
+       WARN_CONSOLE_UNLOCKED();
+
+       if (vc_cons_allocated(currcons)) {
+               struct vc_data *vc = vc_cons[currcons].d;
+               struct vt_notifier_param param = { .vc = vc };
+
+               atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
+               vcs_remove_sysfs(currcons);
+               vc->vc_sw->con_deinit(vc);
+               put_pid(vc->vt_pid);
+               module_put(vc->vc_sw->owner);
+               kfree(vc->vc_screenbuf);
+               if (currcons >= MIN_NR_CONSOLES)
+                       kfree(vc);
+               vc_cons[currcons].d = NULL;
+       }
+}
+
+/*
+ *     VT102 emulator
+ */
+
+#define set_kbd(vc, x) set_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
+#define clr_kbd(vc, x) clr_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
+#define is_kbd(vc, x)  vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
+
+#define decarm         VC_REPEAT
+#define decckm         VC_CKMODE
+#define kbdapplic      VC_APPLIC
+#define lnm            VC_CRLF
+
+/*
+ * this is what the terminal answers to a ESC-Z or csi0c query.
+ */
+#define VT100ID "\033[?1;2c"
+#define VT102ID "\033[?6c"
+
+unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
+                                      8,12,10,14, 9,13,11,15 };
+
+/* the default colour table, for VGA+ colour systems */
+int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
+    0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
+int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
+    0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
+int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
+    0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
+
+module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR);
+module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR);
+module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR);
+
+/*
+ * gotoxy() must verify all boundaries, because the arguments
+ * might also be negative. If the given position is out of
+ * bounds, the cursor is placed at the nearest margin.
+ */
+static void gotoxy(struct vc_data *vc, int new_x, int new_y)
+{
+       int min_y, max_y;
+
+       if (new_x < 0)
+               vc->vc_x = 0;
+       else {
+               if (new_x >= vc->vc_cols)
+                       vc->vc_x = vc->vc_cols - 1;
+               else
+                       vc->vc_x = new_x;
+       }
+
+       if (vc->vc_decom) {
+               min_y = vc->vc_top;
+               max_y = vc->vc_bottom;
+       } else {
+               min_y = 0;
+               max_y = vc->vc_rows;
+       }
+       if (new_y < min_y)
+               vc->vc_y = min_y;
+       else if (new_y >= max_y)
+               vc->vc_y = max_y - 1;
+       else
+               vc->vc_y = new_y;
+       vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
+       vc->vc_need_wrap = 0;
+}
+
+/* for absolute user moves, when decom is set */
+static void gotoxay(struct vc_data *vc, int new_x, int new_y)
+{
+       gotoxy(vc, new_x, vc->vc_decom ? (vc->vc_top + new_y) : new_y);
+}
+
+void scrollback(struct vc_data *vc, int lines)
+{
+       if (!lines)
+               lines = vc->vc_rows / 2;
+       scrolldelta(-lines);
+}
+
+void scrollfront(struct vc_data *vc, int lines)
+{
+       if (!lines)
+               lines = vc->vc_rows / 2;
+       scrolldelta(lines);
+}
+
+static void lf(struct vc_data *vc)
+{
+       /* don't scroll if above bottom of scrolling region, or
+        * if below scrolling region
+        */
+       if (vc->vc_y + 1 == vc->vc_bottom)
+               scrup(vc, vc->vc_top, vc->vc_bottom, 1);
+       else if (vc->vc_y < vc->vc_rows - 1) {
+               vc->vc_y++;
+               vc->vc_pos += vc->vc_size_row;
+       }
+       vc->vc_need_wrap = 0;
+       notify_write(vc, '\n');
+}
+
+static void ri(struct vc_data *vc)
+{
+       /* don't scroll if below top of scrolling region, or
+        * if above scrolling region
+        */
+       if (vc->vc_y == vc->vc_top)
+               scrdown(vc, vc->vc_top, vc->vc_bottom, 1);
+       else if (vc->vc_y > 0) {
+               vc->vc_y--;
+               vc->vc_pos -= vc->vc_size_row;
+       }
+       vc->vc_need_wrap = 0;
+}
+
+static inline void cr(struct vc_data *vc)
+{
+       vc->vc_pos -= vc->vc_x << 1;
+       vc->vc_need_wrap = vc->vc_x = 0;
+       notify_write(vc, '\r');
+}
+
+static inline void bs(struct vc_data *vc)
+{
+       if (vc->vc_x) {
+               vc->vc_pos -= 2;
+               vc->vc_x--;
+               vc->vc_need_wrap = 0;
+               notify_write(vc, '\b');
+       }
+}
+
+static inline void del(struct vc_data *vc)
+{
+       /* ignored */
+}
+
+static void csi_J(struct vc_data *vc, int vpar)
+{
+       unsigned int count;
+       unsigned short * start;
+
+       switch (vpar) {
+               case 0: /* erase from cursor to end of display */
+                       count = (vc->vc_scr_end - vc->vc_pos) >> 1;
+                       start = (unsigned short *)vc->vc_pos;
+                       if (DO_UPDATE(vc)) {
+                               /* do in two stages */
+                               vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
+                                             vc->vc_cols - vc->vc_x);
+                               vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0,
+                                             vc->vc_rows - vc->vc_y - 1,
+                                             vc->vc_cols);
+                       }
+                       break;
+               case 1: /* erase from start to cursor */
+                       count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
+                       start = (unsigned short *)vc->vc_origin;
+                       if (DO_UPDATE(vc)) {
+                               /* do in two stages */
+                               vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y,
+                                             vc->vc_cols);
+                               vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
+                                             vc->vc_x + 1);
+                       }
+                       break;
+               case 2: /* erase whole display */
+                       count = vc->vc_cols * vc->vc_rows;
+                       start = (unsigned short *)vc->vc_origin;
+                       if (DO_UPDATE(vc))
+                               vc->vc_sw->con_clear(vc, 0, 0,
+                                             vc->vc_rows,
+                                             vc->vc_cols);
+                       break;
+               default:
+                       return;
+       }
+       scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
+       vc->vc_need_wrap = 0;
+}
+
+static void csi_K(struct vc_data *vc, int vpar)
+{
+       unsigned int count;
+       unsigned short * start;
+
+       switch (vpar) {
+               case 0: /* erase from cursor to end of line */
+                       count = vc->vc_cols - vc->vc_x;
+                       start = (unsigned short *)vc->vc_pos;
+                       if (DO_UPDATE(vc))
+                               vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
+                                                    vc->vc_cols - vc->vc_x);
+                       break;
+               case 1: /* erase from start of line to cursor */
+                       start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
+                       count = vc->vc_x + 1;
+                       if (DO_UPDATE(vc))
+                               vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
+                                                    vc->vc_x + 1);
+                       break;
+               case 2: /* erase whole line */
+                       start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
+                       count = vc->vc_cols;
+                       if (DO_UPDATE(vc))
+                               vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
+                                             vc->vc_cols);
+                       break;
+               default:
+                       return;
+       }
+       scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
+       vc->vc_need_wrap = 0;
+}
+
+static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
+{                                        /* not vt100? */
+       int count;
+
+       if (!vpar)
+               vpar++;
+       count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;
+
+       scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
+       if (DO_UPDATE(vc))
+               vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
+       vc->vc_need_wrap = 0;
+}
+
+static void default_attr(struct vc_data *vc)
+{
+       vc->vc_intensity = 1;
+       vc->vc_italic = 0;
+       vc->vc_underline = 0;
+       vc->vc_reverse = 0;
+       vc->vc_blink = 0;
+       vc->vc_color = vc->vc_def_color;
+}
+
+/* console_sem is held */
+static void csi_m(struct vc_data *vc)
+{
+       int i;
+
+       for (i = 0; i <= vc->vc_npar; i++)
+               switch (vc->vc_par[i]) {
+                       case 0: /* all attributes off */
+                               default_attr(vc);
+                               break;
+                       case 1:
+                               vc->vc_intensity = 2;
+                               break;
+                       case 2:
+                               vc->vc_intensity = 0;
+                               break;
+                       case 3:
+                               vc->vc_italic = 1;
+                               break;
+                       case 4:
+                               vc->vc_underline = 1;
+                               break;
+                       case 5:
+                               vc->vc_blink = 1;
+                               break;
+                       case 7:
+                               vc->vc_reverse = 1;
+                               break;
+                       case 10: /* ANSI X3.64-1979 (SCO-ish?)
+                                 * Select primary font, don't display
+                                 * control chars if defined, don't set
+                                 * bit 8 on output.
+                                 */
+                               vc->vc_translate = set_translate(vc->vc_charset == 0
+                                               ? vc->vc_G0_charset
+                                               : vc->vc_G1_charset, vc);
+                               vc->vc_disp_ctrl = 0;
+                               vc->vc_toggle_meta = 0;
+                               break;
+                       case 11: /* ANSI X3.64-1979 (SCO-ish?)
+                                 * Select first alternate font, lets
+                                 * chars < 32 be displayed as ROM chars.
+                                 */
+                               vc->vc_translate = set_translate(IBMPC_MAP, vc);
+                               vc->vc_disp_ctrl = 1;
+                               vc->vc_toggle_meta = 0;
+                               break;
+                       case 12: /* ANSI X3.64-1979 (SCO-ish?)
+                                 * Select second alternate font, toggle
+                                 * high bit before displaying as ROM char.
+                                 */
+                               vc->vc_translate = set_translate(IBMPC_MAP, vc);
+                               vc->vc_disp_ctrl = 1;
+                               vc->vc_toggle_meta = 1;
+                               break;
+                       case 21:
+                       case 22:
+                               vc->vc_intensity = 1;
+                               break;
+                       case 23:
+                               vc->vc_italic = 0;
+                               break;
+                       case 24:
+                               vc->vc_underline = 0;
+                               break;
+                       case 25:
+                               vc->vc_blink = 0;
+                               break;
+                       case 27:
+                               vc->vc_reverse = 0;
+                               break;
+                       case 38: /* ANSI X3.64-1979 (SCO-ish?)
+                                 * Enables underscore, white foreground
+                                 * with white underscore (Linux - use
+                                 * default foreground).
+                                 */
+                               vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
+                               vc->vc_underline = 1;
+                               break;
+                       case 39: /* ANSI X3.64-1979 (SCO-ish?)
+                                 * Disable underline option.
+                                 * Reset colour to default? It did this
+                                 * before...
+                                 */
+                               vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
+                               vc->vc_underline = 0;
+                               break;
+                       case 49:
+                               vc->vc_color = (vc->vc_def_color & 0xf0) | (vc->vc_color & 0x0f);
+                               break;
+                       default:
+                               if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
+                                       vc->vc_color = color_table[vc->vc_par[i] - 30]
+                                               | (vc->vc_color & 0xf0);
+                               else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
+                                       vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
+                                               | (vc->vc_color & 0x0f);
+                               break;
+               }
+       update_attr(vc);
+}
+
+static void respond_string(const char *p, struct tty_struct *tty)
+{
+       while (*p) {
+               tty_insert_flip_char(tty, *p, 0);
+               p++;
+       }
+       con_schedule_flip(tty);
+}
+
+static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
+{
+       char buf[40];
+
+       sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1);
+       respond_string(buf, tty);
+}
+
+static inline void status_report(struct tty_struct *tty)
+{
+       respond_string("\033[0n", tty); /* Terminal ok */
+}
+
+static inline void respond_ID(struct tty_struct * tty)
+{
+       respond_string(VT102ID, tty);
+}
+
+void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
+{
+       char buf[8];
+
+       sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
+               (char)('!' + mry));
+       respond_string(buf, tty);
+}
+
+/* invoked via ioctl(TIOCLINUX) and through set_selection */
+int mouse_reporting(void)
+{
+       return vc_cons[fg_console].d->vc_report_mouse;
+}
+
+/* console_sem is held */
+static void set_mode(struct vc_data *vc, int on_off)
+{
+       int i;
+
+       for (i = 0; i <= vc->vc_npar; i++)
+               if (vc->vc_ques) {
+                       switch(vc->vc_par[i]) { /* DEC private modes set/reset */
+                       case 1:                 /* Cursor keys send ^[Ox/^[[x */
+                               if (on_off)
+                                       set_kbd(vc, decckm);
+                               else
+                                       clr_kbd(vc, decckm);
+                               break;
+                       case 3: /* 80/132 mode switch unimplemented */
+                               vc->vc_deccolm = on_off;
+#if 0
+                               vc_resize(deccolm ? 132 : 80, vc->vc_rows);
+                               /* this alone does not suffice; some user mode
+                                  utility has to change the hardware regs */
+#endif
+                               break;
+                       case 5:                 /* Inverted screen on/off */
+                               if (vc->vc_decscnm != on_off) {
+                                       vc->vc_decscnm = on_off;
+                                       invert_screen(vc, 0, vc->vc_screenbuf_size, 0);
+                                       update_attr(vc);
+                               }
+                               break;
+                       case 6:                 /* Origin relative/absolute */
+                               vc->vc_decom = on_off;
+                               gotoxay(vc, 0, 0);
+                               break;
+                       case 7:                 /* Autowrap on/off */
+                               vc->vc_decawm = on_off;
+                               break;
+                       case 8:                 /* Autorepeat on/off */
+                               if (on_off)
+                                       set_kbd(vc, decarm);
+                               else
+                                       clr_kbd(vc, decarm);
+                               break;
+                       case 9:
+                               vc->vc_report_mouse = on_off ? 1 : 0;
+                               break;
+                       case 25:                /* Cursor on/off */
+                               vc->vc_deccm = on_off;
+                               break;
+                       case 1000:
+                               vc->vc_report_mouse = on_off ? 2 : 0;
+                               break;
+                       }
+               } else {
+                       switch(vc->vc_par[i]) { /* ANSI modes set/reset */
+                       case 3:                 /* Monitor (display ctrls) */
+                               vc->vc_disp_ctrl = on_off;
+                               break;
+                       case 4:                 /* Insert Mode on/off */
+                               vc->vc_decim = on_off;
+                               break;
+                       case 20:                /* Lf, Enter == CrLf/Lf */
+                               if (on_off)
+                                       set_kbd(vc, lnm);
+                               else
+                                       clr_kbd(vc, lnm);
+                               break;
+                       }
+               }
+}
+
+/* console_sem is held */
+static void setterm_command(struct vc_data *vc)
+{
+       switch(vc->vc_par[0]) {
+               case 1: /* set color for underline mode */
+                       if (vc->vc_can_do_color &&
+                                       vc->vc_par[1] < 16) {
+                               vc->vc_ulcolor = color_table[vc->vc_par[1]];
+                               if (vc->vc_underline)
+                                       update_attr(vc);
+                       }
+                       break;
+               case 2: /* set color for half intensity mode */
+                       if (vc->vc_can_do_color &&
+                                       vc->vc_par[1] < 16) {
+                               vc->vc_halfcolor = color_table[vc->vc_par[1]];
+                               if (vc->vc_intensity == 0)
+                                       update_attr(vc);
+                       }
+                       break;
+               case 8: /* store colors as defaults */
+                       vc->vc_def_color = vc->vc_attr;
+                       if (vc->vc_hi_font_mask == 0x100)
+                               vc->vc_def_color >>= 1;
+                       default_attr(vc);
+                       update_attr(vc);
+                       break;
+               case 9: /* set blanking interval */
+                       blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60;
+                       poke_blanked_console();
+                       break;
+               case 10: /* set bell frequency in Hz */
+                       if (vc->vc_npar >= 1)
+                               vc->vc_bell_pitch = vc->vc_par[1];
+                       else
+                               vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
+                       break;
+               case 11: /* set bell duration in msec */
+                       if (vc->vc_npar >= 1)
+                               vc->vc_bell_duration = (vc->vc_par[1] < 2000) ?
+                                       vc->vc_par[1] * HZ / 1000 : 0;
+                       else
+                               vc->vc_bell_duration = DEFAULT_BELL_DURATION;
+                       break;
+               case 12: /* bring specified console to the front */
+                       if (vc->vc_par[1] >= 1 && vc_cons_allocated(vc->vc_par[1] - 1))
+                               set_console(vc->vc_par[1] - 1);
+                       break;
+               case 13: /* unblank the screen */
+                       poke_blanked_console();
+                       break;
+               case 14: /* set vesa powerdown interval */
+                       vesa_off_interval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ;
+                       break;
+               case 15: /* activate the previous console */
+                       set_console(last_console);
+                       break;
+       }
+}
+
+/* console_sem is held */
+static void csi_at(struct vc_data *vc, unsigned int nr)
+{
+       if (nr > vc->vc_cols - vc->vc_x)
+               nr = vc->vc_cols - vc->vc_x;
+       else if (!nr)
+               nr = 1;
+       insert_char(vc, nr);
+}
+
+/* console_sem is held */
+static void csi_L(struct vc_data *vc, unsigned int nr)
+{
+       if (nr > vc->vc_rows - vc->vc_y)
+               nr = vc->vc_rows - vc->vc_y;
+       else if (!nr)
+               nr = 1;
+       scrdown(vc, vc->vc_y, vc->vc_bottom, nr);
+       vc->vc_need_wrap = 0;
+}
+
+/* console_sem is held */
+static void csi_P(struct vc_data *vc, unsigned int nr)
+{
+       if (nr > vc->vc_cols - vc->vc_x)
+               nr = vc->vc_cols - vc->vc_x;
+       else if (!nr)
+               nr = 1;
+       delete_char(vc, nr);
+}
+
+/* console_sem is held */
+static void csi_M(struct vc_data *vc, unsigned int nr)
+{
+       if (nr > vc->vc_rows - vc->vc_y)
+               nr = vc->vc_rows - vc->vc_y;
+       else if (!nr)
+               nr=1;
+       scrup(vc, vc->vc_y, vc->vc_bottom, nr);
+       vc->vc_need_wrap = 0;
+}
+
+/* console_sem is held (except via vc_init->reset_terminal */
+static void save_cur(struct vc_data *vc)
+{
+       vc->vc_saved_x          = vc->vc_x;
+       vc->vc_saved_y          = vc->vc_y;
+       vc->vc_s_intensity      = vc->vc_intensity;
+       vc->vc_s_italic         = vc->vc_italic;
+       vc->vc_s_underline      = vc->vc_underline;
+       vc->vc_s_blink          = vc->vc_blink;
+       vc->vc_s_reverse        = vc->vc_reverse;
+       vc->vc_s_charset        = vc->vc_charset;
+       vc->vc_s_color          = vc->vc_color;
+       vc->vc_saved_G0         = vc->vc_G0_charset;
+       vc->vc_saved_G1         = vc->vc_G1_charset;
+}
+
+/* console_sem is held */
+static void restore_cur(struct vc_data *vc)
+{
+       gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
+       vc->vc_intensity        = vc->vc_s_intensity;
+       vc->vc_italic           = vc->vc_s_italic;
+       vc->vc_underline        = vc->vc_s_underline;
+       vc->vc_blink            = vc->vc_s_blink;
+       vc->vc_reverse          = vc->vc_s_reverse;
+       vc->vc_charset          = vc->vc_s_charset;
+       vc->vc_color            = vc->vc_s_color;
+       vc->vc_G0_charset       = vc->vc_saved_G0;
+       vc->vc_G1_charset       = vc->vc_saved_G1;
+       vc->vc_translate        = set_translate(vc->vc_charset ? vc->vc_G1_charset : vc->vc_G0_charset, vc);
+       update_attr(vc);
+       vc->vc_need_wrap = 0;
+}
+
+enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
+       EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
+       ESpalette };
+
+/* console_sem is held (except via vc_init()) */
+static void reset_terminal(struct vc_data *vc, int do_clear)
+{
+       vc->vc_top              = 0;
+       vc->vc_bottom           = vc->vc_rows;
+       vc->vc_state            = ESnormal;
+       vc->vc_ques             = 0;
+       vc->vc_translate        = set_translate(LAT1_MAP, vc);
+       vc->vc_G0_charset       = LAT1_MAP;
+       vc->vc_G1_charset       = GRAF_MAP;
+       vc->vc_charset          = 0;
+       vc->vc_need_wrap        = 0;
+       vc->vc_report_mouse     = 0;
+       vc->vc_utf              = default_utf8;
+       vc->vc_utf_count        = 0;
+
+       vc->vc_disp_ctrl        = 0;
+       vc->vc_toggle_meta      = 0;
+
+       vc->vc_decscnm          = 0;
+       vc->vc_decom            = 0;
+       vc->vc_decawm           = 1;
+       vc->vc_deccm            = global_cursor_default;
+       vc->vc_decim            = 0;
+
+       set_kbd(vc, decarm);
+       clr_kbd(vc, decckm);
+       clr_kbd(vc, kbdapplic);
+       clr_kbd(vc, lnm);
+       kbd_table[vc->vc_num].lockstate = 0;
+       kbd_table[vc->vc_num].slockstate = 0;
+       kbd_table[vc->vc_num].ledmode = LED_SHOW_FLAGS;
+       kbd_table[vc->vc_num].ledflagstate = kbd_table[vc->vc_num].default_ledflagstate;
+       /* do not do set_leds here because this causes an endless tasklet loop
+          when the keyboard hasn't been initialized yet */
+
+       vc->vc_cursor_type = cur_default;
+       vc->vc_complement_mask = vc->vc_s_complement_mask;
+
+       default_attr(vc);
+       update_attr(vc);
+
+       vc->vc_tab_stop[0]      = 0x01010100;
+       vc->vc_tab_stop[1]      =
+       vc->vc_tab_stop[2]      =
+       vc->vc_tab_stop[3]      =
+       vc->vc_tab_stop[4]      =
+       vc->vc_tab_stop[5]      =
+       vc->vc_tab_stop[6]      =
+       vc->vc_tab_stop[7]      = 0x01010101;
+
+       vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
+       vc->vc_bell_duration = DEFAULT_BELL_DURATION;
+
+       gotoxy(vc, 0, 0);
+       save_cur(vc);
+       if (do_clear)
+           csi_J(vc, 2);
+}
+
+/* console_sem is held */
+static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
+{
+       /*
+        *  Control characters can be used in the _middle_
+        *  of an escape sequence.
+        */
+       switch (c) {
+       case 0:
+               return;
+       case 7:
+               if (vc->vc_bell_duration)
+                       kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
+               return;
+       case 8:
+               bs(vc);
+               return;
+       case 9:
+               vc->vc_pos -= (vc->vc_x << 1);
+               while (vc->vc_x < vc->vc_cols - 1) {
+                       vc->vc_x++;
+                       if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31)))
+                               break;
+               }
+               vc->vc_pos += (vc->vc_x << 1);
+               notify_write(vc, '\t');
+               return;
+       case 10: case 11: case 12:
+               lf(vc);
+               if (!is_kbd(vc, lnm))
+                       return;
+       case 13:
+               cr(vc);
+               return;
+       case 14:
+               vc->vc_charset = 1;
+               vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
+               vc->vc_disp_ctrl = 1;
+               return;
+       case 15:
+               vc->vc_charset = 0;
+               vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
+               vc->vc_disp_ctrl = 0;
+               return;
+       case 24: case 26:
+               vc->vc_state = ESnormal;
+               return;
+       case 27:
+               vc->vc_state = ESesc;
+               return;
+       case 127:
+               del(vc);
+               return;
+       case 128+27:
+               vc->vc_state = ESsquare;
+               return;
+       }
+       switch(vc->vc_state) {
+       case ESesc:
+               vc->vc_state = ESnormal;
+               switch (c) {
+               case '[':
+                       vc->vc_state = ESsquare;
+                       return;
+               case ']':
+                       vc->vc_state = ESnonstd;
+                       return;
+               case '%':
+                       vc->vc_state = ESpercent;
+                       return;
+               case 'E':
+                       cr(vc);
+                       lf(vc);
+                       return;
+               case 'M':
+                       ri(vc);
+                       return;
+               case 'D':
+                       lf(vc);
+                       return;
+               case 'H':
+                       vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31));
+                       return;
+               case 'Z':
+                       respond_ID(tty);
+                       return;
+               case '7':
+                       save_cur(vc);
+                       return;
+               case '8':
+                       restore_cur(vc);
+                       return;
+               case '(':
+                       vc->vc_state = ESsetG0;
+                       return;
+               case ')':
+                       vc->vc_state = ESsetG1;
+                       return;
+               case '#':
+                       vc->vc_state = EShash;
+                       return;
+               case 'c':
+                       reset_terminal(vc, 1);
+                       return;
+               case '>':  /* Numeric keypad */
+                       clr_kbd(vc, kbdapplic);
+                       return;
+               case '=':  /* Appl. keypad */
+                       set_kbd(vc, kbdapplic);
+                       return;
+               }
+               return;
+       case ESnonstd:
+               if (c=='P') {   /* palette escape sequence */
+                       for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
+                               vc->vc_par[vc->vc_npar] = 0;
+                       vc->vc_npar = 0;
+                       vc->vc_state = ESpalette;
+                       return;
+               } else if (c=='R') {   /* reset palette */
+                       reset_palette(vc);
+                       vc->vc_state = ESnormal;
+               } else
+                       vc->vc_state = ESnormal;
+               return;
+       case ESpalette:
+               if (isxdigit(c)) {
+                       vc->vc_par[vc->vc_npar++] = hex_to_bin(c);
+                       if (vc->vc_npar == 7) {
+                               int i = vc->vc_par[0] * 3, j = 1;
+                               vc->vc_palette[i] = 16 * vc->vc_par[j++];
+                               vc->vc_palette[i++] += vc->vc_par[j++];
+                               vc->vc_palette[i] = 16 * vc->vc_par[j++];
+                               vc->vc_palette[i++] += vc->vc_par[j++];
+                               vc->vc_palette[i] = 16 * vc->vc_par[j++];
+                               vc->vc_palette[i] += vc->vc_par[j];
+                               set_palette(vc);
+                               vc->vc_state = ESnormal;
+                       }
+               } else
+                       vc->vc_state = ESnormal;
+               return;
+       case ESsquare:
+               for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
+                       vc->vc_par[vc->vc_npar] = 0;
+               vc->vc_npar = 0;
+               vc->vc_state = ESgetpars;
+               if (c == '[') { /* Function key */
+                       vc->vc_state=ESfunckey;
+                       return;
+               }
+               vc->vc_ques = (c == '?');
+               if (vc->vc_ques)
+                       return;
+       case ESgetpars:
+               if (c == ';' && vc->vc_npar < NPAR - 1) {
+                       vc->vc_npar++;
+                       return;
+               } else if (c>='0' && c<='9') {
+                       vc->vc_par[vc->vc_npar] *= 10;
+                       vc->vc_par[vc->vc_npar] += c - '0';
+                       return;
+               } else
+                       vc->vc_state = ESgotpars;
+       case ESgotpars:
+               vc->vc_state = ESnormal;
+               switch(c) {
+               case 'h':
+                       set_mode(vc, 1);
+                       return;
+               case 'l':
+                       set_mode(vc, 0);
+                       return;
+               case 'c':
+                       if (vc->vc_ques) {
+                               if (vc->vc_par[0])
+                                       vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
+                               else
+                                       vc->vc_cursor_type = cur_default;
+                               return;
+                       }
+                       break;
+               case 'm':
+                       if (vc->vc_ques) {
+                               clear_selection();
+                               if (vc->vc_par[0])
+                                       vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
+                               else
+                                       vc->vc_complement_mask = vc->vc_s_complement_mask;
+                               return;
+                       }
+                       break;
+               case 'n':
+                       if (!vc->vc_ques) {
+                               if (vc->vc_par[0] == 5)
+                                       status_report(tty);
+                               else if (vc->vc_par[0] == 6)
+                                       cursor_report(vc, tty);
+                       }
+                       return;
+               }
+               if (vc->vc_ques) {
+                       vc->vc_ques = 0;
+                       return;
+               }
+               switch(c) {
+               case 'G': case '`':
+                       if (vc->vc_par[0])
+                               vc->vc_par[0]--;
+                       gotoxy(vc, vc->vc_par[0], vc->vc_y);
+                       return;
+               case 'A':
+                       if (!vc->vc_par[0])
+                               vc->vc_par[0]++;
+                       gotoxy(vc, vc->vc_x, vc->vc_y - vc->vc_par[0]);
+                       return;
+               case 'B': case 'e':
+                       if (!vc->vc_par[0])
+                               vc->vc_par[0]++;
+                       gotoxy(vc, vc->vc_x, vc->vc_y + vc->vc_par[0]);
+                       return;
+               case 'C': case 'a':
+                       if (!vc->vc_par[0])
+                               vc->vc_par[0]++;
+                       gotoxy(vc, vc->vc_x + vc->vc_par[0], vc->vc_y);
+                       return;
+               case 'D':
+                       if (!vc->vc_par[0])
+                               vc->vc_par[0]++;
+                       gotoxy(vc, vc->vc_x - vc->vc_par[0], vc->vc_y);
+                       return;
+               case 'E':
+                       if (!vc->vc_par[0])
+                               vc->vc_par[0]++;
+                       gotoxy(vc, 0, vc->vc_y + vc->vc_par[0]);
+                       return;
+               case 'F':
+                       if (!vc->vc_par[0])
+                               vc->vc_par[0]++;
+                       gotoxy(vc, 0, vc->vc_y - vc->vc_par[0]);
+                       return;
+               case 'd':
+                       if (vc->vc_par[0])
+                               vc->vc_par[0]--;
+                       gotoxay(vc, vc->vc_x ,vc->vc_par[0]);
+                       return;
+               case 'H': case 'f':
+                       if (vc->vc_par[0])
+                               vc->vc_par[0]--;
+                       if (vc->vc_par[1])
+                               vc->vc_par[1]--;
+                       gotoxay(vc, vc->vc_par[1], vc->vc_par[0]);
+                       return;
+               case 'J':
+                       csi_J(vc, vc->vc_par[0]);
+                       return;
+               case 'K':
+                       csi_K(vc, vc->vc_par[0]);
+                       return;
+               case 'L':
+                       csi_L(vc, vc->vc_par[0]);
+                       return;
+               case 'M':
+                       csi_M(vc, vc->vc_par[0]);
+                       return;
+               case 'P':
+                       csi_P(vc, vc->vc_par[0]);
+                       return;
+               case 'c':
+                       if (!vc->vc_par[0])
+                               respond_ID(tty);
+                       return;
+               case 'g':
+                       if (!vc->vc_par[0])
+                               vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31));
+                       else if (vc->vc_par[0] == 3) {
+                               vc->vc_tab_stop[0] =
+                                       vc->vc_tab_stop[1] =
+                                       vc->vc_tab_stop[2] =
+                                       vc->vc_tab_stop[3] =
+                                       vc->vc_tab_stop[4] =
+                                       vc->vc_tab_stop[5] =
+                                       vc->vc_tab_stop[6] =
+                                       vc->vc_tab_stop[7] = 0;
+                       }
+                       return;
+               case 'm':
+                       csi_m(vc);
+                       return;
+               case 'q': /* DECLL - but only 3 leds */
+                       /* map 0,1,2,3 to 0,1,2,4 */
+                       if (vc->vc_par[0] < 4)
+                               setledstate(kbd_table + vc->vc_num,
+                                           (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
+                       return;
+               case 'r':
+                       if (!vc->vc_par[0])
+                               vc->vc_par[0]++;
+                       if (!vc->vc_par[1])
+                               vc->vc_par[1] = vc->vc_rows;
+                       /* Minimum allowed region is 2 lines */
+                       if (vc->vc_par[0] < vc->vc_par[1] &&
+                           vc->vc_par[1] <= vc->vc_rows) {
+                               vc->vc_top = vc->vc_par[0] - 1;
+                               vc->vc_bottom = vc->vc_par[1];
+                               gotoxay(vc, 0, 0);
+                       }
+                       return;
+               case 's':
+                       save_cur(vc);
+                       return;
+               case 'u':
+                       restore_cur(vc);
+                       return;
+               case 'X':
+                       csi_X(vc, vc->vc_par[0]);
+                       return;
+               case '@':
+                       csi_at(vc, vc->vc_par[0]);
+                       return;
+               case ']': /* setterm functions */
+                       setterm_command(vc);
+                       return;
+               }
+               return;
+       case ESpercent:
+               vc->vc_state = ESnormal;
+               switch (c) {
+               case '@':  /* defined in ISO 2022 */
+                       vc->vc_utf = 0;
+                       return;
+               case 'G':  /* prelim official escape code */
+               case '8':  /* retained for compatibility */
+                       vc->vc_utf = 1;
+                       return;
+               }
+               return;
+       case ESfunckey:
+               vc->vc_state = ESnormal;
+               return;
+       case EShash:
+               vc->vc_state = ESnormal;
+               if (c == '8') {
+                       /* DEC screen alignment test. kludge :-) */
+                       vc->vc_video_erase_char =
+                               (vc->vc_video_erase_char & 0xff00) | 'E';
+                       csi_J(vc, 2);
+                       vc->vc_video_erase_char =
+                               (vc->vc_video_erase_char & 0xff00) | ' ';
+                       do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
+               }
+               return;
+       case ESsetG0:
+               if (c == '0')
+                       vc->vc_G0_charset = GRAF_MAP;
+               else if (c == 'B')
+                       vc->vc_G0_charset = LAT1_MAP;
+               else if (c == 'U')
+                       vc->vc_G0_charset = IBMPC_MAP;
+               else if (c == 'K')
+                       vc->vc_G0_charset = USER_MAP;
+               if (vc->vc_charset == 0)
+                       vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
+               vc->vc_state = ESnormal;
+               return;
+       case ESsetG1:
+               if (c == '0')
+                       vc->vc_G1_charset = GRAF_MAP;
+               else if (c == 'B')
+                       vc->vc_G1_charset = LAT1_MAP;
+               else if (c == 'U')
+                       vc->vc_G1_charset = IBMPC_MAP;
+               else if (c == 'K')
+                       vc->vc_G1_charset = USER_MAP;
+               if (vc->vc_charset == 1)
+                       vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
+               vc->vc_state = ESnormal;
+               return;
+       default:
+               vc->vc_state = ESnormal;
+       }
+}
+
+/* This is a temporary buffer used to prepare a tty console write
+ * so that we can easily avoid touching user space while holding the
+ * console spinlock.  It is allocated in con_init and is shared by
+ * this code and the vc_screen read/write tty calls.
+ *
+ * We have to allocate this statically in the kernel data section
+ * since console_init (and thus con_init) are called before any
+ * kernel memory allocation is available.
+ */
+char con_buf[CON_BUF_SIZE];
+DEFINE_MUTEX(con_buf_mtx);
+
+/* is_double_width() is based on the wcwidth() implementation by
+ * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
+ * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+struct interval {
+       uint32_t first;
+       uint32_t last;
+};
+
+static int bisearch(uint32_t ucs, const struct interval *table, int max)
+{
+       int min = 0;
+       int mid;
+
+       if (ucs < table[0].first || ucs > table[max].last)
+               return 0;
+       while (max >= min) {
+               mid = (min + max) / 2;
+               if (ucs > table[mid].last)
+                       min = mid + 1;
+               else if (ucs < table[mid].first)
+                       max = mid - 1;
+               else
+                       return 1;
+       }
+       return 0;
+}
+
+static int is_double_width(uint32_t ucs)
+{
+       static const struct interval double_width[] = {
+               { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E },
+               { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF },
+               { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 },
+               { 0xFFE0, 0xFFE6 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD }
+       };
+       return bisearch(ucs, double_width, ARRAY_SIZE(double_width) - 1);
+}
+
+/* acquires console_sem */
+static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+#ifdef VT_BUF_VRAM_ONLY
+#define FLUSH do { } while(0);
+#else
+#define FLUSH if (draw_x >= 0) { \
+       vc->vc_sw->con_putcs(vc, (u16 *)draw_from, (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, draw_x); \
+       draw_x = -1; \
+       }
+#endif
+
+       int c, tc, ok, n = 0, draw_x = -1;
+       unsigned int currcons;
+       unsigned long draw_from = 0, draw_to = 0;
+       struct vc_data *vc;
+       unsigned char vc_attr;
+       struct vt_notifier_param param;
+       uint8_t rescan;
+       uint8_t inverse;
+       uint8_t width;
+       u16 himask, charmask;
+
+       if (in_interrupt())
+               return count;
+
+       might_sleep();
+
+       acquire_console_sem();
+       vc = tty->driver_data;
+       if (vc == NULL) {
+               printk(KERN_ERR "vt: argh, driver_data is NULL !\n");
+               release_console_sem();
+               return 0;
+       }
+
+       currcons = vc->vc_num;
+       if (!vc_cons_allocated(currcons)) {
+           /* could this happen? */
+               printk_once("con_write: tty %d not allocated\n", currcons+1);
+           release_console_sem();
+           return 0;
+       }
+
+       himask = vc->vc_hi_font_mask;
+       charmask = himask ? 0x1ff : 0xff;
+
+       /* undraw cursor first */
+       if (IS_FG(vc))
+               hide_cursor(vc);
+
+       param.vc = vc;
+
+       while (!tty->stopped && count) {
+               int orig = *buf;
+               c = orig;
+               buf++;
+               n++;
+               count--;
+               rescan = 0;
+               inverse = 0;
+               width = 1;
+
+               /* Do no translation at all in control states */
+               if (vc->vc_state != ESnormal) {
+                       tc = c;
+               } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
+                   /* Combine UTF-8 into Unicode in vc_utf_char.
+                    * vc_utf_count is the number of continuation bytes still
+                    * expected to arrive.
+                    * vc_npar is the number of continuation bytes arrived so
+                    * far
+                    */
+rescan_last_byte:
+                   if ((c & 0xc0) == 0x80) {
+                       /* Continuation byte received */
+                       static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
+                       if (vc->vc_utf_count) {
+                           vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
+                           vc->vc_npar++;
+                           if (--vc->vc_utf_count) {
+                               /* Still need some bytes */
+                               continue;
+                           }
+                           /* Got a whole character */
+                           c = vc->vc_utf_char;
+                           /* Reject overlong sequences */
+                           if (c <= utf8_length_changes[vc->vc_npar - 1] ||
+                                       c > utf8_length_changes[vc->vc_npar])
+                               c = 0xfffd;
+                       } else {
+                           /* Unexpected continuation byte */
+                           vc->vc_utf_count = 0;
+                           c = 0xfffd;
+                       }
+                   } else {
+                       /* Single ASCII byte or first byte of a sequence received */
+                       if (vc->vc_utf_count) {
+                           /* Continuation byte expected */
+                           rescan = 1;
+                           vc->vc_utf_count = 0;
+                           c = 0xfffd;
+                       } else if (c > 0x7f) {
+                           /* First byte of a multibyte sequence received */
+                           vc->vc_npar = 0;
+                           if ((c & 0xe0) == 0xc0) {
+                               vc->vc_utf_count = 1;
+                               vc->vc_utf_char = (c & 0x1f);
+                           } else if ((c & 0xf0) == 0xe0) {
+                               vc->vc_utf_count = 2;
+                               vc->vc_utf_char = (c & 0x0f);
+                           } else if ((c & 0xf8) == 0xf0) {
+                               vc->vc_utf_count = 3;
+                               vc->vc_utf_char = (c & 0x07);
+                           } else if ((c & 0xfc) == 0xf8) {
+                               vc->vc_utf_count = 4;
+                               vc->vc_utf_char = (c & 0x03);
+                           } else if ((c & 0xfe) == 0xfc) {
+                               vc->vc_utf_count = 5;
+                               vc->vc_utf_char = (c & 0x01);
+                           } else {
+                               /* 254 and 255 are invalid */
+                               c = 0xfffd;
+                           }
+                           if (vc->vc_utf_count) {
+                               /* Still need some bytes */
+                               continue;
+                           }
+                       }
+                       /* Nothing to do if an ASCII byte was received */
+                   }
+                   /* End of UTF-8 decoding. */
+                   /* c is the received character, or U+FFFD for invalid sequences. */
+                   /* Replace invalid Unicode code points with U+FFFD too */
+                   if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
+                       c = 0xfffd;
+                   tc = c;
+               } else {        /* no utf or alternate charset mode */
+                   tc = vc_translate(vc, c);
+               }
+
+               param.c = tc;
+               if (atomic_notifier_call_chain(&vt_notifier_list, VT_PREWRITE,
+                                       &param) == NOTIFY_STOP)
+                       continue;
+
+                /* If the original code was a control character we
+                 * only allow a glyph to be displayed if the code is
+                 * not normally used (such as for cursor movement) or
+                 * if the disp_ctrl mode has been explicitly enabled.
+                 * Certain characters (as given by the CTRL_ALWAYS
+                 * bitmap) are always displayed as control characters,
+                 * as the console would be pretty useless without
+                 * them; to display an arbitrary font position use the
+                 * direct-to-font zone in UTF-8 mode.
+                 */
+                ok = tc && (c >= 32 ||
+                           !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
+                                 vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
+                       && (c != 127 || vc->vc_disp_ctrl)
+                       && (c != 128+27);
+
+               if (vc->vc_state == ESnormal && ok) {
+                       if (vc->vc_utf && !vc->vc_disp_ctrl) {
+                               if (is_double_width(c))
+                                       width = 2;
+                       }
+                       /* Now try to find out how to display it */
+                       tc = conv_uni_to_pc(vc, tc);
+                       if (tc & ~charmask) {
+                               if (tc == -1 || tc == -2) {
+                                   continue; /* nothing to display */
+                               }
+                               /* Glyph not found */
+                               if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
+                                   /* In legacy mode use the glyph we get by a 1:1 mapping.
+                                      This would make absolutely no sense with Unicode in mind,
+                                      but do this for ASCII characters since a font may lack
+                                      Unicode mapping info and we don't want to end up with
+                                      having question marks only. */
+                                   tc = c;
+                               } else {
+                                   /* Display U+FFFD. If it's not found, display an inverse question mark. */
+                                   tc = conv_uni_to_pc(vc, 0xfffd);
+                                   if (tc < 0) {
+                                       inverse = 1;
+                                       tc = conv_uni_to_pc(vc, '?');
+                                       if (tc < 0) tc = '?';
+                                   }
+                               }
+                       }
+
+                       if (!inverse) {
+                               vc_attr = vc->vc_attr;
+                       } else {
+                               /* invert vc_attr */
+                               if (!vc->vc_can_do_color) {
+                                       vc_attr = (vc->vc_attr) ^ 0x08;
+                               } else if (vc->vc_hi_font_mask == 0x100) {
+                                       vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
+                               } else {
+                                       vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
+                               }
+                               FLUSH
+                       }
+
+                       while (1) {
+                               if (vc->vc_need_wrap || vc->vc_decim)
+                                       FLUSH
+                               if (vc->vc_need_wrap) {
+                                       cr(vc);
+                                       lf(vc);
+                               }
+                               if (vc->vc_decim)
+                                       insert_char(vc, 1);
+                               scr_writew(himask ?
+                                            ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+                                            (vc_attr << 8) + tc,
+                                          (u16 *) vc->vc_pos);
+                               if (DO_UPDATE(vc) && draw_x < 0) {
+                                       draw_x = vc->vc_x;
+                                       draw_from = vc->vc_pos;
+                               }
+                               if (vc->vc_x == vc->vc_cols - 1) {
+                                       vc->vc_need_wrap = vc->vc_decawm;
+                                       draw_to = vc->vc_pos + 2;
+                               } else {
+                                       vc->vc_x++;
+                                       draw_to = (vc->vc_pos += 2);
+                               }
+
+                               if (!--width) break;
+
+                               tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
+                               if (tc < 0) tc = ' ';
+                       }
+                       notify_write(vc, c);
+
+                       if (inverse) {
+                               FLUSH
+                       }
+
+                       if (rescan) {
+                               rescan = 0;
+                               inverse = 0;
+                               width = 1;
+                               c = orig;
+                               goto rescan_last_byte;
+                       }
+                       continue;
+               }
+               FLUSH
+               do_con_trol(tty, vc, orig);
+       }
+       FLUSH
+       console_conditional_schedule();
+       release_console_sem();
+       notify_update(vc);
+       return n;
+#undef FLUSH
+}
+
+/*
+ * This is the console switching callback.
+ *
+ * Doing console switching in a process context allows
+ * us to do the switches asynchronously (needed when we want
+ * to switch due to a keyboard interrupt).  Synchronization
+ * with other console code and prevention of re-entrancy is
+ * ensured with console_sem.
+ */
+static void console_callback(struct work_struct *ignored)
+{
+       acquire_console_sem();
+
+       if (want_console >= 0) {
+               if (want_console != fg_console &&
+                   vc_cons_allocated(want_console)) {
+                       hide_cursor(vc_cons[fg_console].d);
+                       change_console(vc_cons[want_console].d);
+                       /* we only changed when the console had already
+                          been allocated - a new console is not created
+                          in an interrupt routine */
+               }
+               want_console = -1;
+       }
+       if (do_poke_blanked_console) { /* do not unblank for a LED change */
+               do_poke_blanked_console = 0;
+               poke_blanked_console();
+       }
+       if (scrollback_delta) {
+               struct vc_data *vc = vc_cons[fg_console].d;
+               clear_selection();
+               if (vc->vc_mode == KD_TEXT)
+                       vc->vc_sw->con_scrolldelta(vc, scrollback_delta);
+               scrollback_delta = 0;
+       }
+       if (blank_timer_expired) {
+               do_blank_screen(0);
+               blank_timer_expired = 0;
+       }
+       notify_update(vc_cons[fg_console].d);
+
+       release_console_sem();
+}
+
+int set_console(int nr)
+{
+       struct vc_data *vc = vc_cons[fg_console].d;
+
+       if (!vc_cons_allocated(nr) || vt_dont_switch ||
+               (vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) {
+
+               /*
+                * Console switch will fail in console_callback() or
+                * change_console() so there is no point scheduling
+                * the callback
+                *
+                * Existing set_console() users don't check the return
+                * value so this shouldn't break anything
+                */
+               return -EINVAL;
+       }
+
+       want_console = nr;
+       schedule_console_callback();
+
+       return 0;
+}
+
+struct tty_driver *console_driver;
+
+#ifdef CONFIG_VT_CONSOLE
+
+/**
+ * vt_kmsg_redirect() - Sets/gets the kernel message console
+ * @new:       The new virtual terminal number or -1 if the console should stay
+ *             unchanged
+ *
+ * By default, the kernel messages are always printed on the current virtual
+ * console. However, the user may modify that default with the
+ * TIOCL_SETKMSGREDIRECT ioctl call.
+ *
+ * This function sets the kernel message console to be @new. It returns the old
+ * virtual console number. The virtual terminal number 0 (both as parameter and
+ * return value) means no redirection (i.e. always printed on the currently
+ * active console).
+ *
+ * The parameter -1 means that only the current console is returned, but the
+ * value is not modified. You may use the macro vt_get_kmsg_redirect() in that
+ * case to make the code more understandable.
+ *
+ * When the kernel is compiled without CONFIG_VT_CONSOLE, this function ignores
+ * the parameter and always returns 0.
+ */
+int vt_kmsg_redirect(int new)
+{
+       static int kmsg_con;
+
+       if (new != -1)
+               return xchg(&kmsg_con, new);
+       else
+               return kmsg_con;
+}
+
+/*
+ *     Console on virtual terminal
+ *
+ * The console must be locked when we get here.
+ */
+
+static void vt_console_print(struct console *co, const char *b, unsigned count)
+{
+       struct vc_data *vc = vc_cons[fg_console].d;
+       unsigned char c;
+       static DEFINE_SPINLOCK(printing_lock);
+       const ushort *start;
+       ushort cnt = 0;
+       ushort myx;
+       int kmsg_console;
+
+       /* console busy or not yet initialized */
+       if (!printable)
+               return;
+       if (!spin_trylock(&printing_lock))
+               return;
+
+       kmsg_console = vt_get_kmsg_redirect();
+       if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
+               vc = vc_cons[kmsg_console - 1].d;
+
+       /* read `x' only after setting currcons properly (otherwise
+          the `x' macro will read the x of the foreground console). */
+       myx = vc->vc_x;
+
+       if (!vc_cons_allocated(fg_console)) {
+               /* impossible */
+               /* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */
+               goto quit;
+       }
+
+       if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
+               goto quit;
+
+       /* undraw cursor first */
+       if (IS_FG(vc))
+               hide_cursor(vc);
+
+       start = (ushort *)vc->vc_pos;
+
+       /* Contrived structure to try to emulate original need_wrap behaviour
+        * Problems caused when we have need_wrap set on '\n' character */
+       while (count--) {
+               c = *b++;
+               if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
+                       if (cnt > 0) {
+                               if (CON_IS_VISIBLE(vc))
+                                       vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
+                               vc->vc_x += cnt;
+                               if (vc->vc_need_wrap)
+                                       vc->vc_x--;
+                               cnt = 0;
+                       }
+                       if (c == 8) {           /* backspace */
+                               bs(vc);
+                               start = (ushort *)vc->vc_pos;
+                               myx = vc->vc_x;
+                               continue;
+                       }
+                       if (c != 13)
+                               lf(vc);
+                       cr(vc);
+                       start = (ushort *)vc->vc_pos;
+                       myx = vc->vc_x;
+                       if (c == 10 || c == 13)
+                               continue;
+               }
+               scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
+               notify_write(vc, c);
+               cnt++;
+               if (myx == vc->vc_cols - 1) {
+                       vc->vc_need_wrap = 1;
+                       continue;
+               }
+               vc->vc_pos += 2;
+               myx++;
+       }
+       if (cnt > 0) {
+               if (CON_IS_VISIBLE(vc))
+                       vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
+               vc->vc_x += cnt;
+               if (vc->vc_x == vc->vc_cols) {
+                       vc->vc_x--;
+                       vc->vc_need_wrap = 1;
+               }
+       }
+       set_cursor(vc);
+       notify_update(vc);
+
+quit:
+       spin_unlock(&printing_lock);
+}
+
+static struct tty_driver *vt_console_device(struct console *c, int *index)
+{
+       *index = c->index ? c->index-1 : fg_console;
+       return console_driver;
+}
+
+static struct console vt_console_driver = {
+       .name           = "tty",
+       .write          = vt_console_print,
+       .device         = vt_console_device,
+       .unblank        = unblank_screen,
+       .flags          = CON_PRINTBUFFER,
+       .index          = -1,
+};
+#endif
+
+/*
+ *     Handling of Linux-specific VC ioctls
+ */
+
+/*
+ * Generally a bit racy with respect to console_sem().
+ *
+ * There are some functions which don't need it.
+ *
+ * There are some functions which can sleep for arbitrary periods
+ * (paste_selection) but we don't need the lock there anyway.
+ *
+ * set_selection has locking, and definitely needs it
+ */
+
+int tioclinux(struct tty_struct *tty, unsigned long arg)
+{
+       char type, data;
+       char __user *p = (char __user *)arg;
+       int lines;
+       int ret;
+
+       if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (get_user(type, p))
+               return -EFAULT;
+       ret = 0;
+
+       switch (type)
+       {
+               case TIOCL_SETSEL:
+                       acquire_console_sem();
+                       ret = set_selection((struct tiocl_selection __user *)(p+1), tty);
+                       release_console_sem();
+                       break;
+               case TIOCL_PASTESEL:
+                       ret = paste_selection(tty);
+                       break;
+               case TIOCL_UNBLANKSCREEN:
+                       acquire_console_sem();
+                       unblank_screen();
+                       release_console_sem();
+                       break;
+               case TIOCL_SELLOADLUT:
+                       ret = sel_loadlut(p);
+                       break;
+               case TIOCL_GETSHIFTSTATE:
+
+       /*
+        * Make it possible to react to Shift+Mousebutton.
+        * Note that 'shift_state' is an undocumented
+        * kernel-internal variable; programs not closely
+        * related to the kernel should not use this.
+        */
+                       data = shift_state;
+                       ret = __put_user(data, p);
+                       break;
+               case TIOCL_GETMOUSEREPORTING:
+                       data = mouse_reporting();
+                       ret = __put_user(data, p);
+                       break;
+               case TIOCL_SETVESABLANK:
+                       ret = set_vesa_blanking(p);
+                       break;
+               case TIOCL_GETKMSGREDIRECT:
+                       data = vt_get_kmsg_redirect();
+                       ret = __put_user(data, p);
+                       break;
+               case TIOCL_SETKMSGREDIRECT:
+                       if (!capable(CAP_SYS_ADMIN)) {
+                               ret = -EPERM;
+                       } else {
+                               if (get_user(data, p+1))
+                                       ret = -EFAULT;
+                               else
+                                       vt_kmsg_redirect(data);
+                       }
+                       break;
+               case TIOCL_GETFGCONSOLE:
+                       ret = fg_console;
+                       break;
+               case TIOCL_SCROLLCONSOLE:
+                       if (get_user(lines, (s32 __user *)(p+4))) {
+                               ret = -EFAULT;
+                       } else {
+                               scrollfront(vc_cons[fg_console].d, lines);
+                               ret = 0;
+                       }
+                       break;
+               case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */
+                       acquire_console_sem();
+                       ignore_poke = 1;
+                       do_blank_screen(0);
+                       release_console_sem();
+                       break;
+               case TIOCL_BLANKEDSCREEN:
+                       ret = console_blanked;
+                       break;
+               default:
+                       ret = -EINVAL;
+                       break;
+       }
+       return ret;
+}
+
+/*
+ * /dev/ttyN handling
+ */
+
+static int con_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+       int     retval;
+
+       retval = do_con_write(tty, buf, count);
+       con_flush_chars(tty);
+
+       return retval;
+}
+
+static int con_put_char(struct tty_struct *tty, unsigned char ch)
+{
+       if (in_interrupt())
+               return 0;       /* n_r3964 calls put_char() from interrupt context */
+       return do_con_write(tty, &ch, 1);
+}
+
+static int con_write_room(struct tty_struct *tty)
+{
+       if (tty->stopped)
+               return 0;
+       return 32768;           /* No limit, really; we're not buffering */
+}
+
+static int con_chars_in_buffer(struct tty_struct *tty)
+{
+       return 0;               /* we're not buffering */
+}
+
+/*
+ * con_throttle and con_unthrottle are only used for
+ * paste_selection(), which has to stuff in a large number of
+ * characters...
+ */
+static void con_throttle(struct tty_struct *tty)
+{
+}
+
+static void con_unthrottle(struct tty_struct *tty)
+{
+       struct vc_data *vc = tty->driver_data;
+
+       wake_up_interruptible(&vc->paste_wait);
+}
+
+/*
+ * Turn the Scroll-Lock LED on when the tty is stopped
+ */
+static void con_stop(struct tty_struct *tty)
+{
+       int console_num;
+       if (!tty)
+               return;
+       console_num = tty->index;
+       if (!vc_cons_allocated(console_num))
+               return;
+       set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
+       set_leds();
+}
+
+/*
+ * Turn the Scroll-Lock LED off when the console is started
+ */
+static void con_start(struct tty_struct *tty)
+{
+       int console_num;
+       if (!tty)
+               return;
+       console_num = tty->index;
+       if (!vc_cons_allocated(console_num))
+               return;
+       clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
+       set_leds();
+}
+
+static void con_flush_chars(struct tty_struct *tty)
+{
+       struct vc_data *vc;
+
+       if (in_interrupt())     /* from flush_to_ldisc */
+               return;
+
+       /* if we race with con_close(), vt may be null */
+       acquire_console_sem();
+       vc = tty->driver_data;
+       if (vc)
+               set_cursor(vc);
+       release_console_sem();
+}
+
+/*
+ * Allocate the console screen memory.
+ */
+static int con_open(struct tty_struct *tty, struct file *filp)
+{
+       unsigned int currcons = tty->index;
+       int ret = 0;
+
+       acquire_console_sem();
+       if (tty->driver_data == NULL) {
+               ret = vc_allocate(currcons);
+               if (ret == 0) {
+                       struct vc_data *vc = vc_cons[currcons].d;
+
+                       /* Still being freed */
+                       if (vc->port.tty) {
+                               release_console_sem();
+                               return -ERESTARTSYS;
+                       }
+                       tty->driver_data = vc;
+                       vc->port.tty = tty;
+
+                       if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
+                               tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
+                               tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
+                       }
+                       if (vc->vc_utf)
+                               tty->termios->c_iflag |= IUTF8;
+                       else
+                               tty->termios->c_iflag &= ~IUTF8;
+                       release_console_sem();
+                       return ret;
+               }
+       }
+       release_console_sem();
+       return ret;
+}
+
+static void con_close(struct tty_struct *tty, struct file *filp)
+{
+       /* Nothing to do - we defer to shutdown */
+}
+
+static void con_shutdown(struct tty_struct *tty)
+{
+       struct vc_data *vc = tty->driver_data;
+       BUG_ON(vc == NULL);
+       acquire_console_sem();
+       vc->port.tty = NULL;
+       release_console_sem();
+       tty_shutdown(tty);
+}
+
+static int default_italic_color    = 2; // green (ASCII)
+static int default_underline_color = 3; // cyan (ASCII)
+module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
+module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
+
+static void vc_init(struct vc_data *vc, unsigned int rows,
+                   unsigned int cols, int do_clear)
+{
+       int j, k ;
+
+       vc->vc_cols = cols;
+       vc->vc_rows = rows;
+       vc->vc_size_row = cols << 1;
+       vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
+
+       set_origin(vc);
+       vc->vc_pos = vc->vc_origin;
+       reset_vc(vc);
+       for (j=k=0; j<16; j++) {
+               vc->vc_palette[k++] = default_red[j] ;
+               vc->vc_palette[k++] = default_grn[j] ;
+               vc->vc_palette[k++] = default_blu[j] ;
+       }
+       vc->vc_def_color       = 0x07;   /* white */
+       vc->vc_ulcolor         = default_underline_color;
+       vc->vc_itcolor         = default_italic_color;
+       vc->vc_halfcolor       = 0x08;   /* grey */
+       init_waitqueue_head(&vc->paste_wait);
+       reset_terminal(vc, do_clear);
+}
+
+/*
+ * This routine initializes console interrupts, and does nothing
+ * else. If you want the screen to clear, call tty_write with
+ * the appropriate escape-sequence.
+ */
+
+static int __init con_init(void)
+{
+       const char *display_desc = NULL;
+       struct vc_data *vc;
+       unsigned int currcons = 0, i;
+
+       acquire_console_sem();
+
+       if (conswitchp)
+               display_desc = conswitchp->con_startup();
+       if (!display_desc) {
+               fg_console = 0;
+               release_console_sem();
+               return 0;
+       }
+
+       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
+               struct con_driver *con_driver = &registered_con_driver[i];
+
+               if (con_driver->con == NULL) {
+                       con_driver->con = conswitchp;
+                       con_driver->desc = display_desc;
+                       con_driver->flag = CON_DRIVER_FLAG_INIT;
+                       con_driver->first = 0;
+                       con_driver->last = MAX_NR_CONSOLES - 1;
+                       break;
+               }
+       }
+
+       for (i = 0; i < MAX_NR_CONSOLES; i++)
+               con_driver_map[i] = conswitchp;
+
+       if (blankinterval) {
+               blank_state = blank_normal_wait;
+               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
+       }
+
+       for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
+               vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
+               INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
+               tty_port_init(&vc->port);
+               visual_init(vc, currcons, 1);
+               vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
+               vc_init(vc, vc->vc_rows, vc->vc_cols,
+                       currcons || !vc->vc_sw->con_save_screen);
+       }
+       currcons = fg_console = 0;
+       master_display_fg = vc = vc_cons[currcons].d;
+       set_origin(vc);
+       save_screen(vc);
+       gotoxy(vc, vc->vc_x, vc->vc_y);
+       csi_J(vc, 0);
+       update_screen(vc);
+       printk("Console: %s %s %dx%d",
+               vc->vc_can_do_color ? "colour" : "mono",
+               display_desc, vc->vc_cols, vc->vc_rows);
+       printable = 1;
+       printk("\n");
+
+       release_console_sem();
+
+#ifdef CONFIG_VT_CONSOLE
+       register_console(&vt_console_driver);
+#endif
+       return 0;
+}
+console_initcall(con_init);
+
+static const struct tty_operations con_ops = {
+       .open = con_open,
+       .close = con_close,
+       .write = con_write,
+       .write_room = con_write_room,
+       .put_char = con_put_char,
+       .flush_chars = con_flush_chars,
+       .chars_in_buffer = con_chars_in_buffer,
+       .ioctl = vt_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = vt_compat_ioctl,
+#endif
+       .stop = con_stop,
+       .start = con_start,
+       .throttle = con_throttle,
+       .unthrottle = con_unthrottle,
+       .resize = vt_resize,
+       .shutdown = con_shutdown
+};
+
+static struct cdev vc0_cdev;
+
+int __init vty_init(const struct file_operations *console_fops)
+{
+       cdev_init(&vc0_cdev, console_fops);
+       if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
+           register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
+               panic("Couldn't register /dev/tty0 driver\n");
+       device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
+
+       vcs_init();
+
+       console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
+       if (!console_driver)
+               panic("Couldn't allocate console driver\n");
+       console_driver->owner = THIS_MODULE;
+       console_driver->name = "tty";
+       console_driver->name_base = 1;
+       console_driver->major = TTY_MAJOR;
+       console_driver->minor_start = 1;
+       console_driver->type = TTY_DRIVER_TYPE_CONSOLE;
+       console_driver->init_termios = tty_std_termios;
+       if (default_utf8)
+               console_driver->init_termios.c_iflag |= IUTF8;
+       console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
+       tty_set_operations(console_driver, &con_ops);
+       if (tty_register_driver(console_driver))
+               panic("Couldn't register console driver\n");
+       kbd_init();
+       console_map_init();
+#ifdef CONFIG_MDA_CONSOLE
+       mda_console_init();
+#endif
+       return 0;
+}
+
+#ifndef VT_SINGLE_DRIVER
+
+static struct class *vtconsole_class;
+
+static int bind_con_driver(const struct consw *csw, int first, int last,
+                          int deflt)
+{
+       struct module *owner = csw->owner;
+       const char *desc = NULL;
+       struct con_driver *con_driver;
+       int i, j = -1, k = -1, retval = -ENODEV;
+
+       if (!try_module_get(owner))
+               return -ENODEV;
+
+       acquire_console_sem();
+
+       /* check if driver is registered */
+       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
+               con_driver = &registered_con_driver[i];
+
+               if (con_driver->con == csw) {
+                       desc = con_driver->desc;
+                       retval = 0;
+                       break;
+               }
+       }
+
+       if (retval)
+               goto err;
+
+       if (!(con_driver->flag & CON_DRIVER_FLAG_INIT)) {
+               csw->con_startup();
+               con_driver->flag |= CON_DRIVER_FLAG_INIT;
+       }
+
+       if (deflt) {
+               if (conswitchp)
+                       module_put(conswitchp->owner);
+
+               __module_get(owner);
+               conswitchp = csw;
+       }
+
+       first = max(first, con_driver->first);
+       last = min(last, con_driver->last);
+
+       for (i = first; i <= last; i++) {
+               int old_was_color;
+               struct vc_data *vc = vc_cons[i].d;
+
+               if (con_driver_map[i])
+                       module_put(con_driver_map[i]->owner);
+               __module_get(owner);
+               con_driver_map[i] = csw;
+
+               if (!vc || !vc->vc_sw)
+                       continue;
+
+               j = i;
+
+               if (CON_IS_VISIBLE(vc)) {
+                       k = i;
+                       save_screen(vc);
+               }
+
+               old_was_color = vc->vc_can_do_color;
+               vc->vc_sw->con_deinit(vc);
+               vc->vc_origin = (unsigned long)vc->vc_screenbuf;
+               visual_init(vc, i, 0);
+               set_origin(vc);
+               update_attr(vc);
+
+               /* If the console changed between mono <-> color, then
+                * the attributes in the screenbuf will be wrong.  The
+                * following resets all attributes to something sane.
+                */
+               if (old_was_color != vc->vc_can_do_color)
+                       clear_buffer_attributes(vc);
+       }
+
+       printk("Console: switching ");
+       if (!deflt)
+               printk("consoles %d-%d ", first+1, last+1);
+       if (j >= 0) {
+               struct vc_data *vc = vc_cons[j].d;
+
+               printk("to %s %s %dx%d\n",
+                      vc->vc_can_do_color ? "colour" : "mono",
+                      desc, vc->vc_cols, vc->vc_rows);
+
+               if (k >= 0) {
+                       vc = vc_cons[k].d;
+                       update_screen(vc);
+               }
+       } else
+               printk("to %s\n", desc);
+
+       retval = 0;
+err:
+       release_console_sem();
+       module_put(owner);
+       return retval;
+};
+
+#ifdef CONFIG_VT_HW_CONSOLE_BINDING
+static int con_is_graphics(const struct consw *csw, int first, int last)
+{
+       int i, retval = 0;
+
+       for (i = first; i <= last; i++) {
+               struct vc_data *vc = vc_cons[i].d;
+
+               if (vc && vc->vc_mode == KD_GRAPHICS) {
+                       retval = 1;
+                       break;
+               }
+       }
+
+       return retval;
+}
+
+/**
+ * unbind_con_driver - unbind a console driver
+ * @csw: pointer to console driver to unregister
+ * @first: first in range of consoles that @csw should be unbound from
+ * @last: last in range of consoles that @csw should be unbound from
+ * @deflt: should next bound console driver be default after @csw is unbound?
+ *
+ * To unbind a driver from all possible consoles, pass 0 as @first and
+ * %MAX_NR_CONSOLES as @last.
+ *
+ * @deflt controls whether the console that ends up replacing @csw should be
+ * the default console.
+ *
+ * RETURNS:
+ * -ENODEV if @csw isn't a registered console driver or can't be unregistered
+ * or 0 on success.
+ */
+int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
+{
+       struct module *owner = csw->owner;
+       const struct consw *defcsw = NULL;
+       struct con_driver *con_driver = NULL, *con_back = NULL;
+       int i, retval = -ENODEV;
+
+       if (!try_module_get(owner))
+               return -ENODEV;
+
+       acquire_console_sem();
+
+       /* check if driver is registered and if it is unbindable */
+       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
+               con_driver = &registered_con_driver[i];
+
+               if (con_driver->con == csw &&
+                   con_driver->flag & CON_DRIVER_FLAG_MODULE) {
+                       retval = 0;
+                       break;
+               }
+       }
+
+       if (retval) {
+               release_console_sem();
+               goto err;
+       }
+
+       retval = -ENODEV;
+
+       /* check if backup driver exists */
+       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
+               con_back = &registered_con_driver[i];
+
+               if (con_back->con &&
+                   !(con_back->flag & CON_DRIVER_FLAG_MODULE)) {
+                       defcsw = con_back->con;
+                       retval = 0;
+                       break;
+               }
+       }
+
+       if (retval) {
+               release_console_sem();
+               goto err;
+       }
+
+       if (!con_is_bound(csw)) {
+               release_console_sem();
+               goto err;
+       }
+
+       first = max(first, con_driver->first);
+       last = min(last, con_driver->last);
+
+       for (i = first; i <= last; i++) {
+               if (con_driver_map[i] == csw) {
+                       module_put(csw->owner);
+                       con_driver_map[i] = NULL;
+               }
+       }
+
+       if (!con_is_bound(defcsw)) {
+               const struct consw *defconsw = conswitchp;
+
+               defcsw->con_startup();
+               con_back->flag |= CON_DRIVER_FLAG_INIT;
+               /*
+                * vgacon may change the default driver to point
+                * to dummycon, we restore it here...
+                */
+               conswitchp = defconsw;
+       }
+
+       if (!con_is_bound(csw))
+               con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
+
+       release_console_sem();
+       /* ignore return value, binding should not fail */
+       bind_con_driver(defcsw, first, last, deflt);
+err:
+       module_put(owner);
+       return retval;
+
+}
+EXPORT_SYMBOL(unbind_con_driver);
+
+static int vt_bind(struct con_driver *con)
+{
+       const struct consw *defcsw = NULL, *csw = NULL;
+       int i, more = 1, first = -1, last = -1, deflt = 0;
+
+       if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
+           con_is_graphics(con->con, con->first, con->last))
+               goto err;
+
+       csw = con->con;
+
+       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
+               struct con_driver *con = &registered_con_driver[i];
+
+               if (con->con && !(con->flag & CON_DRIVER_FLAG_MODULE)) {
+                       defcsw = con->con;
+                       break;
+               }
+       }
+
+       if (!defcsw)
+               goto err;
+
+       while (more) {
+               more = 0;
+
+               for (i = con->first; i <= con->last; i++) {
+                       if (con_driver_map[i] == defcsw) {
+                               if (first == -1)
+                                       first = i;
+                               last = i;
+                               more = 1;
+                       } else if (first != -1)
+                               break;
+               }
+
+               if (first == 0 && last == MAX_NR_CONSOLES -1)
+                       deflt = 1;
+
+               if (first != -1)
+                       bind_con_driver(csw, first, last, deflt);
+
+               first = -1;
+               last = -1;
+               deflt = 0;
+       }
+
+err:
+       return 0;
+}
+
+static int vt_unbind(struct con_driver *con)
+{
+       const struct consw *csw = NULL;
+       int i, more = 1, first = -1, last = -1, deflt = 0;
+
+       if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
+           con_is_graphics(con->con, con->first, con->last))
+               goto err;
+
+       csw = con->con;
+
+       while (more) {
+               more = 0;
+
+               for (i = con->first; i <= con->last; i++) {
+                       if (con_driver_map[i] == csw) {
+                               if (first == -1)
+                                       first = i;
+                               last = i;
+                               more = 1;
+                       } else if (first != -1)
+                               break;
+               }
+
+               if (first == 0 && last == MAX_NR_CONSOLES -1)
+                       deflt = 1;
+
+               if (first != -1)
+                       unbind_con_driver(csw, first, last, deflt);
+
+               first = -1;
+               last = -1;
+               deflt = 0;
+       }
+
+err:
+       return 0;
+}
+#else
+static inline int vt_bind(struct con_driver *con)
+{
+       return 0;
+}
+static inline int vt_unbind(struct con_driver *con)
+{
+       return 0;
+}
+#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
+
+static ssize_t store_bind(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t count)
+{
+       struct con_driver *con = dev_get_drvdata(dev);
+       int bind = simple_strtoul(buf, NULL, 0);
+
+       if (bind)
+               vt_bind(con);
+       else
+               vt_unbind(con);
+
+       return count;
+}
+
+static ssize_t show_bind(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct con_driver *con = dev_get_drvdata(dev);
+       int bind = con_is_bound(con->con);
+
+       return snprintf(buf, PAGE_SIZE, "%i\n", bind);
+}
+
+static ssize_t show_name(struct device *dev, struct device_attribute *attr,
+                        char *buf)
+{
+       struct con_driver *con = dev_get_drvdata(dev);
+
+       return snprintf(buf, PAGE_SIZE, "%s %s\n",
+                       (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)",
+                        con->desc);
+
+}
+
+static struct device_attribute device_attrs[] = {
+       __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind),
+       __ATTR(name, S_IRUGO, show_name, NULL),
+};
+
+static int vtconsole_init_device(struct con_driver *con)
+{
+       int i;
+       int error = 0;
+
+       con->flag |= CON_DRIVER_FLAG_ATTR;
+       dev_set_drvdata(con->dev, con);
+       for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
+               error = device_create_file(con->dev, &device_attrs[i]);
+               if (error)
+                       break;
+       }
+
+       if (error) {
+               while (--i >= 0)
+                       device_remove_file(con->dev, &device_attrs[i]);
+               con->flag &= ~CON_DRIVER_FLAG_ATTR;
+       }
+
+       return error;
+}
+
+static void vtconsole_deinit_device(struct con_driver *con)
+{
+       int i;
+
+       if (con->flag & CON_DRIVER_FLAG_ATTR) {
+               for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
+                       device_remove_file(con->dev, &device_attrs[i]);
+               con->flag &= ~CON_DRIVER_FLAG_ATTR;
+       }
+}
+
+/**
+ * con_is_bound - checks if driver is bound to the console
+ * @csw: console driver
+ *
+ * RETURNS: zero if unbound, nonzero if bound
+ *
+ * Drivers can call this and if zero, they should release
+ * all resources allocated on con_startup()
+ */
+int con_is_bound(const struct consw *csw)
+{
+       int i, bound = 0;
+
+       for (i = 0; i < MAX_NR_CONSOLES; i++) {
+               if (con_driver_map[i] == csw) {
+                       bound = 1;
+                       break;
+               }
+       }
+
+       return bound;
+}
+EXPORT_SYMBOL(con_is_bound);
+
+/**
+ * con_debug_enter - prepare the console for the kernel debugger
+ * @sw: console driver
+ *
+ * Called when the console is taken over by the kernel debugger, this
+ * function needs to save the current console state, then put the console
+ * into a state suitable for the kernel debugger.
+ *
+ * RETURNS:
+ * Zero on success, nonzero if a failure occurred when trying to prepare
+ * the console for the debugger.
+ */
+int con_debug_enter(struct vc_data *vc)
+{
+       int ret = 0;
+
+       saved_fg_console = fg_console;
+       saved_last_console = last_console;
+       saved_want_console = want_console;
+       saved_vc_mode = vc->vc_mode;
+       saved_console_blanked = console_blanked;
+       vc->vc_mode = KD_TEXT;
+       console_blanked = 0;
+       if (vc->vc_sw->con_debug_enter)
+               ret = vc->vc_sw->con_debug_enter(vc);
+#ifdef CONFIG_KGDB_KDB
+       /* Set the initial LINES variable if it is not already set */
+       if (vc->vc_rows < 999) {
+               int linecount;
+               char lns[4];
+               const char *setargs[3] = {
+                       "set",
+                       "LINES",
+                       lns,
+               };
+               if (kdbgetintenv(setargs[0], &linecount)) {
+                       snprintf(lns, 4, "%i", vc->vc_rows);
+                       kdb_set(2, setargs);
+               }
+       }
+#endif /* CONFIG_KGDB_KDB */
+       return ret;
+}
+EXPORT_SYMBOL_GPL(con_debug_enter);
+
+/**
+ * con_debug_leave - restore console state
+ * @sw: console driver
+ *
+ * Restore the console state to what it was before the kernel debugger
+ * was invoked.
+ *
+ * RETURNS:
+ * Zero on success, nonzero if a failure occurred when trying to restore
+ * the console.
+ */
+int con_debug_leave(void)
+{
+       struct vc_data *vc;
+       int ret = 0;
+
+       fg_console = saved_fg_console;
+       last_console = saved_last_console;
+       want_console = saved_want_console;
+       console_blanked = saved_console_blanked;
+       vc_cons[fg_console].d->vc_mode = saved_vc_mode;
+
+       vc = vc_cons[fg_console].d;
+       if (vc->vc_sw->con_debug_leave)
+               ret = vc->vc_sw->con_debug_leave(vc);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(con_debug_leave);
+
+/**
+ * register_con_driver - register console driver to console layer
+ * @csw: console driver
+ * @first: the first console to take over, minimum value is 0
+ * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
+ *
+ * DESCRIPTION: This function registers a console driver which can later
+ * bind to a range of consoles specified by @first and @last. It will
+ * also initialize the console driver by calling con_startup().
+ */
+int register_con_driver(const struct consw *csw, int first, int last)
+{
+       struct module *owner = csw->owner;
+       struct con_driver *con_driver;
+       const char *desc;
+       int i, retval = 0;
+
+       if (!try_module_get(owner))
+               return -ENODEV;
+
+       acquire_console_sem();
+
+       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
+               con_driver = &registered_con_driver[i];
+
+               /* already registered */
+               if (con_driver->con == csw)
+                       retval = -EINVAL;
+       }
+
+       if (retval)
+               goto err;
+
+       desc = csw->con_startup();
+
+       if (!desc)
+               goto err;
+
+       retval = -EINVAL;
+
+       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
+               con_driver = &registered_con_driver[i];
+
+               if (con_driver->con == NULL) {
+                       con_driver->con = csw;
+                       con_driver->desc = desc;
+                       con_driver->node = i;
+                       con_driver->flag = CON_DRIVER_FLAG_MODULE |
+                                          CON_DRIVER_FLAG_INIT;
+                       con_driver->first = first;
+                       con_driver->last = last;
+                       retval = 0;
+                       break;
+               }
+       }
+
+       if (retval)
+               goto err;
+
+       con_driver->dev = device_create(vtconsole_class, NULL,
+                                               MKDEV(0, con_driver->node),
+                                               NULL, "vtcon%i",
+                                               con_driver->node);
+
+       if (IS_ERR(con_driver->dev)) {
+               printk(KERN_WARNING "Unable to create device for %s; "
+                      "errno = %ld\n", con_driver->desc,
+                      PTR_ERR(con_driver->dev));
+               con_driver->dev = NULL;
+       } else {
+               vtconsole_init_device(con_driver);
+       }
+
+err:
+       release_console_sem();
+       module_put(owner);
+       return retval;
+}
+EXPORT_SYMBOL(register_con_driver);
+
+/**
+ * unregister_con_driver - unregister console driver from console layer
+ * @csw: console driver
+ *
+ * DESCRIPTION: All drivers that registers to the console layer must
+ * call this function upon exit, or if the console driver is in a state
+ * where it won't be able to handle console services, such as the
+ * framebuffer console without loaded framebuffer drivers.
+ *
+ * The driver must unbind first prior to unregistration.
+ */
+int unregister_con_driver(const struct consw *csw)
+{
+       int i, retval = -ENODEV;
+
+       acquire_console_sem();
+
+       /* cannot unregister a bound driver */
+       if (con_is_bound(csw))
+               goto err;
+
+       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
+               struct con_driver *con_driver = &registered_con_driver[i];
+
+               if (con_driver->con == csw &&
+                   con_driver->flag & CON_DRIVER_FLAG_MODULE) {
+                       vtconsole_deinit_device(con_driver);
+                       device_destroy(vtconsole_class,
+                                      MKDEV(0, con_driver->node));
+                       con_driver->con = NULL;
+                       con_driver->desc = NULL;
+                       con_driver->dev = NULL;
+                       con_driver->node = 0;
+                       con_driver->flag = 0;
+                       con_driver->first = 0;
+                       con_driver->last = 0;
+                       retval = 0;
+                       break;
+               }
+       }
+err:
+       release_console_sem();
+       return retval;
+}
+EXPORT_SYMBOL(unregister_con_driver);
+
+/*
+ *     If we support more console drivers, this function is used
+ *     when a driver wants to take over some existing consoles
+ *     and become default driver for newly opened ones.
+ *
+ *      take_over_console is basically a register followed by unbind
+ */
+int take_over_console(const struct consw *csw, int first, int last, int deflt)
+{
+       int err;
+
+       err = register_con_driver(csw, first, last);
+
+       if (!err)
+               bind_con_driver(csw, first, last, deflt);
+
+       return err;
+}
+
+/*
+ * give_up_console is a wrapper to unregister_con_driver. It will only
+ * work if driver is fully unbound.
+ */
+void give_up_console(const struct consw *csw)
+{
+       unregister_con_driver(csw);
+}
+
+static int __init vtconsole_class_init(void)
+{
+       int i;
+
+       vtconsole_class = class_create(THIS_MODULE, "vtconsole");
+       if (IS_ERR(vtconsole_class)) {
+               printk(KERN_WARNING "Unable to create vt console class; "
+                      "errno = %ld\n", PTR_ERR(vtconsole_class));
+               vtconsole_class = NULL;
+       }
+
+       /* Add system drivers to sysfs */
+       for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
+               struct con_driver *con = &registered_con_driver[i];
+
+               if (con->con && !con->dev) {
+                       con->dev = device_create(vtconsole_class, NULL,
+                                                        MKDEV(0, con->node),
+                                                        NULL, "vtcon%i",
+                                                        con->node);
+
+                       if (IS_ERR(con->dev)) {
+                               printk(KERN_WARNING "Unable to create "
+                                      "device for %s; errno = %ld\n",
+                                      con->desc, PTR_ERR(con->dev));
+                               con->dev = NULL;
+                       } else {
+                               vtconsole_init_device(con);
+                       }
+               }
+       }
+
+       return 0;
+}
+postcore_initcall(vtconsole_class_init);
+
+#endif
+
+/*
+ *     Screen blanking
+ */
+
+static int set_vesa_blanking(char __user *p)
+{
+       unsigned int mode;
+
+       if (get_user(mode, p + 1))
+               return -EFAULT;
+
+       vesa_blank_mode = (mode < 4) ? mode : 0;
+       return 0;
+}
+
+void do_blank_screen(int entering_gfx)
+{
+       struct vc_data *vc = vc_cons[fg_console].d;
+       int i;
+
+       WARN_CONSOLE_UNLOCKED();
+
+       if (console_blanked) {
+               if (blank_state == blank_vesa_wait) {
+                       blank_state = blank_off;
+                       vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
+               }
+               return;
+       }
+
+       /* entering graphics mode? */
+       if (entering_gfx) {
+               hide_cursor(vc);
+               save_screen(vc);
+               vc->vc_sw->con_blank(vc, -1, 1);
+               console_blanked = fg_console + 1;
+               blank_state = blank_off;
+               set_origin(vc);
+               return;
+       }
+
+       if (blank_state != blank_normal_wait)
+               return;
+       blank_state = blank_off;
+
+       /* don't blank graphics */
+       if (vc->vc_mode != KD_TEXT) {
+               console_blanked = fg_console + 1;
+               return;
+       }
+
+       hide_cursor(vc);
+       del_timer_sync(&console_timer);
+       blank_timer_expired = 0;
+
+       save_screen(vc);
+       /* In case we need to reset origin, blanking hook returns 1 */
+       i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
+       console_blanked = fg_console + 1;
+       if (i)
+               set_origin(vc);
+
+       if (console_blank_hook && console_blank_hook(1))
+               return;
+
+       if (vesa_off_interval && vesa_blank_mode) {
+               blank_state = blank_vesa_wait;
+               mod_timer(&console_timer, jiffies + vesa_off_interval);
+       }
+       vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
+}
+EXPORT_SYMBOL(do_blank_screen);
+
+/*
+ * Called by timer as well as from vt_console_driver
+ */
+void do_unblank_screen(int leaving_gfx)
+{
+       struct vc_data *vc;
+
+       /* This should now always be called from a "sane" (read: can schedule)
+        * context for the sake of the low level drivers, except in the special
+        * case of oops_in_progress
+        */
+       if (!oops_in_progress)
+               might_sleep();
+
+       WARN_CONSOLE_UNLOCKED();
+
+       ignore_poke = 0;
+       if (!console_blanked)
+               return;
+       if (!vc_cons_allocated(fg_console)) {
+               /* impossible */
+               printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
+               return;
+       }
+       vc = vc_cons[fg_console].d;
+       /* Try to unblank in oops case too */
+       if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
+               return; /* but leave console_blanked != 0 */
+
+       if (blankinterval) {
+               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
+               blank_state = blank_normal_wait;
+       }
+
+       console_blanked = 0;
+       if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
+               /* Low-level driver cannot restore -> do it ourselves */
+               update_screen(vc);
+       if (console_blank_hook)
+               console_blank_hook(0);
+       set_palette(vc);
+       set_cursor(vc);
+       vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
+}
+EXPORT_SYMBOL(do_unblank_screen);
+
+/*
+ * This is called by the outside world to cause a forced unblank, mostly for
+ * oopses. Currently, I just call do_unblank_screen(0), but we could eventually
+ * call it with 1 as an argument and so force a mode restore... that may kill
+ * X or at least garbage the screen but would also make the Oops visible...
+ */
+void unblank_screen(void)
+{
+       do_unblank_screen(0);
+}
+
+/*
+ * We defer the timer blanking to work queue so it can take the console mutex
+ * (console operations can still happen at irq time, but only from printk which
+ * has the console mutex. Not perfect yet, but better than no locking
+ */
+static void blank_screen_t(unsigned long dummy)
+{
+       if (unlikely(!keventd_up())) {
+               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
+               return;
+       }
+       blank_timer_expired = 1;
+       schedule_work(&console_work);
+}
+
+void poke_blanked_console(void)
+{
+       WARN_CONSOLE_UNLOCKED();
+
+       /* Add this so we quickly catch whoever might call us in a non
+        * safe context. Nowadays, unblank_screen() isn't to be called in
+        * atomic contexts and is allowed to schedule (with the special case
+        * of oops_in_progress, but that isn't of any concern for this
+        * function. --BenH.
+        */
+       might_sleep();
+
+       /* This isn't perfectly race free, but a race here would be mostly harmless,
+        * at worse, we'll do a spurrious blank and it's unlikely
+        */
+       del_timer(&console_timer);
+       blank_timer_expired = 0;
+
+       if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode == KD_GRAPHICS)
+               return;
+       if (console_blanked)
+               unblank_screen();
+       else if (blankinterval) {
+               mod_timer(&console_timer, jiffies + (blankinterval * HZ));
+               blank_state = blank_normal_wait;
+       }
+}
+
+/*
+ *     Palettes
+ */
+
+static void set_palette(struct vc_data *vc)
+{
+       WARN_CONSOLE_UNLOCKED();
+
+       if (vc->vc_mode != KD_GRAPHICS)
+               vc->vc_sw->con_set_palette(vc, color_table);
+}
+
+static int set_get_cmap(unsigned char __user *arg, int set)
+{
+    int i, j, k;
+
+    WARN_CONSOLE_UNLOCKED();
+
+    for (i = 0; i < 16; i++)
+       if (set) {
+           get_user(default_red[i], arg++);
+           get_user(default_grn[i], arg++);
+           get_user(default_blu[i], arg++);
+       } else {
+           put_user(default_red[i], arg++);
+           put_user(default_grn[i], arg++);
+           put_user(default_blu[i], arg++);
+       }
+    if (set) {
+       for (i = 0; i < MAX_NR_CONSOLES; i++)
+           if (vc_cons_allocated(i)) {
+               for (j = k = 0; j < 16; j++) {
+                   vc_cons[i].d->vc_palette[k++] = default_red[j];
+                   vc_cons[i].d->vc_palette[k++] = default_grn[j];
+                   vc_cons[i].d->vc_palette[k++] = default_blu[j];
+               }
+               set_palette(vc_cons[i].d);
+           }
+    }
+    return 0;
+}
+
+/*
+ * Load palette into the DAC registers. arg points to a colour
+ * map, 3 bytes per colour, 16 colours, range from 0 to 255.
+ */
+
+int con_set_cmap(unsigned char __user *arg)
+{
+       int rc;
+
+       acquire_console_sem();
+       rc = set_get_cmap (arg,1);
+       release_console_sem();
+
+       return rc;
+}
+
+int con_get_cmap(unsigned char __user *arg)
+{
+       int rc;
+
+       acquire_console_sem();
+       rc = set_get_cmap (arg,0);
+       release_console_sem();
+
+       return rc;
+}
+
+void reset_palette(struct vc_data *vc)
+{
+       int j, k;
+       for (j=k=0; j<16; j++) {
+               vc->vc_palette[k++] = default_red[j];
+               vc->vc_palette[k++] = default_grn[j];
+               vc->vc_palette[k++] = default_blu[j];
+       }
+       set_palette(vc);
+}
+
+/*
+ *  Font switching
+ *
+ *  Currently we only support fonts up to 32 pixels wide, at a maximum height
+ *  of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints, 
+ *  depending on width) reserved for each character which is kinda wasty, but 
+ *  this is done in order to maintain compatibility with the EGA/VGA fonts. It 
+ *  is upto the actual low-level console-driver convert data into its favorite
+ *  format (maybe we should add a `fontoffset' field to the `display'
+ *  structure so we won't have to convert the fontdata all the time.
+ *  /Jes
+ */
+
+#define max_font_size 65536
+
+static int con_font_get(struct vc_data *vc, struct console_font_op *op)
+{
+       struct console_font font;
+       int rc = -EINVAL;
+       int c;
+
+       if (vc->vc_mode != KD_TEXT)
+               return -EINVAL;
+
+       if (op->data) {
+               font.data = kmalloc(max_font_size, GFP_KERNEL);
+               if (!font.data)
+                       return -ENOMEM;
+       } else
+               font.data = NULL;
+
+       acquire_console_sem();
+       if (vc->vc_sw->con_font_get)
+               rc = vc->vc_sw->con_font_get(vc, &font);
+       else
+               rc = -ENOSYS;
+       release_console_sem();
+
+       if (rc)
+               goto out;
+
+       c = (font.width+7)/8 * 32 * font.charcount;
+
+       if (op->data && font.charcount > op->charcount)
+               rc = -ENOSPC;
+       if (!(op->flags & KD_FONT_FLAG_OLD)) {
+               if (font.width > op->width || font.height > op->height) 
+                       rc = -ENOSPC;
+       } else {
+               if (font.width != 8)
+                       rc = -EIO;
+               else if ((op->height && font.height > op->height) ||
+                        font.height > 32)
+                       rc = -ENOSPC;
+       }
+       if (rc)
+               goto out;
+
+       op->height = font.height;
+       op->width = font.width;
+       op->charcount = font.charcount;
+
+       if (op->data && copy_to_user(op->data, font.data, c))
+               rc = -EFAULT;
+
+out:
+       kfree(font.data);
+       return rc;
+}
+
+static int con_font_set(struct vc_data *vc, struct console_font_op *op)
+{
+       struct console_font font;
+       int rc = -EINVAL;
+       int size;
+
+       if (vc->vc_mode != KD_TEXT)
+               return -EINVAL;
+       if (!op->data)
+               return -EINVAL;
+       if (op->charcount > 512)
+               return -EINVAL;
+       if (!op->height) {              /* Need to guess font height [compat] */
+               int h, i;
+               u8 __user *charmap = op->data;
+               u8 tmp;
+               
+               /* If from KDFONTOP ioctl, don't allow things which can be done in userland,
+                  so that we can get rid of this soon */
+               if (!(op->flags & KD_FONT_FLAG_OLD))
+                       return -EINVAL;
+               for (h = 32; h > 0; h--)
+                       for (i = 0; i < op->charcount; i++) {
+                               if (get_user(tmp, &charmap[32*i+h-1]))
+                                       return -EFAULT;
+                               if (tmp)
+                                       goto nonzero;
+                       }
+               return -EINVAL;
+       nonzero:
+               op->height = h;
+       }
+       if (op->width <= 0 || op->width > 32 || op->height > 32)
+               return -EINVAL;
+       size = (op->width+7)/8 * 32 * op->charcount;
+       if (size > max_font_size)
+               return -ENOSPC;
+       font.charcount = op->charcount;
+       font.height = op->height;
+       font.width = op->width;
+       font.data = memdup_user(op->data, size);
+       if (IS_ERR(font.data))
+               return PTR_ERR(font.data);
+       acquire_console_sem();
+       if (vc->vc_sw->con_font_set)
+               rc = vc->vc_sw->con_font_set(vc, &font, op->flags);
+       else
+               rc = -ENOSYS;
+       release_console_sem();
+       kfree(font.data);
+       return rc;
+}
+
+static int con_font_default(struct vc_data *vc, struct console_font_op *op)
+{
+       struct console_font font = {.width = op->width, .height = op->height};
+       char name[MAX_FONT_NAME];
+       char *s = name;
+       int rc;
+
+       if (vc->vc_mode != KD_TEXT)
+               return -EINVAL;
+
+       if (!op->data)
+               s = NULL;
+       else if (strncpy_from_user(name, op->data, MAX_FONT_NAME - 1) < 0)
+               return -EFAULT;
+       else
+               name[MAX_FONT_NAME - 1] = 0;
+
+       acquire_console_sem();
+       if (vc->vc_sw->con_font_default)
+               rc = vc->vc_sw->con_font_default(vc, &font, s);
+       else
+               rc = -ENOSYS;
+       release_console_sem();
+       if (!rc) {
+               op->width = font.width;
+               op->height = font.height;
+       }
+       return rc;
+}
+
+static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
+{
+       int con = op->height;
+       int rc;
+
+       if (vc->vc_mode != KD_TEXT)
+               return -EINVAL;
+
+       acquire_console_sem();
+       if (!vc->vc_sw->con_font_copy)
+               rc = -ENOSYS;
+       else if (con < 0 || !vc_cons_allocated(con))
+               rc = -ENOTTY;
+       else if (con == vc->vc_num)     /* nothing to do */
+               rc = 0;
+       else
+               rc = vc->vc_sw->con_font_copy(vc, con);
+       release_console_sem();
+       return rc;
+}
+
+int con_font_op(struct vc_data *vc, struct console_font_op *op)
+{
+       switch (op->op) {
+       case KD_FONT_OP_SET:
+               return con_font_set(vc, op);
+       case KD_FONT_OP_GET:
+               return con_font_get(vc, op);
+       case KD_FONT_OP_SET_DEFAULT:
+               return con_font_default(vc, op);
+       case KD_FONT_OP_COPY:
+               return con_font_copy(vc, op);
+       }
+       return -ENOSYS;
+}
+
+/*
+ *     Interface exported to selection and vcs.
+ */
+
+/* used by selection */
+u16 screen_glyph(struct vc_data *vc, int offset)
+{
+       u16 w = scr_readw(screenpos(vc, offset, 1));
+       u16 c = w & 0xff;
+
+       if (w & vc->vc_hi_font_mask)
+               c |= 0x100;
+       return c;
+}
+EXPORT_SYMBOL_GPL(screen_glyph);
+
+/* used by vcs - note the word offset */
+unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
+{
+       return screenpos(vc, 2 * w_offset, viewed);
+}
+
+void getconsxy(struct vc_data *vc, unsigned char *p)
+{
+       p[0] = vc->vc_x;
+       p[1] = vc->vc_y;
+}
+
+void putconsxy(struct vc_data *vc, unsigned char *p)
+{
+       hide_cursor(vc);
+       gotoxy(vc, p[0], p[1]);
+       set_cursor(vc);
+}
+
+u16 vcs_scr_readw(struct vc_data *vc, const u16 *org)
+{
+       if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
+               return softcursor_original;
+       return scr_readw(org);
+}
+
+void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
+{
+       scr_writew(val, org);
+       if ((unsigned long)org == vc->vc_pos) {
+               softcursor_original = -1;
+               add_softcursor(vc);
+       }
+}
+
+void vcs_scr_updated(struct vc_data *vc)
+{
+       notify_update(vc);
+}
+
+/*
+ *     Visible symbols for modules
+ */
+
+EXPORT_SYMBOL(color_table);
+EXPORT_SYMBOL(default_red);
+EXPORT_SYMBOL(default_grn);
+EXPORT_SYMBOL(default_blu);
+EXPORT_SYMBOL(update_region);
+EXPORT_SYMBOL(redraw_screen);
+EXPORT_SYMBOL(vc_resize);
+EXPORT_SYMBOL(fg_console);
+EXPORT_SYMBOL(console_blank_hook);
+EXPORT_SYMBOL(console_blanked);
+EXPORT_SYMBOL(vc_cons);
+EXPORT_SYMBOL(global_cursor_default);
+#ifndef VT_SINGLE_DRIVER
+EXPORT_SYMBOL(take_over_console);
+EXPORT_SYMBOL(give_up_console);
+#endif
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
new file mode 100644 (file)
index 0000000..6b68a0f
--- /dev/null
@@ -0,0 +1,1788 @@
+/*
+ *  linux/drivers/char/vt_ioctl.c
+ *
+ *  Copyright (C) 1992 obz under the linux copyright
+ *
+ *  Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
+ *  Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
+ *  Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
+ *  Some code moved for less code duplication - Andi Kleen - Mar 1997
+ *  Check put/get_user, cleanups - acme@conectiva.com.br - Jun 2001
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/timer.h>
+#include <linux/kernel.h>
+#include <linux/compat.h>
+#include <linux/module.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/console.h>
+#include <linux/consolemap.h>
+#include <linux/signal.h>
+#include <linux/smp_lock.h>
+#include <linux/timex.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/kbd_diacr.h>
+#include <linux/selection.h>
+
+char vt_dont_switch;
+extern struct tty_driver *console_driver;
+
+#define VT_IS_IN_USE(i)        (console_driver->ttys[i] && console_driver->ttys[i]->count)
+#define VT_BUSY(i)     (VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
+
+/*
+ * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
+ * experimentation and study of X386 SYSV handling.
+ *
+ * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
+ * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
+ * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
+ * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
+ * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
+ * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
+ * to the current console is done by the main ioctl code.
+ */
+
+#ifdef CONFIG_X86
+#include <linux/syscalls.h>
+#endif
+
+static void complete_change_console(struct vc_data *vc);
+
+/*
+ *     User space VT_EVENT handlers
+ */
+
+struct vt_event_wait {
+       struct list_head list;
+       struct vt_event event;
+       int done;
+};
+
+static LIST_HEAD(vt_events);
+static DEFINE_SPINLOCK(vt_event_lock);
+static DECLARE_WAIT_QUEUE_HEAD(vt_event_waitqueue);
+
+/**
+ *     vt_event_post
+ *     @event: the event that occurred
+ *     @old: old console
+ *     @new: new console
+ *
+ *     Post an VT event to interested VT handlers
+ */
+
+void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
+{
+       struct list_head *pos, *head;
+       unsigned long flags;
+       int wake = 0;
+
+       spin_lock_irqsave(&vt_event_lock, flags);
+       head = &vt_events;
+
+       list_for_each(pos, head) {
+               struct vt_event_wait *ve = list_entry(pos,
+                                               struct vt_event_wait, list);
+               if (!(ve->event.event & event))
+                       continue;
+               ve->event.event = event;
+               /* kernel view is consoles 0..n-1, user space view is
+                  console 1..n with 0 meaning current, so we must bias */
+               ve->event.oldev = old + 1;
+               ve->event.newev = new + 1;
+               wake = 1;
+               ve->done = 1;
+       }
+       spin_unlock_irqrestore(&vt_event_lock, flags);
+       if (wake)
+               wake_up_interruptible(&vt_event_waitqueue);
+}
+
+/**
+ *     vt_event_wait           -       wait for an event
+ *     @vw: our event
+ *
+ *     Waits for an event to occur which completes our vt_event_wait
+ *     structure. On return the structure has wv->done set to 1 for success
+ *     or 0 if some event such as a signal ended the wait.
+ */
+
+static void vt_event_wait(struct vt_event_wait *vw)
+{
+       unsigned long flags;
+       /* Prepare the event */
+       INIT_LIST_HEAD(&vw->list);
+       vw->done = 0;
+       /* Queue our event */
+       spin_lock_irqsave(&vt_event_lock, flags);
+       list_add(&vw->list, &vt_events);
+       spin_unlock_irqrestore(&vt_event_lock, flags);
+       /* Wait for it to pass */
+       wait_event_interruptible_tty(vt_event_waitqueue, vw->done);
+       /* Dequeue it */
+       spin_lock_irqsave(&vt_event_lock, flags);
+       list_del(&vw->list);
+       spin_unlock_irqrestore(&vt_event_lock, flags);
+}
+
+/**
+ *     vt_event_wait_ioctl     -       event ioctl handler
+ *     @arg: argument to ioctl
+ *
+ *     Implement the VT_WAITEVENT ioctl using the VT event interface
+ */
+
+static int vt_event_wait_ioctl(struct vt_event __user *event)
+{
+       struct vt_event_wait vw;
+
+       if (copy_from_user(&vw.event, event, sizeof(struct vt_event)))
+               return -EFAULT;
+       /* Highest supported event for now */
+       if (vw.event.event & ~VT_MAX_EVENT)
+               return -EINVAL;
+
+       vt_event_wait(&vw);
+       /* If it occurred report it */
+       if (vw.done) {
+               if (copy_to_user(event, &vw.event, sizeof(struct vt_event)))
+                       return -EFAULT;
+               return 0;
+       }
+       return -EINTR;
+}
+
+/**
+ *     vt_waitactive   -       active console wait
+ *     @event: event code
+ *     @n: new console
+ *
+ *     Helper for event waits. Used to implement the legacy
+ *     event waiting ioctls in terms of events
+ */
+
+int vt_waitactive(int n)
+{
+       struct vt_event_wait vw;
+       do {
+               if (n == fg_console + 1)
+                       break;
+               vw.event.event = VT_EVENT_SWITCH;
+               vt_event_wait(&vw);
+               if (vw.done == 0)
+                       return -EINTR;
+       } while (vw.event.newev != n);
+       return 0;
+}
+
+/*
+ * these are the valid i/o ports we're allowed to change. they map all the
+ * video ports
+ */
+#define GPFIRST 0x3b4
+#define GPLAST 0x3df
+#define GPNUM (GPLAST - GPFIRST + 1)
+
+#define i (tmp.kb_index)
+#define s (tmp.kb_table)
+#define v (tmp.kb_value)
+static inline int
+do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_struct *kbd)
+{
+       struct kbentry tmp;
+       ushort *key_map, val, ov;
+
+       if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
+               return -EFAULT;
+
+       if (!capable(CAP_SYS_TTY_CONFIG))
+               perm = 0;
+
+       switch (cmd) {
+       case KDGKBENT:
+               key_map = key_maps[s];
+               if (key_map) {
+                   val = U(key_map[i]);
+                   if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
+                       val = K_HOLE;
+               } else
+                   val = (i ? K_HOLE : K_NOSUCHMAP);
+               return put_user(val, &user_kbe->kb_value);
+       case KDSKBENT:
+               if (!perm)
+                       return -EPERM;
+               if (!i && v == K_NOSUCHMAP) {
+                       /* deallocate map */
+                       key_map = key_maps[s];
+                       if (s && key_map) {
+                           key_maps[s] = NULL;
+                           if (key_map[0] == U(K_ALLOCATED)) {
+                                       kfree(key_map);
+                                       keymap_count--;
+                           }
+                       }
+                       break;
+               }
+
+               if (KTYP(v) < NR_TYPES) {
+                   if (KVAL(v) > max_vals[KTYP(v)])
+                               return -EINVAL;
+               } else
+                   if (kbd->kbdmode != VC_UNICODE)
+                               return -EINVAL;
+
+               /* ++Geert: non-PC keyboards may generate keycode zero */
+#if !defined(__mc68000__) && !defined(__powerpc__)
+               /* assignment to entry 0 only tests validity of args */
+               if (!i)
+                       break;
+#endif
+
+               if (!(key_map = key_maps[s])) {
+                       int j;
+
+                       if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
+                           !capable(CAP_SYS_RESOURCE))
+                               return -EPERM;
+
+                       key_map = kmalloc(sizeof(plain_map),
+                                                    GFP_KERNEL);
+                       if (!key_map)
+                               return -ENOMEM;
+                       key_maps[s] = key_map;
+                       key_map[0] = U(K_ALLOCATED);
+                       for (j = 1; j < NR_KEYS; j++)
+                               key_map[j] = U(K_HOLE);
+                       keymap_count++;
+               }
+               ov = U(key_map[i]);
+               if (v == ov)
+                       break;  /* nothing to do */
+               /*
+                * Attention Key.
+                */
+               if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               key_map[i] = U(v);
+               if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
+                       compute_shiftstate();
+               break;
+       }
+       return 0;
+}
+#undef i
+#undef s
+#undef v
+
+static inline int 
+do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, int perm)
+{
+       struct kbkeycode tmp;
+       int kc = 0;
+
+       if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
+               return -EFAULT;
+       switch (cmd) {
+       case KDGETKEYCODE:
+               kc = getkeycode(tmp.scancode);
+               if (kc >= 0)
+                       kc = put_user(kc, &user_kbkc->keycode);
+               break;
+       case KDSETKEYCODE:
+               if (!perm)
+                       return -EPERM;
+               kc = setkeycode(tmp.scancode, tmp.keycode);
+               break;
+       }
+       return kc;
+}
+
+static inline int
+do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
+{
+       struct kbsentry *kbs;
+       char *p;
+       u_char *q;
+       u_char __user *up;
+       int sz;
+       int delta;
+       char *first_free, *fj, *fnw;
+       int i, j, k;
+       int ret;
+
+       if (!capable(CAP_SYS_TTY_CONFIG))
+               perm = 0;
+
+       kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
+       if (!kbs) {
+               ret = -ENOMEM;
+               goto reterr;
+       }
+
+       /* we mostly copy too much here (512bytes), but who cares ;) */
+       if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
+               ret = -EFAULT;
+               goto reterr;
+       }
+       kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
+       i = kbs->kb_func;
+
+       switch (cmd) {
+       case KDGKBSENT:
+               sz = sizeof(kbs->kb_string) - 1; /* sz should have been
+                                                 a struct member */
+               up = user_kdgkb->kb_string;
+               p = func_table[i];
+               if(p)
+                       for ( ; *p && sz; p++, sz--)
+                               if (put_user(*p, up++)) {
+                                       ret = -EFAULT;
+                                       goto reterr;
+                               }
+               if (put_user('\0', up)) {
+                       ret = -EFAULT;
+                       goto reterr;
+               }
+               kfree(kbs);
+               return ((p && *p) ? -EOVERFLOW : 0);
+       case KDSKBSENT:
+               if (!perm) {
+                       ret = -EPERM;
+                       goto reterr;
+               }
+
+               q = func_table[i];
+               first_free = funcbufptr + (funcbufsize - funcbufleft);
+               for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
+                       ;
+               if (j < MAX_NR_FUNC)
+                       fj = func_table[j];
+               else
+                       fj = first_free;
+
+               delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
+               if (delta <= funcbufleft) {     /* it fits in current buf */
+                   if (j < MAX_NR_FUNC) {
+                       memmove(fj + delta, fj, first_free - fj);
+                       for (k = j; k < MAX_NR_FUNC; k++)
+                           if (func_table[k])
+                               func_table[k] += delta;
+                   }
+                   if (!q)
+                     func_table[i] = fj;
+                   funcbufleft -= delta;
+               } else {                        /* allocate a larger buffer */
+                   sz = 256;
+                   while (sz < funcbufsize - funcbufleft + delta)
+                     sz <<= 1;
+                   fnw = kmalloc(sz, GFP_KERNEL);
+                   if(!fnw) {
+                     ret = -ENOMEM;
+                     goto reterr;
+                   }
+
+                   if (!q)
+                     func_table[i] = fj;
+                   if (fj > funcbufptr)
+                       memmove(fnw, funcbufptr, fj - funcbufptr);
+                   for (k = 0; k < j; k++)
+                     if (func_table[k])
+                       func_table[k] = fnw + (func_table[k] - funcbufptr);
+
+                   if (first_free > fj) {
+                       memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
+                       for (k = j; k < MAX_NR_FUNC; k++)
+                         if (func_table[k])
+                           func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
+                   }
+                   if (funcbufptr != func_buf)
+                     kfree(funcbufptr);
+                   funcbufptr = fnw;
+                   funcbufleft = funcbufleft - delta + sz - funcbufsize;
+                   funcbufsize = sz;
+               }
+               strcpy(func_table[i], kbs->kb_string);
+               break;
+       }
+       ret = 0;
+reterr:
+       kfree(kbs);
+       return ret;
+}
+
+static inline int 
+do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
+{
+       struct consolefontdesc cfdarg;
+       int i;
+
+       if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) 
+               return -EFAULT;
+       
+       switch (cmd) {
+       case PIO_FONTX:
+               if (!perm)
+                       return -EPERM;
+               op->op = KD_FONT_OP_SET;
+               op->flags = KD_FONT_FLAG_OLD;
+               op->width = 8;
+               op->height = cfdarg.charheight;
+               op->charcount = cfdarg.charcount;
+               op->data = cfdarg.chardata;
+               return con_font_op(vc_cons[fg_console].d, op);
+       case GIO_FONTX: {
+               op->op = KD_FONT_OP_GET;
+               op->flags = KD_FONT_FLAG_OLD;
+               op->width = 8;
+               op->height = cfdarg.charheight;
+               op->charcount = cfdarg.charcount;
+               op->data = cfdarg.chardata;
+               i = con_font_op(vc_cons[fg_console].d, op);
+               if (i)
+                       return i;
+               cfdarg.charheight = op->height;
+               cfdarg.charcount = op->charcount;
+               if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
+                       return -EFAULT;
+               return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static inline int 
+do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc)
+{
+       struct unimapdesc tmp;
+
+       if (copy_from_user(&tmp, user_ud, sizeof tmp))
+               return -EFAULT;
+       if (tmp.entries)
+               if (!access_ok(VERIFY_WRITE, tmp.entries,
+                               tmp.entry_ct*sizeof(struct unipair)))
+                       return -EFAULT;
+       switch (cmd) {
+       case PIO_UNIMAP:
+               if (!perm)
+                       return -EPERM;
+               return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
+       case GIO_UNIMAP:
+               if (!perm && fg_console != vc->vc_num)
+                       return -EPERM;
+               return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
+       }
+       return 0;
+}
+
+
+
+/*
+ * We handle the console-specific ioctl's here.  We allow the
+ * capability to modify any console, not just the fg_console. 
+ */
+int vt_ioctl(struct tty_struct *tty, struct file * file,
+            unsigned int cmd, unsigned long arg)
+{
+       struct vc_data *vc = tty->driver_data;
+       struct console_font_op op;      /* used in multiple places here */
+       struct kbd_struct * kbd;
+       unsigned int console;
+       unsigned char ucval;
+       unsigned int uival;
+       void __user *up = (void __user *)arg;
+       int i, perm;
+       int ret = 0;
+
+       console = vc->vc_num;
+
+       tty_lock();
+
+       if (!vc_cons_allocated(console)) {      /* impossible? */
+               ret = -ENOIOCTLCMD;
+               goto out;
+       }
+
+
+       /*
+        * To have permissions to do most of the vt ioctls, we either have
+        * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
+        */
+       perm = 0;
+       if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
+               perm = 1;
+       kbd = kbd_table + console;
+       switch (cmd) {
+       case TIOCLINUX:
+               ret = tioclinux(tty, arg);
+               break;
+       case KIOCSOUND:
+               if (!perm)
+                       goto eperm;
+               /*
+                * The use of PIT_TICK_RATE is historic, it used to be
+                * the platform-dependent CLOCK_TICK_RATE between 2.6.12
+                * and 2.6.36, which was a minor but unfortunate ABI
+                * change.
+                */
+               if (arg)
+                       arg = PIT_TICK_RATE / arg;
+               kd_mksound(arg, 0);
+               break;
+
+       case KDMKTONE:
+               if (!perm)
+                       goto eperm;
+       {
+               unsigned int ticks, count;
+               
+               /*
+                * Generate the tone for the appropriate number of ticks.
+                * If the time is zero, turn off sound ourselves.
+                */
+               ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
+               count = ticks ? (arg & 0xffff) : 0;
+               if (count)
+                       count = PIT_TICK_RATE / count;
+               kd_mksound(count, ticks);
+               break;
+       }
+
+       case KDGKBTYPE:
+               /*
+                * this is naive.
+                */
+               ucval = KB_101;
+               goto setchar;
+
+               /*
+                * These cannot be implemented on any machine that implements
+                * ioperm() in user level (such as Alpha PCs) or not at all.
+                *
+                * XXX: you should never use these, just call ioperm directly..
+                */
+#ifdef CONFIG_X86
+       case KDADDIO:
+       case KDDELIO:
+               /*
+                * KDADDIO and KDDELIO may be able to add ports beyond what
+                * we reject here, but to be safe...
+                */
+               if (arg < GPFIRST || arg > GPLAST) {
+                       ret = -EINVAL;
+                       break;
+               }
+               ret = sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
+               break;
+
+       case KDENABIO:
+       case KDDISABIO:
+               ret = sys_ioperm(GPFIRST, GPNUM,
+                                 (cmd == KDENABIO)) ? -ENXIO : 0;
+               break;
+#endif
+
+       /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */
+               
+       case KDKBDREP:
+       {
+               struct kbd_repeat kbrep;
+               
+               if (!capable(CAP_SYS_TTY_CONFIG))
+                       goto eperm;
+
+               if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
+                       ret =  -EFAULT;
+                       break;
+               }
+               ret = kbd_rate(&kbrep);
+               if (ret)
+                       break;
+               if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat)))
+                       ret = -EFAULT;
+               break;
+       }
+
+       case KDSETMODE:
+               /*
+                * currently, setting the mode from KD_TEXT to KD_GRAPHICS
+                * doesn't do a whole lot. i'm not sure if it should do any
+                * restoration of modes or what...
+                *
+                * XXX It should at least call into the driver, fbdev's definitely
+                * need to restore their engine state. --BenH
+                */
+               if (!perm)
+                       goto eperm;
+               switch (arg) {
+               case KD_GRAPHICS:
+                       break;
+               case KD_TEXT0:
+               case KD_TEXT1:
+                       arg = KD_TEXT;
+               case KD_TEXT:
+                       break;
+               default:
+                       ret = -EINVAL;
+                       goto out;
+               }
+               if (vc->vc_mode == (unsigned char) arg)
+                       break;
+               vc->vc_mode = (unsigned char) arg;
+               if (console != fg_console)
+                       break;
+               /*
+                * explicitly blank/unblank the screen if switching modes
+                */
+               acquire_console_sem();
+               if (arg == KD_TEXT)
+                       do_unblank_screen(1);
+               else
+                       do_blank_screen(1);
+               release_console_sem();
+               break;
+
+       case KDGETMODE:
+               uival = vc->vc_mode;
+               goto setint;
+
+       case KDMAPDISP:
+       case KDUNMAPDISP:
+               /*
+                * these work like a combination of mmap and KDENABIO.
+                * this could be easily finished.
+                */
+               ret = -EINVAL;
+               break;
+
+       case KDSKBMODE:
+               if (!perm)
+                       goto eperm;
+               switch(arg) {
+                 case K_RAW:
+                       kbd->kbdmode = VC_RAW;
+                       break;
+                 case K_MEDIUMRAW:
+                       kbd->kbdmode = VC_MEDIUMRAW;
+                       break;
+                 case K_XLATE:
+                       kbd->kbdmode = VC_XLATE;
+                       compute_shiftstate();
+                       break;
+                 case K_UNICODE:
+                       kbd->kbdmode = VC_UNICODE;
+                       compute_shiftstate();
+                       break;
+                 default:
+                       ret = -EINVAL;
+                       goto out;
+               }
+               tty_ldisc_flush(tty);
+               break;
+
+       case KDGKBMODE:
+               uival = ((kbd->kbdmode == VC_RAW) ? K_RAW :
+                                (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
+                                (kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
+                                K_XLATE);
+               goto setint;
+
+       /* this could be folded into KDSKBMODE, but for compatibility
+          reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
+       case KDSKBMETA:
+               switch(arg) {
+                 case K_METABIT:
+                       clr_vc_kbd_mode(kbd, VC_META);
+                       break;
+                 case K_ESCPREFIX:
+                       set_vc_kbd_mode(kbd, VC_META);
+                       break;
+                 default:
+                       ret = -EINVAL;
+               }
+               break;
+
+       case KDGKBMETA:
+               uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
+       setint:
+               ret = put_user(uival, (int __user *)arg);
+               break;
+
+       case KDGETKEYCODE:
+       case KDSETKEYCODE:
+               if(!capable(CAP_SYS_TTY_CONFIG))
+                       perm = 0;
+               ret = do_kbkeycode_ioctl(cmd, up, perm);
+               break;
+
+       case KDGKBENT:
+       case KDSKBENT:
+               ret = do_kdsk_ioctl(cmd, up, perm, kbd);
+               break;
+
+       case KDGKBSENT:
+       case KDSKBSENT:
+               ret = do_kdgkb_ioctl(cmd, up, perm);
+               break;
+
+       case KDGKBDIACR:
+       {
+               struct kbdiacrs __user *a = up;
+               struct kbdiacr diacr;
+               int i;
+
+               if (put_user(accent_table_size, &a->kb_cnt)) {
+                       ret = -EFAULT;
+                       break;
+               }
+               for (i = 0; i < accent_table_size; i++) {
+                       diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr);
+                       diacr.base = conv_uni_to_8bit(accent_table[i].base);
+                       diacr.result = conv_uni_to_8bit(accent_table[i].result);
+                       if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) {
+                               ret = -EFAULT;
+                               break;
+                       }
+               }
+               break;
+       }
+       case KDGKBDIACRUC:
+       {
+               struct kbdiacrsuc __user *a = up;
+
+               if (put_user(accent_table_size, &a->kb_cnt))
+                       ret = -EFAULT;
+               else if (copy_to_user(a->kbdiacruc, accent_table,
+                               accent_table_size*sizeof(struct kbdiacruc)))
+                       ret = -EFAULT;
+               break;
+       }
+
+       case KDSKBDIACR:
+       {
+               struct kbdiacrs __user *a = up;
+               struct kbdiacr diacr;
+               unsigned int ct;
+               int i;
+
+               if (!perm)
+                       goto eperm;
+               if (get_user(ct,&a->kb_cnt)) {
+                       ret = -EFAULT;
+                       break;
+               }
+               if (ct >= MAX_DIACR) {
+                       ret = -EINVAL;
+                       break;
+               }
+               accent_table_size = ct;
+               for (i = 0; i < ct; i++) {
+                       if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) {
+                               ret = -EFAULT;
+                               break;
+                       }
+                       accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr);
+                       accent_table[i].base = conv_8bit_to_uni(diacr.base);
+                       accent_table[i].result = conv_8bit_to_uni(diacr.result);
+               }
+               break;
+       }
+
+       case KDSKBDIACRUC:
+       {
+               struct kbdiacrsuc __user *a = up;
+               unsigned int ct;
+
+               if (!perm)
+                       goto eperm;
+               if (get_user(ct,&a->kb_cnt)) {
+                       ret = -EFAULT;
+                       break;
+               }
+               if (ct >= MAX_DIACR) {
+                       ret = -EINVAL;
+                       break;
+               }
+               accent_table_size = ct;
+               if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
+                       ret = -EFAULT;
+               break;
+       }
+
+       /* the ioctls below read/set the flags usually shown in the leds */
+       /* don't use them - they will go away without warning */
+       case KDGKBLED:
+               ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
+               goto setchar;
+
+       case KDSKBLED:
+               if (!perm)
+                       goto eperm;
+               if (arg & ~0x77) {
+                       ret = -EINVAL;
+                       break;
+               }
+               kbd->ledflagstate = (arg & 7);
+               kbd->default_ledflagstate = ((arg >> 4) & 7);
+               set_leds();
+               break;
+
+       /* the ioctls below only set the lights, not the functions */
+       /* for those, see KDGKBLED and KDSKBLED above */
+       case KDGETLED:
+               ucval = getledstate();
+       setchar:
+               ret = put_user(ucval, (char __user *)arg);
+               break;
+
+       case KDSETLED:
+               if (!perm)
+                       goto eperm;
+               setledstate(kbd, arg);
+               break;
+
+       /*
+        * A process can indicate its willingness to accept signals
+        * generated by pressing an appropriate key combination.
+        * Thus, one can have a daemon that e.g. spawns a new console
+        * upon a keypress and then changes to it.
+        * See also the kbrequest field of inittab(5).
+        */
+       case KDSIGACCEPT:
+       {
+               if (!perm || !capable(CAP_KILL))
+                       goto eperm;
+               if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
+                       ret = -EINVAL;
+               else {
+                       spin_lock_irq(&vt_spawn_con.lock);
+                       put_pid(vt_spawn_con.pid);
+                       vt_spawn_con.pid = get_pid(task_pid(current));
+                       vt_spawn_con.sig = arg;
+                       spin_unlock_irq(&vt_spawn_con.lock);
+               }
+               break;
+       }
+
+       case VT_SETMODE:
+       {
+               struct vt_mode tmp;
+
+               if (!perm)
+                       goto eperm;
+               if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
+                       ret = -EFAULT;
+                       goto out;
+               }
+               if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+               acquire_console_sem();
+               vc->vt_mode = tmp;
+               /* the frsig is ignored, so we set it to 0 */
+               vc->vt_mode.frsig = 0;
+               put_pid(vc->vt_pid);
+               vc->vt_pid = get_pid(task_pid(current));
+               /* no switch is required -- saw@shade.msu.ru */
+               vc->vt_newvt = -1;
+               release_console_sem();
+               break;
+       }
+
+       case VT_GETMODE:
+       {
+               struct vt_mode tmp;
+               int rc;
+
+               acquire_console_sem();
+               memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
+               release_console_sem();
+
+               rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
+               if (rc)
+                       ret = -EFAULT;
+               break;
+       }
+
+       /*
+        * Returns global vt state. Note that VT 0 is always open, since
+        * it's an alias for the current VT, and people can't use it here.
+        * We cannot return state for more than 16 VTs, since v_state is short.
+        */
+       case VT_GETSTATE:
+       {
+               struct vt_stat __user *vtstat = up;
+               unsigned short state, mask;
+
+               if (put_user(fg_console + 1, &vtstat->v_active))
+                       ret = -EFAULT;
+               else {
+                       state = 1;      /* /dev/tty0 is always open */
+                       for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
+                                                       ++i, mask <<= 1)
+                               if (VT_IS_IN_USE(i))
+                                       state |= mask;
+                       ret = put_user(state, &vtstat->v_state);
+               }
+               break;
+       }
+
+       /*
+        * Returns the first available (non-opened) console.
+        */
+       case VT_OPENQRY:
+               for (i = 0; i < MAX_NR_CONSOLES; ++i)
+                       if (! VT_IS_IN_USE(i))
+                               break;
+               uival = i < MAX_NR_CONSOLES ? (i+1) : -1;
+               goto setint;             
+
+       /*
+        * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num,
+        * with num >= 1 (switches to vt 0, our console, are not allowed, just
+        * to preserve sanity).
+        */
+       case VT_ACTIVATE:
+               if (!perm)
+                       goto eperm;
+               if (arg == 0 || arg > MAX_NR_CONSOLES)
+                       ret =  -ENXIO;
+               else {
+                       arg--;
+                       acquire_console_sem();
+                       ret = vc_allocate(arg);
+                       release_console_sem();
+                       if (ret)
+                               break;
+                       set_console(arg);
+               }
+               break;
+
+       case VT_SETACTIVATE:
+       {
+               struct vt_setactivate vsa;
+
+               if (!perm)
+                       goto eperm;
+
+               if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
+                                       sizeof(struct vt_setactivate))) {
+                       ret = -EFAULT;
+                       goto out;
+               }
+               if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
+                       ret = -ENXIO;
+               else {
+                       vsa.console--;
+                       acquire_console_sem();
+                       ret = vc_allocate(vsa.console);
+                       if (ret == 0) {
+                               struct vc_data *nvc;
+                               /* This is safe providing we don't drop the
+                                  console sem between vc_allocate and
+                                  finishing referencing nvc */
+                               nvc = vc_cons[vsa.console].d;
+                               nvc->vt_mode = vsa.mode;
+                               nvc->vt_mode.frsig = 0;
+                               put_pid(nvc->vt_pid);
+                               nvc->vt_pid = get_pid(task_pid(current));
+                       }
+                       release_console_sem();
+                       if (ret)
+                               break;
+                       /* Commence switch and lock */
+                       set_console(arg);
+               }
+       }
+
+       /*
+        * wait until the specified VT has been activated
+        */
+       case VT_WAITACTIVE:
+               if (!perm)
+                       goto eperm;
+               if (arg == 0 || arg > MAX_NR_CONSOLES)
+                       ret = -ENXIO;
+               else
+                       ret = vt_waitactive(arg);
+               break;
+
+       /*
+        * If a vt is under process control, the kernel will not switch to it
+        * immediately, but postpone the operation until the process calls this
+        * ioctl, allowing the switch to complete.
+        *
+        * According to the X sources this is the behavior:
+        *      0:      pending switch-from not OK
+        *      1:      pending switch-from OK
+        *      2:      completed switch-to OK
+        */
+       case VT_RELDISP:
+               if (!perm)
+                       goto eperm;
+
+               if (vc->vt_mode.mode != VT_PROCESS) {
+                       ret = -EINVAL;
+                       break;
+               }
+               /*
+                * Switching-from response
+                */
+               acquire_console_sem();
+               if (vc->vt_newvt >= 0) {
+                       if (arg == 0)
+                               /*
+                                * Switch disallowed, so forget we were trying
+                                * to do it.
+                                */
+                               vc->vt_newvt = -1;
+
+                       else {
+                               /*
+                                * The current vt has been released, so
+                                * complete the switch.
+                                */
+                               int newvt;
+                               newvt = vc->vt_newvt;
+                               vc->vt_newvt = -1;
+                               ret = vc_allocate(newvt);
+                               if (ret) {
+                                       release_console_sem();
+                                       break;
+                               }
+                               /*
+                                * When we actually do the console switch,
+                                * make sure we are atomic with respect to
+                                * other console switches..
+                                */
+                               complete_change_console(vc_cons[newvt].d);
+                       }
+               } else {
+                       /*
+                        * Switched-to response
+                        */
+                       /*
+                        * If it's just an ACK, ignore it
+                        */
+                       if (arg != VT_ACKACQ)
+                               ret = -EINVAL;
+               }
+               release_console_sem();
+               break;
+
+        /*
+         * Disallocate memory associated to VT (but leave VT1)
+         */
+        case VT_DISALLOCATE:
+               if (arg > MAX_NR_CONSOLES) {
+                       ret = -ENXIO;
+                       break;
+               }
+               if (arg == 0) {
+                   /* deallocate all unused consoles, but leave 0 */
+                       acquire_console_sem();
+                       for (i=1; i<MAX_NR_CONSOLES; i++)
+                               if (! VT_BUSY(i))
+                                       vc_deallocate(i);
+                       release_console_sem();
+               } else {
+                       /* deallocate a single console, if possible */
+                       arg--;
+                       if (VT_BUSY(arg))
+                               ret = -EBUSY;
+                       else if (arg) {                       /* leave 0 */
+                               acquire_console_sem();
+                               vc_deallocate(arg);
+                               release_console_sem();
+                       }
+               }
+               break;
+
+       case VT_RESIZE:
+       {
+               struct vt_sizes __user *vtsizes = up;
+               struct vc_data *vc;
+
+               ushort ll,cc;
+               if (!perm)
+                       goto eperm;
+               if (get_user(ll, &vtsizes->v_rows) ||
+                   get_user(cc, &vtsizes->v_cols))
+                       ret = -EFAULT;
+               else {
+                       acquire_console_sem();
+                       for (i = 0; i < MAX_NR_CONSOLES; i++) {
+                               vc = vc_cons[i].d;
+
+                               if (vc) {
+                                       vc->vc_resize_user = 1;
+                                       vc_resize(vc_cons[i].d, cc, ll);
+                               }
+                       }
+                       release_console_sem();
+               }
+               break;
+       }
+
+       case VT_RESIZEX:
+       {
+               struct vt_consize __user *vtconsize = up;
+               ushort ll,cc,vlin,clin,vcol,ccol;
+               if (!perm)
+                       goto eperm;
+               if (!access_ok(VERIFY_READ, vtconsize,
+                               sizeof(struct vt_consize))) {
+                       ret = -EFAULT;
+                       break;
+               }
+               /* FIXME: Should check the copies properly */
+               __get_user(ll, &vtconsize->v_rows);
+               __get_user(cc, &vtconsize->v_cols);
+               __get_user(vlin, &vtconsize->v_vlin);
+               __get_user(clin, &vtconsize->v_clin);
+               __get_user(vcol, &vtconsize->v_vcol);
+               __get_user(ccol, &vtconsize->v_ccol);
+               vlin = vlin ? vlin : vc->vc_scan_lines;
+               if (clin) {
+                       if (ll) {
+                               if (ll != vlin/clin) {
+                                       /* Parameters don't add up */
+                                       ret = -EINVAL;
+                                       break;
+                               }
+                       } else 
+                               ll = vlin/clin;
+               }
+               if (vcol && ccol) {
+                       if (cc) {
+                               if (cc != vcol/ccol) {
+                                       ret = -EINVAL;
+                                       break;
+                               }
+                       } else
+                               cc = vcol/ccol;
+               }
+
+               if (clin > 32) {
+                       ret =  -EINVAL;
+                       break;
+               }
+                   
+               for (i = 0; i < MAX_NR_CONSOLES; i++) {
+                       if (!vc_cons[i].d)
+                               continue;
+                       acquire_console_sem();
+                       if (vlin)
+                               vc_cons[i].d->vc_scan_lines = vlin;
+                       if (clin)
+                               vc_cons[i].d->vc_font.height = clin;
+                       vc_cons[i].d->vc_resize_user = 1;
+                       vc_resize(vc_cons[i].d, cc, ll);
+                       release_console_sem();
+               }
+               break;
+       }
+
+       case PIO_FONT: {
+               if (!perm)
+                       goto eperm;
+               op.op = KD_FONT_OP_SET;
+               op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
+               op.width = 8;
+               op.height = 0;
+               op.charcount = 256;
+               op.data = up;
+               ret = con_font_op(vc_cons[fg_console].d, &op);
+               break;
+       }
+
+       case GIO_FONT: {
+               op.op = KD_FONT_OP_GET;
+               op.flags = KD_FONT_FLAG_OLD;
+               op.width = 8;
+               op.height = 32;
+               op.charcount = 256;
+               op.data = up;
+               ret = con_font_op(vc_cons[fg_console].d, &op);
+               break;
+       }
+
+       case PIO_CMAP:
+                if (!perm)
+                       ret = -EPERM;
+               else
+                       ret = con_set_cmap(up);
+               break;
+
+       case GIO_CMAP:
+                ret = con_get_cmap(up);
+               break;
+
+       case PIO_FONTX:
+       case GIO_FONTX:
+               ret = do_fontx_ioctl(cmd, up, perm, &op);
+               break;
+
+       case PIO_FONTRESET:
+       {
+               if (!perm)
+                       goto eperm;
+
+#ifdef BROKEN_GRAPHICS_PROGRAMS
+               /* With BROKEN_GRAPHICS_PROGRAMS defined, the default
+                  font is not saved. */
+               ret = -ENOSYS;
+               break;
+#else
+               {
+               op.op = KD_FONT_OP_SET_DEFAULT;
+               op.data = NULL;
+               ret = con_font_op(vc_cons[fg_console].d, &op);
+               if (ret)
+                       break;
+               con_set_default_unimap(vc_cons[fg_console].d);
+               break;
+               }
+#endif
+       }
+
+       case KDFONTOP: {
+               if (copy_from_user(&op, up, sizeof(op))) {
+                       ret = -EFAULT;
+                       break;
+               }
+               if (!perm && op.op != KD_FONT_OP_GET)
+                       goto eperm;
+               ret = con_font_op(vc, &op);
+               if (ret)
+                       break;
+               if (copy_to_user(up, &op, sizeof(op)))
+                       ret = -EFAULT;
+               break;
+       }
+
+       case PIO_SCRNMAP:
+               if (!perm)
+                       ret = -EPERM;
+               else
+                       ret = con_set_trans_old(up);
+               break;
+
+       case GIO_SCRNMAP:
+               ret = con_get_trans_old(up);
+               break;
+
+       case PIO_UNISCRNMAP:
+               if (!perm)
+                       ret = -EPERM;
+               else
+                       ret = con_set_trans_new(up);
+               break;
+
+       case GIO_UNISCRNMAP:
+               ret = con_get_trans_new(up);
+               break;
+
+       case PIO_UNIMAPCLR:
+             { struct unimapinit ui;
+               if (!perm)
+                       goto eperm;
+               ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
+               if (ret)
+                       ret = -EFAULT;
+               else
+                       con_clear_unimap(vc, &ui);
+               break;
+             }
+
+       case PIO_UNIMAP:
+       case GIO_UNIMAP:
+               ret = do_unimap_ioctl(cmd, up, perm, vc);
+               break;
+
+       case VT_LOCKSWITCH:
+               if (!capable(CAP_SYS_TTY_CONFIG))
+                       goto eperm;
+               vt_dont_switch = 1;
+               break;
+       case VT_UNLOCKSWITCH:
+               if (!capable(CAP_SYS_TTY_CONFIG))
+                       goto eperm;
+               vt_dont_switch = 0;
+               break;
+       case VT_GETHIFONTMASK:
+               ret = put_user(vc->vc_hi_font_mask,
+                                       (unsigned short __user *)arg);
+               break;
+       case VT_WAITEVENT:
+               ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
+               break;
+       default:
+               ret = -ENOIOCTLCMD;
+       }
+out:
+       tty_unlock();
+       return ret;
+eperm:
+       ret = -EPERM;
+       goto out;
+}
+
+void reset_vc(struct vc_data *vc)
+{
+       vc->vc_mode = KD_TEXT;
+       kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
+       vc->vt_mode.mode = VT_AUTO;
+       vc->vt_mode.waitv = 0;
+       vc->vt_mode.relsig = 0;
+       vc->vt_mode.acqsig = 0;
+       vc->vt_mode.frsig = 0;
+       put_pid(vc->vt_pid);
+       vc->vt_pid = NULL;
+       vc->vt_newvt = -1;
+       if (!in_interrupt())    /* Via keyboard.c:SAK() - akpm */
+               reset_palette(vc);
+}
+
+void vc_SAK(struct work_struct *work)
+{
+       struct vc *vc_con =
+               container_of(work, struct vc, SAK_work);
+       struct vc_data *vc;
+       struct tty_struct *tty;
+
+       acquire_console_sem();
+       vc = vc_con->d;
+       if (vc) {
+               tty = vc->port.tty;
+               /*
+                * SAK should also work in all raw modes and reset
+                * them properly.
+                */
+               if (tty)
+                       __do_SAK(tty);
+               reset_vc(vc);
+       }
+       release_console_sem();
+}
+
+#ifdef CONFIG_COMPAT
+
+struct compat_consolefontdesc {
+       unsigned short charcount;       /* characters in font (256 or 512) */
+       unsigned short charheight;      /* scan lines per character (1-32) */
+       compat_caddr_t chardata;        /* font data in expanded form */
+};
+
+static inline int
+compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
+                        int perm, struct console_font_op *op)
+{
+       struct compat_consolefontdesc cfdarg;
+       int i;
+
+       if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc)))
+               return -EFAULT;
+
+       switch (cmd) {
+       case PIO_FONTX:
+               if (!perm)
+                       return -EPERM;
+               op->op = KD_FONT_OP_SET;
+               op->flags = KD_FONT_FLAG_OLD;
+               op->width = 8;
+               op->height = cfdarg.charheight;
+               op->charcount = cfdarg.charcount;
+               op->data = compat_ptr(cfdarg.chardata);
+               return con_font_op(vc_cons[fg_console].d, op);
+       case GIO_FONTX:
+               op->op = KD_FONT_OP_GET;
+               op->flags = KD_FONT_FLAG_OLD;
+               op->width = 8;
+               op->height = cfdarg.charheight;
+               op->charcount = cfdarg.charcount;
+               op->data = compat_ptr(cfdarg.chardata);
+               i = con_font_op(vc_cons[fg_console].d, op);
+               if (i)
+                       return i;
+               cfdarg.charheight = op->height;
+               cfdarg.charcount = op->charcount;
+               if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc)))
+                       return -EFAULT;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+struct compat_console_font_op {
+       compat_uint_t op;        /* operation code KD_FONT_OP_* */
+       compat_uint_t flags;     /* KD_FONT_FLAG_* */
+       compat_uint_t width, height;     /* font size */
+       compat_uint_t charcount;
+       compat_caddr_t data;    /* font data with height fixed to 32 */
+};
+
+static inline int
+compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
+                        int perm, struct console_font_op *op, struct vc_data *vc)
+{
+       int i;
+
+       if (copy_from_user(op, fontop, sizeof(struct compat_console_font_op)))
+               return -EFAULT;
+       if (!perm && op->op != KD_FONT_OP_GET)
+               return -EPERM;
+       op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
+       op->flags |= KD_FONT_FLAG_OLD;
+       i = con_font_op(vc, op);
+       if (i)
+               return i;
+       ((struct compat_console_font_op *)op)->data = (unsigned long)op->data;
+       if (copy_to_user(fontop, op, sizeof(struct compat_console_font_op)))
+               return -EFAULT;
+       return 0;
+}
+
+struct compat_unimapdesc {
+       unsigned short entry_ct;
+       compat_caddr_t entries;
+};
+
+static inline int
+compat_unimap_ioctl(unsigned int cmd, struct compat_unimapdesc __user *user_ud,
+                        int perm, struct vc_data *vc)
+{
+       struct compat_unimapdesc tmp;
+       struct unipair __user *tmp_entries;
+
+       if (copy_from_user(&tmp, user_ud, sizeof tmp))
+               return -EFAULT;
+       tmp_entries = compat_ptr(tmp.entries);
+       if (tmp_entries)
+               if (!access_ok(VERIFY_WRITE, tmp_entries,
+                               tmp.entry_ct*sizeof(struct unipair)))
+                       return -EFAULT;
+       switch (cmd) {
+       case PIO_UNIMAP:
+               if (!perm)
+                       return -EPERM;
+               return con_set_unimap(vc, tmp.entry_ct, tmp_entries);
+       case GIO_UNIMAP:
+               if (!perm && fg_console != vc->vc_num)
+                       return -EPERM;
+               return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp_entries);
+       }
+       return 0;
+}
+
+long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
+            unsigned int cmd, unsigned long arg)
+{
+       struct vc_data *vc = tty->driver_data;
+       struct console_font_op op;      /* used in multiple places here */
+       struct kbd_struct *kbd;
+       unsigned int console;
+       void __user *up = (void __user *)arg;
+       int perm;
+       int ret = 0;
+
+       console = vc->vc_num;
+
+       tty_lock();
+
+       if (!vc_cons_allocated(console)) {      /* impossible? */
+               ret = -ENOIOCTLCMD;
+               goto out;
+       }
+
+       /*
+        * To have permissions to do most of the vt ioctls, we either have
+        * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
+        */
+       perm = 0;
+       if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
+               perm = 1;
+
+       kbd = kbd_table + console;
+       switch (cmd) {
+       /*
+        * these need special handlers for incompatible data structures
+        */
+       case PIO_FONTX:
+       case GIO_FONTX:
+               ret = compat_fontx_ioctl(cmd, up, perm, &op);
+               break;
+
+       case KDFONTOP:
+               ret = compat_kdfontop_ioctl(up, perm, &op, vc);
+               break;
+
+       case PIO_UNIMAP:
+       case GIO_UNIMAP:
+               ret = compat_unimap_ioctl(cmd, up, perm, vc);
+               break;
+
+       /*
+        * all these treat 'arg' as an integer
+        */
+       case KIOCSOUND:
+       case KDMKTONE:
+#ifdef CONFIG_X86
+       case KDADDIO:
+       case KDDELIO:
+#endif
+       case KDSETMODE:
+       case KDMAPDISP:
+       case KDUNMAPDISP:
+       case KDSKBMODE:
+       case KDSKBMETA:
+       case KDSKBLED:
+       case KDSETLED:
+       case KDSIGACCEPT:
+       case VT_ACTIVATE:
+       case VT_WAITACTIVE:
+       case VT_RELDISP:
+       case VT_DISALLOCATE:
+       case VT_RESIZE:
+       case VT_RESIZEX:
+               goto fallback;
+
+       /*
+        * the rest has a compatible data structure behind arg,
+        * but we have to convert it to a proper 64 bit pointer.
+        */
+       default:
+               arg = (unsigned long)compat_ptr(arg);
+               goto fallback;
+       }
+out:
+       tty_unlock();
+       return ret;
+
+fallback:
+       tty_unlock();
+       return vt_ioctl(tty, file, cmd, arg);
+}
+
+
+#endif /* CONFIG_COMPAT */
+
+
+/*
+ * Performs the back end of a vt switch. Called under the console
+ * semaphore.
+ */
+static void complete_change_console(struct vc_data *vc)
+{
+       unsigned char old_vc_mode;
+       int old = fg_console;
+
+       last_console = fg_console;
+
+       /*
+        * If we're switching, we could be going from KD_GRAPHICS to
+        * KD_TEXT mode or vice versa, which means we need to blank or
+        * unblank the screen later.
+        */
+       old_vc_mode = vc_cons[fg_console].d->vc_mode;
+       switch_screen(vc);
+
+       /*
+        * This can't appear below a successful kill_pid().  If it did,
+        * then the *blank_screen operation could occur while X, having
+        * received acqsig, is waking up on another processor.  This
+        * condition can lead to overlapping accesses to the VGA range
+        * and the framebuffer (causing system lockups).
+        *
+        * To account for this we duplicate this code below only if the
+        * controlling process is gone and we've called reset_vc.
+        */
+       if (old_vc_mode != vc->vc_mode) {
+               if (vc->vc_mode == KD_TEXT)
+                       do_unblank_screen(1);
+               else
+                       do_blank_screen(1);
+       }
+
+       /*
+        * If this new console is under process control, send it a signal
+        * telling it that it has acquired. Also check if it has died and
+        * clean up (similar to logic employed in change_console())
+        */
+       if (vc->vt_mode.mode == VT_PROCESS) {
+               /*
+                * Send the signal as privileged - kill_pid() will
+                * tell us if the process has gone or something else
+                * is awry
+                */
+               if (kill_pid(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
+               /*
+                * The controlling process has died, so we revert back to
+                * normal operation. In this case, we'll also change back
+                * to KD_TEXT mode. I'm not sure if this is strictly correct
+                * but it saves the agony when the X server dies and the screen
+                * remains blanked due to KD_GRAPHICS! It would be nice to do
+                * this outside of VT_PROCESS but there is no single process
+                * to account for and tracking tty count may be undesirable.
+                */
+                       reset_vc(vc);
+
+                       if (old_vc_mode != vc->vc_mode) {
+                               if (vc->vc_mode == KD_TEXT)
+                                       do_unblank_screen(1);
+                               else
+                                       do_blank_screen(1);
+                       }
+               }
+       }
+
+       /*
+        * Wake anyone waiting for their VT to activate
+        */
+       vt_event_post(VT_EVENT_SWITCH, old, vc->vc_num);
+       return;
+}
+
+/*
+ * Performs the front-end of a vt switch
+ */
+void change_console(struct vc_data *new_vc)
+{
+       struct vc_data *vc;
+
+       if (!new_vc || new_vc->vc_num == fg_console || vt_dont_switch)
+               return;
+
+       /*
+        * If this vt is in process mode, then we need to handshake with
+        * that process before switching. Essentially, we store where that
+        * vt wants to switch to and wait for it to tell us when it's done
+        * (via VT_RELDISP ioctl).
+        *
+        * We also check to see if the controlling process still exists.
+        * If it doesn't, we reset this vt to auto mode and continue.
+        * This is a cheap way to track process control. The worst thing
+        * that can happen is: we send a signal to a process, it dies, and
+        * the switch gets "lost" waiting for a response; hopefully, the
+        * user will try again, we'll detect the process is gone (unless
+        * the user waits just the right amount of time :-) and revert the
+        * vt to auto control.
+        */
+       vc = vc_cons[fg_console].d;
+       if (vc->vt_mode.mode == VT_PROCESS) {
+               /*
+                * Send the signal as privileged - kill_pid() will
+                * tell us if the process has gone or something else
+                * is awry.
+                *
+                * We need to set vt_newvt *before* sending the signal or we
+                * have a race.
+                */
+               vc->vt_newvt = new_vc->vc_num;
+               if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
+                       /*
+                        * It worked. Mark the vt to switch to and
+                        * return. The process needs to send us a
+                        * VT_RELDISP ioctl to complete the switch.
+                        */
+                       return;
+               }
+
+               /*
+                * The controlling process has died, so we revert back to
+                * normal operation. In this case, we'll also change back
+                * to KD_TEXT mode. I'm not sure if this is strictly correct
+                * but it saves the agony when the X server dies and the screen
+                * remains blanked due to KD_GRAPHICS! It would be nice to do
+                * this outside of VT_PROCESS but there is no single process
+                * to account for and tracking tty count may be undesirable.
+                */
+               reset_vc(vc);
+
+               /*
+                * Fall through to normal (VT_AUTO) handling of the switch...
+                */
+       }
+
+       /*
+        * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
+        */
+       if (vc->vc_mode == KD_GRAPHICS)
+               return;
+
+       complete_change_console(new_vc);
+}
+
+/* Perform a kernel triggered VT switch for suspend/resume */
+
+static int disable_vt_switch;
+
+int vt_move_to_console(unsigned int vt, int alloc)
+{
+       int prev;
+
+       acquire_console_sem();
+       /* Graphics mode - up to X */
+       if (disable_vt_switch) {
+               release_console_sem();
+               return 0;
+       }
+       prev = fg_console;
+
+       if (alloc && vc_allocate(vt)) {
+               /* we can't have a free VC for now. Too bad,
+                * we don't want to mess the screen for now. */
+               release_console_sem();
+               return -ENOSPC;
+       }
+
+       if (set_console(vt)) {
+               /*
+                * We're unable to switch to the SUSPEND_CONSOLE.
+                * Let the calling function know so it can decide
+                * what to do.
+                */
+               release_console_sem();
+               return -EIO;
+       }
+       release_console_sem();
+       tty_lock();
+       if (vt_waitactive(vt + 1)) {
+               pr_debug("Suspend: Can't switch VCs.");
+               tty_unlock();
+               return -EINTR;
+       }
+       tty_unlock();
+       return prev;
+}
+
+/*
+ * Normally during a suspend, we allocate a new console and switch to it.
+ * When we resume, we switch back to the original console.  This switch
+ * can be slow, so on systems where the framebuffer can handle restoration
+ * of video registers anyways, there's little point in doing the console
+ * switch.  This function allows you to disable it by passing it '0'.
+ */
+void pm_set_vt_switch(int do_switch)
+{
+       acquire_console_sem();
+       disable_vt_switch = !do_switch;
+       release_console_sem();
+}
+EXPORT_SYMBOL(pm_set_vt_switch);
index f1aaff6202a58bb386a2947d0df2047322c8c43f..045bb4b823e175fa2d16e228071e138a2c8a44e8 100644 (file)
@@ -965,10 +965,11 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg)
 
 static int proc_connectinfo(struct dev_state *ps, void __user *arg)
 {
-       struct usbdevfs_connectinfo ci;
+       struct usbdevfs_connectinfo ci = {
+               .devnum = ps->dev->devnum,
+               .slow = ps->dev->speed == USB_SPEED_LOW
+       };
 
-       ci.devnum = ps->dev->devnum;
-       ci.slow = ps->dev->speed == USB_SPEED_LOW;
        if (copy_to_user(arg, &ci, sizeof(ci)))
                return -EFAULT;
        return 0;
index e2f63c0ea09df16286ea8c4ad04a743ff3d0a9b5..9819a4cc3b264d48111a08a8d51e242b0b1329d8 100644 (file)
@@ -574,16 +574,16 @@ static void fs_remove_file (struct dentry *dentry)
 
 /* --------------------------------------------------------------------- */
 
-static int usb_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *usb_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, usbfs_fill_super, mnt);
+       return mount_single(fs_type, flags, data, usbfs_fill_super);
 }
 
 static struct file_system_type usb_fs_type = {
        .owner =        THIS_MODULE,
        .name =         "usbfs",
-       .get_sb =       usb_get_sb,
+       .mount =        usb_mount,
        .kill_sb =      kill_litter_super,
 };
 
index b739ca8146511dc96f38d067f139ad79b23e2348..607d0db4a988aa590833209faa37db881cadc728 100644 (file)
@@ -158,7 +158,7 @@ config USB_GADGET_FSL_USB2
        boolean "Freescale Highspeed USB DR Peripheral Controller"
        depends on FSL_SOC || ARCH_MXC
        select USB_GADGET_DUALSPEED
-       select USB_FSL_MPH_DR_OF
+       select USB_FSL_MPH_DR_OF if OF
        help
           Some of Freescale PowerPC processors have a High Speed
           Dual-Role(DR) USB controller, which supports device mode.
index f276e9594f00eab91ff7f789b58e80e7a95a8bcc..4a830df4fc31a1a58692f6b1b5adc29a7a9895c4 100644 (file)
@@ -1176,9 +1176,9 @@ invalid:
 
 /* "mount -t functionfs dev_name /dev/function" ends up here */
 
-static int
-ffs_fs_get_sb(struct file_system_type *t, int flags,
-             const char *dev_name, void *opts, struct vfsmount *mnt)
+static struct dentry *
+ffs_fs_mount(struct file_system_type *t, int flags,
+             const char *dev_name, void *opts)
 {
        struct ffs_sb_fill_data data = {
                .perms = {
@@ -1194,14 +1194,14 @@ ffs_fs_get_sb(struct file_system_type *t, int flags,
 
        ret = functionfs_check_dev_callback(dev_name);
        if (unlikely(ret < 0))
-               return ret;
+               return ERR_PTR(ret);
 
        ret = ffs_fs_parse_opts(&data, opts);
        if (unlikely(ret < 0))
-               return ret;
+               return ERR_PTR(ret);
 
        data.dev_name = dev_name;
-       return get_sb_single(t, flags, &data, ffs_sb_fill, mnt);
+       return mount_single(t, flags, &data, ffs_sb_fill);
 }
 
 static void
@@ -1220,7 +1220,7 @@ ffs_fs_kill_sb(struct super_block *sb)
 static struct file_system_type ffs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "functionfs",
-       .get_sb         = ffs_fs_get_sb,
+       .mount          = ffs_fs_mount,
        .kill_sb        = ffs_fs_kill_sb,
 };
 
index 566cb23190565288ec500fc3c525944801982910..e7e0c69d3b1f4671f1c7b81ca500080bf50672d8 100644 (file)
@@ -251,7 +251,8 @@ struct goku_udc {
                                        got_region:1,
                                        req_config:1,
                                        configured:1,
-                                       enabled:1;
+                                       enabled:1,
+                                       registered:1;
 
        /* pci state used to access those endpoints */
        struct pci_dev                  *pdev;
index ba145e7fbe03ef27fcd37598dc46a9f1fb31eb27..3ed73f49cf188cd98b92cc3e847a6e40f0062efb 100644 (file)
@@ -2097,11 +2097,11 @@ enomem0:
 }
 
 /* "mount -t gadgetfs path /dev/gadget" ends up here */
-static int
-gadgetfs_get_sb (struct file_system_type *t, int flags,
-               const char *path, void *opts, struct vfsmount *mnt)
+static struct dentry *
+gadgetfs_mount (struct file_system_type *t, int flags,
+               const char *path, void *opts)
 {
-       return get_sb_single (t, flags, opts, gadgetfs_fill_super, mnt);
+       return mount_single (t, flags, opts, gadgetfs_fill_super);
 }
 
 static void
@@ -2119,7 +2119,7 @@ gadgetfs_kill_sb (struct super_block *sb)
 static struct file_system_type gadgetfs_type = {
        .owner          = THIS_MODULE,
        .name           = shortname,
-       .get_sb         = gadgetfs_get_sb,
+       .mount          = gadgetfs_mount,
        .kill_sb        = gadgetfs_kill_sb,
 };
 
index 6bb876d652527b24cda02b7d272252418b2830a4..fbe86ca95802b93d68ace2718280a4aeb8b533c2 100644 (file)
@@ -797,7 +797,6 @@ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN])
         *  - iff DATA transfer is active, carrier is "on"
         *  - tx queueing enabled if open *and* carrier is "on"
         */
-       netif_stop_queue(net);
        netif_carrier_off(net);
 
        dev->gadget = g;
index 01e5354a4c20ffd5b072fdff6a828d08e9049317..40f7716b31fcc78244c6db8f36569ddd0cd824cc 100644 (file)
@@ -105,11 +105,15 @@ struct gs_port {
        wait_queue_head_t       close_wait;     /* wait for last close */
 
        struct list_head        read_pool;
+       int read_started;
+       int read_allocated;
        struct list_head        read_queue;
        unsigned                n_read;
        struct tasklet_struct   push;
 
        struct list_head        write_pool;
+       int write_started;
+       int write_allocated;
        struct gs_buf           port_write_buf;
        wait_queue_head_t       drain_wait;     /* wait while writes drain */
 
@@ -363,6 +367,9 @@ __acquires(&port->port_lock)
                struct usb_request      *req;
                int                     len;
 
+               if (port->write_started >= QUEUE_SIZE)
+                       break;
+
                req = list_entry(pool->next, struct usb_request, list);
                len = gs_send_packet(port, req->buf, in->maxpacket);
                if (len == 0) {
@@ -397,6 +404,8 @@ __acquires(&port->port_lock)
                        break;
                }
 
+               port->write_started++;
+
                /* abort immediately after disconnect */
                if (!port->port_usb)
                        break;
@@ -418,7 +427,6 @@ __acquires(&port->port_lock)
 {
        struct list_head        *pool = &port->read_pool;
        struct usb_ep           *out = port->port_usb->out;
-       unsigned                started = 0;
 
        while (!list_empty(pool)) {
                struct usb_request      *req;
@@ -430,6 +438,9 @@ __acquires(&port->port_lock)
                if (!tty)
                        break;
 
+               if (port->read_started >= QUEUE_SIZE)
+                       break;
+
                req = list_entry(pool->next, struct usb_request, list);
                list_del(&req->list);
                req->length = out->maxpacket;
@@ -447,13 +458,13 @@ __acquires(&port->port_lock)
                        list_add(&req->list, pool);
                        break;
                }
-               started++;
+               port->read_started++;
 
                /* abort immediately after disconnect */
                if (!port->port_usb)
                        break;
        }
-       return started;
+       return port->read_started;
 }
 
 /*
@@ -535,6 +546,7 @@ static void gs_rx_push(unsigned long _port)
                }
 recycle:
                list_move(&req->list, &port->read_pool);
+               port->read_started--;
        }
 
        /* Push from tty to ldisc; without low_latency set this is handled by
@@ -587,6 +599,7 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req)
 
        spin_lock(&port->port_lock);
        list_add(&req->list, &port->write_pool);
+       port->write_started--;
 
        switch (req->status) {
        default:
@@ -608,7 +621,8 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req)
        spin_unlock(&port->port_lock);
 }
 
-static void gs_free_requests(struct usb_ep *ep, struct list_head *head)
+static void gs_free_requests(struct usb_ep *ep, struct list_head *head,
+                                                        int *allocated)
 {
        struct usb_request      *req;
 
@@ -616,25 +630,31 @@ static void gs_free_requests(struct usb_ep *ep, struct list_head *head)
                req = list_entry(head->next, struct usb_request, list);
                list_del(&req->list);
                gs_free_req(ep, req);
+               if (allocated)
+                       (*allocated)--;
        }
 }
 
 static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head,
-               void (*fn)(struct usb_ep *, struct usb_request *))
+               void (*fn)(struct usb_ep *, struct usb_request *),
+               int *allocated)
 {
        int                     i;
        struct usb_request      *req;
+       int n = allocated ? QUEUE_SIZE - *allocated : QUEUE_SIZE;
 
        /* Pre-allocate up to QUEUE_SIZE transfers, but if we can't
         * do quite that many this time, don't fail ... we just won't
         * be as speedy as we might otherwise be.
         */
-       for (i = 0; i < QUEUE_SIZE; i++) {
+       for (i = 0; i < n; i++) {
                req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC);
                if (!req)
                        return list_empty(head) ? -ENOMEM : 0;
                req->complete = fn;
                list_add_tail(&req->list, head);
+               if (allocated)
+                       (*allocated)++;
        }
        return 0;
 }
@@ -661,14 +681,15 @@ static int gs_start_io(struct gs_port *port)
         * configurations may use different endpoints with a given port;
         * and high speed vs full speed changes packet sizes too.
         */
-       status = gs_alloc_requests(ep, head, gs_read_complete);
+       status = gs_alloc_requests(ep, head, gs_read_complete,
+               &port->read_allocated);
        if (status)
                return status;
 
        status = gs_alloc_requests(port->port_usb->in, &port->write_pool,
-                       gs_write_complete);
+                       gs_write_complete, &port->write_allocated);
        if (status) {
-               gs_free_requests(ep, head);
+               gs_free_requests(ep, head, &port->read_allocated);
                return status;
        }
 
@@ -680,8 +701,9 @@ static int gs_start_io(struct gs_port *port)
        if (started) {
                tty_wakeup(port->port_tty);
        } else {
-               gs_free_requests(ep, head);
-               gs_free_requests(port->port_usb->in, &port->write_pool);
+               gs_free_requests(ep, head, &port->read_allocated);
+               gs_free_requests(port->port_usb->in, &port->write_pool,
+                       &port->write_allocated);
                status = -EIO;
        }
 
@@ -1315,8 +1337,12 @@ void gserial_disconnect(struct gserial *gser)
        spin_lock_irqsave(&port->port_lock, flags);
        if (port->open_count == 0 && !port->openclose)
                gs_buf_free(&port->port_write_buf);
-       gs_free_requests(gser->out, &port->read_pool);
-       gs_free_requests(gser->out, &port->read_queue);
-       gs_free_requests(gser->in, &port->write_pool);
+       gs_free_requests(gser->out, &port->read_pool, NULL);
+       gs_free_requests(gser->out, &port->read_queue, NULL);
+       gs_free_requests(gser->in, &port->write_pool, NULL);
+
+       port->read_allocated = port->read_started =
+               port->write_allocated = port->write_started = 0;
+
        spin_unlock_irqrestore(&port->port_lock, flags);
 }
index bf2e7d234533ecec3f0697b359b2f2a8f8277fa7..6f4f8e6a40c7e2d1fe034ce3ddb056696fc0be00 100644 (file)
@@ -93,8 +93,9 @@ config USB_EHCI_TT_NEWSCHED
 
 config USB_EHCI_BIG_ENDIAN_MMIO
        bool
-       depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || \
-                                   XPS_USB_HCD_XILINX || PPC_MPC512x)
+       depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \
+                                   ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
+                                   PPC_MPC512x || CPU_CAVIUM_OCTEON)
        default y
 
 config USB_EHCI_BIG_ENDIAN_DESC
@@ -121,7 +122,7 @@ config USB_EHCI_FSL
        bool "Support for Freescale on-chip EHCI USB controller"
        depends on USB_EHCI_HCD && FSL_SOC
        select USB_EHCI_ROOT_HUB_TT
-       select USB_FSL_MPH_DR_OF
+       select USB_FSL_MPH_DR_OF if OF
        ---help---
          Variation of ARC USB block used in some Freescale chips.
 
@@ -434,3 +435,28 @@ config USB_IMX21_HCD
          To compile this driver as a module, choose M here: the
          module will be called "imx21-hcd".
 
+config USB_OCTEON_EHCI
+       bool "Octeon on-chip EHCI support"
+       depends on USB && USB_EHCI_HCD && CPU_CAVIUM_OCTEON
+       default n
+       select USB_EHCI_BIG_ENDIAN_MMIO
+       help
+         Enable support for the Octeon II SOC's on-chip EHCI
+         controller.  It is needed for high-speed (480Mbit/sec)
+         USB 2.0 device support.  All CN6XXX based chips with USB are
+         supported.
+
+config USB_OCTEON_OHCI
+       bool "Octeon on-chip OHCI support"
+       depends on USB && USB_OHCI_HCD && CPU_CAVIUM_OCTEON
+       default USB_OCTEON_EHCI
+       select USB_OHCI_BIG_ENDIAN_MMIO
+       select USB_OHCI_LITTLE_ENDIAN
+       help
+         Enable support for the Octeon II SOC's on-chip OHCI
+         controller.  It is needed for low-speed USB 1.0 device
+         support.  All CN6XXX based chips with USB are supported.
+
+config USB_OCTEON2_COMMON
+       bool
+       default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI
index 91c5a1bd102650ecab98aab1ac1e3f1d32372ac6..624a362f2feeebe862477168a0bc528f6883dabf 100644 (file)
@@ -34,3 +34,4 @@ obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
 obj-$(CONFIG_USB_HWA_HCD)      += hwa-hc.o
 obj-$(CONFIG_USB_IMX21_HCD)    += imx21-hcd.o
 obj-$(CONFIG_USB_FSL_MPH_DR_OF)        += fsl-mph-dr-of.o
+obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
index 2adae8e39bba12d47b06103640800b0e38aaec36..502a7e6fef42a5a5c9ddbfa0ca26b4b971b043e1 100644 (file)
@@ -1211,6 +1211,11 @@ MODULE_LICENSE ("GPL");
 #define        PLATFORM_DRIVER         ehci_atmel_driver
 #endif
 
+#ifdef CONFIG_USB_OCTEON_EHCI
+#include "ehci-octeon.c"
+#define PLATFORM_DRIVER                ehci_octeon_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
     !defined(XILINX_OF_PLATFORM_DRIVER)
index ac9c4d7c44af227ff974b6f5af7636013583bcbc..bce85055019a190d3d835fd0386d8a8cd7f4e746 100644 (file)
@@ -36,6 +36,8 @@ struct ehci_mxc_priv {
 static int ehci_mxc_setup(struct usb_hcd *hcd)
 {
        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+       struct device *dev = hcd->self.controller;
+       struct mxc_usbh_platform_data *pdata = dev_get_platdata(dev);
        int retval;
 
        /* EHCI registers start at offset 0x100 */
@@ -63,6 +65,12 @@ static int ehci_mxc_setup(struct usb_hcd *hcd)
 
        ehci_reset(ehci);
 
+       /* set up the PORTSCx register */
+       ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
+
+       /* is this really needed? */
+       msleep(10);
+
        ehci_port_power(ehci, 0);
        return 0;
 }
@@ -114,7 +122,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
        struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
        struct usb_hcd *hcd;
        struct resource *res;
-       int irq, ret, temp;
+       int irq, ret;
        struct ehci_mxc_priv *priv;
        struct device *dev = &pdev->dev;
 
@@ -188,10 +196,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
                clk_enable(priv->ahbclk);
        }
 
-       /* set up the PORTSCx register */
-       ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
-       mdelay(10);
-
        /* setup specific usb hw */
        ret = mxc_initialize_usb_hw(pdev->id, pdata->flags);
        if (ret < 0)
diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c
new file mode 100644 (file)
index 0000000..a31a031
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * EHCI HCD glue for Cavium Octeon II SOCs.
+ *
+ * Loosely based on ehci-au1xxx.c
+ *
+ * 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) 2010 Cavium Networks
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-uctlx-defs.h>
+
+#define OCTEON_EHCI_HCD_NAME "octeon-ehci"
+
+/* Common clock init code.  */
+void octeon2_usb_clocks_start(void);
+void octeon2_usb_clocks_stop(void);
+
+static void ehci_octeon_start(void)
+{
+       union cvmx_uctlx_ehci_ctl ehci_ctl;
+
+       octeon2_usb_clocks_start();
+
+       ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
+       /* Use 64-bit addressing. */
+       ehci_ctl.s.ehci_64b_addr_en = 1;
+       ehci_ctl.s.l2c_addr_msb = 0;
+       ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
+       ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
+       cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64);
+}
+
+static void ehci_octeon_stop(void)
+{
+       octeon2_usb_clocks_stop();
+}
+
+static const struct hc_driver ehci_octeon_hc_driver = {
+       .description            = hcd_name,
+       .product_desc           = "Octeon EHCI",
+       .hcd_priv_size          = sizeof(struct ehci_hcd),
+
+       /*
+        * generic hardware linkage
+        */
+       .irq                    = ehci_irq,
+       .flags                  = HCD_MEMORY | HCD_USB2,
+
+       /*
+        * basic lifecycle operations
+        */
+       .reset                  = ehci_init,
+       .start                  = ehci_run,
+       .stop                   = ehci_stop,
+       .shutdown               = ehci_shutdown,
+
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue            = ehci_urb_enqueue,
+       .urb_dequeue            = ehci_urb_dequeue,
+       .endpoint_disable       = ehci_endpoint_disable,
+       .endpoint_reset         = ehci_endpoint_reset,
+
+       /*
+        * scheduling support
+        */
+       .get_frame_number       = ehci_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_status_data        = ehci_hub_status_data,
+       .hub_control            = ehci_hub_control,
+       .bus_suspend            = ehci_bus_suspend,
+       .bus_resume             = ehci_bus_resume,
+       .relinquish_port        = ehci_relinquish_port,
+       .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
+};
+
+static u64 ehci_octeon_dma_mask = DMA_BIT_MASK(64);
+
+static int ehci_octeon_drv_probe(struct platform_device *pdev)
+{
+       struct usb_hcd *hcd;
+       struct ehci_hcd *ehci;
+       struct resource *res_mem;
+       int irq;
+       int ret;
+
+       if (usb_disabled())
+               return -ENODEV;
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "No irq assigned\n");
+               return -ENODEV;
+       }
+
+       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res_mem == NULL) {
+               dev_err(&pdev->dev, "No register space assigned\n");
+               return -ENODEV;
+       }
+
+       /*
+        * We can DMA from anywhere. But the descriptors must be in
+        * the lower 4GB.
+        */
+       pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+       pdev->dev.dma_mask = &ehci_octeon_dma_mask;
+
+       hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon");
+       if (!hcd)
+               return -ENOMEM;
+
+       hcd->rsrc_start = res_mem->start;
+       hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+
+       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
+                               OCTEON_EHCI_HCD_NAME)) {
+               dev_err(&pdev->dev, "request_mem_region failed\n");
+               ret = -EBUSY;
+               goto err1;
+       }
+
+       hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+       if (!hcd->regs) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -ENOMEM;
+               goto err2;
+       }
+
+       ehci_octeon_start();
+
+       ehci = hcd_to_ehci(hcd);
+
+       /* Octeon EHCI matches CPU endianness. */
+#ifdef __BIG_ENDIAN
+       ehci->big_endian_mmio = 1;
+#endif
+
+       ehci->caps = hcd->regs;
+       ehci->regs = hcd->regs +
+               HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+       /* cache this readonly data; minimize chip reads */
+       ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+       ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+       if (ret) {
+               dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
+               goto err3;
+       }
+
+       platform_set_drvdata(pdev, hcd);
+
+       /* root ports should always stay powered */
+       ehci_port_power(ehci, 1);
+
+       return 0;
+err3:
+       ehci_octeon_stop();
+
+       iounmap(hcd->regs);
+err2:
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+       usb_put_hcd(hcd);
+       return ret;
+}
+
+static int ehci_octeon_drv_remove(struct platform_device *pdev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+       usb_remove_hcd(hcd);
+
+       ehci_octeon_stop();
+       iounmap(hcd->regs);
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver ehci_octeon_driver = {
+       .probe          = ehci_octeon_drv_probe,
+       .remove         = ehci_octeon_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
+       .driver = {
+               .name   = OCTEON_EHCI_HCD_NAME,
+               .owner  = THIS_MODULE,
+       }
+};
+
+MODULE_ALIAS("platform:" OCTEON_EHCI_HCD_NAME);
diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c
new file mode 100644 (file)
index 0000000..72d672c
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * 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) 2010 Cavium Networks
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <asm/atomic.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-uctlx-defs.h>
+
+static atomic_t  octeon2_usb_clock_start_cnt = ATOMIC_INIT(0);
+
+void octeon2_usb_clocks_start(void)
+{
+       u64 div;
+       union cvmx_uctlx_if_ena if_ena;
+       union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
+       union cvmx_uctlx_uphy_ctl_status uphy_ctl_status;
+       union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
+       int i;
+       unsigned long io_clk_64_to_ns;
+
+       if (atomic_inc_return(&octeon2_usb_clock_start_cnt) != 1)
+               return;
+
+       io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
+
+       /*
+        * Step 1: Wait for voltages stable.  That surely happened
+        * before starting the kernel.
+        *
+        * Step 2: Enable  SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1
+        */
+       if_ena.u64 = 0;
+       if_ena.s.en = 1;
+       cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
+
+       /* Step 3: Configure the reference clock, PHY, and HCLK */
+       clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
+       /* 3a */
+       clk_rst_ctl.s.p_por = 1;
+       clk_rst_ctl.s.hrst = 0;
+       clk_rst_ctl.s.p_prst = 0;
+       clk_rst_ctl.s.h_clkdiv_rst = 0;
+       clk_rst_ctl.s.o_clkdiv_rst = 0;
+       clk_rst_ctl.s.h_clkdiv_en = 0;
+       clk_rst_ctl.s.o_clkdiv_en = 0;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+       /* 3b */
+       /* 12MHz crystal. */
+       clk_rst_ctl.s.p_refclk_sel = 0;
+       clk_rst_ctl.s.p_refclk_div = 0;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+       /* 3c */
+       div = octeon_get_io_clock_rate() / 130000000ull;
+
+       switch (div) {
+       case 0:
+               div = 1;
+               break;
+       case 1:
+       case 2:
+       case 3:
+       case 4:
+               break;
+       case 5:
+               div = 4;
+               break;
+       case 6:
+       case 7:
+               div = 6;
+               break;
+       case 8:
+       case 9:
+       case 10:
+       case 11:
+               div = 8;
+               break;
+       default:
+               div = 12;
+               break;
+       }
+       clk_rst_ctl.s.h_div = div;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+       /* Read it back, */
+       clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
+       clk_rst_ctl.s.h_clkdiv_en = 1;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+       /* 3d */
+       clk_rst_ctl.s.h_clkdiv_rst = 1;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+       /* 3e: delay 64 io clocks */
+       ndelay(io_clk_64_to_ns);
+
+       /*
+        * Step 4: Program the power-on reset field in the UCTL
+        * clock-reset-control register.
+        */
+       clk_rst_ctl.s.p_por = 0;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+       /* Step 5:    Wait 1 ms for the PHY clock to start. */
+       mdelay(1);
+
+       /*
+        * Step 6: Program the reset input from automatic test
+        * equipment field in the UPHY CSR
+        */
+       uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0));
+       uphy_ctl_status.s.ate_reset = 1;
+       cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
+
+       /* Step 7: Wait for at least 10ns. */
+       ndelay(10);
+
+       /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */
+       uphy_ctl_status.s.ate_reset = 0;
+       cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
+
+       /*
+        * Step 9: Wait for at least 20ns for UPHY to output PHY clock
+        * signals and OHCI_CLK48
+        */
+       ndelay(20);
+
+       /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */
+       /* 10a */
+       clk_rst_ctl.s.o_clkdiv_rst = 1;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+       /* 10b */
+       clk_rst_ctl.s.o_clkdiv_en = 1;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+       /* 10c */
+       ndelay(io_clk_64_to_ns);
+
+       /*
+        * Step 11: Program the PHY reset field:
+        * UCTL0_CLK_RST_CTL[P_PRST] = 1
+        */
+       clk_rst_ctl.s.p_prst = 1;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+       /* Step 12: Wait 1 uS. */
+       udelay(1);
+
+       /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */
+       clk_rst_ctl.s.hrst = 1;
+       cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
+
+       /* Now we can set some other registers.  */
+
+       for (i = 0; i <= 1; i++) {
+               port_ctl_status.u64 =
+                       cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0));
+               /* Set txvreftune to 15 to obtain complient 'eye' diagram. */
+               port_ctl_status.s.txvreftune = 15;
+               cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0),
+                              port_ctl_status.u64);
+       }
+}
+EXPORT_SYMBOL(octeon2_usb_clocks_start);
+
+void octeon2_usb_clocks_stop(void)
+{
+       union cvmx_uctlx_if_ena if_ena;
+
+       if (atomic_dec_return(&octeon2_usb_clock_start_cnt) != 0)
+               return;
+
+       if_ena.u64 = 0;
+       if_ena.s.en = 0;
+       cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
+}
+EXPORT_SYMBOL(octeon2_usb_clocks_stop);
index f3713f43f3fea479bdb633e4bcf33584d56cb24a..5179acb7aa2fb08be16b4b5becbabeb449cd1911 100644 (file)
@@ -1106,6 +1106,11 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER        ohci_hcd_jz4740_driver
 #endif
 
+#ifdef CONFIG_USB_OCTEON_OHCI
+#include "ohci-octeon.c"
+#define PLATFORM_DRIVER                ohci_octeon_driver
+#endif
+
 #if    !defined(PCI_DRIVER) &&         \
        !defined(PLATFORM_DRIVER) &&    \
        !defined(OMAP1_PLATFORM_DRIVER) &&      \
index 10e1872f3ab9deb2eb06a150f884a19919d26365..931d588c3fb57ccea160bfde8ef51468cfd46467 100644 (file)
@@ -273,4 +273,4 @@ static struct platform_driver ohci_hcd_jz4740_driver = {
        },
 };
 
-MODULE_ALIAS("platfrom:jz4740-ohci");
+MODULE_ALIAS("platform:jz4740-ohci");
diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c
new file mode 100644 (file)
index 0000000..e4ddfaf
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * EHCI HCD glue for Cavium Octeon II SOCs.
+ *
+ * Loosely based on ehci-au1xxx.c
+ *
+ * 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) 2010 Cavium Networks
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-uctlx-defs.h>
+
+#define OCTEON_OHCI_HCD_NAME "octeon-ohci"
+
+/* Common clock init code.  */
+void octeon2_usb_clocks_start(void);
+void octeon2_usb_clocks_stop(void);
+
+static void ohci_octeon_hw_start(void)
+{
+       union cvmx_uctlx_ohci_ctl ohci_ctl;
+
+       octeon2_usb_clocks_start();
+
+       ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0));
+       ohci_ctl.s.l2c_addr_msb = 0;
+       ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
+       ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
+       cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64);
+
+}
+
+static void ohci_octeon_hw_stop(void)
+{
+       /* Undo ohci_octeon_start() */
+       octeon2_usb_clocks_stop();
+}
+
+static int __devinit ohci_octeon_start(struct usb_hcd *hcd)
+{
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       int ret;
+
+       ret = ohci_init(ohci);
+
+       if (ret < 0)
+               return ret;
+
+       ret = ohci_run(ohci);
+
+       if (ret < 0) {
+               ohci_err(ohci, "can't start %s", hcd->self.bus_name);
+               ohci_stop(hcd);
+               return ret;
+       }
+
+       return 0;
+}
+
+static const struct hc_driver ohci_octeon_hc_driver = {
+       .description            = hcd_name,
+       .product_desc           = "Octeon OHCI",
+       .hcd_priv_size          = sizeof(struct ohci_hcd),
+
+       /*
+        * generic hardware linkage
+        */
+       .irq =                  ohci_irq,
+       .flags =                HCD_USB11 | HCD_MEMORY,
+
+       /*
+        * basic lifecycle operations
+        */
+       .start =                ohci_octeon_start,
+       .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
+
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue =          ohci_urb_enqueue,
+       .urb_dequeue =          ohci_urb_dequeue,
+       .endpoint_disable =     ohci_endpoint_disable,
+
+       /*
+        * scheduling support
+        */
+       .get_frame_number =     ohci_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_status_data =      ohci_hub_status_data,
+       .hub_control =          ohci_hub_control,
+
+       .start_port_reset =     ohci_start_port_reset,
+};
+
+static int ohci_octeon_drv_probe(struct platform_device *pdev)
+{
+       struct usb_hcd *hcd;
+       struct ohci_hcd *ohci;
+       void *reg_base;
+       struct resource *res_mem;
+       int irq;
+       int ret;
+
+       if (usb_disabled())
+               return -ENODEV;
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "No irq assigned\n");
+               return -ENODEV;
+       }
+
+       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res_mem == NULL) {
+               dev_err(&pdev->dev, "No register space assigned\n");
+               return -ENODEV;
+       }
+
+       /* Ohci is a 32-bit device. */
+       pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+       pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+
+       hcd = usb_create_hcd(&ohci_octeon_hc_driver, &pdev->dev, "octeon");
+       if (!hcd)
+               return -ENOMEM;
+
+       hcd->rsrc_start = res_mem->start;
+       hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+
+       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
+                               OCTEON_OHCI_HCD_NAME)) {
+               dev_err(&pdev->dev, "request_mem_region failed\n");
+               ret = -EBUSY;
+               goto err1;
+       }
+
+       reg_base = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+       if (!reg_base) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -ENOMEM;
+               goto err2;
+       }
+
+       ohci_octeon_hw_start();
+
+       hcd->regs = reg_base;
+
+       ohci = hcd_to_ohci(hcd);
+
+       /* Octeon OHCI matches CPU endianness. */
+#ifdef __BIG_ENDIAN
+       ohci->flags |= OHCI_QUIRK_BE_MMIO;
+#endif
+
+       ohci_hcd_init(ohci);
+
+       ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+       if (ret) {
+               dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
+               goto err3;
+       }
+
+       platform_set_drvdata(pdev, hcd);
+
+       return 0;
+
+err3:
+       ohci_octeon_hw_stop();
+
+       iounmap(hcd->regs);
+err2:
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+       usb_put_hcd(hcd);
+       return ret;
+}
+
+static int ohci_octeon_drv_remove(struct platform_device *pdev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+       usb_remove_hcd(hcd);
+
+       ohci_octeon_hw_stop();
+       iounmap(hcd->regs);
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver ohci_octeon_driver = {
+       .probe          = ohci_octeon_drv_probe,
+       .remove         = ohci_octeon_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
+       .driver = {
+               .name   = OCTEON_OHCI_HCD_NAME,
+               .owner  = THIS_MODULE,
+       }
+};
+
+MODULE_ALIAS("platform:" OCTEON_OHCI_HCD_NAME);
index 3756641987762f3ff196bcb16601610a164a883a..c9078e4e1f4d5a5cd384a181d024fbccb83fc1e7 100644 (file)
@@ -553,6 +553,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd,
                        /* needed for power consumption */
                        struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc;
 
+                       memset(&info, 0, sizeof(info));
                        /* directly from the descriptor */
                        info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
                        info.product = dev->product_id;
index 70d00e99a4b40f4c4fde10c0472c087a897e3ed6..dd573abd2d1edf9b32b0a97aa9def3d1abd9d967 100644 (file)
@@ -3008,6 +3008,7 @@ sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 #else
                        x.sisusb_conactive  = 0;
 #endif
+                       memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved));
 
                        if (copy_to_user((void __user *)arg, &x, sizeof(x)))
                                retval = -EFAULT;
index 611a9d274363ee90132e705ea61d8af1aa36657a..fcb5206a65bdfd84eca43a39ce974f20489e2c80 100644 (file)
@@ -171,8 +171,9 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci)
        }
 
        /* Start sampling ID pin, when plug is removed from MUSB */
-       if (is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE
-               || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
+       if ((is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE
+               || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) ||
+               (musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) {
                mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
                musb->a_wait_bcon = TIMER_DELAY;
        }
@@ -323,30 +324,8 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
        return -EIO;
 }
 
-int __init musb_platform_init(struct musb *musb, void *board_data)
+static void musb_platform_reg_init(struct musb *musb)
 {
-
-       /*
-        * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE
-        * and OTG HOST modes, while rev 1.1 and greater require PE7 to
-        * be low for DEVICE mode and high for HOST mode. We set it high
-        * here because we are in host mode
-        */
-
-       if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) {
-               printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n",
-                       musb->config->gpio_vrsel);
-               return -ENODEV;
-       }
-       gpio_direction_output(musb->config->gpio_vrsel, 0);
-
-       usb_nop_xceiv_register();
-       musb->xceiv = otg_get_transceiver();
-       if (!musb->xceiv) {
-               gpio_free(musb->config->gpio_vrsel);
-               return -ENODEV;
-       }
-
        if (ANOMALY_05000346) {
                bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
                SSYNC();
@@ -358,7 +337,8 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
        }
 
        /* Configure PLL oscillator register */
-       bfin_write_USB_PLLOSC_CTRL(0x30a8);
+       bfin_write_USB_PLLOSC_CTRL(0x3080 |
+                       ((480/musb->config->clkin) << 1));
        SSYNC();
 
        bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
@@ -380,6 +360,33 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
                                EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
                                EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
        SSYNC();
+}
+
+int __init musb_platform_init(struct musb *musb, void *board_data)
+{
+
+       /*
+        * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE
+        * and OTG HOST modes, while rev 1.1 and greater require PE7 to
+        * be low for DEVICE mode and high for HOST mode. We set it high
+        * here because we are in host mode
+        */
+
+       if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) {
+               printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d\n",
+                       musb->config->gpio_vrsel);
+               return -ENODEV;
+       }
+       gpio_direction_output(musb->config->gpio_vrsel, 0);
+
+       usb_nop_xceiv_register();
+       musb->xceiv = otg_get_transceiver();
+       if (!musb->xceiv) {
+               gpio_free(musb->config->gpio_vrsel);
+               return -ENODEV;
+       }
+
+       musb_platform_reg_init(musb);
 
        if (is_host_enabled(musb)) {
                musb->board_set_vbus = bfin_set_vbus;
@@ -394,6 +401,27 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
        return 0;
 }
 
+#ifdef CONFIG_PM
+void musb_platform_save_context(struct musb *musb,
+                       struct musb_context_registers *musb_context)
+{
+       if (is_host_active(musb))
+               /*
+                * During hibernate gpio_vrsel will change from high to low
+                * low which will generate wakeup event resume the system
+                * immediately.  Set it to 0 before hibernate to avoid this
+                * wakeup event.
+                */
+               gpio_set_value(musb->config->gpio_vrsel, 0);
+}
+
+void musb_platform_restore_context(struct musb *musb,
+                       struct musb_context_registers *musb_context)
+{
+       musb_platform_reg_init(musb);
+}
+#endif
+
 int musb_platform_exit(struct musb *musb)
 {
        gpio_free(musb->config->gpio_vrsel);
index c9f9024c551525d8704a0d888bb8b1913859d326..e6669fc3b8048c3dfdbbbf5ee1e1a2048561cfaf 100644 (file)
@@ -552,7 +552,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
        if (int_usb & MUSB_INTR_SESSREQ) {
                void __iomem *mbase = musb->mregs;
 
-               if (devctl & MUSB_DEVCTL_BDEVICE) {
+               if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS
+                               && (devctl & MUSB_DEVCTL_BDEVICE)) {
                        DBG(3, "SessReq while on B state\n");
                        return IRQ_HANDLED;
                }
@@ -1052,6 +1053,11 @@ static void musb_shutdown(struct platform_device *pdev)
                clk_put(musb->clock);
        spin_unlock_irqrestore(&musb->lock, flags);
 
+       if (!is_otg_enabled(musb) && is_host_enabled(musb))
+               usb_remove_hcd(musb_to_hcd(musb));
+       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+       musb_platform_exit(musb);
+
        /* FIXME power down */
 }
 
@@ -2244,13 +2250,6 @@ static int __exit musb_remove(struct platform_device *pdev)
         */
        musb_exit_debugfs(musb);
        musb_shutdown(pdev);
-#ifdef CONFIG_USB_MUSB_HDRC_HCD
-       if (musb->board_mode == MUSB_HOST)
-               usb_remove_hcd(musb_to_hcd(musb));
-#endif
-       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-       musb_platform_exit(musb);
-       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
 
        musb_free(musb);
        iounmap(ctrl_base);
@@ -2411,9 +2410,6 @@ static int musb_suspend(struct device *dev)
        unsigned long   flags;
        struct musb     *musb = dev_to_musb(&pdev->dev);
 
-       if (!musb->clock)
-               return 0;
-
        spin_lock_irqsave(&musb->lock, flags);
 
        if (is_peripheral_active(musb)) {
@@ -2428,10 +2424,12 @@ static int musb_suspend(struct device *dev)
 
        musb_save_context(musb);
 
-       if (musb->set_clock)
-               musb->set_clock(musb->clock, 0);
-       else
-               clk_disable(musb->clock);
+       if (musb->clock) {
+               if (musb->set_clock)
+                       musb->set_clock(musb->clock, 0);
+               else
+                       clk_disable(musb->clock);
+       }
        spin_unlock_irqrestore(&musb->lock, flags);
        return 0;
 }
@@ -2441,13 +2439,12 @@ static int musb_resume_noirq(struct device *dev)
        struct platform_device *pdev = to_platform_device(dev);
        struct musb     *musb = dev_to_musb(&pdev->dev);
 
-       if (!musb->clock)
-               return 0;
-
-       if (musb->set_clock)
-               musb->set_clock(musb->clock, 1);
-       else
-               clk_enable(musb->clock);
+       if (musb->clock) {
+               if (musb->set_clock)
+                       musb->set_clock(musb->clock, 1);
+               else
+                       clk_enable(musb->clock);
+       }
 
        musb_restore_context(musb);
 
index 69797e5b46a7fbfbea3ff5bffe9769b902149249..febaabcc2b3568d3538e26ff9912383e60ea1600 100644 (file)
@@ -487,7 +487,7 @@ struct musb_context_registers {
 };
 
 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
-    defined(CONFIG_ARCH_OMAP4)
+    defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_BLACKFIN)
 extern void musb_platform_save_context(struct musb *musb,
                struct musb_context_registers *musb_context);
 extern void musb_platform_restore_context(struct musb *musb,
index 5d815049cbaac4796617ed9e1ae4e0aa6e29a668..36cfd060dbe55bffb7707293f3c1182ed7cbff6e 100644 (file)
@@ -644,10 +644,8 @@ static void rxstate(struct musb *musb, struct musb_request *req)
         */
 
                                csr |= MUSB_RXCSR_DMAENAB;
-                               if (!musb_ep->hb_mult &&
-                                       musb_ep->hw_ep->rx_double_buffered)
-                                       csr |= MUSB_RXCSR_AUTOCLEAR;
 #ifdef USE_MODE1
+                               csr |= MUSB_RXCSR_AUTOCLEAR;
                                /* csr |= MUSB_RXCSR_DMAMODE; */
 
                                /* this special sequence (enabling and then
@@ -656,6 +654,10 @@ static void rxstate(struct musb *musb, struct musb_request *req)
                                 */
                                musb_writew(epio, MUSB_RXCSR,
                                        csr | MUSB_RXCSR_DMAMODE);
+#else
+                               if (!musb_ep->hb_mult &&
+                                       musb_ep->hw_ep->rx_double_buffered)
+                                       csr |= MUSB_RXCSR_AUTOCLEAR;
 #endif
                                musb_writew(epio, MUSB_RXCSR, csr);
 
@@ -807,7 +809,7 @@ void musb_g_rx(struct musb *musb, u8 epnum)
 
 #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
                /* Autoclear doesn't clear RxPktRdy for short packets */
-               if ((dma->desired_mode == 0)
+               if ((dma->desired_mode == 0 && !hw_ep->rx_double_buffered)
                                || (dma->actual_len
                                        & (musb_ep->packet_sz - 1))) {
                        /* ack the read! */
@@ -818,8 +820,16 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                /* incomplete, and not short? wait for next IN packet */
                if ((request->actual < request->length)
                                && (musb_ep->dma->actual_len
-                                       == musb_ep->packet_sz))
+                                       == musb_ep->packet_sz)) {
+                       /* In double buffer case, continue to unload fifo if
+                        * there is Rx packet in FIFO.
+                        **/
+                       csr = musb_readw(epio, MUSB_RXCSR);
+                       if ((csr & MUSB_RXCSR_RXPKTRDY) &&
+                               hw_ep->rx_double_buffered)
+                               goto exit;
                        return;
+               }
 #endif
                musb_g_giveback(musb_ep, request, 0);
 
@@ -827,7 +837,7 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                if (!request)
                        return;
        }
-
+exit:
        /* Analyze request */
        rxstate(musb, to_musb_request(request));
 }
@@ -916,13 +926,9 @@ static int musb_gadget_enable(struct usb_ep *ep,
                 * likewise high bandwidth periodic tx
                 */
                /* Set TXMAXP with the FIFO size of the endpoint
-                * to disable double buffering mode. Currently, It seems that double
-                * buffering has problem if musb RTL revision number < 2.0.
+                * to disable double buffering mode.
                 */
-               if (musb->hwvers < MUSB_HWVERS_2000)
-                       musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx);
-               else
-                       musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
+               musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
 
                csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
                if (musb_readw(regs, MUSB_TXCSR)
@@ -958,10 +964,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
                /* Set RXMAXP with the FIFO size of the endpoint
                 * to disable double buffering mode.
                 */
-               if (musb->hwvers < MUSB_HWVERS_2000)
-                       musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx);
-               else
-                       musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
+               musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
 
                /* force shared fifo to OUT-only mode */
                if (hw_ep->is_shared_fifo) {
@@ -1166,8 +1169,6 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
                                                : DMA_FROM_DEVICE);
                        request->mapped = 0;
                }
-       } else if (!req->buf) {
-               return -ENODATA;
        } else
                request->mapped = 0;
 
@@ -1695,8 +1696,10 @@ int __init musb_gadget_setup(struct musb *musb)
        musb_platform_try_idle(musb, 0);
 
        status = device_register(&musb->g.dev);
-       if (status != 0)
+       if (status != 0) {
+               put_device(&musb->g.dev);
                the_gadget = NULL;
+       }
        return status;
 }
 
index 244267527a60b1421ea7c70a814388dde6951f7f..5a727c5b86763fdb1f65347c9f02a44d49d70568 100644 (file)
@@ -633,8 +633,9 @@ static inline u8  musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
        return 0;
 }
 
-static inline void  musb_read_txhubport(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum)
 {
+       return 0;
 }
 
 #endif /* CONFIG_BLACKFIN */
index 6f771af5cbdb6b61b160c4a73d5ad863b62c051c..563114d613d603a9c4f9b13a194bf4d0f17943be 100644 (file)
@@ -158,6 +158,8 @@ static int dma_channel_program(struct dma_channel *channel,
                                dma_addr_t dma_addr, u32 len)
 {
        struct musb_dma_channel *musb_channel = channel->private_data;
+       struct musb_dma_controller *controller = musb_channel->controller;
+       struct musb *musb = controller->private_data;
 
        DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
                musb_channel->epnum,
@@ -167,6 +169,18 @@ static int dma_channel_program(struct dma_channel *channel,
        BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
                channel->status == MUSB_DMA_STATUS_BUSY);
 
+       /*
+        * The DMA engine in RTL1.8 and above cannot handle
+        * DMA addresses that are not aligned to a 4 byte boundary.
+        * It ends up masking the last two bits of the address
+        * programmed in DMA_ADDR.
+        *
+        * Fail such DMA transfers, so that the backup PIO mode
+        * can carry out the transfer
+        */
+       if ((musb->hwvers >= MUSB_HWVERS_1800) && (dma_addr % 4))
+               return false;
+
        channel->actual_len = 0;
        musb_channel->start_addr = dma_addr;
        musb_channel->len = len;
index 89a9a584780391d7ad6544440aecac540a3fc4f0..76f8b3556672307452c991d6144d6395c7395c65 100644 (file)
@@ -794,6 +794,8 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
+       { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
index 7dfe02f1fb6a09b2763befdced18226e1b9c5365..263f625511972137585c8cdcee3f1fe7a0a74ab9 100644 (file)
 #define FTDI_SCIENCESCOPE_LOGBOOKML_PID                0xFF18
 #define FTDI_SCIENCESCOPE_LS_LOGBOOK_PID       0xFF1C
 #define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID       0xFF1D
+
+/*
+ * Milkymist One JTAG/Serial
+ */
+#define QIHARDWARE_VID                 0x20B7
+#define MILKYMISTONE_JTAGSERIAL_PID    0x0713
+
index 2297fb1bcf6547494c0e733c423be95de1999ed2..ef2977d3a613a441a7300ab37348fb99fa8f636c 100644 (file)
@@ -518,7 +518,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
-       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
index 2054b1e25a6554e3e62e8c96c9ccb8b4dc7fa893..d1268191acbde5ead493c660558fce8a23e833a8 100644 (file)
@@ -331,10 +331,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
 
        iu->iu_id = IU_ID_COMMAND;
        iu->tag = cpu_to_be16(stream_id);
-       if (sdev->ordered_tags && (cmnd->request->cmd_flags & REQ_HARDBARRIER))
-               iu->prio_attr = UAS_ORDERED_TAG;
-       else
-               iu->prio_attr = UAS_SIMPLE_TAG;
+       iu->prio_attr = UAS_SIMPLE_TAG;
        iu->len = len;
        int_to_scsilun(sdev->lun, &iu->lun);
        memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len);
index 436e4f7110cbddc41cda3d4677fdb2eca6c0ab17..e45e673b8770e78a44b9ba0c0ace5f70122606e8 100644 (file)
@@ -326,7 +326,8 @@ int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *availab
        int bit_index;
 
        ai = kzalloc(sizeof(struct uwb_rsv_alloc_info), GFP_KERNEL);
-       
+       if (!ai)
+               return UWB_RSV_ALLOC_NOT_FOUND;
        ai->min_mas = rsv->min_mas;
        ai->max_mas = rsv->max_mas;
        ai->max_interval = rsv->max_interval;
index 3ec24609151e8ec322c48afcebae8dc9ce578b5d..734c650a47c433be7524e27b35b5e3c5b5eea0ad 100644 (file)
@@ -502,8 +502,10 @@ static ssize_t adp8860_bl_l1_daylight_max_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
 {
        struct adp8860_bl *data = dev_get_drvdata(dev);
+       int ret = strict_strtoul(buf, 10, &data->cached_daylight_max);
+       if (ret)
+               return ret;
 
-       strict_strtoul(buf, 10, &data->cached_daylight_max);
        return adp8860_store(dev, buf, count, ADP8860_BLMX1);
 }
 static DEVICE_ATTR(l1_daylight_max, 0664, adp8860_bl_l1_daylight_max_show,
@@ -614,7 +616,7 @@ static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev,
        if (val == 0) {
                /* Enable automatic ambient light sensing */
                adp8860_set_bits(data->client, ADP8860_MDCR, CMP_AUTOEN);
-       } else if ((val > 0) && (val < 6)) {
+       } else if ((val > 0) && (val <= 3)) {
                /* Disable automatic ambient light sensing */
                adp8860_clr_bits(data->client, ADP8860_MDCR, CMP_AUTOEN);
 
@@ -622,7 +624,7 @@ static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev,
                mutex_lock(&data->lock);
                adp8860_read(data->client, ADP8860_CFGR, &reg_val);
                reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT);
-               reg_val |= val << CFGR_BLV_SHIFT;
+               reg_val |= (val - 1) << CFGR_BLV_SHIFT;
                adp8860_write(data->client, ADP8860_CFGR, reg_val);
                mutex_unlock(&data->lock);
        }
index 9093ef0fa8696f2da8b086984042001aa94d8eec..c67801e57aafb24f546250bcbdb45d59bcb5b9d4 100644 (file)
@@ -78,7 +78,7 @@ static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power)
        const u16 slpin = 0x10;
        const u16 disoff = 0x28;
 
-       if (power) {
+       if (power <= FB_BLANK_NORMAL) {
                if (priv->lcd_on)
                        return 0;
 
index abc43a0eb97dd054f7c526b47fa014e61e458dc0..5d3cf33953ac299cd759fb19bfd5a1d53205cc0b 100644 (file)
@@ -129,7 +129,7 @@ static int lms283gf05_power_set(struct lcd_device *ld, int power)
        struct spi_device *spi = st->spi;
        struct lms283gf05_pdata *pdata = spi->dev.platform_data;
 
-       if (power) {
+       if (power <= FB_BLANK_NORMAL) {
                if (pdata)
                        lms283gf05_reset(pdata->reset_gpio,
                                        pdata->reset_inverted);
index 9fb533f6373e6ab958646ccfdcba047c43b99d9d..1485f7345f49ee32586d5d665d1bd624cfcd3e1a 100644 (file)
@@ -335,6 +335,24 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
                },
                .driver_data    = (void *)&nvidia_chipset_data,
        },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBookAir 3,1",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,1"),
+               },
+               .driver_data    = (void *)&nvidia_chipset_data,
+       },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBookAir 3,2",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,2"),
+               },
+               .driver_data    = (void *)&nvidia_chipset_data,
+       },
        { }
 };
 
index 550443518891d41345234f4aa72929798b1f68a8..21866ec69656d6be90e69af18a56316895f9d69f 100644 (file)
@@ -25,6 +25,7 @@ struct pwm_bl_data {
        struct pwm_device       *pwm;
        struct device           *dev;
        unsigned int            period;
+       unsigned int            lth_brightness;
        int                     (*notify)(struct device *,
                                          int brightness);
 };
@@ -48,7 +49,9 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
                pwm_config(pb->pwm, 0, pb->period);
                pwm_disable(pb->pwm);
        } else {
-               pwm_config(pb->pwm, brightness * pb->period / max, pb->period);
+               brightness = pb->lth_brightness +
+                       (brightness * (pb->period - pb->lth_brightness) / max);
+               pwm_config(pb->pwm, brightness, pb->period);
                pwm_enable(pb->pwm);
        }
        return 0;
@@ -92,6 +95,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 
        pb->period = data->pwm_period_ns;
        pb->notify = data->notify;
+       pb->lth_brightness = data->lth_brightness *
+               (data->pwm_period_ns / data->max_brightness);
        pb->dev = &pdev->dev;
 
        pb->pwm = pwm_request(data->pwm_id, "backlight");
index a3128c9cb7ad6b64999eb6e7bffe6a2898c996e0..5927db0da9998f87f273d9430d782c26723fb16e 100644 (file)
@@ -729,10 +729,10 @@ static ssize_t s6e63m0_sysfs_show_gamma_table(struct device *dev,
 
        return strlen(buf);
 }
-static DEVICE_ATTR(gamma_table, 0644,
+static DEVICE_ATTR(gamma_table, 0444,
                s6e63m0_sysfs_show_gamma_table, NULL);
 
-static int __init s6e63m0_probe(struct spi_device *spi)
+static int __devinit s6e63m0_probe(struct spi_device *spi)
 {
        int ret = 0;
        struct s6e63m0 *lcd = NULL;
@@ -829,6 +829,9 @@ static int __devexit s6e63m0_remove(struct spi_device *spi)
        struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev);
 
        s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+       device_remove_file(&spi->dev, &dev_attr_gamma_table);
+       device_remove_file(&spi->dev, &dev_attr_gamma_mode);
+       backlight_device_unregister(lcd->bd);
        lcd_device_unregister(lcd->ld);
        kfree(lcd);
 
index 7c316c34dfca50fe3e76be6438c056682eb159ab..b66d86ac7cea6d19a9ffa4b7fd5a0034ee702cc2 100644 (file)
@@ -318,7 +318,7 @@ static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
 static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask)
 {
        if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0)
-               printk(KERN_INFO KERN_ERR "mddi_wait_interrupt %d, timeout "
+               printk(KERN_INFO "mddi_wait_interrupt %d, timeout "
                       "waiting for %x, INT = %x, STAT = %x gotint = %x\n",
                       current->pid, intmask, mddi_readl(INT), mddi_readl(STAT),
                       mddi->got_int);
@@ -465,8 +465,7 @@ static int __init mddi_get_client_caps(struct mddi_info *mddi)
 
                if (mddi->flags & FLAG_HAVE_CAPS)
                        break;
-               printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for "
-                               "caps\n");
+               printk(KERN_INFO "mddi_init, timeout waiting for caps\n");
        }
        return mddi->flags & FLAG_HAVE_CAPS;
 }
index 3c28db03ad392a66cd773d3d63e673c23a06d1bc..c3636d55a3c5aa1b39cd15accc9e6c7454d5224a 100644 (file)
@@ -90,7 +90,7 @@ static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
        mdp_irq_mask &= ~(mask);
        /* if no one is waiting on the interrupt, disable it */
        if (!mdp_irq_mask) {
-               disable_irq(mdp->irq);
+               disable_irq_nosync(mdp->irq);
                if (clk)
                        clk_disable(clk);
        }
@@ -482,6 +482,7 @@ int mdp_probe(struct platform_device *pdev)
        /* register mdp device */
        mdp->mdp_dev.dev.parent = &pdev->dev;
        mdp->mdp_dev.dev.class = mdp_class;
+       dev_set_name(&mdp->mdp_dev.dev, "mdp%d", pdev->id);
 
        /* if you can remove the platform device you'd have to implement
         * this:
index fed2a72bc6b60a1986172298fbb67bc0eca2b3bc..2fd7e5271be91ea1c9cd5b202ef40f985266dd46 100644 (file)
@@ -554,9 +554,15 @@ void __init omap_vram_reserve_sdram_memblock(void)
        size = PAGE_ALIGN(size);
 
        if (paddr) {
-               if ((paddr & ~PAGE_MASK) ||
-                   !memblock_is_region_memory(paddr, size)) {
-                       pr_err("Illegal SDRAM region for VRAM\n");
+               if (paddr & ~PAGE_MASK) {
+                       pr_err("VRAM start address 0x%08x not page aligned\n",
+                                       paddr);
+                       return;
+               }
+
+               if (!memblock_is_region_memory(paddr, size)) {
+                       pr_err("Illegal SDRAM region 0x%08x..0x%08x for VRAM\n",
+                                       paddr, paddr + size - 1);
                        return;
                }
 
@@ -570,9 +576,12 @@ void __init omap_vram_reserve_sdram_memblock(void)
                        return;
                }
        } else {
-               paddr = memblock_alloc_base(size, PAGE_SIZE, MEMBLOCK_REAL_LIMIT);
+               paddr = memblock_alloc(size, PAGE_SIZE);
        }
 
+       memblock_free(paddr, size);
+       memblock_remove(paddr, size);
+
        omap_vram_add_region(paddr, size);
 
        pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
index a0e22ac483a3d65161f7e54bdfad322c8918d93c..167400e2a18204f359edc38b6cfe2499e7992aa5 100644 (file)
@@ -94,7 +94,6 @@ static int __devinit riva_setup_i2c_bus(struct riva_i2c_chan *chan,
 
        strcpy(chan->adapter.name, name);
        chan->adapter.owner             = THIS_MODULE;
-       chan->adapter.id                = I2C_HW_B_RIVA;
        chan->adapter.class             = i2c_class;
        chan->adapter.algo_data         = &chan->algo;
        chan->adapter.dev.parent        = &chan->par->pdev->dev;
index 5699ce0c1780c57fe23474259ec7ad9022ef1ba6..3f3d431033cac3c6775341e1decc4625b787e840 100644 (file)
@@ -123,83 +123,87 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
        u32 linelength;
        bool yuv;
 
-       /* Select data format */
+       /*
+        * Select data format. MIPI DSI is not hot-pluggable, so, we just use
+        * the default videomode. If this ever becomes a problem, We'll have to
+        * move this to mipi_display_on() above and use info->var.xres
+        */
        switch (pdata->data_format) {
        case MIPI_RGB888:
                pctype = 0;
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
                pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
-               linelength = ch->lcd_cfg.xres * 3;
+               linelength = ch->lcd_cfg[0].xres * 3;
                yuv = false;
                break;
        case MIPI_RGB565:
                pctype = 1;
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
                pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
-               linelength = ch->lcd_cfg.xres * 2;
+               linelength = ch->lcd_cfg[0].xres * 2;
                yuv = false;
                break;
        case MIPI_RGB666_LP:
                pctype = 2;
                datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
                pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
-               linelength = ch->lcd_cfg.xres * 3;
+               linelength = ch->lcd_cfg[0].xres * 3;
                yuv = false;
                break;
        case MIPI_RGB666:
                pctype = 3;
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
                pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
-               linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
+               linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8;
                yuv = false;
                break;
        case MIPI_BGR888:
                pctype = 8;
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
                pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
-               linelength = ch->lcd_cfg.xres * 3;
+               linelength = ch->lcd_cfg[0].xres * 3;
                yuv = false;
                break;
        case MIPI_BGR565:
                pctype = 9;
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
                pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
-               linelength = ch->lcd_cfg.xres * 2;
+               linelength = ch->lcd_cfg[0].xres * 2;
                yuv = false;
                break;
        case MIPI_BGR666_LP:
                pctype = 0xa;
                datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
                pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
-               linelength = ch->lcd_cfg.xres * 3;
+               linelength = ch->lcd_cfg[0].xres * 3;
                yuv = false;
                break;
        case MIPI_BGR666:
                pctype = 0xb;
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
                pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
-               linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
+               linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8;
                yuv = false;
                break;
        case MIPI_YUYV:
                pctype = 4;
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
                pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
-               linelength = ch->lcd_cfg.xres * 2;
+               linelength = ch->lcd_cfg[0].xres * 2;
                yuv = true;
                break;
        case MIPI_UYVY:
                pctype = 5;
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
                pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
-               linelength = ch->lcd_cfg.xres * 2;
+               linelength = ch->lcd_cfg[0].xres * 2;
                yuv = true;
                break;
        case MIPI_YUV420_L:
                pctype = 6;
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
                pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
-               linelength = (ch->lcd_cfg.xres * 12 + 7) / 8;
+               linelength = (ch->lcd_cfg[0].xres * 12 + 7) / 8;
                yuv = true;
                break;
        case MIPI_YUV420:
@@ -207,7 +211,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
                datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
                pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
                /* Length of U/V line */
-               linelength = (ch->lcd_cfg.xres + 1) / 2;
+               linelength = (ch->lcd_cfg[0].xres + 1) / 2;
                yuv = true;
                break;
        default:
@@ -281,7 +285,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
        iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */
        /*
         * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see
-        * sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default
+        * sh_mobile_lcdc_info.ch[0].lcd_cfg[0].xres), HSALEN = 1 - default
         * (unused, since VMCTR2[HSABM] = 0)
         */
        iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */
index ef989d94511c1fccdae24fbb1482ab986340f7f1..d7df10315d8d6f51aba676328985a52128e81876 100644 (file)
@@ -28,6 +28,8 @@
 #include <video/sh_mobile_hdmi.h>
 #include <video/sh_mobile_lcdc.h>
 
+#include "sh_mobile_lcdcfb.h"
+
 #define HDMI_SYSTEM_CTRL                       0x00 /* System control */
 #define HDMI_L_R_DATA_SWAP_CTRL_RPKT           0x01 /* L/R data swap control,
                                                        bits 19..16 of 20-bit N for Audio Clock Regeneration packet */
@@ -206,12 +208,15 @@ enum hotplug_state {
 
 struct sh_hdmi {
        void __iomem *base;
-       enum hotplug_state hp_state;
+       enum hotplug_state hp_state;    /* hot-plug status */
+       bool preprogrammed_mode;        /* use a pre-programmed VIC or the external mode */
        struct clk *hdmi_clk;
        struct device *dev;
        struct fb_info *info;
+       struct mutex mutex;             /* Protect the info pointer */
        struct delayed_work edid_work;
        struct fb_var_screeninfo var;
+       struct fb_monspecs monspec;
 };
 
 static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
@@ -277,7 +282,7 @@ static struct snd_soc_codec_driver soc_codec_dev_sh_hdmi = {
  */
 
 /* External video parameter settings */
-static void hdmi_external_video_param(struct sh_hdmi *hdmi)
+static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi)
 {
        struct fb_var_screeninfo *var = &hdmi->var;
        u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset;
@@ -309,9 +314,9 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
        if (var->sync & FB_SYNC_VERT_HIGH_ACT)
                sync |= 8;
 
-       pr_debug("H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n",
-                htotal, hblank, hdelay, var->hsync_len,
-                vtotal, vblank, vdelay, var->vsync_len, sync);
+       dev_dbg(hdmi->dev, "H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n",
+               htotal, hblank, hdelay, var->hsync_len,
+               vtotal, vblank, vdelay, var->vsync_len, sync);
 
        hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
 
@@ -336,7 +341,10 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
 
        hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION);
 
-       /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for manual mode */
+       /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */
+       if (!hdmi->preprogrammed_mode)
+               hdmi_write(hdmi, sync | 1 | (voffset << 4),
+                          HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
 }
 
 /**
@@ -454,21 +462,61 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
 }
 
 /**
- * sh_hdmi_phy_config()
+ * sh_hdmi_phy_config() - configure the HDMI PHY for the used video mode
  */
 static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
 {
-       /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
-       hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
-       hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
-       hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
-       /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */
-       hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
-       hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
-       hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
-       hdmi_write(hdmi, 0x0E, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
-       hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
-       hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
+       if (hdmi->var.yres > 480) {
+               /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
+               /*
+                * [1:0]        Speed_A
+                * [3:2]        Speed_B
+                * [4]          PLLA_Bypass
+                * [6]          DRV_TEST_EN
+                * [7]          DRV_TEST_IN
+                */
+               hdmi_write(hdmi, 0x0f, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
+               /* PLLB_CONFIG[17], PLLA_CONFIG[17] - not in PHY datasheet */
+               hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
+               /*
+                * [2:0]        BGR_I_OFFSET
+                * [6:4]        BGR_V_OFFSET
+                */
+               hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
+               /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */
+               hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
+               /*
+                * PLLA_CONFIG[15:8]: regulator voltage[0], CP current,
+                * LPF capacitance, LPF resistance[1]
+                */
+               hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
+               /* PLLB_CONFIG[7:0]: LPF resistance[0], VCO offset, VCO gain */
+               hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
+               /*
+                * PLLB_CONFIG[15:8]: regulator voltage[0], CP current,
+                * LPF capacitance, LPF resistance[1]
+                */
+               hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
+               /* DRV_CONFIG, PE_CONFIG */
+               hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
+               /*
+                * [2:0]        AMON_SEL (4 == LPF voltage)
+                * [4]          PLLA_CONFIG[16]
+                * [5]          PLLB_CONFIG[16]
+                */
+               hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
+       } else {
+               /* for 480p8bit 27MHz */
+               hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
+               hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
+               hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
+               hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
+               hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
+               hdmi_write(hdmi, 0x48, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
+               hdmi_write(hdmi, 0x0F, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
+               hdmi_write(hdmi, 0x20, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
+               hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
+       }
 }
 
 /**
@@ -476,6 +524,8 @@ static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
  */
 static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
 {
+       u8 vic;
+
        /* AVI InfoFrame */
        hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX);
 
@@ -500,9 +550,9 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
        hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1);
 
        /*
-        * C = No Data
-        * M = 16:9 Picture Aspect Ratio
-        * R = Same as picture aspect ratio
+        * [7:6] C = Colorimetry: no data
+        * [5:4] M = 2: 16:9, 1: 4:3 Picture Aspect Ratio
+        * [3:0] R = 8: Active Frame Aspect Ratio: same as picture aspect ratio
         */
        hdmi_write(hdmi, 0x28, HDMI_CTRL_PKT_BUF_ACCESS_PB2);
 
@@ -516,9 +566,15 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
 
        /*
         * VIC = 1280 x 720p: ignored if external config is used
-        * Send 2 for 720 x 480p, 16 for 1080p
+        * Send 2 for 720 x 480p, 16 for 1080p, ignored in external mode
         */
-       hdmi_write(hdmi, 4, HDMI_CTRL_PKT_BUF_ACCESS_PB4);
+       if (hdmi->var.yres == 1080 && hdmi->var.xres == 1920)
+               vic = 16;
+       else if (hdmi->var.yres == 480 && hdmi->var.xres == 720)
+               vic = 2;
+       else
+               vic = 4;
+       hdmi_write(hdmi, vic, HDMI_CTRL_PKT_BUF_ACCESS_PB4);
 
        /* PR = No Repetition */
        hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5);
@@ -591,100 +647,6 @@ static void sh_hdmi_audio_infoframe_setup(struct sh_hdmi *hdmi)
        hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB10);
 }
 
-/**
- * sh_hdmi_gamut_metadata_setup() - Gamut Metadata Packet of CONTROL PACKET
- */
-static void sh_hdmi_gamut_metadata_setup(struct sh_hdmi *hdmi)
-{
-       int i;
-
-       /* Gamut Metadata Packet */
-       hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_INDEX);
-
-       /* Packet Type = 0x0A */
-       hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
-       /* Gamut Packet is not used, so default value */
-       hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
-       /* Gamut Packet is not used, so default value */
-       hdmi_write(hdmi, 0x10, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
-
-       /* GBD bytes 0 through 27 */
-       for (i = 0; i <= 27; i++)
-               /* HDMI_CTRL_PKT_BUF_ACCESS_PB0_63H - PB27_7EH */
-               hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
-}
-
-/**
- * sh_hdmi_acp_setup() - Audio Content Protection Packet (ACP)
- */
-static void sh_hdmi_acp_setup(struct sh_hdmi *hdmi)
-{
-       int i;
-
-       /* Audio Content Protection Packet (ACP) */
-       hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_INDEX);
-
-       /* Packet Type = 0x04 */
-       hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
-       /* ACP_Type */
-       hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
-       /* Reserved (0) */
-       hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
-
-       /* GBD bytes 0 through 27 */
-       for (i = 0; i <= 27; i++)
-               /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
-               hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
-}
-
-/**
- * sh_hdmi_isrc1_setup() - ISRC1 Packet
- */
-static void sh_hdmi_isrc1_setup(struct sh_hdmi *hdmi)
-{
-       int i;
-
-       /* ISRC1 Packet */
-       hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_INDEX);
-
-       /* Packet Type = 0x05 */
-       hdmi_write(hdmi, 0x05, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
-       /* ISRC_Cont, ISRC_Valid, Reserved (0), ISRC_Status */
-       hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
-       /* Reserved (0) */
-       hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
-
-       /* PB0 UPC_EAN_ISRC_0-15 */
-       /* Bytes PB16-PB27 shall be set to a value of 0. */
-       for (i = 0; i <= 27; i++)
-               /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
-               hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
-}
-
-/**
- * sh_hdmi_isrc2_setup() - ISRC2 Packet
- */
-static void sh_hdmi_isrc2_setup(struct sh_hdmi *hdmi)
-{
-       int i;
-
-       /* ISRC2 Packet */
-       hdmi_write(hdmi, 0x03, HDMI_CTRL_PKT_BUF_INDEX);
-
-       /* HB0 Packet Type = 0x06 */
-       hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
-       /* Reserved (0) */
-       hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
-       /* Reserved (0) */
-       hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
-
-       /* PB0 UPC_EAN_ISRC_16-31 */
-       /* Bytes PB16-PB27 shall be set to a value of 0. */
-       for (i = 0; i <= 27; i++)
-               /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
-               hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
-}
-
 /**
  * sh_hdmi_configure() - Initialise HDMI for output
  */
@@ -705,18 +667,6 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
        /* Audio InfoFrame */
        sh_hdmi_audio_infoframe_setup(hdmi);
 
-       /* Gamut Metadata packet */
-       sh_hdmi_gamut_metadata_setup(hdmi);
-
-       /* Audio Content Protection (ACP) Packet */
-       sh_hdmi_acp_setup(hdmi);
-
-       /* ISRC1 Packet */
-       sh_hdmi_isrc1_setup(hdmi);
-
-       /* ISRC2 Packet */
-       sh_hdmi_isrc2_setup(hdmi);
-
        /*
         * Control packet auto send with VSYNC control: auto send
         * General control, Gamut metadata, ISRC, and ACP packets
@@ -734,17 +684,42 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
        hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL);
 }
 
-static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
+static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi,
+                                       const struct fb_videomode *mode)
 {
-       struct fb_var_screeninfo *var = &hdmi->var;
-       struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
-       struct fb_videomode *lcd_cfg = &pdata->lcd_chan->lcd_cfg;
-       unsigned long height = var->height, width = var->width;
-       int i;
+       long target = PICOS2KHZ(mode->pixclock) * 1000,
+               rate = clk_round_rate(hdmi->hdmi_clk, target);
+       unsigned long rate_error = rate > 0 ? abs(rate - target) : ULONG_MAX;
+
+       dev_dbg(hdmi->dev, "%u-%u-%u-%u x %u-%u-%u-%u\n",
+               mode->left_margin, mode->xres,
+               mode->right_margin, mode->hsync_len,
+               mode->upper_margin, mode->yres,
+               mode->lower_margin, mode->vsync_len);
+
+       dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz\n", target,
+                rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0,
+                mode->refresh);
+
+       return rate_error;
+}
+
+static int sh_hdmi_read_edid(struct sh_hdmi *hdmi)
+{
+       struct fb_var_screeninfo tmpvar;
+       struct fb_var_screeninfo *var = &tmpvar;
+       const struct fb_videomode *mode, *found = NULL;
+       struct fb_info *info = hdmi->info;
+       struct fb_modelist *modelist = NULL;
+       unsigned int f_width = 0, f_height = 0, f_refresh = 0;
+       unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
+       bool exact_match = false;
        u8 edid[128];
+       char *forced;
+       int i;
 
        /* Read EDID */
-       pr_debug("Read back EDID code:");
+       dev_dbg(hdmi->dev, "Read back EDID code:");
        for (i = 0; i < 128; i++) {
                edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW);
 #ifdef DEBUG
@@ -759,29 +734,97 @@ static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
 #ifdef DEBUG
        printk(KERN_CONT "\n");
 #endif
-       fb_parse_edid(edid, var);
-       pr_debug("%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected\n",
-                var->left_margin, var->xres, var->right_margin, var->hsync_len,
-                var->upper_margin, var->yres, var->lower_margin, var->vsync_len,
-                PICOS2KHZ(var->pixclock));
-
-       /* FIXME: Use user-provided configuration instead of EDID */
-       var->width              = width;
-       var->xres               = lcd_cfg->xres;
-       var->xres_virtual       = lcd_cfg->xres;
-       var->left_margin        = lcd_cfg->left_margin;
-       var->right_margin       = lcd_cfg->right_margin;
-       var->hsync_len          = lcd_cfg->hsync_len;
-       var->height             = height;
-       var->yres               = lcd_cfg->yres;
-       var->yres_virtual       = lcd_cfg->yres * 2;
-       var->upper_margin       = lcd_cfg->upper_margin;
-       var->lower_margin       = lcd_cfg->lower_margin;
-       var->vsync_len          = lcd_cfg->vsync_len;
-       var->sync               = lcd_cfg->sync;
-       var->pixclock           = lcd_cfg->pixclock;
-
-       hdmi_external_video_param(hdmi);
+
+       fb_edid_to_monspecs(edid, &hdmi->monspec);
+
+       fb_get_options("sh_mobile_lcdc", &forced);
+       if (forced && *forced) {
+               /* Only primitive parsing so far */
+               i = sscanf(forced, "%ux%u@%u",
+                          &f_width, &f_height, &f_refresh);
+               if (i < 2) {
+                       f_width = 0;
+                       f_height = 0;
+               }
+               dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n",
+                       f_width, f_height, f_refresh);
+       }
+
+       /* Walk monitor modes to find the best or the exact match */
+       for (i = 0, mode = hdmi->monspec.modedb;
+            f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match;
+            i++, mode++) {
+               unsigned long rate_error = sh_hdmi_rate_error(hdmi, mode);
+
+               /* No interest in unmatching modes */
+               if (f_width != mode->xres || f_height != mode->yres)
+                       continue;
+               if (f_refresh == mode->refresh || (!f_refresh && !rate_error))
+                       /*
+                        * Exact match if either the refresh rate matches or it
+                        * hasn't been specified and we've found a mode, for
+                        * which we can configure the clock precisely
+                        */
+                       exact_match = true;
+               else if (found && found_rate_error <= rate_error)
+                       /*
+                        * We otherwise search for the closest matching clock
+                        * rate - either if no refresh rate has been specified
+                        * or we cannot find an exactly matching one
+                        */
+                       continue;
+
+               /* Check if supported: sufficient fb memory, supported clock-rate */
+               fb_videomode_to_var(var, mode);
+
+               if (info && info->fbops->fb_check_var &&
+                   info->fbops->fb_check_var(var, info)) {
+                       exact_match = false;
+                       continue;
+               }
+
+               found = mode;
+               found_rate_error = rate_error;
+       }
+
+       /*
+        * TODO 1: if no ->info is present, postpone running the config until
+        * after ->info first gets registered.
+        * TODO 2: consider registering the HDMI platform device from the LCDC
+        * driver, and passing ->info with HDMI platform data.
+        */
+       if (info && !found) {
+               modelist = hdmi->info->modelist.next &&
+                       !list_empty(&hdmi->info->modelist) ?
+                       list_entry(hdmi->info->modelist.next,
+                                  struct fb_modelist, list) :
+                       NULL;
+
+               if (modelist) {
+                       found = &modelist->mode;
+                       found_rate_error = sh_hdmi_rate_error(hdmi, found);
+               }
+       }
+
+       /* No cookie today */
+       if (!found)
+               return -ENXIO;
+
+       dev_info(hdmi->dev, "Using %s mode %ux%u@%uHz (%luHz), clock error %luHz\n",
+                modelist ? "default" : "EDID", found->xres, found->yres,
+                found->refresh, PICOS2KHZ(found->pixclock) * 1000, found_rate_error);
+
+       if ((found->xres == 720 && found->yres == 480) ||
+           (found->xres == 1280 && found->yres == 720) ||
+           (found->xres == 1920 && found->yres == 1080))
+               hdmi->preprogrammed_mode = true;
+       else
+               hdmi->preprogrammed_mode = false;
+
+       fb_videomode_to_var(&hdmi->var, found);
+       sh_hdmi_external_video_param(hdmi);
+
+       return 0;
 }
 
 static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
@@ -809,8 +852,8 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
        hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2);
 
        if (printk_ratelimit())
-               pr_debug("IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n",
-                        irq, status1, mask1, status2, mask2);
+               dev_dbg(hdmi->dev, "IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n",
+                       irq, status1, mask1, status2, mask2);
 
        if (!((status1 & mask1) | (status2 & mask2))) {
                return IRQ_NONE;
@@ -821,7 +864,7 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
                udelay(500);
 
                msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS);
-               pr_debug("MSENS 0x%x\n", msens);
+               dev_dbg(hdmi->dev, "MSENS 0x%x\n", msens);
                /* Check, if hot plug & MSENS pin status are both high */
                if ((msens & 0xC0) == 0xC0) {
                        /* Display plug in */
@@ -857,83 +900,180 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static void hdmi_display_on(void *arg, struct fb_info *info)
+/* locking:    called with info->lock held, or before register_framebuffer() */
+static void sh_hdmi_display_on(void *arg, struct fb_info *info)
 {
+       /*
+        * info is guaranteed to be valid, when we are called, because our
+        * FB_EVENT_FB_UNBIND notify is also called with info->lock held
+        */
        struct sh_hdmi *hdmi = arg;
        struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
+       struct sh_mobile_lcdc_chan *ch = info->par;
 
-       if (info->var.xres != 1280 || info->var.yres != 720) {
-               dev_warn(info->device, "Unsupported framebuffer geometry %ux%u\n",
-                        info->var.xres, info->var.yres);
-               return;
-       }
+       dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__,
+               pdata->lcd_dev, info->state);
+
+       /* No need to lock */
+       hdmi->info = info;
 
-       pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state);
        /*
-        * FIXME: not a good place to store fb_info. And we cannot nullify it
-        * even on monitor disconnect. What should the lifecycle be?
+        * hp_state can be set to
+        * HDMI_HOTPLUG_DISCONNECTED:   on monitor unplug
+        * HDMI_HOTPLUG_CONNECTED:      on monitor plug-in
+        * HDMI_HOTPLUG_EDID_DONE:      on EDID read completion
         */
-       hdmi->info = info;
        switch (hdmi->hp_state) {
        case HDMI_HOTPLUG_EDID_DONE:
                /* PS mode d->e. All functions are active */
                hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL);
-               pr_debug("HDMI running\n");
+               dev_dbg(hdmi->dev, "HDMI running\n");
                break;
        case HDMI_HOTPLUG_DISCONNECTED:
                info->state = FBINFO_STATE_SUSPENDED;
        default:
-               hdmi->var = info->var;
+               hdmi->var = ch->display_var;
        }
 }
 
-static void hdmi_display_off(void *arg)
+/* locking: called with info->lock held */
+static void sh_hdmi_display_off(void *arg)
 {
        struct sh_hdmi *hdmi = arg;
        struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
 
-       pr_debug("%s(%p)\n", __func__, pdata->lcd_dev);
+       dev_dbg(hdmi->dev, "%s(%p)\n", __func__, pdata->lcd_dev);
        /* PS mode e->a */
        hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
 }
 
+static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
+{
+       struct fb_info *info = hdmi->info;
+       struct sh_mobile_lcdc_chan *ch = info->par;
+       struct fb_var_screeninfo *new_var = &hdmi->var, *old_var = &ch->display_var;
+       struct fb_videomode mode1, mode2;
+
+       fb_var_to_videomode(&mode1, old_var);
+       fb_var_to_videomode(&mode2, new_var);
+
+       dev_dbg(info->dev, "Old %ux%u, new %ux%u\n",
+               mode1.xres, mode1.yres, mode2.xres, mode2.yres);
+
+       if (fb_mode_is_equal(&mode1, &mode2))
+               return false;
+
+       dev_dbg(info->dev, "Switching %u -> %u lines\n",
+               mode1.yres, mode2.yres);
+       *old_var = *new_var;
+
+       return true;
+}
+
+/**
+ * sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock
+ * @hdmi:      driver context
+ * @pixclock:  pixel clock period in picoseconds
+ * return:     configured positive rate if successful
+ *             0 if couldn't set the rate, but managed to enable the clock
+ *             negative error, if couldn't enable the clock
+ */
+static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long pixclock)
+{
+       long rate;
+       int ret;
+
+       rate = PICOS2KHZ(pixclock) * 1000;
+       rate = clk_round_rate(hdmi->hdmi_clk, rate);
+       if (rate > 0) {
+               ret = clk_set_rate(hdmi->hdmi_clk, rate);
+               if (ret < 0) {
+                       dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", rate, ret);
+                       rate = 0;
+               } else {
+                       dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", rate);
+               }
+       } else {
+               rate = 0;
+               dev_warn(hdmi->dev, "Cannot get suitable rate: %ld\n", rate);
+       }
+
+       ret = clk_enable(hdmi->hdmi_clk);
+       if (ret < 0) {
+               dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret);
+               return ret;
+       }
+
+       return rate;
+}
+
 /* Hotplug interrupt occurred, read EDID */
-static void edid_work_fn(struct work_struct *work)
+static void sh_hdmi_edid_work_fn(struct work_struct *work)
 {
        struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
        struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
+       struct sh_mobile_lcdc_chan *ch;
+       int ret;
 
-       pr_debug("%s(%p): begin, hotplug status %d\n", __func__,
-                pdata->lcd_dev, hdmi->hp_state);
+       dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__,
+               pdata->lcd_dev, hdmi->hp_state);
 
        if (!pdata->lcd_dev)
                return;
 
+       mutex_lock(&hdmi->mutex);
+
        if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) {
-               pm_runtime_get_sync(hdmi->dev);
                /* A device has been plugged in */
-               sh_hdmi_read_edid(hdmi);
+               pm_runtime_get_sync(hdmi->dev);
+
+               ret = sh_hdmi_read_edid(hdmi);
+               if (ret < 0)
+                       goto out;
+
+               /* Reconfigure the clock */
+               clk_disable(hdmi->hdmi_clk);
+               ret = sh_hdmi_clk_configure(hdmi, hdmi->var.pixclock);
+               if (ret < 0)
+                       goto out;
+
                msleep(10);
                sh_hdmi_configure(hdmi);
                /* Switched to another (d) power-save mode */
                msleep(10);
 
                if (!hdmi->info)
-                       return;
+                       goto out;
+
+               ch = hdmi->info->par;
 
                acquire_console_sem();
 
                /* HDMI plug in */
-               hdmi->info->var = hdmi->var;
-               if (hdmi->info->state != FBINFO_STATE_RUNNING)
+               if (!sh_hdmi_must_reconfigure(hdmi) &&
+                   hdmi->info->state == FBINFO_STATE_RUNNING) {
+                       /*
+                        * First activation with the default monitor - just turn
+                        * on, if we run a resume here, the logo disappears
+                        */
+                       if (lock_fb_info(hdmi->info)) {
+                               sh_hdmi_display_on(hdmi, hdmi->info);
+                               unlock_fb_info(hdmi->info);
+                       }
+               } else {
+                       /* New monitor or have to wake up */
                        fb_set_suspend(hdmi->info, 0);
-               else
-                       hdmi_display_on(hdmi, hdmi->info);
+               }
 
                release_console_sem();
        } else {
+               ret = 0;
                if (!hdmi->info)
-                       return;
+                       goto out;
+
+               hdmi->monspec.modedb_len = 0;
+               fb_destroy_modedb(hdmi->monspec.modedb);
+               hdmi->monspec.modedb = NULL;
 
                acquire_console_sem();
 
@@ -944,13 +1084,64 @@ static void edid_work_fn(struct work_struct *work)
                pm_runtime_put(hdmi->dev);
        }
 
-       pr_debug("%s(%p): end\n", __func__, pdata->lcd_dev);
+out:
+       if (ret < 0)
+               hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
+       mutex_unlock(&hdmi->mutex);
+
+       dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, pdata->lcd_dev);
+}
+
+static int sh_hdmi_notify(struct notifier_block *nb,
+                         unsigned long action, void *data);
+
+static struct notifier_block sh_hdmi_notifier = {
+       .notifier_call = sh_hdmi_notify,
+};
+
+static int sh_hdmi_notify(struct notifier_block *nb,
+                         unsigned long action, void *data)
+{
+       struct fb_event *event = data;
+       struct fb_info *info = event->info;
+       struct sh_mobile_lcdc_chan *ch = info->par;
+       struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+       struct sh_hdmi *hdmi = board_cfg->board_data;
+
+       if (nb != &sh_hdmi_notifier || !hdmi || hdmi->info != info)
+               return NOTIFY_DONE;
+
+       switch(action) {
+       case FB_EVENT_FB_REGISTERED:
+               /* Unneeded, activation taken care by sh_hdmi_display_on() */
+               break;
+       case FB_EVENT_FB_UNREGISTERED:
+               /*
+                * We are called from unregister_framebuffer() with the
+                * info->lock held. This is bad for us, because we can race with
+                * the scheduled work, which has to call fb_set_suspend(), which
+                * takes info->lock internally, so, sh_hdmi_edid_work_fn()
+                * cannot take and hold info->lock for the whole function
+                * duration. Using an additional lock creates a classical AB-BA
+                * lock up. Therefore, we have to release the info->lock
+                * temporarily, synchronise with the work queue and re-acquire
+                * the info->lock.
+                */
+               unlock_fb_info(hdmi->info);
+               mutex_lock(&hdmi->mutex);
+               hdmi->info = NULL;
+               mutex_unlock(&hdmi->mutex);
+               lock_fb_info(hdmi->info);
+               return NOTIFY_OK;
+       }
+       return NOTIFY_DONE;
 }
 
 static int __init sh_hdmi_probe(struct platform_device *pdev)
 {
        struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       struct sh_mobile_lcdc_board_cfg *board_cfg;
        int irq = platform_get_irq(pdev, 0), ret;
        struct sh_hdmi *hdmi;
        long rate;
@@ -964,10 +1155,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       ret =  snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1);
-       if (ret < 0)
-               goto esndreg;
+       mutex_init(&hdmi->mutex);
 
        hdmi->dev = &pdev->dev;
 
@@ -978,30 +1166,14 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
                goto egetclk;
        }
 
-       rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg.pixclock) * 1000;
-
-       rate = clk_round_rate(hdmi->hdmi_clk, rate);
+       /* Some arbitrary relaxed pixclock just to get things started */
+       rate = sh_hdmi_clk_configure(hdmi, 37037);
        if (rate < 0) {
                ret = rate;
-               dev_err(&pdev->dev, "Cannot get suitable rate: %ld\n", rate);
                goto erate;
        }
 
-       ret = clk_set_rate(hdmi->hdmi_clk, rate);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Cannot set rate %ld: %d\n", rate, ret);
-               goto erate;
-       }
-
-       pr_debug("HDMI set frequency %lu\n", rate);
-
-       ret = clk_enable(hdmi->hdmi_clk);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Cannot enable clock: %d\n", ret);
-               goto eclkenable;
-       }
-
-       dev_info(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);
+       dev_dbg(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);
 
        if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) {
                dev_err(&pdev->dev, "HDMI register region already claimed\n");
@@ -1018,18 +1190,18 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, hdmi);
 
-#if 1
        /* Product and revision IDs are 0 in sh-mobile version */
        dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
                 hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));
-#endif
 
        /* Set up LCDC callbacks */
-       pdata->lcd_chan->board_cfg.board_data = hdmi;
-       pdata->lcd_chan->board_cfg.display_on = hdmi_display_on;
-       pdata->lcd_chan->board_cfg.display_off = hdmi_display_off;
+       board_cfg = &pdata->lcd_chan->board_cfg;
+       board_cfg->owner = THIS_MODULE;
+       board_cfg->board_data = hdmi;
+       board_cfg->display_on = sh_hdmi_display_on;
+       board_cfg->display_off = sh_hdmi_display_off;
 
-       INIT_DELAYED_WORK(&hdmi->edid_work, edid_work_fn);
+       INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn);
 
        pm_runtime_enable(&pdev->dev);
        pm_runtime_resume(&pdev->dev);
@@ -1041,8 +1213,17 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
                goto ereqirq;
        }
 
+       ret = snd_soc_register_codec(&pdev->dev,
+                       &soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "codec registration failed\n");
+               goto ecodec;
+       }
+
        return 0;
 
+ecodec:
+       free_irq(irq, hdmi);
 ereqirq:
        pm_runtime_disable(&pdev->dev);
        iounmap(hdmi->base);
@@ -1050,12 +1231,10 @@ emap:
        release_mem_region(res->start, resource_size(res));
 ereqreg:
        clk_disable(hdmi->hdmi_clk);
-eclkenable:
 erate:
        clk_put(hdmi->hdmi_clk);
 egetclk:
-       snd_soc_unregister_codec(&pdev->dev);
-esndreg:
+       mutex_destroy(&hdmi->mutex);
        kfree(hdmi);
 
        return ret;
@@ -1066,21 +1245,26 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
        struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
        struct sh_hdmi *hdmi = platform_get_drvdata(pdev);
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg;
        int irq = platform_get_irq(pdev, 0);
 
        snd_soc_unregister_codec(&pdev->dev);
 
-       pdata->lcd_chan->board_cfg.display_on = NULL;
-       pdata->lcd_chan->board_cfg.display_off = NULL;
-       pdata->lcd_chan->board_cfg.board_data = NULL;
+       board_cfg->display_on = NULL;
+       board_cfg->display_off = NULL;
+       board_cfg->board_data = NULL;
+       board_cfg->owner = NULL;
 
+       /* No new work will be scheduled, wait for running ISR */
        free_irq(irq, hdmi);
-       pm_runtime_disable(&pdev->dev);
+       /* Wait for already scheduled work */
        cancel_delayed_work_sync(&hdmi->edid_work);
+       pm_runtime_disable(&pdev->dev);
        clk_disable(hdmi->hdmi_clk);
        clk_put(hdmi->hdmi_clk);
        iounmap(hdmi->base);
        release_mem_region(res->start, resource_size(res));
+       mutex_destroy(&hdmi->mutex);
        kfree(hdmi);
 
        return 0;
index 7a1419279c8f501bf4d94a4101259cf6aaa0860e..9b1364723c65e2fcff4dcec661d59ab50b960ee1 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
-#include <linux/fb.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
 #include <linux/platform_device.h>
 #include <linux/vmalloc.h>
 #include <linux/ioctl.h>
 #include <linux/slab.h>
+#include <linux/console.h>
 #include <video/sh_mobile_lcdc.h>
 #include <asm/atomic.h>
 
-#define PALETTE_NR 16
+#include "sh_mobile_lcdcfb.h"
+
 #define SIDE_B_OFFSET 0x1000
 #define MIRROR_OFFSET 0x2000
 
@@ -53,11 +54,8 @@ static int lcdc_shared_regs[] = {
 };
 #define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
 
-/* per-channel registers */
-enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
-       LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
-       LDHAJR,
-       NR_CH_REGS };
+#define DEFAULT_XRES 1280
+#define DEFAULT_YRES 1024
 
 static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
        [LDDCKPAT1R] = 0x400,
@@ -112,23 +110,22 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
 #define LDRCNTR_MRC    0x00000001
 #define LDSR_MRS       0x00000100
 
-struct sh_mobile_lcdc_priv;
-struct sh_mobile_lcdc_chan {
-       struct sh_mobile_lcdc_priv *lcdc;
-       unsigned long *reg_offs;
-       unsigned long ldmt1r_value;
-       unsigned long enabled; /* ME and SE in LDCNT2R */
-       struct sh_mobile_lcdc_chan_cfg cfg;
-       u32 pseudo_palette[PALETTE_NR];
-       unsigned long saved_ch_regs[NR_CH_REGS];
-       struct fb_info *info;
-       dma_addr_t dma_handle;
-       struct fb_deferred_io defio;
-       struct scatterlist *sglist;
-       unsigned long frame_end;
-       unsigned long pan_offset;
-       wait_queue_head_t frame_end_wait;
-       struct completion vsync_completion;
+static const struct fb_videomode default_720p = {
+       .name = "HDMI 720p",
+       .xres = 1280,
+       .yres = 720,
+
+       .left_margin = 220,
+       .right_margin = 110,
+       .hsync_len = 40,
+
+       .upper_margin = 20,
+       .lower_margin = 5,
+       .vsync_len = 5,
+
+       .pixclock = 13468,
+       .refresh = 60,
+       .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
 };
 
 struct sh_mobile_lcdc_priv {
@@ -409,8 +406,8 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
 
 static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
 {
-       struct fb_var_screeninfo *var = &ch->info->var;
-       unsigned long h_total, hsync_pos;
+       struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var;
+       unsigned long h_total, hsync_pos, display_h_total;
        u32 tmp;
 
        tmp = ch->ldmt1r_value;
@@ -428,31 +425,33 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
        lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
 
        /* horizontal configuration */
-       h_total = var->xres + var->hsync_len +
-               var->left_margin + var->right_margin;
+       h_total = display_var->xres + display_var->hsync_len +
+               display_var->left_margin + display_var->right_margin;
        tmp = h_total / 8; /* HTCN */
-       tmp |= (var->xres / 8) << 16; /* HDCN */
+       tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */
        lcdc_write_chan(ch, LDHCNR, tmp);
 
-       hsync_pos = var->xres + var->right_margin;
+       hsync_pos = display_var->xres + display_var->right_margin;
        tmp = hsync_pos / 8; /* HSYNP */
-       tmp |= (var->hsync_len / 8) << 16; /* HSYNW */
+       tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */
        lcdc_write_chan(ch, LDHSYNR, tmp);
 
        /* vertical configuration */
-       tmp = var->yres + var->vsync_len +
-               var->upper_margin + var->lower_margin; /* VTLN */
-       tmp |= var->yres << 16; /* VDLN */
+       tmp = display_var->yres + display_var->vsync_len +
+               display_var->upper_margin + display_var->lower_margin; /* VTLN */
+       tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */
        lcdc_write_chan(ch, LDVLNR, tmp);
 
-       tmp = var->yres + var->lower_margin; /* VSYNP */
-       tmp |= var->vsync_len << 16; /* VSYNW */
+       tmp = display_var->yres + display_var->lower_margin; /* VSYNP */
+       tmp |= display_var->vsync_len << 16; /* VSYNW */
        lcdc_write_chan(ch, LDVSYNR, tmp);
 
        /* Adjust horizontal synchronisation for HDMI */
-       tmp = ((var->xres & 7) << 24) |
-               ((h_total & 7) << 16) |
-               ((var->hsync_len & 7) << 8) |
+       display_h_total = display_var->xres + display_var->hsync_len +
+               display_var->left_margin + display_var->right_margin;
+       tmp = ((display_var->xres & 7) << 24) |
+               ((display_h_total & 7) << 16) |
+               ((display_var->hsync_len & 7) << 8) |
                hsync_pos;
        lcdc_write_chan(ch, LDHAJR, tmp);
 }
@@ -460,7 +459,6 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
 static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 {
        struct sh_mobile_lcdc_chan *ch;
-       struct fb_videomode *lcd_cfg;
        struct sh_mobile_lcdc_board_cfg *board_cfg;
        unsigned long tmp;
        int k, m;
@@ -503,7 +501,8 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
                        m = 1 << 6;
                tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0);
 
-               lcdc_write_chan(ch, LDDCKPAT1R, 0x00000000);
+               /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider denominator */
+               lcdc_write_chan(ch, LDDCKPAT1R, 0);
                lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1);
        }
 
@@ -518,7 +517,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 
        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
                ch = &priv->ch[k];
-               lcd_cfg = &ch->cfg.lcd_cfg;
 
                if (!ch->enabled)
                        continue;
@@ -547,7 +545,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 
                /* set bpp format in PKF[4:0] */
                tmp = lcdc_read_chan(ch, LDDFR);
-               tmp &= ~(0x0001001f);
+               tmp &= ~0x0001001f;
                tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0;
                lcdc_write_chan(ch, LDDFR, tmp);
 
@@ -591,8 +589,10 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
                        continue;
 
                board_cfg = &ch->cfg.board_cfg;
-               if (board_cfg->display_on)
+               if (try_module_get(board_cfg->owner) && board_cfg->display_on) {
                        board_cfg->display_on(board_cfg->board_data, ch->info);
+                       module_put(board_cfg->owner);
+               }
        }
 
        return 0;
@@ -614,7 +614,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
                 * flush frame, and wait for frame end interrupt
                 * clean up deferred io and enable clock
                 */
-               if (ch->info->fbdefio) {
+               if (ch->info && ch->info->fbdefio) {
                        ch->frame_end = 0;
                        schedule_delayed_work(&ch->info->deferred_work, 0);
                        wait_event(ch->frame_end_wait, ch->frame_end);
@@ -624,8 +624,10 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
                }
 
                board_cfg = &ch->cfg.board_cfg;
-               if (board_cfg->display_off)
+               if (try_module_get(board_cfg->owner) && board_cfg->display_off) {
                        board_cfg->display_off(board_cfg->board_data);
+                       module_put(board_cfg->owner);
+               }
        }
 
        /* stop the lcdc */
@@ -704,7 +706,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
                        return PTR_ERR(priv->dot_clk);
                }
        }
-       atomic_set(&priv->hw_usecnt, -1);
 
        /* Runtime PM support involves two step for this driver:
         * 1) Enable Runtime PM
@@ -837,6 +838,102 @@ static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
        return retval;
 }
 
+static void sh_mobile_fb_reconfig(struct fb_info *info)
+{
+       struct sh_mobile_lcdc_chan *ch = info->par;
+       struct fb_videomode mode1, mode2;
+       struct fb_event event;
+       int evnt = FB_EVENT_MODE_CHANGE_ALL;
+
+       if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par))
+               /* More framebuffer users are active */
+               return;
+
+       fb_var_to_videomode(&mode1, &ch->display_var);
+       fb_var_to_videomode(&mode2, &info->var);
+
+       if (fb_mode_is_equal(&mode1, &mode2))
+               return;
+
+       /* Display has been re-plugged, framebuffer is free now, reconfigure */
+       if (fb_set_var(info, &ch->display_var) < 0)
+               /* Couldn't reconfigure, hopefully, can continue as before */
+               return;
+
+       info->fix.line_length = mode2.xres * (ch->cfg.bpp / 8);
+
+       /*
+        * fb_set_var() calls the notifier change internally, only if
+        * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a
+        * user event, we have to call the chain ourselves.
+        */
+       event.info = info;
+       event.data = &mode2;
+       fb_notifier_call_chain(evnt, &event);
+}
+
+/*
+ * Locking: both .fb_release() and .fb_open() are called with info->lock held if
+ * user == 1, or with console sem held, if user == 0.
+ */
+static int sh_mobile_release(struct fb_info *info, int user)
+{
+       struct sh_mobile_lcdc_chan *ch = info->par;
+
+       mutex_lock(&ch->open_lock);
+       dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count);
+
+       ch->use_count--;
+
+       /* Nothing to reconfigure, when called from fbcon */
+       if (user) {
+               acquire_console_sem();
+               sh_mobile_fb_reconfig(info);
+               release_console_sem();
+       }
+
+       mutex_unlock(&ch->open_lock);
+
+       return 0;
+}
+
+static int sh_mobile_open(struct fb_info *info, int user)
+{
+       struct sh_mobile_lcdc_chan *ch = info->par;
+
+       mutex_lock(&ch->open_lock);
+       ch->use_count++;
+
+       dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count);
+       mutex_unlock(&ch->open_lock);
+
+       return 0;
+}
+
+static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+       struct sh_mobile_lcdc_chan *ch = info->par;
+
+       if (var->xres < 160 || var->xres > 1920 ||
+           var->yres < 120 || var->yres > 1080 ||
+           var->left_margin < 32 || var->left_margin > 320 ||
+           var->right_margin < 12 || var->right_margin > 240 ||
+           var->upper_margin < 12 || var->upper_margin > 120 ||
+           var->lower_margin < 1 || var->lower_margin > 64 ||
+           var->hsync_len < 32 || var->hsync_len > 240 ||
+           var->vsync_len < 2 || var->vsync_len > 64 ||
+           var->pixclock < 6000 || var->pixclock > 40000 ||
+           var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) {
+               dev_warn(info->dev, "Invalid info: %u %u %u %u %u %u %u %u %u!\n",
+                        var->xres, var->yres,
+                        var->left_margin, var->right_margin,
+                        var->upper_margin, var->lower_margin,
+                        var->hsync_len, var->vsync_len,
+                        var->pixclock);
+               return -EINVAL;
+       }
+       return 0;
+}
 
 static struct fb_ops sh_mobile_lcdc_ops = {
        .owner          = THIS_MODULE,
@@ -848,6 +945,9 @@ static struct fb_ops sh_mobile_lcdc_ops = {
        .fb_imageblit   = sh_mobile_lcdc_imageblit,
        .fb_pan_display = sh_mobile_fb_pan_display,
        .fb_ioctl       = sh_mobile_ioctl,
+       .fb_open        = sh_mobile_open,
+       .fb_release     = sh_mobile_release,
+       .fb_check_var   = sh_mobile_check_var,
 };
 
 static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -958,6 +1058,7 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
        .runtime_resume = sh_mobile_lcdc_runtime_resume,
 };
 
+/* locking: called with info->lock held */
 static int sh_mobile_lcdc_notify(struct notifier_block *nb,
                                 unsigned long action, void *data)
 {
@@ -965,53 +1066,40 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
        struct fb_info *info = event->info;
        struct sh_mobile_lcdc_chan *ch = info->par;
        struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
-       struct fb_var_screeninfo *var;
+       int ret;
 
        if (&ch->lcdc->notifier != nb)
-               return 0;
+               return NOTIFY_DONE;
 
        dev_dbg(info->dev, "%s(): action = %lu, data = %p\n",
                __func__, action, event->data);
 
        switch(action) {
        case FB_EVENT_SUSPEND:
-               if (board_cfg->display_off)
+               if (try_module_get(board_cfg->owner) && board_cfg->display_off) {
                        board_cfg->display_off(board_cfg->board_data);
+                       module_put(board_cfg->owner);
+               }
                pm_runtime_put(info->device);
+               sh_mobile_lcdc_stop(ch->lcdc);
                break;
        case FB_EVENT_RESUME:
-               var = &info->var;
+               mutex_lock(&ch->open_lock);
+               sh_mobile_fb_reconfig(info);
+               mutex_unlock(&ch->open_lock);
 
                /* HDMI must be enabled before LCDC configuration */
-               if (board_cfg->display_on)
-                       board_cfg->display_on(board_cfg->board_data, ch->info);
-
-               /* Check if the new display is not in our modelist */
-               if (ch->info->modelist.next &&
-                   !fb_match_mode(var, &ch->info->modelist)) {
-                       struct fb_videomode mode;
-                       int ret;
-
-                       /* Can we handle this display? */
-                       if (var->xres > ch->cfg.lcd_cfg.xres ||
-                           var->yres > ch->cfg.lcd_cfg.yres)
-                               return -ENOMEM;
-
-                       /* Add to the modelist */
-                       fb_var_to_videomode(&mode, var);
-                       ret = fb_add_videomode(&mode, &ch->info->modelist);
-                       if (ret < 0)
-                               return ret;
+               if (try_module_get(board_cfg->owner) && board_cfg->display_on) {
+                       board_cfg->display_on(board_cfg->board_data, info);
+                       module_put(board_cfg->owner);
                }
 
-               pm_runtime_get_sync(info->device);
-
-               sh_mobile_lcdc_geometry(ch);
-
-               break;
+               ret = sh_mobile_lcdc_start(ch->lcdc);
+               if (!ret)
+                       pm_runtime_get_sync(info->device);
        }
 
-       return 0;
+       return NOTIFY_OK;
 }
 
 static int sh_mobile_lcdc_remove(struct platform_device *pdev);
@@ -1020,14 +1108,13 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
 {
        struct fb_info *info;
        struct sh_mobile_lcdc_priv *priv;
-       struct sh_mobile_lcdc_info *pdata;
-       struct sh_mobile_lcdc_chan_cfg *cfg;
+       struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data;
        struct resource *res;
        int error;
        void *buf;
        int i, j;
 
-       if (!pdev->dev.platform_data) {
+       if (!pdata) {
                dev_err(&pdev->dev, "no platform data defined\n");
                return -EINVAL;
        }
@@ -1055,31 +1142,33 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
        }
 
        priv->irq = i;
-       pdata = pdev->dev.platform_data;
+       atomic_set(&priv->hw_usecnt, -1);
 
        j = 0;
        for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) {
-               priv->ch[j].lcdc = priv;
-               memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
+               struct sh_mobile_lcdc_chan *ch = priv->ch + j;
+
+               ch->lcdc = priv;
+               memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
 
-               error = sh_mobile_lcdc_check_interface(&priv->ch[j]);
+               error = sh_mobile_lcdc_check_interface(ch);
                if (error) {
                        dev_err(&pdev->dev, "unsupported interface type\n");
                        goto err1;
                }
-               init_waitqueue_head(&priv->ch[j].frame_end_wait);
-               init_completion(&priv->ch[j].vsync_completion);
-               priv->ch[j].pan_offset = 0;
+               init_waitqueue_head(&ch->frame_end_wait);
+               init_completion(&ch->vsync_completion);
+               ch->pan_offset = 0;
 
                switch (pdata->ch[i].chan) {
                case LCDC_CHAN_MAINLCD:
-                       priv->ch[j].enabled = 1 << 1;
-                       priv->ch[j].reg_offs = lcdc_offs_mainlcd;
+                       ch->enabled = 1 << 1;
+                       ch->reg_offs = lcdc_offs_mainlcd;
                        j++;
                        break;
                case LCDC_CHAN_SUBLCD:
-                       priv->ch[j].enabled = 1 << 2;
-                       priv->ch[j].reg_offs = lcdc_offs_sublcd;
+                       ch->enabled = 1 << 2;
+                       ch->reg_offs = lcdc_offs_sublcd;
                        j++;
                        break;
                }
@@ -1103,69 +1192,90 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
 
        for (i = 0; i < j; i++) {
                struct fb_var_screeninfo *var;
-               struct fb_videomode *lcd_cfg;
-               cfg = &priv->ch[i].cfg;
-
-               priv->ch[i].info = framebuffer_alloc(0, &pdev->dev);
-               if (!priv->ch[i].info) {
+               const struct fb_videomode *lcd_cfg, *max_cfg = NULL;
+               struct sh_mobile_lcdc_chan *ch = priv->ch + i;
+               struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg;
+               const struct fb_videomode *mode = cfg->lcd_cfg;
+               unsigned long max_size = 0;
+               int k;
+               int num_cfg;
+
+               ch->info = framebuffer_alloc(0, &pdev->dev);
+               if (!ch->info) {
                        dev_err(&pdev->dev, "unable to allocate fb_info\n");
                        error = -ENOMEM;
                        break;
                }
 
-               info = priv->ch[i].info;
+               info = ch->info;
                var = &info->var;
-               lcd_cfg = &cfg->lcd_cfg;
                info->fbops = &sh_mobile_lcdc_ops;
-               var->xres = var->xres_virtual = lcd_cfg->xres;
-               var->yres = lcd_cfg->yres;
+               info->par = ch;
+
+               mutex_init(&ch->open_lock);
+
+               for (k = 0, lcd_cfg = mode;
+                    k < cfg->num_cfg && lcd_cfg;
+                    k++, lcd_cfg++) {
+                       unsigned long size = lcd_cfg->yres * lcd_cfg->xres;
+
+                       if (size > max_size) {
+                               max_cfg = lcd_cfg;
+                               max_size = size;
+                       }
+               }
+
+               if (!mode)
+                       max_size = DEFAULT_XRES * DEFAULT_YRES;
+               else if (max_cfg)
+                       dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n",
+                               max_cfg->xres, max_cfg->yres);
+
+               info->fix = sh_mobile_lcdc_fix;
+               info->fix.smem_len = max_size * (cfg->bpp / 8) * 2;
+
+               if (!mode) {
+                       mode = &default_720p;
+                       num_cfg = 1;
+               } else {
+                       num_cfg = ch->cfg.num_cfg;
+               }
+
+               fb_videomode_to_modelist(mode, num_cfg, &info->modelist);
+
+               fb_videomode_to_var(var, mode);
                /* Default Y virtual resolution is 2x panel size */
                var->yres_virtual = var->yres * 2;
-               var->width = cfg->lcd_size_cfg.width;
-               var->height = cfg->lcd_size_cfg.height;
                var->activate = FB_ACTIVATE_NOW;
-               var->left_margin = lcd_cfg->left_margin;
-               var->right_margin = lcd_cfg->right_margin;
-               var->upper_margin = lcd_cfg->upper_margin;
-               var->lower_margin = lcd_cfg->lower_margin;
-               var->hsync_len = lcd_cfg->hsync_len;
-               var->vsync_len = lcd_cfg->vsync_len;
-               var->sync = lcd_cfg->sync;
-               var->pixclock = lcd_cfg->pixclock;
 
                error = sh_mobile_lcdc_set_bpp(var, cfg->bpp);
                if (error)
                        break;
 
-               info->fix = sh_mobile_lcdc_fix;
-               info->fix.line_length = lcd_cfg->xres * (cfg->bpp / 8);
-               info->fix.smem_len = info->fix.line_length *
-                       var->yres_virtual;
-
                buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
-                                        &priv->ch[i].dma_handle, GFP_KERNEL);
+                                        &ch->dma_handle, GFP_KERNEL);
                if (!buf) {
                        dev_err(&pdev->dev, "unable to allocate buffer\n");
                        error = -ENOMEM;
                        break;
                }
 
-               info->pseudo_palette = &priv->ch[i].pseudo_palette;
+               info->pseudo_palette = &ch->pseudo_palette;
                info->flags = FBINFO_FLAG_DEFAULT;
 
                error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
                if (error < 0) {
                        dev_err(&pdev->dev, "unable to allocate cmap\n");
                        dma_free_coherent(&pdev->dev, info->fix.smem_len,
-                                         buf, priv->ch[i].dma_handle);
+                                         buf, ch->dma_handle);
                        break;
                }
 
-               memset(buf, 0, info->fix.smem_len);
-               info->fix.smem_start = priv->ch[i].dma_handle;
+               info->fix.smem_start = ch->dma_handle;
+               info->fix.line_length = var->xres * (cfg->bpp / 8);
                info->screen_base = buf;
                info->device = &pdev->dev;
-               info->par = &priv->ch[i];
+               ch->display_var = *var;
        }
 
        if (error)
@@ -1200,8 +1310,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
                         pdev->name,
                         (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
                         "mainlcd" : "sublcd",
-                        (int) ch->cfg.lcd_cfg.xres,
-                        (int) ch->cfg.lcd_cfg.yres,
+                        info->var.xres, info->var.yres,
                         ch->cfg.bpp);
 
                /* deferred io mode: disable clock to save power */
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
new file mode 100644 (file)
index 0000000..9ecee2f
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef SH_MOBILE_LCDCFB_H
+#define SH_MOBILE_LCDCFB_H
+
+#include <linux/completion.h>
+#include <linux/fb.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+
+/* per-channel registers */
+enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
+       LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
+       LDHAJR,
+       NR_CH_REGS };
+
+#define PALETTE_NR 16
+
+struct sh_mobile_lcdc_priv;
+struct fb_info;
+
+struct sh_mobile_lcdc_chan {
+       struct sh_mobile_lcdc_priv *lcdc;
+       unsigned long *reg_offs;
+       unsigned long ldmt1r_value;
+       unsigned long enabled; /* ME and SE in LDCNT2R */
+       struct sh_mobile_lcdc_chan_cfg cfg;
+       u32 pseudo_palette[PALETTE_NR];
+       unsigned long saved_ch_regs[NR_CH_REGS];
+       struct fb_info *info;
+       dma_addr_t dma_handle;
+       struct fb_deferred_io defio;
+       struct scatterlist *sglist;
+       unsigned long frame_end;
+       unsigned long pan_offset;
+       wait_queue_head_t frame_end_wait;
+       struct completion vsync_completion;
+       struct fb_var_screeninfo display_var;
+       int use_count;
+       struct mutex open_lock;         /* protects the use counter */
+};
+
+#endif
index b52f8e4ef1fdbe3cd19c70d4fb282d15f5b99f85..3dde12b0ab06420c58b0e6a41fc5f23350b28a75 100644 (file)
@@ -4181,6 +4181,9 @@ static void __devinit
 sisfb_post_map_vram(struct sis_video_info *ivideo, unsigned int *mapsize,
                        unsigned int min)
 {
+       if (*mapsize < (min << 20))
+               return;
+
        ivideo->video_vbase = ioremap(ivideo->video_base, (*mapsize));
 
        if(!ivideo->video_vbase) {
@@ -4514,7 +4517,7 @@ sisfb_post_sis300(struct pci_dev *pdev)
        } else {
 #endif
                /* Need to map max FB size for finding out about RAM size */
-               mapsize = 64 << 20;
+               mapsize = ivideo->video_size;
                sisfb_post_map_vram(ivideo, &mapsize, 4);
 
                if(ivideo->video_vbase) {
@@ -4680,7 +4683,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
        orSISIDXREG(SISSR, 0x20, (0x80 | 0x04));
 
        /* Need to map max FB size for finding out about RAM size */
-       mapsize = 256 << 20;
+       mapsize = ivideo->video_size;
        sisfb_post_map_vram(ivideo, &mapsize, 32);
 
        if(!ivideo->video_vbase) {
@@ -5936,6 +5939,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        ivideo->video_base = pci_resource_start(pdev, 0);
+       ivideo->video_size = pci_resource_len(pdev, 0);
        ivideo->mmio_base  = pci_resource_start(pdev, 1);
        ivideo->mmio_size  = pci_resource_len(pdev, 1);
        ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
index 909923800a02291bee821038ca3b62f6eb0a1ea8..945ee8300306c0e322cd69a26180231879f02acc 100644 (file)
@@ -478,7 +478,7 @@ static void octeon_wdt_calc_parameters(int t)
 
        countdown_reset = periods > 2 ? periods - 2 : 0;
        heartbeat = t;
-       timeout_cnt = ((octeon_get_clock_rate() >> 8) * timeout_sec) >> 8;
+       timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * timeout_sec) >> 8;
 }
 
 static int octeon_wdt_set_heartbeat(int t)
@@ -677,7 +677,7 @@ static int __init octeon_wdt_init(void)
        max_timeout_sec = 6;
        do {
                max_timeout_sec--;
-               timeout_cnt = ((octeon_get_clock_rate() >> 8) * max_timeout_sec) >> 8;
+               timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * max_timeout_sec) >> 8;
        } while (timeout_cnt > 65535);
 
        BUG_ON(timeout_cnt == 0);
index eb8a78d77d9d2a7fb70f81ac54ae902e6b29204d..533a199e7a3f94911ef9665ab5e1789c63bef6d2 100644 (file)
@@ -8,9 +8,12 @@ obj-$(CONFIG_BLOCK)            += biomerge.o
 obj-$(CONFIG_HOTPLUG_CPU)      += cpu_hotplug.o
 obj-$(CONFIG_XEN_XENCOMM)      += xencomm.o
 obj-$(CONFIG_XEN_BALLOON)      += balloon.o
-obj-$(CONFIG_XEN_DEV_EVTCHN)   += evtchn.o
+obj-$(CONFIG_XEN_DEV_EVTCHN)   += xen-evtchn.o
 obj-$(CONFIG_XENFS)            += xenfs/
 obj-$(CONFIG_XEN_SYS_HYPERVISOR)       += sys-hypervisor.o
 obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o
 obj-$(CONFIG_SWIOTLB_XEN)      += swiotlb-xen.o
 obj-$(CONFIG_XEN_DOM0)         += pci.o
+
+xen-evtchn-y                   := evtchn.o
+
index fec6ba3c08a8e885d663ce3ac9c8b031ff971273..ef11daf0cafe9f086f3944b42fd32ff48811f4b2 100644 (file)
@@ -69,20 +69,51 @@ struct per_user_data {
        const char *name;
 };
 
-/* Who's bound to each port? */
-static struct per_user_data *port_user[NR_EVENT_CHANNELS];
+/*
+ * Who's bound to each port?  This is logically an array of struct
+ * per_user_data *, but we encode the current enabled-state in bit 0.
+ */
+static unsigned long *port_user;
 static DEFINE_SPINLOCK(port_user_lock); /* protects port_user[] and ring_prod */
 
-irqreturn_t evtchn_interrupt(int irq, void *data)
+static inline struct per_user_data *get_port_user(unsigned port)
+{
+       return (struct per_user_data *)(port_user[port] & ~1);
+}
+
+static inline void set_port_user(unsigned port, struct per_user_data *u)
+{
+       port_user[port] = (unsigned long)u;
+}
+
+static inline bool get_port_enabled(unsigned port)
+{
+       return port_user[port] & 1;
+}
+
+static inline void set_port_enabled(unsigned port, bool enabled)
+{
+       if (enabled)
+               port_user[port] |= 1;
+       else
+               port_user[port] &= ~1;
+}
+
+static irqreturn_t evtchn_interrupt(int irq, void *data)
 {
        unsigned int port = (unsigned long)data;
        struct per_user_data *u;
 
        spin_lock(&port_user_lock);
 
-       u = port_user[port];
+       u = get_port_user(port);
+
+       WARN(!get_port_enabled(port),
+            "Interrupt for port %d, but apparently not enabled; per-user %p\n",
+            port, u);
 
        disable_irq_nosync(irq);
+       set_port_enabled(port, false);
 
        if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
                u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
@@ -92,9 +123,8 @@ irqreturn_t evtchn_interrupt(int irq, void *data)
                        kill_fasync(&u->evtchn_async_queue,
                                    SIGIO, POLL_IN);
                }
-       } else {
+       } else
                u->ring_overflow = 1;
-       }
 
        spin_unlock(&port_user_lock);
 
@@ -198,9 +228,18 @@ static ssize_t evtchn_write(struct file *file, const char __user *buf,
                goto out;
 
        spin_lock_irq(&port_user_lock);
-       for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
-               if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
-                       enable_irq(irq_from_evtchn(kbuf[i]));
+
+       for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) {
+               unsigned port = kbuf[i];
+
+               if (port < NR_EVENT_CHANNELS &&
+                   get_port_user(port) == u &&
+                   !get_port_enabled(port)) {
+                       set_port_enabled(port, true);
+                       enable_irq(irq_from_evtchn(port));
+               }
+       }
+
        spin_unlock_irq(&port_user_lock);
 
        rc = count;
@@ -222,8 +261,9 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port)
         * interrupt handler yet, and our caller has already
         * serialized bind operations.)
         */
-       BUG_ON(port_user[port] != NULL);
-       port_user[port] = u;
+       BUG_ON(get_port_user(port) != NULL);
+       set_port_user(port, u);
+       set_port_enabled(port, true); /* start enabled */
 
        rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED,
                                       u->name, (void *)(unsigned long)port);
@@ -239,10 +279,7 @@ static void evtchn_unbind_from_user(struct per_user_data *u, int port)
 
        unbind_from_irqhandler(irq, (void *)(unsigned long)port);
 
-       /* make sure we unbind the irq handler before clearing the port */
-       barrier();
-
-       port_user[port] = NULL;
+       set_port_user(port, NULL);
 }
 
 static long evtchn_ioctl(struct file *file,
@@ -333,15 +370,17 @@ static long evtchn_ioctl(struct file *file,
                spin_lock_irq(&port_user_lock);
 
                rc = -ENOTCONN;
-               if (port_user[unbind.port] != u) {
+               if (get_port_user(unbind.port) != u) {
                        spin_unlock_irq(&port_user_lock);
                        break;
                }
 
-               evtchn_unbind_from_user(u, unbind.port);
+               disable_irq(irq_from_evtchn(unbind.port));
 
                spin_unlock_irq(&port_user_lock);
 
+               evtchn_unbind_from_user(u, unbind.port);
+
                rc = 0;
                break;
        }
@@ -355,7 +394,7 @@ static long evtchn_ioctl(struct file *file,
 
                if (notify.port >= NR_EVENT_CHANNELS) {
                        rc = -EINVAL;
-               } else if (port_user[notify.port] != u) {
+               } else if (get_port_user(notify.port) != u) {
                        rc = -ENOTCONN;
                } else {
                        notify_remote_via_evtchn(notify.port);
@@ -431,7 +470,7 @@ static int evtchn_open(struct inode *inode, struct file *filp)
 
        filp->private_data = u;
 
-       return 0;
+       return nonseekable_open(inode, filp);;
 }
 
 static int evtchn_release(struct inode *inode, struct file *filp)
@@ -444,14 +483,21 @@ static int evtchn_release(struct inode *inode, struct file *filp)
        free_page((unsigned long)u->ring);
 
        for (i = 0; i < NR_EVENT_CHANNELS; i++) {
-               if (port_user[i] != u)
+               if (get_port_user(i) != u)
                        continue;
 
-               evtchn_unbind_from_user(port_user[i], i);
+               disable_irq(irq_from_evtchn(i));
        }
 
        spin_unlock_irq(&port_user_lock);
 
+       for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+               if (get_port_user(i) != u)
+                       continue;
+
+               evtchn_unbind_from_user(get_port_user(i), i);
+       }
+
        kfree(u->name);
        kfree(u);
 
@@ -467,12 +513,12 @@ static const struct file_operations evtchn_fops = {
        .fasync  = evtchn_fasync,
        .open    = evtchn_open,
        .release = evtchn_release,
-       .llseek = noop_llseek,
+       .llseek  = no_llseek,
 };
 
 static struct miscdevice evtchn_miscdev = {
        .minor        = MISC_DYNAMIC_MINOR,
-       .name         = "evtchn",
+       .name         = "xen/evtchn",
        .fops         = &evtchn_fops,
 };
 static int __init evtchn_init(void)
@@ -482,8 +528,11 @@ static int __init evtchn_init(void)
        if (!xen_domain())
                return -ENODEV;
 
+       port_user = kcalloc(NR_EVENT_CHANNELS, sizeof(*port_user), GFP_KERNEL);
+       if (port_user == NULL)
+               return -ENOMEM;
+
        spin_lock_init(&port_user_lock);
-       memset(port_user, 0, sizeof(port_user));
 
        /* Create '/dev/misc/evtchn'. */
        err = misc_register(&evtchn_miscdev);
@@ -499,6 +548,9 @@ static int __init evtchn_init(void)
 
 static void __exit evtchn_cleanup(void)
 {
+       kfree(port_user);
+       port_user = NULL;
+
        misc_deregister(&evtchn_miscdev);
 }
 
index f80be7f6eb95265d223a40f2166bc29b6fb8d3c6..88474d460d82fdba45474d5c4b58706b61e047ae 100644 (file)
@@ -266,9 +266,7 @@ static int mmap_return_errors(void *data, void *state)
        xen_pfn_t *mfnp = data;
        struct mmap_batch_state *st = state;
 
-       put_user(*mfnp, st->user++);
-
-       return 0;
+       return put_user(*mfnp, st->user++);
 }
 
 static struct vm_operations_struct privcmd_vm_ops;
@@ -323,10 +321,8 @@ static long privcmd_ioctl_mmap_batch(void __user *udata)
        up_write(&mm->mmap_sem);
 
        if (state.err > 0) {
-               ret = 0;
-
                state.user = m.arr;
-               traverse_pages(m.num, sizeof(xen_pfn_t),
+               ret = traverse_pages(m.num, sizeof(xen_pfn_t),
                               &pagelist,
                               mmap_return_errors, &state);
        }
@@ -384,8 +380,9 @@ static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return -ENOSYS;
 
-       /* DONTCOPY is essential for Xen as copy_page_range is broken. */
-       vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
+       /* DONTCOPY is essential for Xen because copy_page_range doesn't know
+        * how to recreate these mappings */
+       vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
        vma->vm_ops = &privcmd_vm_ops;
        vma->vm_private_data = NULL;
 
index d6662b789b6bf05a3cc172623216ea662e681781..1aa3897198462112a3bc1db479986653cf0a716f 100644 (file)
@@ -12,8 +12,6 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/magic.h>
-#include <linux/mm.h>
-#include <linux/backing-dev.h>
 
 #include <xen/xen.h>
 
 MODULE_DESCRIPTION("Xen filesystem");
 MODULE_LICENSE("GPL");
 
-static int xenfs_set_page_dirty(struct page *page)
-{
-       return !TestSetPageDirty(page);
-}
-
-static const struct address_space_operations xenfs_aops = {
-       .set_page_dirty = xenfs_set_page_dirty,
-};
-
-static struct backing_dev_info xenfs_backing_dev_info = {
-       .ra_pages       = 0,    /* No readahead */
-       .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK,
-};
-
 static struct inode *xenfs_make_inode(struct super_block *sb, int mode)
 {
        struct inode *ret = new_inode(sb);
 
        if (ret) {
                ret->i_mode = mode;
-               ret->i_mapping->a_ops = &xenfs_aops;
-               ret->i_mapping->backing_dev_info = &xenfs_backing_dev_info;
                ret->i_uid = ret->i_gid = 0;
                ret->i_blocks = 0;
                ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
@@ -121,41 +103,27 @@ static int xenfs_fill_super(struct super_block *sb, void *data, int silent)
        return rc;
 }
 
-static int xenfs_get_sb(struct file_system_type *fs_type,
-                       int flags, const char *dev_name,
-                       void *data, struct vfsmount *mnt)
+static struct dentry *xenfs_mount(struct file_system_type *fs_type,
+                                 int flags, const char *dev_name,
+                                 void *data)
 {
-       return get_sb_single(fs_type, flags, data, xenfs_fill_super, mnt);
+       return mount_single(fs_type, flags, data, xenfs_fill_super);
 }
 
 static struct file_system_type xenfs_type = {
        .owner =        THIS_MODULE,
        .name =         "xenfs",
-       .get_sb =       xenfs_get_sb,
+       .mount =        xenfs_mount,
        .kill_sb =      kill_litter_super,
 };
 
 static int __init xenfs_init(void)
 {
-       int err;
-       if (!xen_domain()) {
-               printk(KERN_INFO "xenfs: not registering filesystem on non-xen platform\n");
-               return 0;
-       }
-
-       err = register_filesystem(&xenfs_type);
-       if (err) {
-               printk(KERN_ERR "xenfs: Unable to register filesystem!\n");
-               goto out;
-       }
-
-       err = bdi_init(&xenfs_backing_dev_info);
-       if (err)
-               unregister_filesystem(&xenfs_type);
-
- out:
+       if (xen_domain())
+               return register_filesystem(&xenfs_type);
 
-       return err;
+       printk(KERN_INFO "XENFS: not registering filesystem on non-xen platform\n");
+       return 0;
 }
 
 static void __exit xenfs_exit(void)
index 48d4215c60a8924df5dbb35706a28f84ac9ea5eb..c55c614500ad4e4e74561264e9766fe65b0633a3 100644 (file)
@@ -68,7 +68,7 @@ static int v9fs_set_super(struct super_block *s, void *data)
  * v9fs_fill_super - populate superblock with info
  * @sb: superblock
  * @v9ses: session information
- * @flags: flags propagated from v9fs_get_sb()
+ * @flags: flags propagated from v9fs_mount()
  *
  */
 
@@ -99,18 +99,16 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
 }
 
 /**
- * v9fs_get_sb - mount a superblock
+ * v9fs_mount - mount a superblock
  * @fs_type: file system type
  * @flags: mount flags
  * @dev_name: device name that was mounted
  * @data: mount options
- * @mnt: mountpoint record to be instantiated
  *
  */
 
-static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
-                      const char *dev_name, void *data,
-                      struct vfsmount *mnt)
+static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
+                      const char *dev_name, void *data)
 {
        struct super_block *sb = NULL;
        struct inode *inode = NULL;
@@ -124,7 +122,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
 
        v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
        if (!v9ses)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        fid = v9fs_session_init(v9ses, dev_name, data);
        if (IS_ERR(fid)) {
@@ -186,15 +184,15 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
        v9fs_fid_add(root, fid);
 
        P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
-       simple_set_mnt(mnt, sb);
-       return 0;
+       return dget(sb->s_root);
 
 clunk_fid:
        p9_client_clunk(fid);
 close_session:
        v9fs_session_close(v9ses);
        kfree(v9ses);
-       return retval;
+       return ERR_PTR(retval);
+
 release_sb:
        /*
         * we will do the session_close and root dentry release
@@ -204,7 +202,7 @@ release_sb:
         */
        p9_client_clunk(fid);
        deactivate_locked_super(sb);
-       return retval;
+       return ERR_PTR(retval);
 }
 
 /**
@@ -300,7 +298,7 @@ static const struct super_operations v9fs_super_ops_dotl = {
 
 struct file_system_type v9fs_fs_type = {
        .name = "9p",
-       .get_sb = v9fs_get_sb,
+       .mount = v9fs_mount,
        .kill_sb = v9fs_kill_super,
        .owner = THIS_MODULE,
        .fs_flags = FS_RENAME_DOES_D_MOVE,
index d9803f73236f543fca9764cbe453414f6fe22286..959dbff2d42dc4a0a0026e3b3aad5f7f0008a7f3 100644 (file)
@@ -490,17 +490,16 @@ error:
        return -EINVAL;
 }
 
-static int adfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *adfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, adfs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, adfs_fill_super);
 }
 
 static struct file_system_type adfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "adfs",
-       .get_sb         = adfs_get_sb,
+       .mount          = adfs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index fa4fbe1e238a344bbe35207e635461f07ac81691..0cf7f4384cbd472b46f3c50f1812cb84b4ab6f91 100644 (file)
@@ -573,17 +573,16 @@ affs_statfs(struct dentry *dentry, struct kstatfs *buf)
        return 0;
 }
 
-static int affs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *affs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, affs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, affs_fill_super);
 }
 
 static struct file_system_type affs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "affs",
-       .get_sb         = affs_get_sb,
+       .mount          = affs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index eacf76d98ae02345d00d62f22f5ab4893a0452e6..27201cffece4946879f01482f7aa61ffdbc6b339 100644 (file)
@@ -29,9 +29,8 @@
 #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
 
 static void afs_i_init_once(void *foo);
-static int afs_get_sb(struct file_system_type *fs_type,
-                     int flags, const char *dev_name,
-                     void *data, struct vfsmount *mnt);
+static struct dentry *afs_mount(struct file_system_type *fs_type,
+                     int flags, const char *dev_name, void *data);
 static struct inode *afs_alloc_inode(struct super_block *sb);
 static void afs_put_super(struct super_block *sb);
 static void afs_destroy_inode(struct inode *inode);
@@ -40,7 +39,7 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf);
 struct file_system_type afs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "afs",
-       .get_sb         = afs_get_sb,
+       .mount          = afs_mount,
        .kill_sb        = kill_anon_super,
        .fs_flags       = 0,
 };
@@ -359,11 +358,8 @@ error:
 /*
  * get an AFS superblock
  */
-static int afs_get_sb(struct file_system_type *fs_type,
-                     int flags,
-                     const char *dev_name,
-                     void *options,
-                     struct vfsmount *mnt)
+static struct dentry *afs_mount(struct file_system_type *fs_type,
+                     int flags, const char *dev_name, void *options)
 {
        struct afs_mount_params params;
        struct super_block *sb;
@@ -427,12 +423,11 @@ static int afs_get_sb(struct file_system_type *fs_type,
                ASSERTCMP(sb->s_flags, &, MS_ACTIVE);
        }
 
-       simple_set_mnt(mnt, sb);
        afs_put_volume(params.volume);
        afs_put_cell(params.cell);
        kfree(new_opts);
        _leave(" = 0 [%p]", sb);
-       return 0;
+       return dget(sb->s_root);
 
 error:
        afs_put_volume(params.volume);
@@ -440,7 +435,7 @@ error:
        key_put(params.key);
        kfree(new_opts);
        _leave(" = %d", ret);
-       return ret;
+       return ERR_PTR(ret);
 }
 
 /*
index 5365527ca43fec37cdc021afbc21acf76c321889..57ce55b2564cf38159638fa146c2b653c5fc66a6 100644 (file)
@@ -26,12 +26,10 @@ static struct vfsmount *anon_inode_mnt __read_mostly;
 static struct inode *anon_inode_inode;
 static const struct file_operations anon_inode_fops;
 
-static int anon_inodefs_get_sb(struct file_system_type *fs_type, int flags,
-                              const char *dev_name, void *data,
-                              struct vfsmount *mnt)
+static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
+                               int flags, const char *dev_name, void *data)
 {
-       return get_sb_pseudo(fs_type, "anon_inode:", NULL, ANON_INODE_FS_MAGIC,
-                            mnt);
+       return mount_pseudo(fs_type, "anon_inode:", NULL, ANON_INODE_FS_MAGIC);
 }
 
 /*
@@ -45,7 +43,7 @@ static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen)
 
 static struct file_system_type anon_inode_fs_type = {
        .name           = "anon_inodefs",
-       .get_sb         = anon_inodefs_get_sb,
+       .mount          = anon_inodefs_mount,
        .kill_sb        = kill_anon_super,
 };
 static const struct dentry_operations anon_inodefs_dentry_operations = {
index 9722e4bd895725f42361b86d74355c3c4656bfbe..c038727b405031fb91052c7af314d62508c3a5bd 100644 (file)
 #include <linux/init.h>
 #include "autofs_i.h"
 
-static int autofs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *autofs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, autofs4_fill_super, mnt);
+       return mount_nodev(fs_type, flags, data, autofs4_fill_super);
 }
 
 static struct file_system_type autofs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "autofs",
-       .get_sb         = autofs_get_sb,
+       .mount          = autofs_mount,
        .kill_sb        = autofs4_kill_sb,
 };
 
index dc39d282488514418a7bedeeaf01fc1560ffb0cb..aa4e7c7ae3c657e9c4b11efb77cbd46982fa3389 100644 (file)
@@ -913,18 +913,17 @@ befs_statfs(struct dentry *dentry, struct kstatfs *buf)
        return 0;
 }
 
-static int
-befs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name,
-           void *data, struct vfsmount *mnt)
+static struct dentry *
+befs_mount(struct file_system_type *fs_type, int flags, const char *dev_name,
+           void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, befs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, befs_fill_super);
 }
 
 static struct file_system_type befs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "befs",
-       .get_sb         = befs_get_sb,
+       .mount          = befs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,      
 };
index 883e77acd5a8cd8e0c3598cb62e5993e82725d97..76db6d7d49bbd75d22a23016ab0b9df3449d0b00 100644 (file)
@@ -450,16 +450,16 @@ out:
        return ret;
 }
 
-static int bfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *bfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super, mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, bfs_fill_super);
 }
 
 static struct file_system_type bfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "bfs",
-       .get_sb         = bfs_get_sb,
+       .mount          = bfs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 29990f0eee0c90adb18771c2c327fc99ee32c765..1befe2ec8186768a7b7baebc4a4c4d20418cfc14 100644 (file)
@@ -706,10 +706,10 @@ static int bm_fill_super(struct super_block * sb, void * data, int silent)
        return err;
 }
 
-static int bm_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *bm_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, bm_fill_super, mnt);
+       return mount_single(fs_type, flags, data, bm_fill_super);
 }
 
 static struct linux_binfmt misc_format = {
@@ -720,7 +720,7 @@ static struct linux_binfmt misc_format = {
 static struct file_system_type bm_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "binfmt_misc",
-       .get_sb         = bm_get_sb,
+       .mount          = bm_mount,
        .kill_sb        = kill_litter_super,
 };
 
index 8abb2dfb2e7c8b006f9c80b716808a1ff07a0189..4bd454fa844e3efc8c44755c7ea9847477f813ff 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -370,6 +370,9 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs)
 {
        struct bio *bio;
 
+       if (nr_iovecs > UIO_MAXIOV)
+               return NULL;
+
        bio = kmalloc(sizeof(struct bio) + nr_iovecs * sizeof(struct bio_vec),
                      gfp_mask);
        if (unlikely(!bio))
@@ -697,8 +700,12 @@ static void bio_free_map_data(struct bio_map_data *bmd)
 static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count,
                                               gfp_t gfp_mask)
 {
-       struct bio_map_data *bmd = kmalloc(sizeof(*bmd), gfp_mask);
+       struct bio_map_data *bmd;
 
+       if (iov_count > UIO_MAXIOV)
+               return NULL;
+
+       bmd = kmalloc(sizeof(*bmd), gfp_mask);
        if (!bmd)
                return NULL;
 
@@ -827,6 +834,12 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
                end = (uaddr + iov[i].iov_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
                start = uaddr >> PAGE_SHIFT;
 
+               /*
+                * Overflow, abort
+                */
+               if (end < start)
+                       return ERR_PTR(-EINVAL);
+
                nr_pages += end - start;
                len += iov[i].iov_len;
        }
@@ -955,6 +968,12 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
                unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
                unsigned long start = uaddr >> PAGE_SHIFT;
 
+               /*
+                * Overflow, abort
+                */
+               if (end < start)
+                       return ERR_PTR(-EINVAL);
+
                nr_pages += end - start;
                /*
                 * buffer must be aligned to at least hardsector size for now
@@ -982,7 +1001,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
                unsigned long start = uaddr >> PAGE_SHIFT;
                const int local_nr_pages = end - start;
                const int page_limit = cur_page + local_nr_pages;
-               
+
                ret = get_user_pages_fast(uaddr, local_nr_pages,
                                write_to_vm, &pages[cur_page]);
                if (ret < local_nr_pages) {
index dea3b628a6ce9a9058c24d2b13c364b7c6adb3c3..06e8ff12b97c8fa74d4b2eb05c900801b3adb150 100644 (file)
@@ -464,15 +464,15 @@ static const struct super_operations bdev_sops = {
        .evict_inode = bdev_evict_inode,
 };
 
-static int bd_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *bd_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576, mnt);
+       return mount_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576);
 }
 
 static struct file_system_type bd_type = {
        .name           = "bdev",
-       .get_sb         = bd_get_sb,
+       .mount          = bd_mount,
        .kill_sb        = kill_anon_super,
 };
 
index 396039b3a8a24ecb7f37fbec9ef831ed05d5cf94..7845d1f7d1d927f79ac45c09af730963a426b8e5 100644 (file)
@@ -163,7 +163,6 @@ fail:
  */
 static void end_compressed_bio_read(struct bio *bio, int err)
 {
-       struct extent_io_tree *tree;
        struct compressed_bio *cb = bio->bi_private;
        struct inode *inode;
        struct page *page;
@@ -187,7 +186,6 @@ static void end_compressed_bio_read(struct bio *bio, int err)
        /* ok, we're the last bio for this extent, lets start
         * the decompression.
         */
-       tree = &BTRFS_I(inode)->io_tree;
        ret = btrfs_zlib_decompress_biovec(cb->compressed_pages,
                                        cb->start,
                                        cb->orig_bio->bi_io_vec,
index c3df14ce2cc2c00d232028d1238121ff9c37e35c..9ac17159925819a399dc10413d5261dd67bb5584 100644 (file)
@@ -200,7 +200,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
                      struct extent_buffer **cow_ret, u64 new_root_objectid)
 {
        struct extent_buffer *cow;
-       u32 nritems;
        int ret = 0;
        int level;
        struct btrfs_disk_key disk_key;
@@ -210,7 +209,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
        WARN_ON(root->ref_cows && trans->transid != root->last_trans);
 
        level = btrfs_header_level(buf);
-       nritems = btrfs_header_nritems(buf);
        if (level == 0)
                btrfs_item_key(buf, &disk_key, 0);
        else
@@ -1008,7 +1006,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
        int wret;
        int pslot;
        int orig_slot = path->slots[level];
-       int err_on_enospc = 0;
        u64 orig_ptr;
 
        if (level == 0)
@@ -1071,8 +1068,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
            BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
                return 0;
 
-       if (btrfs_header_nritems(mid) < 2)
-               err_on_enospc = 1;
+       btrfs_header_nritems(mid);
 
        left = read_node_slot(root, parent, pslot - 1);
        if (left) {
@@ -1103,8 +1099,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                wret = push_node_left(trans, root, left, mid, 1);
                if (wret < 0)
                        ret = wret;
-               if (btrfs_header_nritems(mid) < 2)
-                       err_on_enospc = 1;
+               btrfs_header_nritems(mid);
        }
 
        /*
@@ -1224,14 +1219,12 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
        int wret;
        int pslot;
        int orig_slot = path->slots[level];
-       u64 orig_ptr;
 
        if (level == 0)
                return 1;
 
        mid = path->nodes[level];
        WARN_ON(btrfs_header_generation(mid) != trans->transid);
-       orig_ptr = btrfs_node_blockptr(mid, orig_slot);
 
        if (level < BTRFS_MAX_LEVEL - 1)
                parent = path->nodes[level + 1];
@@ -1577,13 +1570,33 @@ read_block_for_search(struct btrfs_trans_handle *trans,
        blocksize = btrfs_level_size(root, level - 1);
 
        tmp = btrfs_find_tree_block(root, blocknr, blocksize);
-       if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
-               /*
-                * we found an up to date block without sleeping, return
-                * right away
-                */
-               *eb_ret = tmp;
-               return 0;
+       if (tmp) {
+               if (btrfs_buffer_uptodate(tmp, 0)) {
+                       if (btrfs_buffer_uptodate(tmp, gen)) {
+                               /*
+                                * we found an up to date block without
+                                * sleeping, return
+                                * right away
+                                */
+                               *eb_ret = tmp;
+                               return 0;
+                       }
+                       /* the pages were up to date, but we failed
+                        * the generation number check.  Do a full
+                        * read for the generation number that is correct.
+                        * We must do this without dropping locks so
+                        * we can trust our generation number
+                        */
+                       free_extent_buffer(tmp);
+                       tmp = read_tree_block(root, blocknr, blocksize, gen);
+                       if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
+                               *eb_ret = tmp;
+                               return 0;
+                       }
+                       free_extent_buffer(tmp);
+                       btrfs_release_path(NULL, p);
+                       return -EIO;
+               }
        }
 
        /*
@@ -1596,8 +1609,7 @@ read_block_for_search(struct btrfs_trans_handle *trans,
        btrfs_unlock_up_safe(p, level + 1);
        btrfs_set_path_blocking(p);
 
-       if (tmp)
-               free_extent_buffer(tmp);
+       free_extent_buffer(tmp);
        if (p->reada)
                reada_for_search(root, p, level, slot, key->objectid);
 
@@ -2548,7 +2560,6 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
 {
        struct btrfs_disk_key disk_key;
        struct extent_buffer *right = path->nodes[0];
-       int slot;
        int i;
        int push_space = 0;
        int push_items = 0;
@@ -2560,8 +2571,6 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
        u32 this_item_size;
        u32 old_left_item_size;
 
-       slot = path->slots[1];
-
        if (empty)
                nr = min(right_nritems, max_slot);
        else
@@ -3330,7 +3339,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
 {
        int ret = 0;
        int slot;
-       int slot_orig;
        struct extent_buffer *leaf;
        struct btrfs_item *item;
        u32 nritems;
@@ -3340,7 +3348,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
        unsigned int size_diff;
        int i;
 
-       slot_orig = path->slots[0];
        leaf = path->nodes[0];
        slot = path->slots[0];
 
@@ -3445,7 +3452,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
 {
        int ret = 0;
        int slot;
-       int slot_orig;
        struct extent_buffer *leaf;
        struct btrfs_item *item;
        u32 nritems;
@@ -3454,7 +3460,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
        unsigned int old_size;
        int i;
 
-       slot_orig = path->slots[0];
        leaf = path->nodes[0];
 
        nritems = btrfs_header_nritems(leaf);
@@ -3787,7 +3792,6 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
                            struct btrfs_key *cpu_key, u32 *data_size,
                            int nr)
 {
-       struct extent_buffer *leaf;
        int ret = 0;
        int slot;
        int i;
@@ -3804,7 +3808,6 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
        if (ret < 0)
                goto out;
 
-       leaf = path->nodes[0];
        slot = path->slots[0];
        BUG_ON(slot < 0);
 
index eaf286abad1754f8cbc244cecd2a35c91c3f1abd..8db9234f6b418db0cc1f99afa6876f369116a1b8 100644 (file)
@@ -99,6 +99,9 @@ struct btrfs_ordered_sum;
  */
 #define BTRFS_EXTENT_CSUM_OBJECTID -10ULL
 
+/* For storing free space cache */
+#define BTRFS_FREE_SPACE_OBJECTID -11ULL
+
 /* dummy objectid represents multiple objectids */
 #define BTRFS_MULTIPLE_OBJECTIDS -255ULL
 
@@ -265,6 +268,22 @@ struct btrfs_chunk {
        /* additional stripes go here */
 } __attribute__ ((__packed__));
 
+#define BTRFS_FREE_SPACE_EXTENT        1
+#define BTRFS_FREE_SPACE_BITMAP        2
+
+struct btrfs_free_space_entry {
+       __le64 offset;
+       __le64 bytes;
+       u8 type;
+} __attribute__ ((__packed__));
+
+struct btrfs_free_space_header {
+       struct btrfs_disk_key location;
+       __le64 generation;
+       __le64 num_entries;
+       __le64 num_bitmaps;
+} __attribute__ ((__packed__));
+
 static inline unsigned long btrfs_chunk_item_size(int num_stripes)
 {
        BUG_ON(num_stripes == 0);
@@ -365,8 +384,10 @@ struct btrfs_super_block {
 
        char label[BTRFS_LABEL_SIZE];
 
+       __le64 cache_generation;
+
        /* future expansion */
-       __le64 reserved[32];
+       __le64 reserved[31];
        u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
 } __attribute__ ((__packed__));
 
@@ -375,13 +396,15 @@ struct btrfs_super_block {
  * ones specified below then we will fail to mount
  */
 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF   (1ULL << 0)
-#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL  (2ULL << 0)
+#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL  (1ULL << 1)
+#define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS    (1ULL << 2)
 
 #define BTRFS_FEATURE_COMPAT_SUPP              0ULL
 #define BTRFS_FEATURE_COMPAT_RO_SUPP           0ULL
-#define BTRFS_FEATURE_INCOMPAT_SUPP            \
-       (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
-        BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)
+#define BTRFS_FEATURE_INCOMPAT_SUPP                    \
+       (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF |         \
+        BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL |        \
+        BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
 
 /*
  * A leaf is full of items. offset and size tell us where to find
@@ -675,7 +698,8 @@ struct btrfs_block_group_item {
 struct btrfs_space_info {
        u64 flags;
 
-       u64 total_bytes;        /* total bytes in the space */
+       u64 total_bytes;        /* total bytes in the space,
+                                  this doesn't take mirrors into account */
        u64 bytes_used;         /* total bytes used,
                                   this does't take mirrors into account */
        u64 bytes_pinned;       /* total bytes pinned, will be freed when the
@@ -687,6 +711,8 @@ struct btrfs_space_info {
        u64 bytes_may_use;      /* number of bytes that may be used for
                                   delalloc/allocations */
        u64 disk_used;          /* total bytes used on disk */
+       u64 disk_total;         /* total bytes on disk, takes mirrors into
+                                  account */
 
        int full;               /* indicates that we cannot allocate any more
                                   chunks for this space */
@@ -750,6 +776,14 @@ enum btrfs_caching_type {
        BTRFS_CACHE_FINISHED    = 2,
 };
 
+enum btrfs_disk_cache_state {
+       BTRFS_DC_WRITTEN        = 0,
+       BTRFS_DC_ERROR          = 1,
+       BTRFS_DC_CLEAR          = 2,
+       BTRFS_DC_SETUP          = 3,
+       BTRFS_DC_NEED_WRITE     = 4,
+};
+
 struct btrfs_caching_control {
        struct list_head list;
        struct mutex mutex;
@@ -763,6 +797,7 @@ struct btrfs_block_group_cache {
        struct btrfs_key key;
        struct btrfs_block_group_item item;
        struct btrfs_fs_info *fs_info;
+       struct inode *inode;
        spinlock_t lock;
        u64 pinned;
        u64 reserved;
@@ -773,8 +808,11 @@ struct btrfs_block_group_cache {
        int extents_thresh;
        int free_extents;
        int total_bitmaps;
-       int ro;
-       int dirty;
+       int ro:1;
+       int dirty:1;
+       int iref:1;
+
+       int disk_cache_state;
 
        /* cache tracking stuff */
        int cached;
@@ -863,6 +901,7 @@ struct btrfs_fs_info {
        struct btrfs_transaction *running_transaction;
        wait_queue_head_t transaction_throttle;
        wait_queue_head_t transaction_wait;
+       wait_queue_head_t transaction_blocked_wait;
        wait_queue_head_t async_submit_wait;
 
        struct btrfs_super_block super_copy;
@@ -949,6 +988,7 @@ struct btrfs_fs_info {
        struct btrfs_workers endio_meta_workers;
        struct btrfs_workers endio_meta_write_workers;
        struct btrfs_workers endio_write_workers;
+       struct btrfs_workers endio_freespace_worker;
        struct btrfs_workers submit_workers;
        /*
         * fixup workers take dirty pages that didn't properly go through
@@ -1192,6 +1232,9 @@ struct btrfs_root {
 #define BTRFS_MOUNT_NOSSD              (1 << 9)
 #define BTRFS_MOUNT_DISCARD            (1 << 10)
 #define BTRFS_MOUNT_FORCE_COMPRESS      (1 << 11)
+#define BTRFS_MOUNT_SPACE_CACHE                (1 << 12)
+#define BTRFS_MOUNT_CLEAR_CACHE                (1 << 13)
+#define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14)
 
 #define btrfs_clear_opt(o, opt)                ((o) &= ~BTRFS_MOUNT_##opt)
 #define btrfs_set_opt(o, opt)          ((o) |= BTRFS_MOUNT_##opt)
@@ -1665,6 +1708,27 @@ static inline void btrfs_set_dir_item_key(struct extent_buffer *eb,
        write_eb_member(eb, item, struct btrfs_dir_item, location, key);
 }
 
+BTRFS_SETGET_FUNCS(free_space_entries, struct btrfs_free_space_header,
+                  num_entries, 64);
+BTRFS_SETGET_FUNCS(free_space_bitmaps, struct btrfs_free_space_header,
+                  num_bitmaps, 64);
+BTRFS_SETGET_FUNCS(free_space_generation, struct btrfs_free_space_header,
+                  generation, 64);
+
+static inline void btrfs_free_space_key(struct extent_buffer *eb,
+                                       struct btrfs_free_space_header *h,
+                                       struct btrfs_disk_key *key)
+{
+       read_eb_member(eb, h, struct btrfs_free_space_header, location, key);
+}
+
+static inline void btrfs_set_free_space_key(struct extent_buffer *eb,
+                                           struct btrfs_free_space_header *h,
+                                           struct btrfs_disk_key *key)
+{
+       write_eb_member(eb, h, struct btrfs_free_space_header, location, key);
+}
+
 /* struct btrfs_disk_key */
 BTRFS_SETGET_STACK_FUNCS(disk_key_objectid, struct btrfs_disk_key,
                         objectid, 64);
@@ -1876,6 +1940,8 @@ BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block,
                         incompat_flags, 64);
 BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block,
                         csum_type, 16);
+BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block,
+                        cache_generation, 64);
 
 static inline int btrfs_super_csum_size(struct btrfs_super_block *s)
 {
@@ -1988,6 +2054,12 @@ static inline struct dentry *fdentry(struct file *file)
        return file->f_path.dentry;
 }
 
+static inline bool btrfs_mixed_space_info(struct btrfs_space_info *space_info)
+{
+       return ((space_info->flags & BTRFS_BLOCK_GROUP_METADATA) &&
+               (space_info->flags & BTRFS_BLOCK_GROUP_DATA));
+}
+
 /* extent-tree.c */
 void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
 int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
@@ -2079,7 +2151,7 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes);
 void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes);
 int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root,
-                               int num_items, int *retries);
+                               int num_items);
 void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root);
 int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans,
@@ -2100,7 +2172,7 @@ void btrfs_add_durable_block_rsv(struct btrfs_fs_info *fs_info,
 int btrfs_block_rsv_add(struct btrfs_trans_handle *trans,
                        struct btrfs_root *root,
                        struct btrfs_block_rsv *block_rsv,
-                       u64 num_bytes, int *retries);
+                       u64 num_bytes);
 int btrfs_block_rsv_check(struct btrfs_trans_handle *trans,
                          struct btrfs_root *root,
                          struct btrfs_block_rsv *block_rsv,
@@ -2115,6 +2187,7 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
                             struct btrfs_block_group_cache *cache);
 int btrfs_set_block_group_rw(struct btrfs_root *root,
                             struct btrfs_block_group_cache *cache);
+void btrfs_put_block_group_cache(struct btrfs_fs_info *info);
 /* ctree.c */
 int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
                     int level, int *slot);
@@ -2373,7 +2446,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
                               u32 min_type);
 
 int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
-int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput);
+int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput,
+                                  int sync);
 int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
                              struct extent_state **cached_state);
 int btrfs_writepages(struct address_space *mapping,
@@ -2426,6 +2500,10 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root);
 int btrfs_prealloc_file_range(struct inode *inode, int mode,
                              u64 start, u64 num_bytes, u64 min_size,
                              loff_t actual_len, u64 *alloc_hint);
+int btrfs_prealloc_file_range_trans(struct inode *inode,
+                                   struct btrfs_trans_handle *trans, int mode,
+                                   u64 start, u64 num_bytes, u64 min_size,
+                                   loff_t actual_len, u64 *alloc_hint);
 extern const struct dentry_operations btrfs_dentry_operations;
 
 /* ioctl.c */
index e9103b3baa49f4309c94eca9e0d7b7069665359c..f0cad5ae5be75679c273583b6c6f535118acc093 100644 (file)
@@ -427,5 +427,5 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
                ret = btrfs_truncate_item(trans, root, path,
                                          item_len - sub_item_len, 1);
        }
-       return 0;
+       return ret;
 }
index 5e789f4a3ed0f0da401526d6a86de10db5c74f67..fb827d0d71811baff7aec0f49a2584f7eedbaf84 100644 (file)
@@ -338,7 +338,6 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
        struct extent_io_tree *tree;
        u64 start = (u64)page->index << PAGE_CACHE_SHIFT;
        u64 found_start;
-       int found_level;
        unsigned long len;
        struct extent_buffer *eb;
        int ret;
@@ -369,8 +368,6 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
                WARN_ON(1);
                goto err;
        }
-       found_level = btrfs_header_level(eb);
-
        csum_tree_block(root, eb, 0);
 err:
        free_extent_buffer(eb);
@@ -481,9 +478,12 @@ static void end_workqueue_bio(struct bio *bio, int err)
        end_io_wq->work.flags = 0;
 
        if (bio->bi_rw & REQ_WRITE) {
-               if (end_io_wq->metadata)
+               if (end_io_wq->metadata == 1)
                        btrfs_queue_worker(&fs_info->endio_meta_write_workers,
                                           &end_io_wq->work);
+               else if (end_io_wq->metadata == 2)
+                       btrfs_queue_worker(&fs_info->endio_freespace_worker,
+                                          &end_io_wq->work);
                else
                        btrfs_queue_worker(&fs_info->endio_write_workers,
                                           &end_io_wq->work);
@@ -497,6 +497,13 @@ static void end_workqueue_bio(struct bio *bio, int err)
        }
 }
 
+/*
+ * For the metadata arg you want
+ *
+ * 0 - if data
+ * 1 - if normal metadta
+ * 2 - if writing to the free space cache area
+ */
 int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio,
                        int metadata)
 {
@@ -533,11 +540,9 @@ int btrfs_congested_async(struct btrfs_fs_info *info, int iodone)
 
 static void run_one_async_start(struct btrfs_work *work)
 {
-       struct btrfs_fs_info *fs_info;
        struct async_submit_bio *async;
 
        async = container_of(work, struct  async_submit_bio, work);
-       fs_info = BTRFS_I(async->inode)->root->fs_info;
        async->submit_bio_start(async->inode, async->rw, async->bio,
                               async->mirror_num, async->bio_flags,
                               async->bio_offset);
@@ -850,12 +855,8 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
                                      u32 blocksize, u64 parent_transid)
 {
        struct extent_buffer *buf = NULL;
-       struct inode *btree_inode = root->fs_info->btree_inode;
-       struct extent_io_tree *io_tree;
        int ret;
 
-       io_tree = &BTRFS_I(btree_inode)->io_tree;
-
        buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
        if (!buf)
                return NULL;
@@ -1377,7 +1378,6 @@ static int bio_ready_for_csum(struct bio *bio)
        u64 start = 0;
        struct page *page;
        struct extent_io_tree *io_tree = NULL;
-       struct btrfs_fs_info *info = NULL;
        struct bio_vec *bvec;
        int i;
        int ret;
@@ -1396,7 +1396,6 @@ static int bio_ready_for_csum(struct bio *bio)
                buf_len = page->private >> 2;
                start = page_offset(page) + bvec->bv_offset;
                io_tree = &BTRFS_I(page->mapping->host)->io_tree;
-               info = BTRFS_I(page->mapping->host)->root->fs_info;
        }
        /* are we fully contained in this bio? */
        if (buf_len <= length)
@@ -1680,12 +1679,12 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 
        init_waitqueue_head(&fs_info->transaction_throttle);
        init_waitqueue_head(&fs_info->transaction_wait);
+       init_waitqueue_head(&fs_info->transaction_blocked_wait);
        init_waitqueue_head(&fs_info->async_submit_wait);
 
        __setup_root(4096, 4096, 4096, 4096, tree_root,
                     fs_info, BTRFS_ROOT_TREE_OBJECTID);
 
-
        bh = btrfs_read_dev_super(fs_devices->latest_bdev);
        if (!bh)
                goto fail_iput;
@@ -1775,6 +1774,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        btrfs_init_workers(&fs_info->endio_write_workers, "endio-write",
                           fs_info->thread_pool_size,
                           &fs_info->generic_worker);
+       btrfs_init_workers(&fs_info->endio_freespace_worker, "freespace-write",
+                          1, &fs_info->generic_worker);
 
        /*
         * endios are largely parallel and should have a very
@@ -1795,6 +1796,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        btrfs_start_workers(&fs_info->endio_meta_workers, 1);
        btrfs_start_workers(&fs_info->endio_meta_write_workers, 1);
        btrfs_start_workers(&fs_info->endio_write_workers, 1);
+       btrfs_start_workers(&fs_info->endio_freespace_worker, 1);
 
        fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
        fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
@@ -1993,6 +1995,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
        if (!(sb->s_flags & MS_RDONLY)) {
                down_read(&fs_info->cleanup_work_sem);
                btrfs_orphan_cleanup(fs_info->fs_root);
+               btrfs_orphan_cleanup(fs_info->tree_root);
                up_read(&fs_info->cleanup_work_sem);
        }
 
@@ -2035,6 +2038,7 @@ fail_sb_buffer:
        btrfs_stop_workers(&fs_info->endio_meta_workers);
        btrfs_stop_workers(&fs_info->endio_meta_write_workers);
        btrfs_stop_workers(&fs_info->endio_write_workers);
+       btrfs_stop_workers(&fs_info->endio_freespace_worker);
        btrfs_stop_workers(&fs_info->submit_workers);
 fail_iput:
        invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
@@ -2410,6 +2414,7 @@ int close_ctree(struct btrfs_root *root)
        fs_info->closing = 1;
        smp_mb();
 
+       btrfs_put_block_group_cache(fs_info);
        if (!(fs_info->sb->s_flags & MS_RDONLY)) {
                ret =  btrfs_commit_super(root);
                if (ret)
@@ -2456,6 +2461,7 @@ int close_ctree(struct btrfs_root *root)
        btrfs_stop_workers(&fs_info->endio_meta_workers);
        btrfs_stop_workers(&fs_info->endio_meta_write_workers);
        btrfs_stop_workers(&fs_info->endio_write_workers);
+       btrfs_stop_workers(&fs_info->endio_freespace_worker);
        btrfs_stop_workers(&fs_info->submit_workers);
 
        btrfs_close_devices(fs_info->fs_devices);
index 0b81ecdb101cc2dfea708a8ad9a6274b84acb81d..0c097f3aec418564e25df5b7e0af8d9a81a79d1d 100644 (file)
@@ -242,6 +242,12 @@ get_caching_control(struct btrfs_block_group_cache *cache)
                return NULL;
        }
 
+       /* We're loading it the fast way, so we don't have a caching_ctl. */
+       if (!cache->caching_ctl) {
+               spin_unlock(&cache->lock);
+               return NULL;
+       }
+
        ctl = cache->caching_ctl;
        atomic_inc(&ctl->count);
        spin_unlock(&cache->lock);
@@ -421,7 +427,9 @@ err:
        return 0;
 }
 
-static int cache_block_group(struct btrfs_block_group_cache *cache)
+static int cache_block_group(struct btrfs_block_group_cache *cache,
+                            struct btrfs_trans_handle *trans,
+                            int load_cache_only)
 {
        struct btrfs_fs_info *fs_info = cache->fs_info;
        struct btrfs_caching_control *caching_ctl;
@@ -432,6 +440,36 @@ static int cache_block_group(struct btrfs_block_group_cache *cache)
        if (cache->cached != BTRFS_CACHE_NO)
                return 0;
 
+       /*
+        * We can't do the read from on-disk cache during a commit since we need
+        * to have the normal tree locking.
+        */
+       if (!trans->transaction->in_commit) {
+               spin_lock(&cache->lock);
+               if (cache->cached != BTRFS_CACHE_NO) {
+                       spin_unlock(&cache->lock);
+                       return 0;
+               }
+               cache->cached = BTRFS_CACHE_STARTED;
+               spin_unlock(&cache->lock);
+
+               ret = load_free_space_cache(fs_info, cache);
+
+               spin_lock(&cache->lock);
+               if (ret == 1) {
+                       cache->cached = BTRFS_CACHE_FINISHED;
+                       cache->last_byte_to_unpin = (u64)-1;
+               } else {
+                       cache->cached = BTRFS_CACHE_NO;
+               }
+               spin_unlock(&cache->lock);
+               if (ret == 1)
+                       return 0;
+       }
+
+       if (load_cache_only)
+               return 0;
+
        caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_KERNEL);
        BUG_ON(!caching_ctl);
 
@@ -509,7 +547,7 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
 
        rcu_read_lock();
        list_for_each_entry_rcu(found, head, list) {
-               if (found->flags == flags) {
+               if (found->flags & flags) {
                        rcu_read_unlock();
                        return found;
                }
@@ -542,6 +580,15 @@ static u64 div_factor(u64 num, int factor)
        return num;
 }
 
+static u64 div_factor_fine(u64 num, int factor)
+{
+       if (factor == 100)
+               return num;
+       num *= factor;
+       do_div(num, 100);
+       return num;
+}
+
 u64 btrfs_find_block_group(struct btrfs_root *root,
                           u64 search_start, u64 search_hint, int owner)
 {
@@ -2687,6 +2734,109 @@ next_block_group(struct btrfs_root *root,
        return cache;
 }
 
+static int cache_save_setup(struct btrfs_block_group_cache *block_group,
+                           struct btrfs_trans_handle *trans,
+                           struct btrfs_path *path)
+{
+       struct btrfs_root *root = block_group->fs_info->tree_root;
+       struct inode *inode = NULL;
+       u64 alloc_hint = 0;
+       int num_pages = 0;
+       int retries = 0;
+       int ret = 0;
+
+       /*
+        * If this block group is smaller than 100 megs don't bother caching the
+        * block group.
+        */
+       if (block_group->key.offset < (100 * 1024 * 1024)) {
+               spin_lock(&block_group->lock);
+               block_group->disk_cache_state = BTRFS_DC_WRITTEN;
+               spin_unlock(&block_group->lock);
+               return 0;
+       }
+
+again:
+       inode = lookup_free_space_inode(root, block_group, path);
+       if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
+               ret = PTR_ERR(inode);
+               btrfs_release_path(root, path);
+               goto out;
+       }
+
+       if (IS_ERR(inode)) {
+               BUG_ON(retries);
+               retries++;
+
+               if (block_group->ro)
+                       goto out_free;
+
+               ret = create_free_space_inode(root, trans, block_group, path);
+               if (ret)
+                       goto out_free;
+               goto again;
+       }
+
+       /*
+        * We want to set the generation to 0, that way if anything goes wrong
+        * from here on out we know not to trust this cache when we load up next
+        * time.
+        */
+       BTRFS_I(inode)->generation = 0;
+       ret = btrfs_update_inode(trans, root, inode);
+       WARN_ON(ret);
+
+       if (i_size_read(inode) > 0) {
+               ret = btrfs_truncate_free_space_cache(root, trans, path,
+                                                     inode);
+               if (ret)
+                       goto out_put;
+       }
+
+       spin_lock(&block_group->lock);
+       if (block_group->cached != BTRFS_CACHE_FINISHED) {
+               spin_unlock(&block_group->lock);
+               goto out_put;
+       }
+       spin_unlock(&block_group->lock);
+
+       num_pages = (int)div64_u64(block_group->key.offset, 1024 * 1024 * 1024);
+       if (!num_pages)
+               num_pages = 1;
+
+       /*
+        * Just to make absolutely sure we have enough space, we're going to
+        * preallocate 12 pages worth of space for each block group.  In
+        * practice we ought to use at most 8, but we need extra space so we can
+        * add our header and have a terminator between the extents and the
+        * bitmaps.
+        */
+       num_pages *= 16;
+       num_pages *= PAGE_CACHE_SIZE;
+
+       ret = btrfs_check_data_free_space(inode, num_pages);
+       if (ret)
+               goto out_put;
+
+       ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages,
+                                             num_pages, num_pages,
+                                             &alloc_hint);
+       btrfs_free_reserved_data_space(inode, num_pages);
+out_put:
+       iput(inode);
+out_free:
+       btrfs_release_path(root, path);
+out:
+       spin_lock(&block_group->lock);
+       if (ret)
+               block_group->disk_cache_state = BTRFS_DC_ERROR;
+       else
+               block_group->disk_cache_state = BTRFS_DC_SETUP;
+       spin_unlock(&block_group->lock);
+
+       return ret;
+}
+
 int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root)
 {
@@ -2699,6 +2849,25 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
        if (!path)
                return -ENOMEM;
 
+again:
+       while (1) {
+               cache = btrfs_lookup_first_block_group(root->fs_info, last);
+               while (cache) {
+                       if (cache->disk_cache_state == BTRFS_DC_CLEAR)
+                               break;
+                       cache = next_block_group(root, cache);
+               }
+               if (!cache) {
+                       if (last == 0)
+                               break;
+                       last = 0;
+                       continue;
+               }
+               err = cache_save_setup(cache, trans, path);
+               last = cache->key.objectid + cache->key.offset;
+               btrfs_put_block_group(cache);
+       }
+
        while (1) {
                if (last == 0) {
                        err = btrfs_run_delayed_refs(trans, root,
@@ -2708,6 +2877,11 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
 
                cache = btrfs_lookup_first_block_group(root->fs_info, last);
                while (cache) {
+                       if (cache->disk_cache_state == BTRFS_DC_CLEAR) {
+                               btrfs_put_block_group(cache);
+                               goto again;
+                       }
+
                        if (cache->dirty)
                                break;
                        cache = next_block_group(root, cache);
@@ -2719,6 +2893,8 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
                        continue;
                }
 
+               if (cache->disk_cache_state == BTRFS_DC_SETUP)
+                       cache->disk_cache_state = BTRFS_DC_NEED_WRITE;
                cache->dirty = 0;
                last = cache->key.objectid + cache->key.offset;
 
@@ -2727,6 +2903,52 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
                btrfs_put_block_group(cache);
        }
 
+       while (1) {
+               /*
+                * I don't think this is needed since we're just marking our
+                * preallocated extent as written, but just in case it can't
+                * hurt.
+                */
+               if (last == 0) {
+                       err = btrfs_run_delayed_refs(trans, root,
+                                                    (unsigned long)-1);
+                       BUG_ON(err);
+               }
+
+               cache = btrfs_lookup_first_block_group(root->fs_info, last);
+               while (cache) {
+                       /*
+                        * Really this shouldn't happen, but it could if we
+                        * couldn't write the entire preallocated extent and
+                        * splitting the extent resulted in a new block.
+                        */
+                       if (cache->dirty) {
+                               btrfs_put_block_group(cache);
+                               goto again;
+                       }
+                       if (cache->disk_cache_state == BTRFS_DC_NEED_WRITE)
+                               break;
+                       cache = next_block_group(root, cache);
+               }
+               if (!cache) {
+                       if (last == 0)
+                               break;
+                       last = 0;
+                       continue;
+               }
+
+               btrfs_write_out_cache(root, trans, cache, path);
+
+               /*
+                * If we didn't have an error then the cache state is still
+                * NEED_WRITE, so we can set it to WRITTEN.
+                */
+               if (cache->disk_cache_state == BTRFS_DC_NEED_WRITE)
+                       cache->disk_cache_state = BTRFS_DC_WRITTEN;
+               last = cache->key.objectid + cache->key.offset;
+               btrfs_put_block_group(cache);
+       }
+
        btrfs_free_path(path);
        return 0;
 }
@@ -2762,6 +2984,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
        if (found) {
                spin_lock(&found->lock);
                found->total_bytes += total_bytes;
+               found->disk_total += total_bytes * factor;
                found->bytes_used += bytes_used;
                found->disk_used += bytes_used * factor;
                found->full = 0;
@@ -2781,6 +3004,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
                                BTRFS_BLOCK_GROUP_SYSTEM |
                                BTRFS_BLOCK_GROUP_METADATA);
        found->total_bytes = total_bytes;
+       found->disk_total = total_bytes * factor;
        found->bytes_used = bytes_used;
        found->disk_used = bytes_used * factor;
        found->bytes_pinned = 0;
@@ -2882,11 +3106,16 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes)
        struct btrfs_space_info *data_sinfo;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        u64 used;
-       int ret = 0, committed = 0;
+       int ret = 0, committed = 0, alloc_chunk = 1;
 
        /* make sure bytes are sectorsize aligned */
        bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
 
+       if (root == root->fs_info->tree_root) {
+               alloc_chunk = 0;
+               committed = 1;
+       }
+
        data_sinfo = BTRFS_I(inode)->space_info;
        if (!data_sinfo)
                goto alloc;
@@ -2905,7 +3134,7 @@ again:
                 * if we don't have enough free bytes in this space then we need
                 * to alloc a new chunk.
                 */
-               if (!data_sinfo->full) {
+               if (!data_sinfo->full && alloc_chunk) {
                        u64 alloc_target;
 
                        data_sinfo->force_alloc = 1;
@@ -2997,10 +3226,11 @@ static void force_metadata_allocation(struct btrfs_fs_info *info)
        rcu_read_unlock();
 }
 
-static int should_alloc_chunk(struct btrfs_space_info *sinfo,
-                             u64 alloc_bytes)
+static int should_alloc_chunk(struct btrfs_root *root,
+                             struct btrfs_space_info *sinfo, u64 alloc_bytes)
 {
        u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly;
+       u64 thresh;
 
        if (sinfo->bytes_used + sinfo->bytes_reserved +
            alloc_bytes + 256 * 1024 * 1024 < num_bytes)
@@ -3010,6 +3240,12 @@ static int should_alloc_chunk(struct btrfs_space_info *sinfo,
            alloc_bytes < div_factor(num_bytes, 8))
                return 0;
 
+       thresh = btrfs_super_total_bytes(&root->fs_info->super_copy);
+       thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 5));
+
+       if (num_bytes > thresh && sinfo->bytes_used < div_factor(num_bytes, 3))
+               return 0;
+
        return 1;
 }
 
@@ -3041,12 +3277,20 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
                goto out;
        }
 
-       if (!force && !should_alloc_chunk(space_info, alloc_bytes)) {
+       if (!force && !should_alloc_chunk(extent_root, space_info,
+                                         alloc_bytes)) {
                spin_unlock(&space_info->lock);
                goto out;
        }
        spin_unlock(&space_info->lock);
 
+       /*
+        * If we have mixed data/metadata chunks we want to make sure we keep
+        * allocating mixed chunks instead of individual chunks.
+        */
+       if (btrfs_mixed_space_info(space_info))
+               flags |= (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA);
+
        /*
         * if we're doing a data chunk, go ahead and make sure that
         * we keep a reasonable number of metadata chunks allocated in the
@@ -3072,55 +3316,25 @@ out:
        return ret;
 }
 
-static int maybe_allocate_chunk(struct btrfs_trans_handle *trans,
-                               struct btrfs_root *root,
-                               struct btrfs_space_info *sinfo, u64 num_bytes)
-{
-       int ret;
-       int end_trans = 0;
-
-       if (sinfo->full)
-               return 0;
-
-       spin_lock(&sinfo->lock);
-       ret = should_alloc_chunk(sinfo, num_bytes + 2 * 1024 * 1024);
-       spin_unlock(&sinfo->lock);
-       if (!ret)
-               return 0;
-
-       if (!trans) {
-               trans = btrfs_join_transaction(root, 1);
-               BUG_ON(IS_ERR(trans));
-               end_trans = 1;
-       }
-
-       ret = do_chunk_alloc(trans, root->fs_info->extent_root,
-                            num_bytes + 2 * 1024 * 1024,
-                            get_alloc_profile(root, sinfo->flags), 0);
-
-       if (end_trans)
-               btrfs_end_transaction(trans, root);
-
-       return ret == 1 ? 1 : 0;
-}
-
 /*
  * shrink metadata reservation for delalloc
  */
 static int shrink_delalloc(struct btrfs_trans_handle *trans,
-                          struct btrfs_root *root, u64 to_reclaim)
+                          struct btrfs_root *root, u64 to_reclaim, int sync)
 {
        struct btrfs_block_rsv *block_rsv;
+       struct btrfs_space_info *space_info;
        u64 reserved;
        u64 max_reclaim;
        u64 reclaimed = 0;
        int pause = 1;
-       int ret;
+       int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT;
 
        block_rsv = &root->fs_info->delalloc_block_rsv;
-       spin_lock(&block_rsv->lock);
-       reserved = block_rsv->reserved;
-       spin_unlock(&block_rsv->lock);
+       space_info = block_rsv->space_info;
+
+       smp_mb();
+       reserved = space_info->bytes_reserved;
 
        if (reserved == 0)
                return 0;
@@ -3128,104 +3342,169 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
        max_reclaim = min(reserved, to_reclaim);
 
        while (1) {
-               ret = btrfs_start_one_delalloc_inode(root, trans ? 1 : 0);
-               if (!ret) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(pause);
-                       pause <<= 1;
-                       if (pause > HZ / 10)
-                               pause = HZ / 10;
-               } else {
-                       pause = 1;
-               }
+               /* have the flusher threads jump in and do some IO */
+               smp_mb();
+               nr_pages = min_t(unsigned long, nr_pages,
+                      root->fs_info->delalloc_bytes >> PAGE_CACHE_SHIFT);
+               writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages);
 
-               spin_lock(&block_rsv->lock);
-               if (reserved > block_rsv->reserved)
-                       reclaimed = reserved - block_rsv->reserved;
-               reserved = block_rsv->reserved;
-               spin_unlock(&block_rsv->lock);
+               spin_lock(&space_info->lock);
+               if (reserved > space_info->bytes_reserved)
+                       reclaimed += reserved - space_info->bytes_reserved;
+               reserved = space_info->bytes_reserved;
+               spin_unlock(&space_info->lock);
 
                if (reserved == 0 || reclaimed >= max_reclaim)
                        break;
 
                if (trans && trans->transaction->blocked)
                        return -EAGAIN;
+
+               __set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(pause);
+               pause <<= 1;
+               if (pause > HZ / 10)
+                       pause = HZ / 10;
+
        }
        return reclaimed >= to_reclaim;
 }
 
-static int should_retry_reserve(struct btrfs_trans_handle *trans,
-                               struct btrfs_root *root,
-                               struct btrfs_block_rsv *block_rsv,
-                               u64 num_bytes, int *retries)
+/*
+ * Retries tells us how many times we've called reserve_metadata_bytes.  The
+ * idea is if this is the first call (retries == 0) then we will add to our
+ * reserved count if we can't make the allocation in order to hold our place
+ * while we go and try and free up space.  That way for retries > 1 we don't try
+ * and add space, we just check to see if the amount of unused space is >= the
+ * total space, meaning that our reservation is valid.
+ *
+ * However if we don't intend to retry this reservation, pass -1 as retries so
+ * that it short circuits this logic.
+ */
+static int reserve_metadata_bytes(struct btrfs_trans_handle *trans,
+                                 struct btrfs_root *root,
+                                 struct btrfs_block_rsv *block_rsv,
+                                 u64 orig_bytes, int flush)
 {
        struct btrfs_space_info *space_info = block_rsv->space_info;
-       int ret;
+       u64 unused;
+       u64 num_bytes = orig_bytes;
+       int retries = 0;
+       int ret = 0;
+       bool reserved = false;
+       bool committed = false;
 
-       if ((*retries) > 2)
-               return -ENOSPC;
+again:
+       ret = -ENOSPC;
+       if (reserved)
+               num_bytes = 0;
 
-       ret = maybe_allocate_chunk(trans, root, space_info, num_bytes);
-       if (ret)
-               return 1;
+       spin_lock(&space_info->lock);
+       unused = space_info->bytes_used + space_info->bytes_reserved +
+                space_info->bytes_pinned + space_info->bytes_readonly +
+                space_info->bytes_may_use;
 
-       if (trans && trans->transaction->in_commit)
-               return -ENOSPC;
+       /*
+        * The idea here is that we've not already over-reserved the block group
+        * then we can go ahead and save our reservation first and then start
+        * flushing if we need to.  Otherwise if we've already overcommitted
+        * lets start flushing stuff first and then come back and try to make
+        * our reservation.
+        */
+       if (unused <= space_info->total_bytes) {
+               unused -= space_info->total_bytes;
+               if (unused >= num_bytes) {
+                       if (!reserved)
+                               space_info->bytes_reserved += orig_bytes;
+                       ret = 0;
+               } else {
+                       /*
+                        * Ok set num_bytes to orig_bytes since we aren't
+                        * overocmmitted, this way we only try and reclaim what
+                        * we need.
+                        */
+                       num_bytes = orig_bytes;
+               }
+       } else {
+               /*
+                * Ok we're over committed, set num_bytes to the overcommitted
+                * amount plus the amount of bytes that we need for this
+                * reservation.
+                */
+               num_bytes = unused - space_info->total_bytes +
+                       (orig_bytes * (retries + 1));
+       }
 
-       ret = shrink_delalloc(trans, root, num_bytes);
-       if (ret)
-               return ret;
+       /*
+        * Couldn't make our reservation, save our place so while we're trying
+        * to reclaim space we can actually use it instead of somebody else
+        * stealing it from us.
+        */
+       if (ret && !reserved) {
+               space_info->bytes_reserved += orig_bytes;
+               reserved = true;
+       }
 
-       spin_lock(&space_info->lock);
-       if (space_info->bytes_pinned < num_bytes)
-               ret = 1;
        spin_unlock(&space_info->lock);
-       if (ret)
-               return -ENOSPC;
-
-       (*retries)++;
 
-       if (trans)
-               return -EAGAIN;
+       if (!ret)
+               return 0;
 
-       trans = btrfs_join_transaction(root, 1);
-       BUG_ON(IS_ERR(trans));
-       ret = btrfs_commit_transaction(trans, root);
-       BUG_ON(ret);
+       if (!flush)
+               goto out;
 
-       return 1;
-}
+       /*
+        * We do synchronous shrinking since we don't actually unreserve
+        * metadata until after the IO is completed.
+        */
+       ret = shrink_delalloc(trans, root, num_bytes, 1);
+       if (ret > 0)
+               return 0;
+       else if (ret < 0)
+               goto out;
 
-static int reserve_metadata_bytes(struct btrfs_block_rsv *block_rsv,
-                                 u64 num_bytes)
-{
-       struct btrfs_space_info *space_info = block_rsv->space_info;
-       u64 unused;
-       int ret = -ENOSPC;
+       /*
+        * So if we were overcommitted it's possible that somebody else flushed
+        * out enough space and we simply didn't have enough space to reclaim,
+        * so go back around and try again.
+        */
+       if (retries < 2) {
+               retries++;
+               goto again;
+       }
 
        spin_lock(&space_info->lock);
-       unused = space_info->bytes_used + space_info->bytes_reserved +
-                space_info->bytes_pinned + space_info->bytes_readonly;
+       /*
+        * Not enough space to be reclaimed, don't bother committing the
+        * transaction.
+        */
+       if (space_info->bytes_pinned < orig_bytes)
+               ret = -ENOSPC;
+       spin_unlock(&space_info->lock);
+       if (ret)
+               goto out;
 
-       if (unused < space_info->total_bytes)
-               unused = space_info->total_bytes - unused;
-       else
-               unused = 0;
+       ret = -EAGAIN;
+       if (trans || committed)
+               goto out;
 
-       if (unused >= num_bytes) {
-               if (block_rsv->priority >= 10) {
-                       space_info->bytes_reserved += num_bytes;
-                       ret = 0;
-               } else {
-                       if ((unused + block_rsv->reserved) *
-                           block_rsv->priority >=
-                           (num_bytes + block_rsv->reserved) * 10) {
-                               space_info->bytes_reserved += num_bytes;
-                               ret = 0;
-                       }
-               }
+       ret = -ENOSPC;
+       trans = btrfs_join_transaction(root, 1);
+       if (IS_ERR(trans))
+               goto out;
+       ret = btrfs_commit_transaction(trans, root);
+       if (!ret) {
+               trans = NULL;
+               committed = true;
+               goto again;
+       }
+
+out:
+       if (reserved) {
+               spin_lock(&space_info->lock);
+               space_info->bytes_reserved -= orig_bytes;
+               spin_unlock(&space_info->lock);
        }
-       spin_unlock(&space_info->lock);
 
        return ret;
 }
@@ -3327,18 +3606,14 @@ struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root)
 {
        struct btrfs_block_rsv *block_rsv;
        struct btrfs_fs_info *fs_info = root->fs_info;
-       u64 alloc_target;
 
        block_rsv = kmalloc(sizeof(*block_rsv), GFP_NOFS);
        if (!block_rsv)
                return NULL;
 
        btrfs_init_block_rsv(block_rsv);
-
-       alloc_target = btrfs_get_alloc_profile(root, 0);
        block_rsv->space_info = __find_space_info(fs_info,
                                                  BTRFS_BLOCK_GROUP_METADATA);
-
        return block_rsv;
 }
 
@@ -3369,23 +3644,19 @@ void btrfs_add_durable_block_rsv(struct btrfs_fs_info *fs_info,
 int btrfs_block_rsv_add(struct btrfs_trans_handle *trans,
                        struct btrfs_root *root,
                        struct btrfs_block_rsv *block_rsv,
-                       u64 num_bytes, int *retries)
+                       u64 num_bytes)
 {
        int ret;
 
        if (num_bytes == 0)
                return 0;
-again:
-       ret = reserve_metadata_bytes(block_rsv, num_bytes);
+
+       ret = reserve_metadata_bytes(trans, root, block_rsv, num_bytes, 1);
        if (!ret) {
                block_rsv_add_bytes(block_rsv, num_bytes, 1);
                return 0;
        }
 
-       ret = should_retry_reserve(trans, root, block_rsv, num_bytes, retries);
-       if (ret > 0)
-               goto again;
-
        return ret;
 }
 
@@ -3420,7 +3691,8 @@ int btrfs_block_rsv_check(struct btrfs_trans_handle *trans,
                return 0;
 
        if (block_rsv->refill_used) {
-               ret = reserve_metadata_bytes(block_rsv, num_bytes);
+               ret = reserve_metadata_bytes(trans, root, block_rsv,
+                                            num_bytes, 0);
                if (!ret) {
                        block_rsv_add_bytes(block_rsv, num_bytes, 0);
                        return 0;
@@ -3499,6 +3771,8 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info)
 
        sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
        spin_lock(&sinfo->lock);
+       if (sinfo->flags & BTRFS_BLOCK_GROUP_DATA)
+               data_used = 0;
        meta_used = sinfo->bytes_used;
        spin_unlock(&sinfo->lock);
 
@@ -3526,7 +3800,8 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
        block_rsv->size = num_bytes;
 
        num_bytes = sinfo->bytes_used + sinfo->bytes_pinned +
-                   sinfo->bytes_reserved + sinfo->bytes_readonly;
+                   sinfo->bytes_reserved + sinfo->bytes_readonly +
+                   sinfo->bytes_may_use;
 
        if (sinfo->total_bytes > num_bytes) {
                num_bytes = sinfo->total_bytes - num_bytes;
@@ -3597,7 +3872,7 @@ static u64 calc_trans_metadata_size(struct btrfs_root *root, int num_items)
 
 int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
                                 struct btrfs_root *root,
-                                int num_items, int *retries)
+                                int num_items)
 {
        u64 num_bytes;
        int ret;
@@ -3607,7 +3882,7 @@ int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
 
        num_bytes = calc_trans_metadata_size(root, num_items);
        ret = btrfs_block_rsv_add(trans, root, &root->fs_info->trans_block_rsv,
-                                 num_bytes, retries);
+                                 num_bytes);
        if (!ret) {
                trans->bytes_reserved += num_bytes;
                trans->block_rsv = &root->fs_info->trans_block_rsv;
@@ -3681,14 +3956,13 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
        struct btrfs_block_rsv *block_rsv = &root->fs_info->delalloc_block_rsv;
        u64 to_reserve;
        int nr_extents;
-       int retries = 0;
        int ret;
 
        if (btrfs_transaction_in_commit(root->fs_info))
                schedule_timeout(1);
 
        num_bytes = ALIGN(num_bytes, root->sectorsize);
-again:
+
        spin_lock(&BTRFS_I(inode)->accounting_lock);
        nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents) + 1;
        if (nr_extents > BTRFS_I(inode)->reserved_extents) {
@@ -3698,18 +3972,14 @@ again:
                nr_extents = 0;
                to_reserve = 0;
        }
+       spin_unlock(&BTRFS_I(inode)->accounting_lock);
 
        to_reserve += calc_csum_metadata_size(inode, num_bytes);
-       ret = reserve_metadata_bytes(block_rsv, to_reserve);
-       if (ret) {
-               spin_unlock(&BTRFS_I(inode)->accounting_lock);
-               ret = should_retry_reserve(NULL, root, block_rsv, to_reserve,
-                                          &retries);
-               if (ret > 0)
-                       goto again;
+       ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1);
+       if (ret)
                return ret;
-       }
 
+       spin_lock(&BTRFS_I(inode)->accounting_lock);
        BTRFS_I(inode)->reserved_extents += nr_extents;
        atomic_inc(&BTRFS_I(inode)->outstanding_extents);
        spin_unlock(&BTRFS_I(inode)->accounting_lock);
@@ -3717,7 +3987,7 @@ again:
        block_rsv_add_bytes(block_rsv, to_reserve, 1);
 
        if (block_rsv->size > 512 * 1024 * 1024)
-               shrink_delalloc(NULL, root, to_reserve);
+               shrink_delalloc(NULL, root, to_reserve, 0);
 
        return 0;
 }
@@ -3776,12 +4046,12 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                              struct btrfs_root *root,
                              u64 bytenr, u64 num_bytes, int alloc)
 {
-       struct btrfs_block_group_cache *cache;
+       struct btrfs_block_group_cache *cache = NULL;
        struct btrfs_fs_info *info = root->fs_info;
-       int factor;
        u64 total = num_bytes;
        u64 old_val;
        u64 byte_in_group;
+       int factor;
 
        /* block accounting for super block */
        spin_lock(&info->delalloc_lock);
@@ -3803,11 +4073,25 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                        factor = 2;
                else
                        factor = 1;
+               /*
+                * If this block group has free space cache written out, we
+                * need to make sure to load it if we are removing space.  This
+                * is because we need the unpinning stage to actually add the
+                * space back to the block group, otherwise we will leak space.
+                */
+               if (!alloc && cache->cached == BTRFS_CACHE_NO)
+                       cache_block_group(cache, trans, 1);
+
                byte_in_group = bytenr - cache->key.objectid;
                WARN_ON(byte_in_group > cache->key.offset);
 
                spin_lock(&cache->space_info->lock);
                spin_lock(&cache->lock);
+
+               if (btrfs_super_cache_generation(&info->super_copy) != 0 &&
+                   cache->disk_cache_state < BTRFS_DC_CLEAR)
+                       cache->disk_cache_state = BTRFS_DC_CLEAR;
+
                cache->dirty = 1;
                old_val = btrfs_block_group_used(&cache->item);
                num_bytes = min(total, cache->key.offset - byte_in_group);
@@ -4554,6 +4838,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
        bool found_uncached_bg = false;
        bool failed_cluster_refill = false;
        bool failed_alloc = false;
+       bool use_cluster = true;
        u64 ideal_cache_percent = 0;
        u64 ideal_cache_offset = 0;
 
@@ -4568,16 +4853,24 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
                return -ENOSPC;
        }
 
+       /*
+        * If the space info is for both data and metadata it means we have a
+        * small filesystem and we can't use the clustering stuff.
+        */
+       if (btrfs_mixed_space_info(space_info))
+               use_cluster = false;
+
        if (orig_root->ref_cows || empty_size)
                allowed_chunk_alloc = 1;
 
-       if (data & BTRFS_BLOCK_GROUP_METADATA) {
+       if (data & BTRFS_BLOCK_GROUP_METADATA && use_cluster) {
                last_ptr = &root->fs_info->meta_alloc_cluster;
                if (!btrfs_test_opt(root, SSD))
                        empty_cluster = 64 * 1024;
        }
 
-       if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) {
+       if ((data & BTRFS_BLOCK_GROUP_DATA) && use_cluster &&
+           btrfs_test_opt(root, SSD)) {
                last_ptr = &root->fs_info->data_alloc_cluster;
        }
 
@@ -4641,6 +4934,10 @@ have_block_group:
                if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
                        u64 free_percent;
 
+                       ret = cache_block_group(block_group, trans, 1);
+                       if (block_group->cached == BTRFS_CACHE_FINISHED)
+                               goto have_block_group;
+
                        free_percent = btrfs_block_group_used(&block_group->item);
                        free_percent *= 100;
                        free_percent = div64_u64(free_percent,
@@ -4661,7 +4958,7 @@ have_block_group:
                        if (loop > LOOP_CACHING_NOWAIT ||
                            (loop > LOOP_FIND_IDEAL &&
                             atomic_read(&space_info->caching_threads) < 2)) {
-                               ret = cache_block_group(block_group);
+                               ret = cache_block_group(block_group, trans, 0);
                                BUG_ON(ret);
                        }
                        found_uncached_bg = true;
@@ -5218,7 +5515,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
        u64 num_bytes = ins->offset;
 
        block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid);
-       cache_block_group(block_group);
+       cache_block_group(block_group, trans, 0);
        caching_ctl = get_caching_control(block_group);
 
        if (!caching_ctl) {
@@ -5308,7 +5605,8 @@ use_block_rsv(struct btrfs_trans_handle *trans,
        block_rsv = get_block_rsv(trans, root);
 
        if (block_rsv->size == 0) {
-               ret = reserve_metadata_bytes(block_rsv, blocksize);
+               ret = reserve_metadata_bytes(trans, root, block_rsv,
+                                            blocksize, 0);
                if (ret)
                        return ERR_PTR(ret);
                return block_rsv;
@@ -5318,11 +5616,6 @@ use_block_rsv(struct btrfs_trans_handle *trans,
        if (!ret)
                return block_rsv;
 
-       WARN_ON(1);
-       printk(KERN_INFO"block_rsv size %llu reserved %llu freed %llu %llu\n",
-               block_rsv->size, block_rsv->reserved,
-               block_rsv->freed[0], block_rsv->freed[1]);
-
        return ERR_PTR(-ENOSPC);
 }
 
@@ -5421,7 +5714,6 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
        u64 generation;
        u64 refs;
        u64 flags;
-       u64 last = 0;
        u32 nritems;
        u32 blocksize;
        struct btrfs_key key;
@@ -5489,7 +5781,6 @@ reada:
                                           generation);
                if (ret)
                        break;
-               last = bytenr + blocksize;
                nread++;
        }
        wc->reada_slot = slot;
@@ -7813,6 +8104,40 @@ out:
        return ret;
 }
 
+void btrfs_put_block_group_cache(struct btrfs_fs_info *info)
+{
+       struct btrfs_block_group_cache *block_group;
+       u64 last = 0;
+
+       while (1) {
+               struct inode *inode;
+
+               block_group = btrfs_lookup_first_block_group(info, last);
+               while (block_group) {
+                       spin_lock(&block_group->lock);
+                       if (block_group->iref)
+                               break;
+                       spin_unlock(&block_group->lock);
+                       block_group = next_block_group(info->tree_root,
+                                                      block_group);
+               }
+               if (!block_group) {
+                       if (last == 0)
+                               break;
+                       last = 0;
+                       continue;
+               }
+
+               inode = block_group->inode;
+               block_group->iref = 0;
+               block_group->inode = NULL;
+               spin_unlock(&block_group->lock);
+               iput(inode);
+               last = block_group->key.objectid + block_group->key.offset;
+               btrfs_put_block_group(block_group);
+       }
+}
+
 int btrfs_free_block_groups(struct btrfs_fs_info *info)
 {
        struct btrfs_block_group_cache *block_group;
@@ -7896,6 +8221,8 @@ int btrfs_read_block_groups(struct btrfs_root *root)
        struct btrfs_key key;
        struct btrfs_key found_key;
        struct extent_buffer *leaf;
+       int need_clear = 0;
+       u64 cache_gen;
 
        root = info->extent_root;
        key.objectid = 0;
@@ -7905,6 +8232,15 @@ int btrfs_read_block_groups(struct btrfs_root *root)
        if (!path)
                return -ENOMEM;
 
+       cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy);
+       if (cache_gen != 0 &&
+           btrfs_super_generation(&root->fs_info->super_copy) != cache_gen)
+               need_clear = 1;
+       if (btrfs_test_opt(root, CLEAR_CACHE))
+               need_clear = 1;
+       if (!btrfs_test_opt(root, SPACE_CACHE) && cache_gen)
+               printk(KERN_INFO "btrfs: disk space caching is enabled\n");
+
        while (1) {
                ret = find_first_block_group(root, path, &key);
                if (ret > 0)
@@ -7927,6 +8263,9 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                INIT_LIST_HEAD(&cache->list);
                INIT_LIST_HEAD(&cache->cluster_list);
 
+               if (need_clear)
+                       cache->disk_cache_state = BTRFS_DC_CLEAR;
+
                /*
                 * we only want to have 32k of ram per block group for keeping
                 * track of free space, and if we pass 1/2 of that we want to
@@ -8031,6 +8370,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
        cache->key.offset = size;
        cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
        cache->sectorsize = root->sectorsize;
+       cache->fs_info = root->fs_info;
 
        /*
         * we only want to have 32k of ram per block group for keeping track
@@ -8087,8 +8427,11 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
        struct btrfs_path *path;
        struct btrfs_block_group_cache *block_group;
        struct btrfs_free_cluster *cluster;
+       struct btrfs_root *tree_root = root->fs_info->tree_root;
        struct btrfs_key key;
+       struct inode *inode;
        int ret;
+       int factor;
 
        root = root->fs_info->extent_root;
 
@@ -8097,6 +8440,12 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
        BUG_ON(!block_group->ro);
 
        memcpy(&key, &block_group->key, sizeof(key));
+       if (block_group->flags & (BTRFS_BLOCK_GROUP_DUP |
+                                 BTRFS_BLOCK_GROUP_RAID1 |
+                                 BTRFS_BLOCK_GROUP_RAID10))
+               factor = 2;
+       else
+               factor = 1;
 
        /* make sure this block group isn't part of an allocation cluster */
        cluster = &root->fs_info->data_alloc_cluster;
@@ -8116,6 +8465,40 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
        path = btrfs_alloc_path();
        BUG_ON(!path);
 
+       inode = lookup_free_space_inode(root, block_group, path);
+       if (!IS_ERR(inode)) {
+               btrfs_orphan_add(trans, inode);
+               clear_nlink(inode);
+               /* One for the block groups ref */
+               spin_lock(&block_group->lock);
+               if (block_group->iref) {
+                       block_group->iref = 0;
+                       block_group->inode = NULL;
+                       spin_unlock(&block_group->lock);
+                       iput(inode);
+               } else {
+                       spin_unlock(&block_group->lock);
+               }
+               /* One for our lookup ref */
+               iput(inode);
+       }
+
+       key.objectid = BTRFS_FREE_SPACE_OBJECTID;
+       key.offset = block_group->key.objectid;
+       key.type = 0;
+
+       ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
+       if (ret < 0)
+               goto out;
+       if (ret > 0)
+               btrfs_release_path(tree_root, path);
+       if (ret == 0) {
+               ret = btrfs_del_item(trans, tree_root, path);
+               if (ret)
+                       goto out;
+               btrfs_release_path(tree_root, path);
+       }
+
        spin_lock(&root->fs_info->block_group_cache_lock);
        rb_erase(&block_group->cache_node,
                 &root->fs_info->block_group_cache_tree);
@@ -8137,8 +8520,11 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
        spin_lock(&block_group->space_info->lock);
        block_group->space_info->total_bytes -= block_group->key.offset;
        block_group->space_info->bytes_readonly -= block_group->key.offset;
+       block_group->space_info->disk_total -= block_group->key.offset * factor;
        spin_unlock(&block_group->space_info->lock);
 
+       memcpy(&key, &block_group->key, sizeof(key));
+
        btrfs_clear_space_info_full(root->fs_info);
 
        btrfs_put_block_group(block_group);
index d74e6af9b53a598a26bf83357f1bed61d2103ef2..eac10e3260a982e24149957981c3f2a7be792d09 100644 (file)
@@ -104,7 +104,7 @@ void extent_io_tree_init(struct extent_io_tree *tree,
                          struct address_space *mapping, gfp_t mask)
 {
        tree->state = RB_ROOT;
-       tree->buffer = RB_ROOT;
+       INIT_RADIX_TREE(&tree->buffer, GFP_ATOMIC);
        tree->ops = NULL;
        tree->dirty_bytes = 0;
        spin_lock_init(&tree->lock);
@@ -235,50 +235,6 @@ static inline struct rb_node *tree_search(struct extent_io_tree *tree,
        return ret;
 }
 
-static struct extent_buffer *buffer_tree_insert(struct extent_io_tree *tree,
-                                         u64 offset, struct rb_node *node)
-{
-       struct rb_root *root = &tree->buffer;
-       struct rb_node **p = &root->rb_node;
-       struct rb_node *parent = NULL;
-       struct extent_buffer *eb;
-
-       while (*p) {
-               parent = *p;
-               eb = rb_entry(parent, struct extent_buffer, rb_node);
-
-               if (offset < eb->start)
-                       p = &(*p)->rb_left;
-               else if (offset > eb->start)
-                       p = &(*p)->rb_right;
-               else
-                       return eb;
-       }
-
-       rb_link_node(node, parent, p);
-       rb_insert_color(node, root);
-       return NULL;
-}
-
-static struct extent_buffer *buffer_search(struct extent_io_tree *tree,
-                                          u64 offset)
-{
-       struct rb_root *root = &tree->buffer;
-       struct rb_node *n = root->rb_node;
-       struct extent_buffer *eb;
-
-       while (n) {
-               eb = rb_entry(n, struct extent_buffer, rb_node);
-               if (offset < eb->start)
-                       n = n->rb_left;
-               else if (offset > eb->start)
-                       n = n->rb_right;
-               else
-                       return eb;
-       }
-       return NULL;
-}
-
 static void merge_cb(struct extent_io_tree *tree, struct extent_state *new,
                     struct extent_state *other)
 {
@@ -1901,10 +1857,8 @@ static int submit_one_bio(int rw, struct bio *bio, int mirror_num,
        struct page *page = bvec->bv_page;
        struct extent_io_tree *tree = bio->bi_private;
        u64 start;
-       u64 end;
 
        start = ((u64)page->index << PAGE_CACHE_SHIFT) + bvec->bv_offset;
-       end = start + bvec->bv_len - 1;
 
        bio->bi_private = NULL;
 
@@ -2204,7 +2158,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
        u64 last_byte = i_size_read(inode);
        u64 block_start;
        u64 iosize;
-       u64 unlock_start;
        sector_t sector;
        struct extent_state *cached_state = NULL;
        struct extent_map *em;
@@ -2329,7 +2282,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
                if (tree->ops && tree->ops->writepage_end_io_hook)
                        tree->ops->writepage_end_io_hook(page, start,
                                                         page_end, NULL, 1);
-               unlock_start = page_end + 1;
                goto done;
        }
 
@@ -2340,7 +2292,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
                        if (tree->ops && tree->ops->writepage_end_io_hook)
                                tree->ops->writepage_end_io_hook(page, cur,
                                                         page_end, NULL, 1);
-                       unlock_start = page_end + 1;
                        break;
                }
                em = epd->get_extent(inode, page, pg_offset, cur,
@@ -2387,7 +2338,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
 
                        cur += iosize;
                        pg_offset += iosize;
-                       unlock_start = cur;
                        continue;
                }
                /* leave this out until we have a page_mkwrite call */
@@ -2473,7 +2423,6 @@ static int extent_write_cache_pages(struct extent_io_tree *tree,
        pgoff_t index;
        pgoff_t end;            /* Inclusive */
        int scanned = 0;
-       int range_whole = 0;
 
        pagevec_init(&pvec, 0);
        if (wbc->range_cyclic) {
@@ -2482,8 +2431,6 @@ static int extent_write_cache_pages(struct extent_io_tree *tree,
        } else {
                index = wbc->range_start >> PAGE_CACHE_SHIFT;
                end = wbc->range_end >> PAGE_CACHE_SHIFT;
-               if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
-                       range_whole = 1;
                scanned = 1;
        }
 retry:
@@ -2823,6 +2770,8 @@ int extent_prepare_write(struct extent_io_tree *tree,
                                         NULL, 1,
                                         end_bio_extent_preparewrite, 0,
                                         0, 0);
+                       if (ret && !err)
+                               err = ret;
                        iocount++;
                        block_start = block_start + iosize;
                } else {
@@ -3104,6 +3053,39 @@ static void __free_extent_buffer(struct extent_buffer *eb)
        kmem_cache_free(extent_buffer_cache, eb);
 }
 
+/*
+ * Helper for releasing extent buffer page.
+ */
+static void btrfs_release_extent_buffer_page(struct extent_buffer *eb,
+                                               unsigned long start_idx)
+{
+       unsigned long index;
+       struct page *page;
+
+       if (!eb->first_page)
+               return;
+
+       index = num_extent_pages(eb->start, eb->len);
+       if (start_idx >= index)
+               return;
+
+       do {
+               index--;
+               page = extent_buffer_page(eb, index);
+               if (page)
+                       page_cache_release(page);
+       } while (index != start_idx);
+}
+
+/*
+ * Helper for releasing the extent buffer.
+ */
+static inline void btrfs_release_extent_buffer(struct extent_buffer *eb)
+{
+       btrfs_release_extent_buffer_page(eb, 0);
+       __free_extent_buffer(eb);
+}
+
 struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
                                          u64 start, unsigned long len,
                                          struct page *page0,
@@ -3117,16 +3099,16 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
        struct page *p;
        struct address_space *mapping = tree->mapping;
        int uptodate = 1;
+       int ret;
 
-       spin_lock(&tree->buffer_lock);
-       eb = buffer_search(tree, start);
-       if (eb) {
-               atomic_inc(&eb->refs);
-               spin_unlock(&tree->buffer_lock);
+       rcu_read_lock();
+       eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
+       if (eb && atomic_inc_not_zero(&eb->refs)) {
+               rcu_read_unlock();
                mark_page_accessed(eb->first_page);
                return eb;
        }
-       spin_unlock(&tree->buffer_lock);
+       rcu_read_unlock();
 
        eb = __alloc_extent_buffer(tree, start, len, mask);
        if (!eb)
@@ -3165,26 +3147,31 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
        if (uptodate)
                set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
 
+       ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
+       if (ret)
+               goto free_eb;
+
        spin_lock(&tree->buffer_lock);
-       exists = buffer_tree_insert(tree, start, &eb->rb_node);
-       if (exists) {
+       ret = radix_tree_insert(&tree->buffer, start >> PAGE_CACHE_SHIFT, eb);
+       if (ret == -EEXIST) {
+               exists = radix_tree_lookup(&tree->buffer,
+                                               start >> PAGE_CACHE_SHIFT);
                /* add one reference for the caller */
                atomic_inc(&exists->refs);
                spin_unlock(&tree->buffer_lock);
+               radix_tree_preload_end();
                goto free_eb;
        }
        /* add one reference for the tree */
        atomic_inc(&eb->refs);
        spin_unlock(&tree->buffer_lock);
+       radix_tree_preload_end();
        return eb;
 
 free_eb:
        if (!atomic_dec_and_test(&eb->refs))
                return exists;
-       for (index = 1; index < i; index++)
-               page_cache_release(extent_buffer_page(eb, index));
-       page_cache_release(extent_buffer_page(eb, 0));
-       __free_extent_buffer(eb);
+       btrfs_release_extent_buffer(eb);
        return exists;
 }
 
@@ -3194,16 +3181,16 @@ struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
 {
        struct extent_buffer *eb;
 
-       spin_lock(&tree->buffer_lock);
-       eb = buffer_search(tree, start);
-       if (eb)
-               atomic_inc(&eb->refs);
-       spin_unlock(&tree->buffer_lock);
-
-       if (eb)
+       rcu_read_lock();
+       eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
+       if (eb && atomic_inc_not_zero(&eb->refs)) {
+               rcu_read_unlock();
                mark_page_accessed(eb->first_page);
+               return eb;
+       }
+       rcu_read_unlock();
 
-       return eb;
+       return NULL;
 }
 
 void free_extent_buffer(struct extent_buffer *eb)
@@ -3833,34 +3820,45 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
        }
 }
 
+static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head)
+{
+       struct extent_buffer *eb =
+                       container_of(head, struct extent_buffer, rcu_head);
+
+       btrfs_release_extent_buffer(eb);
+}
+
 int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page)
 {
        u64 start = page_offset(page);
        struct extent_buffer *eb;
        int ret = 1;
-       unsigned long i;
-       unsigned long num_pages;
 
        spin_lock(&tree->buffer_lock);
-       eb = buffer_search(tree, start);
+       eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT);
        if (!eb)
                goto out;
 
-       if (atomic_read(&eb->refs) > 1) {
+       if (test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
                ret = 0;
                goto out;
        }
-       if (test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
+
+       /*
+        * set @eb->refs to 0 if it is already 1, and then release the @eb.
+        * Or go back.
+        */
+       if (atomic_cmpxchg(&eb->refs, 1, 0) != 1) {
                ret = 0;
                goto out;
        }
-       /* at this point we can safely release the extent buffer */
-       num_pages = num_extent_pages(eb->start, eb->len);
-       for (i = 0; i < num_pages; i++)
-               page_cache_release(extent_buffer_page(eb, i));
-       rb_erase(&eb->rb_node, &tree->buffer);
-       __free_extent_buffer(eb);
+
+       radix_tree_delete(&tree->buffer, start >> PAGE_CACHE_SHIFT);
 out:
        spin_unlock(&tree->buffer_lock);
+
+       /* at this point we can safely release the extent buffer */
+       if (atomic_read(&eb->refs) == 0)
+               call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu);
        return ret;
 }
index 5691c7b590dae86844ccbeccecdb5d8a2b3e2554..1c6d4f342ef7e8089ac6f17e3e6ed40e83722e45 100644 (file)
@@ -85,7 +85,7 @@ struct extent_io_ops {
 
 struct extent_io_tree {
        struct rb_root state;
-       struct rb_root buffer;
+       struct radix_tree_root buffer;
        struct address_space *mapping;
        u64 dirty_bytes;
        spinlock_t lock;
@@ -123,7 +123,7 @@ struct extent_buffer {
        unsigned long bflags;
        atomic_t refs;
        struct list_head leak_list;
-       struct rb_node rb_node;
+       struct rcu_head rcu_head;
 
        /* the spinlock is used to protect most operations */
        spinlock_t lock;
index 454ca52d6451b649b78b48cba908f3fd1eb2bada..23cb8da3ff6633dd83ba0b4cb435e8f742ad0632 100644 (file)
@@ -335,7 +335,7 @@ struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree,
                goto out;
        }
        if (IS_ERR(rb_node)) {
-               em = ERR_PTR(PTR_ERR(rb_node));
+               em = ERR_CAST(rb_node);
                goto out;
        }
        em = rb_entry(rb_node, struct extent_map, rb_node);
@@ -384,7 +384,7 @@ struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
                goto out;
        }
        if (IS_ERR(rb_node)) {
-               em = ERR_PTR(PTR_ERR(rb_node));
+               em = ERR_CAST(rb_node);
                goto out;
        }
        em = rb_entry(rb_node, struct extent_map, rb_node);
index f488fac04d99ea45eea93607bbf17c021b5b2207..22ee0dc2e6b8a712900c68a8c44df4a453fb86f0 100644 (file)
 #include "ctree.h"
 #include "free-space-cache.h"
 #include "transaction.h"
+#include "disk-io.h"
 
 #define BITS_PER_BITMAP                (PAGE_CACHE_SIZE * 8)
 #define MAX_CACHE_BYTES_PER_GIG        (32 * 1024)
 
+static void recalculate_thresholds(struct btrfs_block_group_cache
+                                  *block_group);
+static int link_free_space(struct btrfs_block_group_cache *block_group,
+                          struct btrfs_free_space *info);
+
+struct inode *lookup_free_space_inode(struct btrfs_root *root,
+                                     struct btrfs_block_group_cache
+                                     *block_group, struct btrfs_path *path)
+{
+       struct btrfs_key key;
+       struct btrfs_key location;
+       struct btrfs_disk_key disk_key;
+       struct btrfs_free_space_header *header;
+       struct extent_buffer *leaf;
+       struct inode *inode = NULL;
+       int ret;
+
+       spin_lock(&block_group->lock);
+       if (block_group->inode)
+               inode = igrab(block_group->inode);
+       spin_unlock(&block_group->lock);
+       if (inode)
+               return inode;
+
+       key.objectid = BTRFS_FREE_SPACE_OBJECTID;
+       key.offset = block_group->key.objectid;
+       key.type = 0;
+
+       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       if (ret < 0)
+               return ERR_PTR(ret);
+       if (ret > 0) {
+               btrfs_release_path(root, path);
+               return ERR_PTR(-ENOENT);
+       }
+
+       leaf = path->nodes[0];
+       header = btrfs_item_ptr(leaf, path->slots[0],
+                               struct btrfs_free_space_header);
+       btrfs_free_space_key(leaf, header, &disk_key);
+       btrfs_disk_key_to_cpu(&location, &disk_key);
+       btrfs_release_path(root, path);
+
+       inode = btrfs_iget(root->fs_info->sb, &location, root, NULL);
+       if (!inode)
+               return ERR_PTR(-ENOENT);
+       if (IS_ERR(inode))
+               return inode;
+       if (is_bad_inode(inode)) {
+               iput(inode);
+               return ERR_PTR(-ENOENT);
+       }
+
+       spin_lock(&block_group->lock);
+       if (!root->fs_info->closing) {
+               block_group->inode = igrab(inode);
+               block_group->iref = 1;
+       }
+       spin_unlock(&block_group->lock);
+
+       return inode;
+}
+
+int create_free_space_inode(struct btrfs_root *root,
+                           struct btrfs_trans_handle *trans,
+                           struct btrfs_block_group_cache *block_group,
+                           struct btrfs_path *path)
+{
+       struct btrfs_key key;
+       struct btrfs_disk_key disk_key;
+       struct btrfs_free_space_header *header;
+       struct btrfs_inode_item *inode_item;
+       struct extent_buffer *leaf;
+       u64 objectid;
+       int ret;
+
+       ret = btrfs_find_free_objectid(trans, root, 0, &objectid);
+       if (ret < 0)
+               return ret;
+
+       ret = btrfs_insert_empty_inode(trans, root, path, objectid);
+       if (ret)
+               return ret;
+
+       leaf = path->nodes[0];
+       inode_item = btrfs_item_ptr(leaf, path->slots[0],
+                                   struct btrfs_inode_item);
+       btrfs_item_key(leaf, &disk_key, path->slots[0]);
+       memset_extent_buffer(leaf, 0, (unsigned long)inode_item,
+                            sizeof(*inode_item));
+       btrfs_set_inode_generation(leaf, inode_item, trans->transid);
+       btrfs_set_inode_size(leaf, inode_item, 0);
+       btrfs_set_inode_nbytes(leaf, inode_item, 0);
+       btrfs_set_inode_uid(leaf, inode_item, 0);
+       btrfs_set_inode_gid(leaf, inode_item, 0);
+       btrfs_set_inode_mode(leaf, inode_item, S_IFREG | 0600);
+       btrfs_set_inode_flags(leaf, inode_item, BTRFS_INODE_NOCOMPRESS |
+                             BTRFS_INODE_PREALLOC | BTRFS_INODE_NODATASUM);
+       btrfs_set_inode_nlink(leaf, inode_item, 1);
+       btrfs_set_inode_transid(leaf, inode_item, trans->transid);
+       btrfs_set_inode_block_group(leaf, inode_item,
+                                   block_group->key.objectid);
+       btrfs_mark_buffer_dirty(leaf);
+       btrfs_release_path(root, path);
+
+       key.objectid = BTRFS_FREE_SPACE_OBJECTID;
+       key.offset = block_group->key.objectid;
+       key.type = 0;
+
+       ret = btrfs_insert_empty_item(trans, root, path, &key,
+                                     sizeof(struct btrfs_free_space_header));
+       if (ret < 0) {
+               btrfs_release_path(root, path);
+               return ret;
+       }
+       leaf = path->nodes[0];
+       header = btrfs_item_ptr(leaf, path->slots[0],
+                               struct btrfs_free_space_header);
+       memset_extent_buffer(leaf, 0, (unsigned long)header, sizeof(*header));
+       btrfs_set_free_space_key(leaf, header, &disk_key);
+       btrfs_mark_buffer_dirty(leaf);
+       btrfs_release_path(root, path);
+
+       return 0;
+}
+
+int btrfs_truncate_free_space_cache(struct btrfs_root *root,
+                                   struct btrfs_trans_handle *trans,
+                                   struct btrfs_path *path,
+                                   struct inode *inode)
+{
+       loff_t oldsize;
+       int ret = 0;
+
+       trans->block_rsv = root->orphan_block_rsv;
+       ret = btrfs_block_rsv_check(trans, root,
+                                   root->orphan_block_rsv,
+                                   0, 5);
+       if (ret)
+               return ret;
+
+       oldsize = i_size_read(inode);
+       btrfs_i_size_write(inode, 0);
+       truncate_pagecache(inode, oldsize, 0);
+
+       /*
+        * We don't need an orphan item because truncating the free space cache
+        * will never be split across transactions.
+        */
+       ret = btrfs_truncate_inode_items(trans, root, inode,
+                                        0, BTRFS_EXTENT_DATA_KEY);
+       if (ret) {
+               WARN_ON(1);
+               return ret;
+       }
+
+       return btrfs_update_inode(trans, root, inode);
+}
+
+static int readahead_cache(struct inode *inode)
+{
+       struct file_ra_state *ra;
+       unsigned long last_index;
+
+       ra = kzalloc(sizeof(*ra), GFP_NOFS);
+       if (!ra)
+               return -ENOMEM;
+
+       file_ra_state_init(ra, inode->i_mapping);
+       last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
+
+       page_cache_sync_readahead(inode->i_mapping, ra, NULL, 0, last_index);
+
+       kfree(ra);
+
+       return 0;
+}
+
+int load_free_space_cache(struct btrfs_fs_info *fs_info,
+                         struct btrfs_block_group_cache *block_group)
+{
+       struct btrfs_root *root = fs_info->tree_root;
+       struct inode *inode;
+       struct btrfs_free_space_header *header;
+       struct extent_buffer *leaf;
+       struct page *page;
+       struct btrfs_path *path;
+       u32 *checksums = NULL, *crc;
+       char *disk_crcs = NULL;
+       struct btrfs_key key;
+       struct list_head bitmaps;
+       u64 num_entries;
+       u64 num_bitmaps;
+       u64 generation;
+       u32 cur_crc = ~(u32)0;
+       pgoff_t index = 0;
+       unsigned long first_page_offset;
+       int num_checksums;
+       int ret = 0;
+
+       /*
+        * If we're unmounting then just return, since this does a search on the
+        * normal root and not the commit root and we could deadlock.
+        */
+       smp_mb();
+       if (fs_info->closing)
+               return 0;
+
+       /*
+        * If this block group has been marked to be cleared for one reason or
+        * another then we can't trust the on disk cache, so just return.
+        */
+       spin_lock(&block_group->lock);
+       if (block_group->disk_cache_state != BTRFS_DC_WRITTEN) {
+               spin_unlock(&block_group->lock);
+               return 0;
+       }
+       spin_unlock(&block_group->lock);
+
+       INIT_LIST_HEAD(&bitmaps);
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return 0;
+
+       inode = lookup_free_space_inode(root, block_group, path);
+       if (IS_ERR(inode)) {
+               btrfs_free_path(path);
+               return 0;
+       }
+
+       /* Nothing in the space cache, goodbye */
+       if (!i_size_read(inode)) {
+               btrfs_free_path(path);
+               goto out;
+       }
+
+       key.objectid = BTRFS_FREE_SPACE_OBJECTID;
+       key.offset = block_group->key.objectid;
+       key.type = 0;
+
+       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       if (ret) {
+               btrfs_free_path(path);
+               goto out;
+       }
+
+       leaf = path->nodes[0];
+       header = btrfs_item_ptr(leaf, path->slots[0],
+                               struct btrfs_free_space_header);
+       num_entries = btrfs_free_space_entries(leaf, header);
+       num_bitmaps = btrfs_free_space_bitmaps(leaf, header);
+       generation = btrfs_free_space_generation(leaf, header);
+       btrfs_free_path(path);
+
+       if (BTRFS_I(inode)->generation != generation) {
+               printk(KERN_ERR "btrfs: free space inode generation (%llu) did"
+                      " not match free space cache generation (%llu) for "
+                      "block group %llu\n",
+                      (unsigned long long)BTRFS_I(inode)->generation,
+                      (unsigned long long)generation,
+                      (unsigned long long)block_group->key.objectid);
+               goto out;
+       }
+
+       if (!num_entries)
+               goto out;
+
+       /* Setup everything for doing checksumming */
+       num_checksums = i_size_read(inode) / PAGE_CACHE_SIZE;
+       checksums = crc = kzalloc(sizeof(u32) * num_checksums, GFP_NOFS);
+       if (!checksums)
+               goto out;
+       first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64);
+       disk_crcs = kzalloc(first_page_offset, GFP_NOFS);
+       if (!disk_crcs)
+               goto out;
+
+       ret = readahead_cache(inode);
+       if (ret) {
+               ret = 0;
+               goto out;
+       }
+
+       while (1) {
+               struct btrfs_free_space_entry *entry;
+               struct btrfs_free_space *e;
+               void *addr;
+               unsigned long offset = 0;
+               unsigned long start_offset = 0;
+               int need_loop = 0;
+
+               if (!num_entries && !num_bitmaps)
+                       break;
+
+               if (index == 0) {
+                       start_offset = first_page_offset;
+                       offset = start_offset;
+               }
+
+               page = grab_cache_page(inode->i_mapping, index);
+               if (!page) {
+                       ret = 0;
+                       goto free_cache;
+               }
+
+               if (!PageUptodate(page)) {
+                       btrfs_readpage(NULL, page);
+                       lock_page(page);
+                       if (!PageUptodate(page)) {
+                               unlock_page(page);
+                               page_cache_release(page);
+                               printk(KERN_ERR "btrfs: error reading free "
+                                      "space cache: %llu\n",
+                                      (unsigned long long)
+                                      block_group->key.objectid);
+                               goto free_cache;
+                       }
+               }
+               addr = kmap(page);
+
+               if (index == 0) {
+                       u64 *gen;
+
+                       memcpy(disk_crcs, addr, first_page_offset);
+                       gen = addr + (sizeof(u32) * num_checksums);
+                       if (*gen != BTRFS_I(inode)->generation) {
+                               printk(KERN_ERR "btrfs: space cache generation"
+                                      " (%llu) does not match inode (%llu) "
+                                      "for block group %llu\n",
+                                      (unsigned long long)*gen,
+                                      (unsigned long long)
+                                      BTRFS_I(inode)->generation,
+                                      (unsigned long long)
+                                      block_group->key.objectid);
+                               kunmap(page);
+                               unlock_page(page);
+                               page_cache_release(page);
+                               goto free_cache;
+                       }
+                       crc = (u32 *)disk_crcs;
+               }
+               entry = addr + start_offset;
+
+               /* First lets check our crc before we do anything fun */
+               cur_crc = ~(u32)0;
+               cur_crc = btrfs_csum_data(root, addr + start_offset, cur_crc,
+                                         PAGE_CACHE_SIZE - start_offset);
+               btrfs_csum_final(cur_crc, (char *)&cur_crc);
+               if (cur_crc != *crc) {
+                       printk(KERN_ERR "btrfs: crc mismatch for page %lu in "
+                              "block group %llu\n", index,
+                              (unsigned long long)block_group->key.objectid);
+                       kunmap(page);
+                       unlock_page(page);
+                       page_cache_release(page);
+                       goto free_cache;
+               }
+               crc++;
+
+               while (1) {
+                       if (!num_entries)
+                               break;
+
+                       need_loop = 1;
+                       e = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS);
+                       if (!e) {
+                               kunmap(page);
+                               unlock_page(page);
+                               page_cache_release(page);
+                               goto free_cache;
+                       }
+
+                       e->offset = le64_to_cpu(entry->offset);
+                       e->bytes = le64_to_cpu(entry->bytes);
+                       if (!e->bytes) {
+                               kunmap(page);
+                               kfree(e);
+                               unlock_page(page);
+                               page_cache_release(page);
+                               goto free_cache;
+                       }
+
+                       if (entry->type == BTRFS_FREE_SPACE_EXTENT) {
+                               spin_lock(&block_group->tree_lock);
+                               ret = link_free_space(block_group, e);
+                               spin_unlock(&block_group->tree_lock);
+                               BUG_ON(ret);
+                       } else {
+                               e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS);
+                               if (!e->bitmap) {
+                                       kunmap(page);
+                                       kfree(e);
+                                       unlock_page(page);
+                                       page_cache_release(page);
+                                       goto free_cache;
+                               }
+                               spin_lock(&block_group->tree_lock);
+                               ret = link_free_space(block_group, e);
+                               block_group->total_bitmaps++;
+                               recalculate_thresholds(block_group);
+                               spin_unlock(&block_group->tree_lock);
+                               list_add_tail(&e->list, &bitmaps);
+                       }
+
+                       num_entries--;
+                       offset += sizeof(struct btrfs_free_space_entry);
+                       if (offset + sizeof(struct btrfs_free_space_entry) >=
+                           PAGE_CACHE_SIZE)
+                               break;
+                       entry++;
+               }
+
+               /*
+                * We read an entry out of this page, we need to move on to the
+                * next page.
+                */
+               if (need_loop) {
+                       kunmap(page);
+                       goto next;
+               }
+
+               /*
+                * We add the bitmaps at the end of the entries in order that
+                * the bitmap entries are added to the cache.
+                */
+               e = list_entry(bitmaps.next, struct btrfs_free_space, list);
+               list_del_init(&e->list);
+               memcpy(e->bitmap, addr, PAGE_CACHE_SIZE);
+               kunmap(page);
+               num_bitmaps--;
+next:
+               unlock_page(page);
+               page_cache_release(page);
+               index++;
+       }
+
+       ret = 1;
+out:
+       kfree(checksums);
+       kfree(disk_crcs);
+       iput(inode);
+       return ret;
+
+free_cache:
+       /* This cache is bogus, make sure it gets cleared */
+       spin_lock(&block_group->lock);
+       block_group->disk_cache_state = BTRFS_DC_CLEAR;
+       spin_unlock(&block_group->lock);
+       btrfs_remove_free_space_cache(block_group);
+       goto out;
+}
+
+int btrfs_write_out_cache(struct btrfs_root *root,
+                         struct btrfs_trans_handle *trans,
+                         struct btrfs_block_group_cache *block_group,
+                         struct btrfs_path *path)
+{
+       struct btrfs_free_space_header *header;
+       struct extent_buffer *leaf;
+       struct inode *inode;
+       struct rb_node *node;
+       struct list_head *pos, *n;
+       struct page *page;
+       struct extent_state *cached_state = NULL;
+       struct list_head bitmap_list;
+       struct btrfs_key key;
+       u64 bytes = 0;
+       u32 *crc, *checksums;
+       pgoff_t index = 0, last_index = 0;
+       unsigned long first_page_offset;
+       int num_checksums;
+       int entries = 0;
+       int bitmaps = 0;
+       int ret = 0;
+
+       root = root->fs_info->tree_root;
+
+       INIT_LIST_HEAD(&bitmap_list);
+
+       spin_lock(&block_group->lock);
+       if (block_group->disk_cache_state < BTRFS_DC_SETUP) {
+               spin_unlock(&block_group->lock);
+               return 0;
+       }
+       spin_unlock(&block_group->lock);
+
+       inode = lookup_free_space_inode(root, block_group, path);
+       if (IS_ERR(inode))
+               return 0;
+
+       if (!i_size_read(inode)) {
+               iput(inode);
+               return 0;
+       }
+
+       last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
+       filemap_write_and_wait(inode->i_mapping);
+       btrfs_wait_ordered_range(inode, inode->i_size &
+                                ~(root->sectorsize - 1), (u64)-1);
+
+       /* We need a checksum per page. */
+       num_checksums = i_size_read(inode) / PAGE_CACHE_SIZE;
+       crc = checksums  = kzalloc(sizeof(u32) * num_checksums, GFP_NOFS);
+       if (!crc) {
+               iput(inode);
+               return 0;
+       }
+
+       /* Since the first page has all of our checksums and our generation we
+        * need to calculate the offset into the page that we can start writing
+        * our entries.
+        */
+       first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64);
+
+       node = rb_first(&block_group->free_space_offset);
+       if (!node)
+               goto out_free;
+
+       /*
+        * Lock all pages first so we can lock the extent safely.
+        *
+        * NOTE: Because we hold the ref the entire time we're going to write to
+        * the page find_get_page should never fail, so we don't do a check
+        * after find_get_page at this point.  Just putting this here so people
+        * know and don't freak out.
+        */
+       while (index <= last_index) {
+               page = grab_cache_page(inode->i_mapping, index);
+               if (!page) {
+                       pgoff_t i = 0;
+
+                       while (i < index) {
+                               page = find_get_page(inode->i_mapping, i);
+                               unlock_page(page);
+                               page_cache_release(page);
+                               page_cache_release(page);
+                               i++;
+                       }
+                       goto out_free;
+               }
+               index++;
+       }
+
+       index = 0;
+       lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1,
+                        0, &cached_state, GFP_NOFS);
+
+       /* Write out the extent entries */
+       do {
+               struct btrfs_free_space_entry *entry;
+               void *addr;
+               unsigned long offset = 0;
+               unsigned long start_offset = 0;
+
+               if (index == 0) {
+                       start_offset = first_page_offset;
+                       offset = start_offset;
+               }
+
+               page = find_get_page(inode->i_mapping, index);
+
+               addr = kmap(page);
+               entry = addr + start_offset;
+
+               memset(addr, 0, PAGE_CACHE_SIZE);
+               while (1) {
+                       struct btrfs_free_space *e;
+
+                       e = rb_entry(node, struct btrfs_free_space, offset_index);
+                       entries++;
+
+                       entry->offset = cpu_to_le64(e->offset);
+                       entry->bytes = cpu_to_le64(e->bytes);
+                       if (e->bitmap) {
+                               entry->type = BTRFS_FREE_SPACE_BITMAP;
+                               list_add_tail(&e->list, &bitmap_list);
+                               bitmaps++;
+                       } else {
+                               entry->type = BTRFS_FREE_SPACE_EXTENT;
+                       }
+                       node = rb_next(node);
+                       if (!node)
+                               break;
+                       offset += sizeof(struct btrfs_free_space_entry);
+                       if (offset + sizeof(struct btrfs_free_space_entry) >=
+                           PAGE_CACHE_SIZE)
+                               break;
+                       entry++;
+               }
+               *crc = ~(u32)0;
+               *crc = btrfs_csum_data(root, addr + start_offset, *crc,
+                                      PAGE_CACHE_SIZE - start_offset);
+               kunmap(page);
+
+               btrfs_csum_final(*crc, (char *)crc);
+               crc++;
+
+               bytes += PAGE_CACHE_SIZE;
+
+               ClearPageChecked(page);
+               set_page_extent_mapped(page);
+               SetPageUptodate(page);
+               set_page_dirty(page);
+
+               /*
+                * We need to release our reference we got for grab_cache_page,
+                * except for the first page which will hold our checksums, we
+                * do that below.
+                */
+               if (index != 0) {
+                       unlock_page(page);
+                       page_cache_release(page);
+               }
+
+               page_cache_release(page);
+
+               index++;
+       } while (node);
+
+       /* Write out the bitmaps */
+       list_for_each_safe(pos, n, &bitmap_list) {
+               void *addr;
+               struct btrfs_free_space *entry =
+                       list_entry(pos, struct btrfs_free_space, list);
+
+               page = find_get_page(inode->i_mapping, index);
+
+               addr = kmap(page);
+               memcpy(addr, entry->bitmap, PAGE_CACHE_SIZE);
+               *crc = ~(u32)0;
+               *crc = btrfs_csum_data(root, addr, *crc, PAGE_CACHE_SIZE);
+               kunmap(page);
+               btrfs_csum_final(*crc, (char *)crc);
+               crc++;
+               bytes += PAGE_CACHE_SIZE;
+
+               ClearPageChecked(page);
+               set_page_extent_mapped(page);
+               SetPageUptodate(page);
+               set_page_dirty(page);
+               unlock_page(page);
+               page_cache_release(page);
+               page_cache_release(page);
+               list_del_init(&entry->list);
+               index++;
+       }
+
+       /* Zero out the rest of the pages just to make sure */
+       while (index <= last_index) {
+               void *addr;
+
+               page = find_get_page(inode->i_mapping, index);
+
+               addr = kmap(page);
+               memset(addr, 0, PAGE_CACHE_SIZE);
+               kunmap(page);
+               ClearPageChecked(page);
+               set_page_extent_mapped(page);
+               SetPageUptodate(page);
+               set_page_dirty(page);
+               unlock_page(page);
+               page_cache_release(page);
+               page_cache_release(page);
+               bytes += PAGE_CACHE_SIZE;
+               index++;
+       }
+
+       btrfs_set_extent_delalloc(inode, 0, bytes - 1, &cached_state);
+
+       /* Write the checksums and trans id to the first page */
+       {
+               void *addr;
+               u64 *gen;
+
+               page = find_get_page(inode->i_mapping, 0);
+
+               addr = kmap(page);
+               memcpy(addr, checksums, sizeof(u32) * num_checksums);
+               gen = addr + (sizeof(u32) * num_checksums);
+               *gen = trans->transid;
+               kunmap(page);
+               ClearPageChecked(page);
+               set_page_extent_mapped(page);
+               SetPageUptodate(page);
+               set_page_dirty(page);
+               unlock_page(page);
+               page_cache_release(page);
+               page_cache_release(page);
+       }
+       BTRFS_I(inode)->generation = trans->transid;
+
+       unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
+                            i_size_read(inode) - 1, &cached_state, GFP_NOFS);
+
+       filemap_write_and_wait(inode->i_mapping);
+
+       key.objectid = BTRFS_FREE_SPACE_OBJECTID;
+       key.offset = block_group->key.objectid;
+       key.type = 0;
+
+       ret = btrfs_search_slot(trans, root, &key, path, 1, 1);
+       if (ret < 0) {
+               ret = 0;
+               clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, bytes - 1,
+                                EXTENT_DIRTY | EXTENT_DELALLOC |
+                                EXTENT_DO_ACCOUNTING, 0, 0, NULL, GFP_NOFS);
+               goto out_free;
+       }
+       leaf = path->nodes[0];
+       if (ret > 0) {
+               struct btrfs_key found_key;
+               BUG_ON(!path->slots[0]);
+               path->slots[0]--;
+               btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
+               if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID ||
+                   found_key.offset != block_group->key.objectid) {
+                       ret = 0;
+                       clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, bytes - 1,
+                                        EXTENT_DIRTY | EXTENT_DELALLOC |
+                                        EXTENT_DO_ACCOUNTING, 0, 0, NULL,
+                                        GFP_NOFS);
+                       btrfs_release_path(root, path);
+                       goto out_free;
+               }
+       }
+       header = btrfs_item_ptr(leaf, path->slots[0],
+                               struct btrfs_free_space_header);
+       btrfs_set_free_space_entries(leaf, header, entries);
+       btrfs_set_free_space_bitmaps(leaf, header, bitmaps);
+       btrfs_set_free_space_generation(leaf, header, trans->transid);
+       btrfs_mark_buffer_dirty(leaf);
+       btrfs_release_path(root, path);
+
+       ret = 1;
+
+out_free:
+       if (ret == 0) {
+               invalidate_inode_pages2_range(inode->i_mapping, 0, index);
+               spin_lock(&block_group->lock);
+               block_group->disk_cache_state = BTRFS_DC_ERROR;
+               spin_unlock(&block_group->lock);
+               BTRFS_I(inode)->generation = 0;
+       }
+       kfree(checksums);
+       btrfs_update_inode(trans, root, inode);
+       iput(inode);
+       return ret;
+}
+
 static inline unsigned long offset_to_bit(u64 bitmap_start, u64 sectorsize,
                                          u64 offset)
 {
index 890a8e79011b2cadc6adc545909289ed90707a27..e49ca5c321b571e5886c557e76d131441f1acc87 100644 (file)
@@ -27,6 +27,24 @@ struct btrfs_free_space {
        struct list_head list;
 };
 
+struct inode *lookup_free_space_inode(struct btrfs_root *root,
+                                     struct btrfs_block_group_cache
+                                     *block_group, struct btrfs_path *path);
+int create_free_space_inode(struct btrfs_root *root,
+                           struct btrfs_trans_handle *trans,
+                           struct btrfs_block_group_cache *block_group,
+                           struct btrfs_path *path);
+
+int btrfs_truncate_free_space_cache(struct btrfs_root *root,
+                                   struct btrfs_trans_handle *trans,
+                                   struct btrfs_path *path,
+                                   struct inode *inode);
+int load_free_space_cache(struct btrfs_fs_info *fs_info,
+                         struct btrfs_block_group_cache *block_group);
+int btrfs_write_out_cache(struct btrfs_root *root,
+                         struct btrfs_trans_handle *trans,
+                         struct btrfs_block_group_cache *block_group,
+                         struct btrfs_path *path);
 int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
                         u64 bytenr, u64 size);
 int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
index 64f99cf69ce0c6b2da2cb62c4884fa44c150bdda..558cac2dfa547032637bd0a746153eba46d73f8d 100644 (file)
@@ -319,8 +319,6 @@ static noinline int compress_file_range(struct inode *inode,
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_trans_handle *trans;
        u64 num_bytes;
-       u64 orig_start;
-       u64 disk_num_bytes;
        u64 blocksize = root->sectorsize;
        u64 actual_end;
        u64 isize = i_size_read(inode);
@@ -335,8 +333,6 @@ static noinline int compress_file_range(struct inode *inode,
        int i;
        int will_compress;
 
-       orig_start = start;
-
        actual_end = min_t(u64, isize, end + 1);
 again:
        will_compress = 0;
@@ -371,7 +367,6 @@ again:
        total_compressed = min(total_compressed, max_uncompressed);
        num_bytes = (end - start + blocksize) & ~(blocksize - 1);
        num_bytes = max(blocksize,  num_bytes);
-       disk_num_bytes = num_bytes;
        total_in = 0;
        ret = 0;
 
@@ -467,7 +462,6 @@ again:
                if (total_compressed >= total_in) {
                        will_compress = 0;
                } else {
-                       disk_num_bytes = total_compressed;
                        num_bytes = total_in;
                }
        }
@@ -757,20 +751,17 @@ static noinline int cow_file_range(struct inode *inode,
        u64 disk_num_bytes;
        u64 cur_alloc_size;
        u64 blocksize = root->sectorsize;
-       u64 actual_end;
-       u64 isize = i_size_read(inode);
        struct btrfs_key ins;
        struct extent_map *em;
        struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
        int ret = 0;
 
+       BUG_ON(root == root->fs_info->tree_root);
        trans = btrfs_join_transaction(root, 1);
        BUG_ON(!trans);
        btrfs_set_trans_block_group(trans, inode);
        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
 
-       actual_end = min_t(u64, isize, end + 1);
-
        num_bytes = (end - start + blocksize) & ~(blocksize - 1);
        num_bytes = max(blocksize,  num_bytes);
        disk_num_bytes = num_bytes;
@@ -1035,10 +1026,16 @@ static noinline int run_delalloc_nocow(struct inode *inode,
        int type;
        int nocow;
        int check_prev = 1;
+       bool nolock = false;
 
        path = btrfs_alloc_path();
        BUG_ON(!path);
-       trans = btrfs_join_transaction(root, 1);
+       if (root == root->fs_info->tree_root) {
+               nolock = true;
+               trans = btrfs_join_transaction_nolock(root, 1);
+       } else {
+               trans = btrfs_join_transaction(root, 1);
+       }
        BUG_ON(!trans);
 
        cow_start = (u64)-1;
@@ -1211,8 +1208,13 @@ out_check:
                BUG_ON(ret);
        }
 
-       ret = btrfs_end_transaction(trans, root);
-       BUG_ON(ret);
+       if (nolock) {
+               ret = btrfs_end_transaction_nolock(trans, root);
+               BUG_ON(ret);
+       } else {
+               ret = btrfs_end_transaction(trans, root);
+               BUG_ON(ret);
+       }
        btrfs_free_path(path);
        return 0;
 }
@@ -1289,6 +1291,8 @@ static int btrfs_set_bit_hook(struct inode *inode,
        if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
                struct btrfs_root *root = BTRFS_I(inode)->root;
                u64 len = state->end + 1 - state->start;
+               int do_list = (root->root_key.objectid !=
+                              BTRFS_ROOT_TREE_OBJECTID);
 
                if (*bits & EXTENT_FIRST_DELALLOC)
                        *bits &= ~EXTENT_FIRST_DELALLOC;
@@ -1298,7 +1302,7 @@ static int btrfs_set_bit_hook(struct inode *inode,
                spin_lock(&root->fs_info->delalloc_lock);
                BTRFS_I(inode)->delalloc_bytes += len;
                root->fs_info->delalloc_bytes += len;
-               if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
+               if (do_list && list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
                        list_add_tail(&BTRFS_I(inode)->delalloc_inodes,
                                      &root->fs_info->delalloc_inodes);
                }
@@ -1321,6 +1325,8 @@ static int btrfs_clear_bit_hook(struct inode *inode,
        if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
                struct btrfs_root *root = BTRFS_I(inode)->root;
                u64 len = state->end + 1 - state->start;
+               int do_list = (root->root_key.objectid !=
+                              BTRFS_ROOT_TREE_OBJECTID);
 
                if (*bits & EXTENT_FIRST_DELALLOC)
                        *bits &= ~EXTENT_FIRST_DELALLOC;
@@ -1330,14 +1336,15 @@ static int btrfs_clear_bit_hook(struct inode *inode,
                if (*bits & EXTENT_DO_ACCOUNTING)
                        btrfs_delalloc_release_metadata(inode, len);
 
-               if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID)
+               if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID
+                   && do_list)
                        btrfs_free_reserved_data_space(inode, len);
 
                spin_lock(&root->fs_info->delalloc_lock);
                root->fs_info->delalloc_bytes -= len;
                BTRFS_I(inode)->delalloc_bytes -= len;
 
-               if (BTRFS_I(inode)->delalloc_bytes == 0 &&
+               if (do_list && BTRFS_I(inode)->delalloc_bytes == 0 &&
                    !list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
                        list_del_init(&BTRFS_I(inode)->delalloc_inodes);
                }
@@ -1372,7 +1379,7 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
 
        if (map_length < length + size)
                return 1;
-       return 0;
+       return ret;
 }
 
 /*
@@ -1426,7 +1433,10 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
 
        skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
 
-       ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
+       if (root == root->fs_info->tree_root)
+               ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2);
+       else
+               ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
        BUG_ON(ret);
 
        if (!(rw & REQ_WRITE)) {
@@ -1662,6 +1672,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
        struct extent_state *cached_state = NULL;
        int compressed = 0;
        int ret;
+       bool nolock = false;
 
        ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start,
                                             end - start + 1);
@@ -1669,11 +1680,17 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
                return 0;
        BUG_ON(!ordered_extent);
 
+       nolock = (root == root->fs_info->tree_root);
+
        if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
                BUG_ON(!list_empty(&ordered_extent->list));
                ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent);
                if (!ret) {
-                       trans = btrfs_join_transaction(root, 1);
+                       if (nolock)
+                               trans = btrfs_join_transaction_nolock(root, 1);
+                       else
+                               trans = btrfs_join_transaction(root, 1);
+                       BUG_ON(!trans);
                        btrfs_set_trans_block_group(trans, inode);
                        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
                        ret = btrfs_update_inode(trans, root, inode);
@@ -1686,7 +1703,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
                         ordered_extent->file_offset + ordered_extent->len - 1,
                         0, &cached_state, GFP_NOFS);
 
-       trans = btrfs_join_transaction(root, 1);
+       if (nolock)
+               trans = btrfs_join_transaction_nolock(root, 1);
+       else
+               trans = btrfs_join_transaction(root, 1);
        btrfs_set_trans_block_group(trans, inode);
        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
 
@@ -1700,6 +1720,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
                                                ordered_extent->len);
                BUG_ON(ret);
        } else {
+               BUG_ON(root == root->fs_info->tree_root);
                ret = insert_reserved_file_extent(trans, inode,
                                                ordered_extent->file_offset,
                                                ordered_extent->start,
@@ -1724,9 +1745,15 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
        ret = btrfs_update_inode(trans, root, inode);
        BUG_ON(ret);
 out:
-       btrfs_delalloc_release_metadata(inode, ordered_extent->len);
-       if (trans)
-               btrfs_end_transaction(trans, root);
+       if (nolock) {
+               if (trans)
+                       btrfs_end_transaction_nolock(trans, root);
+       } else {
+               btrfs_delalloc_release_metadata(inode, ordered_extent->len);
+               if (trans)
+                       btrfs_end_transaction(trans, root);
+       }
+
        /* once for us */
        btrfs_put_ordered_extent(ordered_extent);
        /* once for the tree */
@@ -2237,7 +2264,6 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
 {
        struct btrfs_path *path;
        struct extent_buffer *leaf;
-       struct btrfs_item *item;
        struct btrfs_key key, found_key;
        struct btrfs_trans_handle *trans;
        struct inode *inode;
@@ -2275,7 +2301,6 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
 
                /* pull out the item */
                leaf = path->nodes[0];
-               item = btrfs_item_nr(leaf, path->slots[0]);
                btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
 
                /* make sure the item matches what we want */
@@ -2651,7 +2676,8 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
 
        ret = btrfs_del_dir_entries_in_log(trans, root, name, name_len,
                                           dir, index);
-       BUG_ON(ret);
+       if (ret == -ENOENT)
+               ret = 0;
 err:
        btrfs_free_path(path);
        if (ret)
@@ -2672,8 +2698,8 @@ static int check_path_shared(struct btrfs_root *root,
 {
        struct extent_buffer *eb;
        int level;
-       int ret;
        u64 refs = 1;
+       int uninitialized_var(ret);
 
        for (level = 0; level < BTRFS_MAX_LEVEL; level++) {
                if (!path->nodes[level])
@@ -2686,7 +2712,7 @@ static int check_path_shared(struct btrfs_root *root,
                if (refs > 1)
                        return 1;
        }
-       return 0;
+       return ret; /* XXX callers? */
 }
 
 /*
@@ -3196,7 +3222,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
 
        BUG_ON(new_size > 0 && min_type != BTRFS_EXTENT_DATA_KEY);
 
-       if (root->ref_cows)
+       if (root->ref_cows || root == root->fs_info->tree_root)
                btrfs_drop_extent_cache(inode, new_size & (~mask), (u64)-1, 0);
 
        path = btrfs_alloc_path();
@@ -3344,7 +3370,8 @@ delete:
                } else {
                        break;
                }
-               if (found_extent && root->ref_cows) {
+               if (found_extent && (root->ref_cows ||
+                                    root == root->fs_info->tree_root)) {
                        btrfs_set_path_blocking(path);
                        ret = btrfs_free_extent(trans, root, extent_start,
                                                extent_num_bytes, 0,
@@ -3675,7 +3702,8 @@ void btrfs_evict_inode(struct inode *inode)
        int ret;
 
        truncate_inode_pages(&inode->i_data, 0);
-       if (inode->i_nlink && btrfs_root_refs(&root->root_item) != 0)
+       if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
+                              root == root->fs_info->tree_root))
                goto no_delete;
 
        if (is_bad_inode(inode)) {
@@ -3888,7 +3916,14 @@ static void inode_tree_del(struct inode *inode)
        }
        spin_unlock(&root->inode_lock);
 
-       if (empty && btrfs_root_refs(&root->root_item) == 0) {
+       /*
+        * Free space cache has inodes in the tree root, but the tree root has a
+        * root_refs of 0, so this could end up dropping the tree root as a
+        * snapshot, so we need the extra !root->fs_info->tree_root check to
+        * make sure we don't drop it.
+        */
+       if (empty && btrfs_root_refs(&root->root_item) == 0 &&
+           root != root->fs_info->tree_root) {
                synchronize_srcu(&root->fs_info->subvol_srcu);
                spin_lock(&root->inode_lock);
                empty = RB_EMPTY_ROOT(&root->inode_tree);
@@ -4282,14 +4317,24 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_trans_handle *trans;
        int ret = 0;
+       bool nolock = false;
 
        if (BTRFS_I(inode)->dummy_inode)
                return 0;
 
+       smp_mb();
+       nolock = (root->fs_info->closing && root == root->fs_info->tree_root);
+
        if (wbc->sync_mode == WB_SYNC_ALL) {
-               trans = btrfs_join_transaction(root, 1);
+               if (nolock)
+                       trans = btrfs_join_transaction_nolock(root, 1);
+               else
+                       trans = btrfs_join_transaction(root, 1);
                btrfs_set_trans_block_group(trans, inode);
-               ret = btrfs_commit_transaction(trans, root);
+               if (nolock)
+                       ret = btrfs_end_transaction_nolock(trans, root);
+               else
+                       ret = btrfs_commit_transaction(trans, root);
        }
        return ret;
 }
@@ -5645,7 +5690,6 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_dio_private *dip;
        struct bio_vec *bvec = bio->bi_io_vec;
-       u64 start;
        int skip_sum;
        int write = rw & REQ_WRITE;
        int ret = 0;
@@ -5671,7 +5715,6 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
        dip->inode = inode;
        dip->logical_offset = file_offset;
 
-       start = dip->logical_offset;
        dip->bytes = 0;
        do {
                dip->bytes += bvec->bv_len;
@@ -6308,6 +6351,21 @@ void btrfs_destroy_inode(struct inode *inode)
                spin_unlock(&root->fs_info->ordered_extent_lock);
        }
 
+       if (root == root->fs_info->tree_root) {
+               struct btrfs_block_group_cache *block_group;
+
+               block_group = btrfs_lookup_block_group(root->fs_info,
+                                               BTRFS_I(inode)->block_group);
+               if (block_group && block_group->inode == inode) {
+                       spin_lock(&block_group->lock);
+                       block_group->inode = NULL;
+                       spin_unlock(&block_group->lock);
+                       btrfs_put_block_group(block_group);
+               } else if (block_group) {
+                       btrfs_put_block_group(block_group);
+               }
+       }
+
        spin_lock(&root->orphan_lock);
        if (!list_empty(&BTRFS_I(inode)->i_orphan)) {
                printk(KERN_INFO "BTRFS: inode %lu still on the orphan list\n",
@@ -6340,7 +6398,8 @@ int btrfs_drop_inode(struct inode *inode)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
 
-       if (btrfs_root_refs(&root->root_item) == 0)
+       if (btrfs_root_refs(&root->root_item) == 0 &&
+           root != root->fs_info->tree_root)
                return 1;
        else
                return generic_drop_inode(inode);
@@ -6609,7 +6668,8 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
        return 0;
 }
 
-int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput)
+int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput,
+                                  int sync)
 {
        struct btrfs_inode *binode;
        struct inode *inode = NULL;
@@ -6631,7 +6691,26 @@ int btrfs_start_one_delalloc_inode(struct btrfs_root *root, int delay_iput)
        spin_unlock(&root->fs_info->delalloc_lock);
 
        if (inode) {
-               write_inode_now(inode, 0);
+               if (sync) {
+                       filemap_write_and_wait(inode->i_mapping);
+                       /*
+                        * We have to do this because compression doesn't
+                        * actually set PG_writeback until it submits the pages
+                        * for IO, which happens in an async thread, so we could
+                        * race and not actually wait for any writeback pages
+                        * because they've not been submitted yet.  Technically
+                        * this could still be the case for the ordered stuff
+                        * since the async thread may not have started to do its
+                        * work yet.  If this becomes the case then we need to
+                        * figure out a way to make sure that in writepage we
+                        * wait for any async pages to be submitted before
+                        * returning so that fdatawait does what its supposed to
+                        * do.
+                        */
+                       btrfs_wait_ordered_range(inode, 0, (u64)-1);
+               } else {
+                       filemap_flush(inode->i_mapping);
+               }
                if (delay_iput)
                        btrfs_add_delayed_iput(inode);
                else
@@ -6757,27 +6836,33 @@ out_unlock:
        return err;
 }
 
-int btrfs_prealloc_file_range(struct inode *inode, int mode,
-                             u64 start, u64 num_bytes, u64 min_size,
-                             loff_t actual_len, u64 *alloc_hint)
+static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
+                                      u64 start, u64 num_bytes, u64 min_size,
+                                      loff_t actual_len, u64 *alloc_hint,
+                                      struct btrfs_trans_handle *trans)
 {
-       struct btrfs_trans_handle *trans;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_key ins;
        u64 cur_offset = start;
        int ret = 0;
+       bool own_trans = true;
 
+       if (trans)
+               own_trans = false;
        while (num_bytes > 0) {
-               trans = btrfs_start_transaction(root, 3);
-               if (IS_ERR(trans)) {
-                       ret = PTR_ERR(trans);
-                       break;
+               if (own_trans) {
+                       trans = btrfs_start_transaction(root, 3);
+                       if (IS_ERR(trans)) {
+                               ret = PTR_ERR(trans);
+                               break;
+                       }
                }
 
                ret = btrfs_reserve_extent(trans, root, num_bytes, min_size,
                                           0, *alloc_hint, (u64)-1, &ins, 1);
                if (ret) {
-                       btrfs_end_transaction(trans, root);
+                       if (own_trans)
+                               btrfs_end_transaction(trans, root);
                        break;
                }
 
@@ -6810,11 +6895,30 @@ int btrfs_prealloc_file_range(struct inode *inode, int mode,
                ret = btrfs_update_inode(trans, root, inode);
                BUG_ON(ret);
 
-               btrfs_end_transaction(trans, root);
+               if (own_trans)
+                       btrfs_end_transaction(trans, root);
        }
        return ret;
 }
 
+int btrfs_prealloc_file_range(struct inode *inode, int mode,
+                             u64 start, u64 num_bytes, u64 min_size,
+                             loff_t actual_len, u64 *alloc_hint)
+{
+       return __btrfs_prealloc_file_range(inode, mode, start, num_bytes,
+                                          min_size, actual_len, alloc_hint,
+                                          NULL);
+}
+
+int btrfs_prealloc_file_range_trans(struct inode *inode,
+                                   struct btrfs_trans_handle *trans, int mode,
+                                   u64 start, u64 num_bytes, u64 min_size,
+                                   loff_t actual_len, u64 *alloc_hint)
+{
+       return __btrfs_prealloc_file_range(inode, mode, start, num_bytes,
+                                          min_size, actual_len, alloc_hint, trans);
+}
+
 static long btrfs_fallocate(struct inode *inode, int mode,
                            loff_t offset, loff_t len)
 {
index 9254b3d58dbef22974af3c7c61dbc9a4af7a33b6..463d91b4dd3a720ece2afb592b2edefca855aaba 100644 (file)
@@ -224,7 +224,8 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg)
 
 static noinline int create_subvol(struct btrfs_root *root,
                                  struct dentry *dentry,
-                                 char *name, int namelen)
+                                 char *name, int namelen,
+                                 u64 *async_transid)
 {
        struct btrfs_trans_handle *trans;
        struct btrfs_key key;
@@ -338,13 +339,19 @@ static noinline int create_subvol(struct btrfs_root *root,
 
        d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
 fail:
-       err = btrfs_commit_transaction(trans, root);
+       if (async_transid) {
+               *async_transid = trans->transid;
+               err = btrfs_commit_transaction_async(trans, root, 1);
+       } else {
+               err = btrfs_commit_transaction(trans, root);
+       }
        if (err && !ret)
                ret = err;
        return ret;
 }
 
-static int create_snapshot(struct btrfs_root *root, struct dentry *dentry)
+static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
+                          char *name, int namelen, u64 *async_transid)
 {
        struct inode *inode;
        struct btrfs_pending_snapshot *pending_snapshot;
@@ -373,7 +380,14 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry)
 
        list_add(&pending_snapshot->list,
                 &trans->transaction->pending_snapshots);
-       ret = btrfs_commit_transaction(trans, root->fs_info->extent_root);
+       if (async_transid) {
+               *async_transid = trans->transid;
+               ret = btrfs_commit_transaction_async(trans,
+                                    root->fs_info->extent_root, 1);
+       } else {
+               ret = btrfs_commit_transaction(trans,
+                                              root->fs_info->extent_root);
+       }
        BUG_ON(ret);
 
        ret = pending_snapshot->error;
@@ -395,6 +409,76 @@ fail:
        return ret;
 }
 
+/*  copy of check_sticky in fs/namei.c()
+* It's inline, so penalty for filesystems that don't use sticky bit is
+* minimal.
+*/
+static inline int btrfs_check_sticky(struct inode *dir, struct inode *inode)
+{
+       uid_t fsuid = current_fsuid();
+
+       if (!(dir->i_mode & S_ISVTX))
+               return 0;
+       if (inode->i_uid == fsuid)
+               return 0;
+       if (dir->i_uid == fsuid)
+               return 0;
+       return !capable(CAP_FOWNER);
+}
+
+/*  copy of may_delete in fs/namei.c()
+ *     Check whether we can remove a link victim from directory dir, check
+ *  whether the type of victim is right.
+ *  1. We can't do it if dir is read-only (done in permission())
+ *  2. We should have write and exec permissions on dir
+ *  3. We can't remove anything from append-only dir
+ *  4. We can't do anything with immutable dir (done in permission())
+ *  5. If the sticky bit on dir is set we should either
+ *     a. be owner of dir, or
+ *     b. be owner of victim, or
+ *     c. have CAP_FOWNER capability
+ *  6. If the victim is append-only or immutable we can't do antyhing with
+ *     links pointing to it.
+ *  7. If we were asked to remove a directory and victim isn't one - ENOTDIR.
+ *  8. If we were asked to remove a non-directory and victim isn't one - EISDIR.
+ *  9. We can't remove a root or mountpoint.
+ * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
+ *     nfs_async_unlink().
+ */
+
+static int btrfs_may_delete(struct inode *dir,struct dentry *victim,int isdir)
+{
+       int error;
+
+       if (!victim->d_inode)
+               return -ENOENT;
+
+       BUG_ON(victim->d_parent->d_inode != dir);
+       audit_inode_child(victim, dir);
+
+       error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
+       if (error)
+               return error;
+       if (IS_APPEND(dir))
+               return -EPERM;
+       if (btrfs_check_sticky(dir, victim->d_inode)||
+               IS_APPEND(victim->d_inode)||
+           IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
+               return -EPERM;
+       if (isdir) {
+               if (!S_ISDIR(victim->d_inode->i_mode))
+                       return -ENOTDIR;
+               if (IS_ROOT(victim))
+                       return -EBUSY;
+       } else if (S_ISDIR(victim->d_inode->i_mode))
+               return -EISDIR;
+       if (IS_DEADDIR(dir))
+               return -ENOENT;
+       if (victim->d_flags & DCACHE_NFSFS_RENAMED)
+               return -EBUSY;
+       return 0;
+}
+
 /* copy of may_create in fs/namei.c() */
 static inline int btrfs_may_create(struct inode *dir, struct dentry *child)
 {
@@ -412,7 +496,8 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child)
  */
 static noinline int btrfs_mksubvol(struct path *parent,
                                   char *name, int namelen,
-                                  struct btrfs_root *snap_src)
+                                  struct btrfs_root *snap_src,
+                                  u64 *async_transid)
 {
        struct inode *dir  = parent->dentry->d_inode;
        struct dentry *dentry;
@@ -443,10 +528,11 @@ static noinline int btrfs_mksubvol(struct path *parent,
                goto out_up_read;
 
        if (snap_src) {
-               error = create_snapshot(snap_src, dentry);
+               error = create_snapshot(snap_src, dentry,
+                                       name, namelen, async_transid);
        } else {
                error = create_subvol(BTRFS_I(dir)->root, dentry,
-                                     name, namelen);
+                                     name, namelen, async_transid);
        }
        if (!error)
                fsnotify_mkdir(dir, dentry);
@@ -708,7 +794,6 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
        char *sizestr;
        char *devstr = NULL;
        int ret = 0;
-       int namelen;
        int mod = 0;
 
        if (root->fs_info->sb->s_flags & MS_RDONLY)
@@ -722,7 +807,6 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
                return PTR_ERR(vol_args);
 
        vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
-       namelen = strlen(vol_args->name);
 
        mutex_lock(&root->fs_info->volume_mutex);
        sizestr = vol_args->name;
@@ -801,11 +885,13 @@ out_unlock:
        return ret;
 }
 
-static noinline int btrfs_ioctl_snap_create(struct file *file,
-                                           void __user *arg, int subvol)
+static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
+                                                   char *name,
+                                                   unsigned long fd,
+                                                   int subvol,
+                                                   u64 *transid)
 {
        struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root;
-       struct btrfs_ioctl_vol_args *vol_args;
        struct file *src_file;
        int namelen;
        int ret = 0;
@@ -813,23 +899,18 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
        if (root->fs_info->sb->s_flags & MS_RDONLY)
                return -EROFS;
 
-       vol_args = memdup_user(arg, sizeof(*vol_args));
-       if (IS_ERR(vol_args))
-               return PTR_ERR(vol_args);
-
-       vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
-       namelen = strlen(vol_args->name);
-       if (strchr(vol_args->name, '/')) {
+       namelen = strlen(name);
+       if (strchr(name, '/')) {
                ret = -EINVAL;
                goto out;
        }
 
        if (subvol) {
-               ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen,
-                                    NULL);
+               ret = btrfs_mksubvol(&file->f_path, name, namelen,
+                                    NULL, transid);
        } else {
                struct inode *src_inode;
-               src_file = fget(vol_args->fd);
+               src_file = fget(fd);
                if (!src_file) {
                        ret = -EINVAL;
                        goto out;
@@ -843,12 +924,56 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
                        fput(src_file);
                        goto out;
                }
-               ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen,
-                                    BTRFS_I(src_inode)->root);
+               ret = btrfs_mksubvol(&file->f_path, name, namelen,
+                                    BTRFS_I(src_inode)->root,
+                                    transid);
                fput(src_file);
        }
 out:
+       return ret;
+}
+
+static noinline int btrfs_ioctl_snap_create(struct file *file,
+                                           void __user *arg, int subvol,
+                                           int async)
+{
+       struct btrfs_ioctl_vol_args *vol_args = NULL;
+       struct btrfs_ioctl_async_vol_args *async_vol_args = NULL;
+       char *name;
+       u64 fd;
+       u64 transid = 0;
+       int ret;
+
+       if (async) {
+               async_vol_args = memdup_user(arg, sizeof(*async_vol_args));
+               if (IS_ERR(async_vol_args))
+                       return PTR_ERR(async_vol_args);
+
+               name = async_vol_args->name;
+               fd = async_vol_args->fd;
+               async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0';
+       } else {
+               vol_args = memdup_user(arg, sizeof(*vol_args));
+               if (IS_ERR(vol_args))
+                       return PTR_ERR(vol_args);
+               name = vol_args->name;
+               fd = vol_args->fd;
+               vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
+       }
+
+       ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+                                             subvol, &transid);
+
+       if (!ret && async) {
+               if (copy_to_user(arg +
+                               offsetof(struct btrfs_ioctl_async_vol_args,
+                               transid), &transid, sizeof(transid)))
+                       return -EFAULT;
+       }
+
        kfree(vol_args);
+       kfree(async_vol_args);
+
        return ret;
 }
 
@@ -1073,14 +1198,10 @@ static noinline int btrfs_ioctl_tree_search(struct file *file,
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       args = kmalloc(sizeof(*args), GFP_KERNEL);
-       if (!args)
-               return -ENOMEM;
+       args = memdup_user(argp, sizeof(*args));
+       if (IS_ERR(args))
+               return PTR_ERR(args);
 
-       if (copy_from_user(args, argp, sizeof(*args))) {
-               kfree(args);
-               return -EFAULT;
-       }
        inode = fdentry(file)->d_inode;
        ret = search_ioctl(inode, args);
        if (ret == 0 && copy_to_user(argp, args, sizeof(*args)))
@@ -1188,14 +1309,10 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file,
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       args = kmalloc(sizeof(*args), GFP_KERNEL);
-       if (!args)
-               return -ENOMEM;
+       args = memdup_user(argp, sizeof(*args));
+       if (IS_ERR(args))
+               return PTR_ERR(args);
 
-       if (copy_from_user(args, argp, sizeof(*args))) {
-               kfree(args);
-               return -EFAULT;
-       }
        inode = fdentry(file)->d_inode;
 
        if (args->treeid == 0)
@@ -1227,9 +1344,6 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
        int ret;
        int err = 0;
 
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
        vol_args = memdup_user(arg, sizeof(*vol_args));
        if (IS_ERR(vol_args))
                return PTR_ERR(vol_args);
@@ -1259,13 +1373,51 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
        }
 
        inode = dentry->d_inode;
+       dest = BTRFS_I(inode)->root;
+       if (!capable(CAP_SYS_ADMIN)){
+               /*
+                * Regular user.  Only allow this with a special mount
+                * option, when the user has write+exec access to the
+                * subvol root, and when rmdir(2) would have been
+                * allowed.
+                *
+                * Note that this is _not_ check that the subvol is
+                * empty or doesn't contain data that we wouldn't
+                * otherwise be able to delete.
+                *
+                * Users who want to delete empty subvols should try
+                * rmdir(2).
+                */
+               err = -EPERM;
+               if (!btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED))
+                       goto out_dput;
+
+               /*
+                * Do not allow deletion if the parent dir is the same
+                * as the dir to be deleted.  That means the ioctl
+                * must be called on the dentry referencing the root
+                * of the subvol, not a random directory contained
+                * within it.
+                */
+               err = -EINVAL;
+               if (root == dest)
+                       goto out_dput;
+
+               err = inode_permission(inode, MAY_WRITE | MAY_EXEC);
+               if (err)
+                       goto out_dput;
+
+               /* check if subvolume may be deleted by a non-root user */
+               err = btrfs_may_delete(dir, dentry, 1);
+               if (err)
+                       goto out_dput;
+       }
+
        if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) {
                err = -EINVAL;
                goto out_dput;
        }
 
-       dest = BTRFS_I(inode)->root;
-
        mutex_lock(&inode->i_mutex);
        err = d_invalidate(dentry);
        if (err)
@@ -1304,7 +1456,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
                BUG_ON(ret);
        }
 
-       ret = btrfs_commit_transaction(trans, root);
+       ret = btrfs_end_transaction(trans, root);
        BUG_ON(ret);
        inode->i_flags |= S_DEAD;
 out_up_write:
@@ -1502,11 +1654,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
        path->reada = 2;
 
        if (inode < src) {
-               mutex_lock(&inode->i_mutex);
-               mutex_lock(&src->i_mutex);
+               mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
+               mutex_lock_nested(&src->i_mutex, I_MUTEX_CHILD);
        } else {
-               mutex_lock(&src->i_mutex);
-               mutex_lock(&inode->i_mutex);
+               mutex_lock_nested(&src->i_mutex, I_MUTEX_PARENT);
+               mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
        }
 
        /* determine range to clone */
@@ -1530,13 +1682,15 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
        while (1) {
                struct btrfs_ordered_extent *ordered;
                lock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS);
-               ordered = btrfs_lookup_first_ordered_extent(inode, off+len);
-               if (BTRFS_I(src)->delalloc_bytes == 0 && !ordered)
+               ordered = btrfs_lookup_first_ordered_extent(src, off+len);
+               if (!ordered &&
+                   !test_range_bit(&BTRFS_I(src)->io_tree, off, off+len,
+                                  EXTENT_DELALLOC, 0, NULL))
                        break;
                unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS);
                if (ordered)
                        btrfs_put_ordered_extent(ordered);
-               btrfs_wait_ordered_range(src, off, off+len);
+               btrfs_wait_ordered_range(src, off, len);
        }
 
        /* clone data */
@@ -1605,7 +1759,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
                        }
                        btrfs_release_path(root, path);
 
-                       if (key.offset + datal < off ||
+                       if (key.offset + datal <= off ||
                            key.offset >= off+len)
                                goto next;
 
@@ -1879,6 +2033,22 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
        return 0;
 }
 
+static void get_block_group_info(struct list_head *groups_list,
+                                struct btrfs_ioctl_space_info *space)
+{
+       struct btrfs_block_group_cache *block_group;
+
+       space->total_bytes = 0;
+       space->used_bytes = 0;
+       space->flags = 0;
+       list_for_each_entry(block_group, groups_list, list) {
+               space->flags = block_group->flags;
+               space->total_bytes += block_group->key.offset;
+               space->used_bytes +=
+                       btrfs_block_group_used(&block_group->item);
+       }
+}
+
 long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
 {
        struct btrfs_ioctl_space_args space_args;
@@ -1887,27 +2057,56 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
        struct btrfs_ioctl_space_info *dest_orig;
        struct btrfs_ioctl_space_info *user_dest;
        struct btrfs_space_info *info;
+       u64 types[] = {BTRFS_BLOCK_GROUP_DATA,
+                      BTRFS_BLOCK_GROUP_SYSTEM,
+                      BTRFS_BLOCK_GROUP_METADATA,
+                      BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA};
+       int num_types = 4;
        int alloc_size;
        int ret = 0;
        int slot_count = 0;
+       int i, c;
 
        if (copy_from_user(&space_args,
                           (struct btrfs_ioctl_space_args __user *)arg,
                           sizeof(space_args)))
                return -EFAULT;
 
-       /* first we count slots */
-       rcu_read_lock();
-       list_for_each_entry_rcu(info, &root->fs_info->space_info, list)
-               slot_count++;
-       rcu_read_unlock();
+       for (i = 0; i < num_types; i++) {
+               struct btrfs_space_info *tmp;
+
+               info = NULL;
+               rcu_read_lock();
+               list_for_each_entry_rcu(tmp, &root->fs_info->space_info,
+                                       list) {
+                       if (tmp->flags == types[i]) {
+                               info = tmp;
+                               break;
+                       }
+               }
+               rcu_read_unlock();
+
+               if (!info)
+                       continue;
+
+               down_read(&info->groups_sem);
+               for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
+                       if (!list_empty(&info->block_groups[c]))
+                               slot_count++;
+               }
+               up_read(&info->groups_sem);
+       }
 
        /* space_slots == 0 means they are asking for a count */
        if (space_args.space_slots == 0) {
                space_args.total_spaces = slot_count;
                goto out;
        }
+
+       slot_count = min_t(int, space_args.space_slots, slot_count);
+
        alloc_size = sizeof(*dest) * slot_count;
+
        /* we generally have at most 6 or so space infos, one for each raid
         * level.  So, a whole page should be more than enough for everyone
         */
@@ -1921,27 +2120,34 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
        dest_orig = dest;
 
        /* now we have a buffer to copy into */
-       rcu_read_lock();
-       list_for_each_entry_rcu(info, &root->fs_info->space_info, list) {
-               /* make sure we don't copy more than we allocated
-                * in our buffer
-                */
-               if (slot_count == 0)
-                       break;
-               slot_count--;
-
-               /* make sure userland has enough room in their buffer */
-               if (space_args.total_spaces >= space_args.space_slots)
-                       break;
+       for (i = 0; i < num_types; i++) {
+               struct btrfs_space_info *tmp;
+
+               info = NULL;
+               rcu_read_lock();
+               list_for_each_entry_rcu(tmp, &root->fs_info->space_info,
+                                       list) {
+                       if (tmp->flags == types[i]) {
+                               info = tmp;
+                               break;
+                       }
+               }
+               rcu_read_unlock();
 
-               space.flags = info->flags;
-               space.total_bytes = info->total_bytes;
-               space.used_bytes = info->bytes_used;
-               memcpy(dest, &space, sizeof(space));
-               dest++;
-               space_args.total_spaces++;
+               if (!info)
+                       continue;
+               down_read(&info->groups_sem);
+               for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
+                       if (!list_empty(&info->block_groups[c])) {
+                               get_block_group_info(&info->block_groups[c],
+                                                    &space);
+                               memcpy(dest, &space, sizeof(space));
+                               dest++;
+                               space_args.total_spaces++;
+                       }
+               }
+               up_read(&info->groups_sem);
        }
-       rcu_read_unlock();
 
        user_dest = (struct btrfs_ioctl_space_info *)
                (arg + sizeof(struct btrfs_ioctl_space_args));
@@ -1984,6 +2190,36 @@ long btrfs_ioctl_trans_end(struct file *file)
        return 0;
 }
 
+static noinline long btrfs_ioctl_start_sync(struct file *file, void __user *argp)
+{
+       struct btrfs_root *root = BTRFS_I(file->f_dentry->d_inode)->root;
+       struct btrfs_trans_handle *trans;
+       u64 transid;
+
+       trans = btrfs_start_transaction(root, 0);
+       transid = trans->transid;
+       btrfs_commit_transaction_async(trans, root, 0);
+
+       if (argp)
+               if (copy_to_user(argp, &transid, sizeof(transid)))
+                       return -EFAULT;
+       return 0;
+}
+
+static noinline long btrfs_ioctl_wait_sync(struct file *file, void __user *argp)
+{
+       struct btrfs_root *root = BTRFS_I(file->f_dentry->d_inode)->root;
+       u64 transid;
+
+       if (argp) {
+               if (copy_from_user(&transid, argp, sizeof(transid)))
+                       return -EFAULT;
+       } else {
+               transid = 0;  /* current trans */
+       }
+       return btrfs_wait_for_commit(root, transid);
+}
+
 long btrfs_ioctl(struct file *file, unsigned int
                cmd, unsigned long arg)
 {
@@ -1998,9 +2234,11 @@ long btrfs_ioctl(struct file *file, unsigned int
        case FS_IOC_GETVERSION:
                return btrfs_ioctl_getversion(file, argp);
        case BTRFS_IOC_SNAP_CREATE:
-               return btrfs_ioctl_snap_create(file, argp, 0);
+               return btrfs_ioctl_snap_create(file, argp, 0, 0);
+       case BTRFS_IOC_SNAP_CREATE_ASYNC:
+               return btrfs_ioctl_snap_create(file, argp, 0, 1);
        case BTRFS_IOC_SUBVOL_CREATE:
-               return btrfs_ioctl_snap_create(file, argp, 1);
+               return btrfs_ioctl_snap_create(file, argp, 1, 0);
        case BTRFS_IOC_SNAP_DESTROY:
                return btrfs_ioctl_snap_destroy(file, argp);
        case BTRFS_IOC_DEFAULT_SUBVOL:
@@ -2034,6 +2272,10 @@ long btrfs_ioctl(struct file *file, unsigned int
        case BTRFS_IOC_SYNC:
                btrfs_sync_fs(file->f_dentry->d_sb, 1);
                return 0;
+       case BTRFS_IOC_START_SYNC:
+               return btrfs_ioctl_start_sync(file, argp);
+       case BTRFS_IOC_WAIT_SYNC:
+               return btrfs_ioctl_wait_sync(file, argp);
        }
 
        return -ENOTTY;
index 424694aa517f5b03fd5ee16e4052d4c6c7fd6777..17c99ebdf96049a8ad028cd6e138355df86f0c9e 100644 (file)
 
 #define BTRFS_IOCTL_MAGIC 0x94
 #define BTRFS_VOL_NAME_MAX 255
-#define BTRFS_PATH_NAME_MAX 4087
 
 /* this should be 4k */
+#define BTRFS_PATH_NAME_MAX 4087
 struct btrfs_ioctl_vol_args {
        __s64 fd;
        char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
+#define BTRFS_SNAPSHOT_NAME_MAX 4079
+struct btrfs_ioctl_async_vol_args {
+       __s64 fd;
+       __u64 transid;
+       char name[BTRFS_SNAPSHOT_NAME_MAX + 1];
+};
+
 #define BTRFS_INO_LOOKUP_PATH_MAX 4080
 struct btrfs_ioctl_ino_lookup_args {
        __u64 treeid;
@@ -178,4 +185,8 @@ struct btrfs_ioctl_space_args {
 #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
 #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
                                    struct btrfs_ioctl_space_args)
+#define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
+#define BTRFS_IOC_WAIT_SYNC  _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
+#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \
+                                  struct btrfs_ioctl_async_vol_args)
 #endif
index e56c72bc5adddcdb4338b573a2f7cbc05e2b4a37..f4621f6deca1d51f91db57ea406c4c7351a7fd5d 100644 (file)
@@ -526,7 +526,6 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
 {
        u64 end;
        u64 orig_end;
-       u64 wait_end;
        struct btrfs_ordered_extent *ordered;
        int found;
 
@@ -537,7 +536,6 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
                if (orig_end > INT_LIMIT(loff_t))
                        orig_end = INT_LIMIT(loff_t);
        }
-       wait_end = orig_end;
 again:
        /* start IO across the range first to instantiate any delalloc
         * extents
index b37d723b9d4a8a137b05256a85788074b5f03c5e..045c9c2b2d7ef7399f00370e4137d9da0b370836 100644 (file)
@@ -29,6 +29,7 @@
 #include "locking.h"
 #include "btrfs_inode.h"
 #include "async-thread.h"
+#include "free-space-cache.h"
 
 /*
  * backref_node, mapping_node and tree_block start with this
@@ -178,8 +179,6 @@ struct reloc_control {
        u64 search_start;
        u64 extents_found;
 
-       int block_rsv_retries;
-
        unsigned int stage:8;
        unsigned int create_reloc_tree:1;
        unsigned int merge_reloc_tree:1;
@@ -2133,7 +2132,6 @@ int prepare_to_merge(struct reloc_control *rc, int err)
        LIST_HEAD(reloc_roots);
        u64 num_bytes = 0;
        int ret;
-       int retries = 0;
 
        mutex_lock(&root->fs_info->trans_mutex);
        rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2;
@@ -2143,7 +2141,7 @@ again:
        if (!err) {
                num_bytes = rc->merging_rsv_size;
                ret = btrfs_block_rsv_add(NULL, root, rc->block_rsv,
-                                         num_bytes, &retries);
+                                         num_bytes);
                if (ret)
                        err = ret;
        }
@@ -2155,7 +2153,6 @@ again:
                        btrfs_end_transaction(trans, rc->extent_root);
                        btrfs_block_rsv_release(rc->extent_root,
                                                rc->block_rsv, num_bytes);
-                       retries = 0;
                        goto again;
                }
        }
@@ -2405,15 +2402,13 @@ static int reserve_metadata_space(struct btrfs_trans_handle *trans,
        num_bytes = calcu_metadata_size(rc, node, 1) * 2;
 
        trans->block_rsv = rc->block_rsv;
-       ret = btrfs_block_rsv_add(trans, root, rc->block_rsv, num_bytes,
-                                 &rc->block_rsv_retries);
+       ret = btrfs_block_rsv_add(trans, root, rc->block_rsv, num_bytes);
        if (ret) {
                if (ret == -EAGAIN)
                        rc->commit_transaction = 1;
                return ret;
        }
 
-       rc->block_rsv_retries = 0;
        return 0;
 }
 
@@ -3099,6 +3094,8 @@ static int add_tree_block(struct reloc_control *rc,
                BUG_ON(item_size != sizeof(struct btrfs_extent_item_v0));
                ret = get_ref_objectid_v0(rc, path, extent_key,
                                          &ref_owner, NULL);
+               if (ret < 0)
+                       return ret;
                BUG_ON(ref_owner >= BTRFS_MAX_LEVEL);
                level = (int)ref_owner;
                /* FIXME: get real generation */
@@ -3191,6 +3188,54 @@ static int block_use_full_backref(struct reloc_control *rc,
        return ret;
 }
 
+static int delete_block_group_cache(struct btrfs_fs_info *fs_info,
+                                   struct inode *inode, u64 ino)
+{
+       struct btrfs_key key;
+       struct btrfs_path *path;
+       struct btrfs_root *root = fs_info->tree_root;
+       struct btrfs_trans_handle *trans;
+       unsigned long nr;
+       int ret = 0;
+
+       if (inode)
+               goto truncate;
+
+       key.objectid = ino;
+       key.type = BTRFS_INODE_ITEM_KEY;
+       key.offset = 0;
+
+       inode = btrfs_iget(fs_info->sb, &key, root, NULL);
+       if (!inode || IS_ERR(inode) || is_bad_inode(inode)) {
+               if (inode && !IS_ERR(inode))
+                       iput(inode);
+               return -ENOENT;
+       }
+
+truncate:
+       path = btrfs_alloc_path();
+       if (!path) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       trans = btrfs_join_transaction(root, 0);
+       if (IS_ERR(trans)) {
+               btrfs_free_path(path);
+               goto out;
+       }
+
+       ret = btrfs_truncate_free_space_cache(root, trans, path, inode);
+
+       btrfs_free_path(path);
+       nr = trans->blocks_used;
+       btrfs_end_transaction(trans, root);
+       btrfs_btree_balance_dirty(root, nr);
+out:
+       iput(inode);
+       return ret;
+}
+
 /*
  * helper to add tree blocks for backref of type BTRFS_EXTENT_DATA_REF_KEY
  * this function scans fs tree to find blocks reference the data extent
@@ -3217,15 +3262,27 @@ static int find_data_references(struct reloc_control *rc,
        int counted;
        int ret;
 
-       path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
-
        ref_root = btrfs_extent_data_ref_root(leaf, ref);
        ref_objectid = btrfs_extent_data_ref_objectid(leaf, ref);
        ref_offset = btrfs_extent_data_ref_offset(leaf, ref);
        ref_count = btrfs_extent_data_ref_count(leaf, ref);
 
+       /*
+        * This is an extent belonging to the free space cache, lets just delete
+        * it and redo the search.
+        */
+       if (ref_root == BTRFS_ROOT_TREE_OBJECTID) {
+               ret = delete_block_group_cache(rc->extent_root->fs_info,
+                                              NULL, ref_objectid);
+               if (ret != -ENOENT)
+                       return ret;
+               ret = 0;
+       }
+
+       path = btrfs_alloc_path();
+       if (!path)
+               return -ENOMEM;
+
        root = read_fs_root(rc->extent_root->fs_info, ref_root);
        if (IS_ERR(root)) {
                err = PTR_ERR(root);
@@ -3554,8 +3611,7 @@ int prepare_to_relocate(struct reloc_control *rc)
         * is no reservation in transaction handle.
         */
        ret = btrfs_block_rsv_add(NULL, rc->extent_root, rc->block_rsv,
-                                 rc->extent_root->nodesize * 256,
-                                 &rc->block_rsv_retries);
+                                 rc->extent_root->nodesize * 256);
        if (ret)
                return ret;
 
@@ -3567,7 +3623,6 @@ int prepare_to_relocate(struct reloc_control *rc)
        rc->extents_found = 0;
        rc->nodes_relocated = 0;
        rc->merging_rsv_size = 0;
-       rc->block_rsv_retries = 0;
 
        rc->create_reloc_tree = 1;
        set_reloc_control(rc);
@@ -3860,6 +3915,8 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
 {
        struct btrfs_fs_info *fs_info = extent_root->fs_info;
        struct reloc_control *rc;
+       struct inode *inode;
+       struct btrfs_path *path;
        int ret;
        int rw = 0;
        int err = 0;
@@ -3882,6 +3939,26 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
                rw = 1;
        }
 
+       path = btrfs_alloc_path();
+       if (!path) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       inode = lookup_free_space_inode(fs_info->tree_root, rc->block_group,
+                                       path);
+       btrfs_free_path(path);
+
+       if (!IS_ERR(inode))
+               ret = delete_block_group_cache(fs_info, inode, 0);
+       else
+               ret = PTR_ERR(inode);
+
+       if (ret && ret != -ENOENT) {
+               err = ret;
+               goto out;
+       }
+
        rc->data_inode = create_reloc_inode(fs_info, rc->block_group);
        if (IS_ERR(rc->data_inode)) {
                err = PTR_ERR(rc->data_inode);
@@ -4143,7 +4220,7 @@ int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len)
                btrfs_add_ordered_sum(inode, ordered, sums);
        }
        btrfs_put_ordered_extent(ordered);
-       return 0;
+       return ret;
 }
 
 void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
index 2d958be761c84556b39c60afa39999b0f3fd75d6..6a1086e83ffc898ff3ab7f7b33d91c2c442019d7 100644 (file)
@@ -181,7 +181,6 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
 int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid)
 {
        struct btrfs_root *dead_root;
-       struct btrfs_item *item;
        struct btrfs_root_item *ri;
        struct btrfs_key key;
        struct btrfs_key found_key;
@@ -214,7 +213,6 @@ again:
                        nritems = btrfs_header_nritems(leaf);
                        slot = path->slots[0];
                }
-               item = btrfs_item_nr(leaf, slot);
                btrfs_item_key_to_cpu(leaf, &key, slot);
                if (btrfs_key_type(&key) != BTRFS_ROOT_ITEM_KEY)
                        goto next;
index 144f8a5730f56991cda69558daadfaf1eb458081..8299a25ffc8f8313064cbd3e54278e9f5ebbc662 100644 (file)
@@ -61,6 +61,8 @@ static void btrfs_put_super(struct super_block *sb)
 
        ret = close_ctree(root);
        sb->s_fs_info = NULL;
+
+       (void)ret; /* FIXME: need to fix VFS to return error? */
 }
 
 enum {
@@ -68,7 +70,8 @@ enum {
        Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd,
        Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress,
        Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
-       Opt_discard, Opt_err,
+       Opt_discard, Opt_space_cache, Opt_clear_cache, Opt_err,
+       Opt_user_subvol_rm_allowed,
 };
 
 static match_table_t tokens = {
@@ -92,6 +95,9 @@ static match_table_t tokens = {
        {Opt_flushoncommit, "flushoncommit"},
        {Opt_ratio, "metadata_ratio=%d"},
        {Opt_discard, "discard"},
+       {Opt_space_cache, "space_cache"},
+       {Opt_clear_cache, "clear_cache"},
+       {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"},
        {Opt_err, NULL},
 };
 
@@ -235,6 +241,16 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                case Opt_discard:
                        btrfs_set_opt(info->mount_opt, DISCARD);
                        break;
+               case Opt_space_cache:
+                       printk(KERN_INFO "btrfs: enabling disk space caching\n");
+                       btrfs_set_opt(info->mount_opt, SPACE_CACHE);
+               case Opt_clear_cache:
+                       printk(KERN_INFO "btrfs: force clearing of disk cache\n");
+                       btrfs_set_opt(info->mount_opt, CLEAR_CACHE);
+                       break;
+               case Opt_user_subvol_rm_allowed:
+                       btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED);
+                       break;
                case Opt_err:
                        printk(KERN_INFO "btrfs: unrecognized mount option "
                               "'%s'\n", p);
@@ -380,7 +396,7 @@ static struct dentry *get_default_root(struct super_block *sb,
 find_root:
        new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
        if (IS_ERR(new_root))
-               return ERR_PTR(PTR_ERR(new_root));
+               return ERR_CAST(new_root);
 
        if (btrfs_root_refs(&new_root->root_item) == 0)
                return ERR_PTR(-ENOENT);
@@ -436,7 +452,6 @@ static int btrfs_fill_super(struct super_block *sb,
 {
        struct inode *inode;
        struct dentry *root_dentry;
-       struct btrfs_super_block *disk_super;
        struct btrfs_root *tree_root;
        struct btrfs_key key;
        int err;
@@ -458,7 +473,6 @@ static int btrfs_fill_super(struct super_block *sb,
                return PTR_ERR(tree_root);
        }
        sb->s_fs_info = tree_root;
-       disk_super = &tree_root->fs_info->super_copy;
 
        key.objectid = BTRFS_FIRST_FREE_OBJECTID;
        key.type = BTRFS_INODE_ITEM_KEY;
@@ -560,8 +574,8 @@ static int btrfs_test_super(struct super_block *s, void *data)
  * Note:  This is based on get_sb_bdev from fs/super.c with a few additions
  *       for multiple device setup.  Make sure to keep it in sync.
  */
-static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
-               const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
+               const char *dev_name, void *data)
 {
        struct block_device *bdev = NULL;
        struct super_block *s;
@@ -571,7 +585,6 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
        char *subvol_name = NULL;
        u64 subvol_objectid = 0;
        int error = 0;
-       int found = 0;
 
        if (!(flags & MS_RDONLY))
                mode |= FMODE_WRITE;
@@ -580,7 +593,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
                                          &subvol_name, &subvol_objectid,
                                          &fs_devices);
        if (error)
-               return error;
+               return ERR_PTR(error);
 
        error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices);
        if (error)
@@ -607,7 +620,6 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
                        goto error_close_devices;
                }
 
-               found = 1;
                btrfs_close_devices(fs_devices);
        } else {
                char b[BDEVNAME_SIZE];
@@ -629,7 +641,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
        if (IS_ERR(root)) {
                error = PTR_ERR(root);
                deactivate_locked_super(s);
-               goto error;
+               goto error_free_subvol_name;
        }
        /* if they gave us a subvolume name bind mount into that */
        if (strcmp(subvol_name, ".")) {
@@ -643,24 +655,21 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
                        deactivate_locked_super(s);
                        error = PTR_ERR(new_root);
                        dput(root);
-                       goto error_close_devices;
+                       goto error_free_subvol_name;
                }
                if (!new_root->d_inode) {
                        dput(root);
                        dput(new_root);
                        deactivate_locked_super(s);
                        error = -ENXIO;
-                       goto error_close_devices;
+                       goto error_free_subvol_name;
                }
                dput(root);
                root = new_root;
        }
 
-       mnt->mnt_sb = s;
-       mnt->mnt_root = root;
-
        kfree(subvol_name);
-       return 0;
+       return root;
 
 error_s:
        error = PTR_ERR(s);
@@ -668,8 +677,7 @@ error_close_devices:
        btrfs_close_devices(fs_devices);
 error_free_subvol_name:
        kfree(subvol_name);
-error:
-       return error;
+       return ERR_PTR(error);
 }
 
 static int btrfs_remount(struct super_block *sb, int *flags, char *data)
@@ -716,18 +724,25 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct list_head *head = &root->fs_info->space_info;
        struct btrfs_space_info *found;
        u64 total_used = 0;
+       u64 total_used_data = 0;
        int bits = dentry->d_sb->s_blocksize_bits;
        __be32 *fsid = (__be32 *)root->fs_info->fsid;
 
        rcu_read_lock();
-       list_for_each_entry_rcu(found, head, list)
+       list_for_each_entry_rcu(found, head, list) {
+               if (found->flags & (BTRFS_BLOCK_GROUP_METADATA |
+                                   BTRFS_BLOCK_GROUP_SYSTEM))
+                       total_used_data += found->disk_total;
+               else
+                       total_used_data += found->disk_used;
                total_used += found->disk_used;
+       }
        rcu_read_unlock();
 
        buf->f_namelen = BTRFS_NAME_LEN;
        buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
        buf->f_bfree = buf->f_blocks - (total_used >> bits);
-       buf->f_bavail = buf->f_bfree;
+       buf->f_bavail = buf->f_blocks - (total_used_data >> bits);
        buf->f_bsize = dentry->d_sb->s_blocksize;
        buf->f_type = BTRFS_SUPER_MAGIC;
 
@@ -746,7 +761,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 static struct file_system_type btrfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "btrfs",
-       .get_sb         = btrfs_get_sb,
+       .mount          = btrfs_mount,
        .kill_sb        = kill_anon_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 66e4c66cc63bf114900c6da4462c32e6bd0e65e0..1fffbc017bdfe0451cc2e67ccf5fd85623a12aee 100644 (file)
@@ -163,6 +163,7 @@ enum btrfs_trans_type {
        TRANS_START,
        TRANS_JOIN,
        TRANS_USERSPACE,
+       TRANS_JOIN_NOLOCK,
 };
 
 static int may_wait_transaction(struct btrfs_root *root, int type)
@@ -179,14 +180,14 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
 {
        struct btrfs_trans_handle *h;
        struct btrfs_transaction *cur_trans;
-       int retries = 0;
        int ret;
 again:
        h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
        if (!h)
                return ERR_PTR(-ENOMEM);
 
-       mutex_lock(&root->fs_info->trans_mutex);
+       if (type != TRANS_JOIN_NOLOCK)
+               mutex_lock(&root->fs_info->trans_mutex);
        if (may_wait_transaction(root, type))
                wait_current_trans(root);
 
@@ -195,7 +196,8 @@ again:
 
        cur_trans = root->fs_info->running_transaction;
        cur_trans->use_count++;
-       mutex_unlock(&root->fs_info->trans_mutex);
+       if (type != TRANS_JOIN_NOLOCK)
+               mutex_unlock(&root->fs_info->trans_mutex);
 
        h->transid = cur_trans->transid;
        h->transaction = cur_trans;
@@ -212,8 +214,7 @@ again:
        }
 
        if (num_items > 0) {
-               ret = btrfs_trans_reserve_metadata(h, root, num_items,
-                                                  &retries);
+               ret = btrfs_trans_reserve_metadata(h, root, num_items);
                if (ret == -EAGAIN) {
                        btrfs_commit_transaction(h, root);
                        goto again;
@@ -224,9 +225,11 @@ again:
                }
        }
 
-       mutex_lock(&root->fs_info->trans_mutex);
+       if (type != TRANS_JOIN_NOLOCK)
+               mutex_lock(&root->fs_info->trans_mutex);
        record_root_in_trans(h, root);
-       mutex_unlock(&root->fs_info->trans_mutex);
+       if (type != TRANS_JOIN_NOLOCK)
+               mutex_unlock(&root->fs_info->trans_mutex);
 
        if (!current->journal_info && type != TRANS_USERSPACE)
                current->journal_info = h;
@@ -244,6 +247,12 @@ struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
        return start_transaction(root, 0, TRANS_JOIN);
 }
 
+struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root,
+                                                         int num_blocks)
+{
+       return start_transaction(root, 0, TRANS_JOIN_NOLOCK);
+}
+
 struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
                                                         int num_blocks)
 {
@@ -270,6 +279,58 @@ static noinline int wait_for_commit(struct btrfs_root *root,
        return 0;
 }
 
+int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid)
+{
+       struct btrfs_transaction *cur_trans = NULL, *t;
+       int ret;
+
+       mutex_lock(&root->fs_info->trans_mutex);
+
+       ret = 0;
+       if (transid) {
+               if (transid <= root->fs_info->last_trans_committed)
+                       goto out_unlock;
+
+               /* find specified transaction */
+               list_for_each_entry(t, &root->fs_info->trans_list, list) {
+                       if (t->transid == transid) {
+                               cur_trans = t;
+                               break;
+                       }
+                       if (t->transid > transid)
+                               break;
+               }
+               ret = -EINVAL;
+               if (!cur_trans)
+                       goto out_unlock;  /* bad transid */
+       } else {
+               /* find newest transaction that is committing | committed */
+               list_for_each_entry_reverse(t, &root->fs_info->trans_list,
+                                           list) {
+                       if (t->in_commit) {
+                               if (t->commit_done)
+                                       goto out_unlock;
+                               cur_trans = t;
+                               break;
+                       }
+               }
+               if (!cur_trans)
+                       goto out_unlock;  /* nothing committing|committed */
+       }
+
+       cur_trans->use_count++;
+       mutex_unlock(&root->fs_info->trans_mutex);
+
+       wait_for_commit(root, cur_trans);
+
+       mutex_lock(&root->fs_info->trans_mutex);
+       put_transaction(cur_trans);
+       ret = 0;
+out_unlock:
+       mutex_unlock(&root->fs_info->trans_mutex);
+       return ret;
+}
+
 #if 0
 /*
  * rate limit against the drop_snapshot code.  This helps to slow down new
@@ -348,7 +409,7 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
 }
 
 static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
-                         struct btrfs_root *root, int throttle)
+                         struct btrfs_root *root, int throttle, int lock)
 {
        struct btrfs_transaction *cur_trans = trans->transaction;
        struct btrfs_fs_info *info = root->fs_info;
@@ -376,26 +437,29 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
 
        btrfs_trans_release_metadata(trans, root);
 
-       if (!root->fs_info->open_ioctl_trans &&
+       if (lock && !root->fs_info->open_ioctl_trans &&
            should_end_transaction(trans, root))
                trans->transaction->blocked = 1;
 
-       if (cur_trans->blocked && !cur_trans->in_commit) {
+       if (lock && cur_trans->blocked && !cur_trans->in_commit) {
                if (throttle)
                        return btrfs_commit_transaction(trans, root);
                else
                        wake_up_process(info->transaction_kthread);
        }
 
-       mutex_lock(&info->trans_mutex);
+       if (lock)
+               mutex_lock(&info->trans_mutex);
        WARN_ON(cur_trans != info->running_transaction);
        WARN_ON(cur_trans->num_writers < 1);
        cur_trans->num_writers--;
 
+       smp_mb();
        if (waitqueue_active(&cur_trans->writer_wait))
                wake_up(&cur_trans->writer_wait);
        put_transaction(cur_trans);
-       mutex_unlock(&info->trans_mutex);
+       if (lock)
+               mutex_unlock(&info->trans_mutex);
 
        if (current->journal_info == trans)
                current->journal_info = NULL;
@@ -411,13 +475,19 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
 int btrfs_end_transaction(struct btrfs_trans_handle *trans,
                          struct btrfs_root *root)
 {
-       return __btrfs_end_transaction(trans, root, 0);
+       return __btrfs_end_transaction(trans, root, 0, 1);
 }
 
 int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root)
 {
-       return __btrfs_end_transaction(trans, root, 1);
+       return __btrfs_end_transaction(trans, root, 1, 1);
+}
+
+int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
+                                struct btrfs_root *root)
+{
+       return __btrfs_end_transaction(trans, root, 0, 0);
 }
 
 /*
@@ -836,7 +906,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        struct extent_buffer *tmp;
        struct extent_buffer *old;
        int ret;
-       int retries = 0;
        u64 to_reserve = 0;
        u64 index = 0;
        u64 objectid;
@@ -858,7 +927,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
 
        if (to_reserve > 0) {
                ret = btrfs_block_rsv_add(trans, root, &pending->block_rsv,
-                                         to_reserve, &retries);
+                                         to_reserve);
                if (ret) {
                        pending->error = ret;
                        goto fail;
@@ -966,6 +1035,8 @@ static void update_super_roots(struct btrfs_root *root)
        super->root = root_item->bytenr;
        super->generation = root_item->generation;
        super->root_level = root_item->level;
+       if (super->cache_generation != 0 || btrfs_test_opt(root, SPACE_CACHE))
+               super->cache_generation = root_item->generation;
 }
 
 int btrfs_transaction_in_commit(struct btrfs_fs_info *info)
@@ -988,11 +1059,127 @@ int btrfs_transaction_blocked(struct btrfs_fs_info *info)
        return ret;
 }
 
+/*
+ * wait for the current transaction commit to start and block subsequent
+ * transaction joins
+ */
+static void wait_current_trans_commit_start(struct btrfs_root *root,
+                                           struct btrfs_transaction *trans)
+{
+       DEFINE_WAIT(wait);
+
+       if (trans->in_commit)
+               return;
+
+       while (1) {
+               prepare_to_wait(&root->fs_info->transaction_blocked_wait, &wait,
+                               TASK_UNINTERRUPTIBLE);
+               if (trans->in_commit) {
+                       finish_wait(&root->fs_info->transaction_blocked_wait,
+                                   &wait);
+                       break;
+               }
+               mutex_unlock(&root->fs_info->trans_mutex);
+               schedule();
+               mutex_lock(&root->fs_info->trans_mutex);
+               finish_wait(&root->fs_info->transaction_blocked_wait, &wait);
+       }
+}
+
+/*
+ * wait for the current transaction to start and then become unblocked.
+ * caller holds ref.
+ */
+static void wait_current_trans_commit_start_and_unblock(struct btrfs_root *root,
+                                        struct btrfs_transaction *trans)
+{
+       DEFINE_WAIT(wait);
+
+       if (trans->commit_done || (trans->in_commit && !trans->blocked))
+               return;
+
+       while (1) {
+               prepare_to_wait(&root->fs_info->transaction_wait, &wait,
+                               TASK_UNINTERRUPTIBLE);
+               if (trans->commit_done ||
+                   (trans->in_commit && !trans->blocked)) {
+                       finish_wait(&root->fs_info->transaction_wait,
+                                   &wait);
+                       break;
+               }
+               mutex_unlock(&root->fs_info->trans_mutex);
+               schedule();
+               mutex_lock(&root->fs_info->trans_mutex);
+               finish_wait(&root->fs_info->transaction_wait,
+                           &wait);
+       }
+}
+
+/*
+ * commit transactions asynchronously. once btrfs_commit_transaction_async
+ * returns, any subsequent transaction will not be allowed to join.
+ */
+struct btrfs_async_commit {
+       struct btrfs_trans_handle *newtrans;
+       struct btrfs_root *root;
+       struct delayed_work work;
+};
+
+static void do_async_commit(struct work_struct *work)
+{
+       struct btrfs_async_commit *ac =
+               container_of(work, struct btrfs_async_commit, work.work);
+
+       btrfs_commit_transaction(ac->newtrans, ac->root);
+       kfree(ac);
+}
+
+int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
+                                  struct btrfs_root *root,
+                                  int wait_for_unblock)
+{
+       struct btrfs_async_commit *ac;
+       struct btrfs_transaction *cur_trans;
+
+       ac = kmalloc(sizeof(*ac), GFP_NOFS);
+       BUG_ON(!ac);
+
+       INIT_DELAYED_WORK(&ac->work, do_async_commit);
+       ac->root = root;
+       ac->newtrans = btrfs_join_transaction(root, 0);
+
+       /* take transaction reference */
+       mutex_lock(&root->fs_info->trans_mutex);
+       cur_trans = trans->transaction;
+       cur_trans->use_count++;
+       mutex_unlock(&root->fs_info->trans_mutex);
+
+       btrfs_end_transaction(trans, root);
+       schedule_delayed_work(&ac->work, 0);
+
+       /* wait for transaction to start and unblock */
+       mutex_lock(&root->fs_info->trans_mutex);
+       if (wait_for_unblock)
+               wait_current_trans_commit_start_and_unblock(root, cur_trans);
+       else
+               wait_current_trans_commit_start(root, cur_trans);
+       put_transaction(cur_trans);
+       mutex_unlock(&root->fs_info->trans_mutex);
+
+       return 0;
+}
+
+/*
+ * btrfs_transaction state sequence:
+ *    in_commit = 0, blocked = 0  (initial)
+ *    in_commit = 1, blocked = 1
+ *    blocked = 0
+ *    commit_done = 1
+ */
 int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
                             struct btrfs_root *root)
 {
        unsigned long joined = 0;
-       unsigned long timeout = 1;
        struct btrfs_transaction *cur_trans;
        struct btrfs_transaction *prev_trans = NULL;
        DEFINE_WAIT(wait);
@@ -1039,6 +1226,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 
        trans->transaction->in_commit = 1;
        trans->transaction->blocked = 1;
+       wake_up(&root->fs_info->transaction_blocked_wait);
+
        if (cur_trans->list.prev != &root->fs_info->trans_list) {
                prev_trans = list_entry(cur_trans->list.prev,
                                        struct btrfs_transaction, list);
@@ -1063,11 +1252,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
                        snap_pending = 1;
 
                WARN_ON(cur_trans != trans->transaction);
-               if (cur_trans->num_writers > 1)
-                       timeout = MAX_SCHEDULE_TIMEOUT;
-               else if (should_grow)
-                       timeout = 1;
-
                mutex_unlock(&root->fs_info->trans_mutex);
 
                if (flush_on_commit || snap_pending) {
@@ -1089,8 +1273,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
                                TASK_UNINTERRUPTIBLE);
 
                smp_mb();
-               if (cur_trans->num_writers > 1 || should_grow)
-                       schedule_timeout(timeout);
+               if (cur_trans->num_writers > 1)
+                       schedule_timeout(MAX_SCHEDULE_TIMEOUT);
+               else if (should_grow)
+                       schedule_timeout(1);
 
                mutex_lock(&root->fs_info->trans_mutex);
                finish_wait(&cur_trans->writer_wait, &wait);
index e104986d0bfd682e036ec67d236d65d062422164..f104b57ad4efad42ce6f98d257cd62f3297c3cea 100644 (file)
@@ -87,12 +87,17 @@ static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
 
 int btrfs_end_transaction(struct btrfs_trans_handle *trans,
                          struct btrfs_root *root);
+int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
+                                struct btrfs_root *root);
 struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
                                                   int num_items);
 struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
                                                  int num_blocks);
+struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root,
+                                                         int num_blocks);
 struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
                                                         int num_blocks);
+int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid);
 int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root);
 int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
@@ -104,6 +109,9 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly);
 int btrfs_clean_old_snapshots(struct btrfs_root *root);
 int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
                             struct btrfs_root *root);
+int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
+                                  struct btrfs_root *root,
+                                  int wait_for_unblock);
 int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root);
 int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
index f7ac8e013ed73459139ae07b00189ffa952bba08..992ab425599d10bfe0b32e866b9c4bd366a1a9b9 100644 (file)
@@ -36,7 +36,6 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
        int ret = 0;
        int wret;
        int level;
-       int orig_level;
        int is_extent = 0;
        int next_key_ret = 0;
        u64 last_ret = 0;
@@ -64,7 +63,6 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
                return -ENOMEM;
 
        level = btrfs_header_level(root->node);
-       orig_level = level;
 
        if (level == 0)
                goto out;
index fb102a9aee9cc1ee3213d04bc1bae6fec6644f2d..a29f19384a27bc91526d46fb3cbefdbe2bd8a5ce 100644 (file)
@@ -786,7 +786,6 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
 {
        struct inode *dir;
        int ret;
-       struct btrfs_key location;
        struct btrfs_inode_ref *ref;
        struct btrfs_dir_item *di;
        struct inode *inode;
@@ -795,10 +794,6 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
        unsigned long ref_ptr;
        unsigned long ref_end;
 
-       location.objectid = key->objectid;
-       location.type = BTRFS_INODE_ITEM_KEY;
-       location.offset = 0;
-
        /*
         * it is possible that we didn't log all the parent directories
         * for a given inode.  If we don't find the dir, just don't
@@ -1583,7 +1578,6 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
        struct btrfs_path *path;
        struct btrfs_root *root = wc->replay_dest;
        struct btrfs_key key;
-       u32 item_size;
        int level;
        int i;
        int ret;
@@ -1601,7 +1595,6 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
        nritems = btrfs_header_nritems(eb);
        for (i = 0; i < nritems; i++) {
                btrfs_item_key_to_cpu(eb, &key, i);
-               item_size = btrfs_item_size_nr(eb, i);
 
                /* inode keys are done during the first stage */
                if (key.type == BTRFS_INODE_ITEM_KEY &&
@@ -1668,7 +1661,6 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
                                   struct walk_control *wc)
 {
        u64 root_owner;
-       u64 root_gen;
        u64 bytenr;
        u64 ptr_gen;
        struct extent_buffer *next;
@@ -1698,7 +1690,6 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
 
                parent = path->nodes[*level];
                root_owner = btrfs_header_owner(parent);
-               root_gen = btrfs_header_generation(parent);
 
                next = btrfs_find_create_tree_block(root, bytenr, blocksize);
 
@@ -1749,7 +1740,6 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
                                 struct walk_control *wc)
 {
        u64 root_owner;
-       u64 root_gen;
        int i;
        int slot;
        int ret;
@@ -1757,8 +1747,6 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
        for (i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) {
                slot = path->slots[i];
                if (slot + 1 < btrfs_header_nritems(path->nodes[i])) {
-                       struct extent_buffer *node;
-                       node = path->nodes[i];
                        path->slots[i]++;
                        *level = i;
                        WARN_ON(*level == 0);
@@ -1771,7 +1759,6 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
                                parent = path->nodes[*level + 1];
 
                        root_owner = btrfs_header_owner(parent);
-                       root_gen = btrfs_header_generation(parent);
                        wc->process_func(root, path->nodes[*level], wc,
                                 btrfs_header_generation(path->nodes[*level]));
                        if (wc->free) {
@@ -2273,7 +2260,7 @@ fail:
        }
        btrfs_end_log_trans(root);
 
-       return 0;
+       return err;
 }
 
 /* see comments for btrfs_del_dir_entries_in_log */
@@ -2729,7 +2716,6 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
        struct btrfs_key max_key;
        struct btrfs_root *log = root->log_root;
        struct extent_buffer *src = NULL;
-       u32 size;
        int err = 0;
        int ret;
        int nritems;
@@ -2793,7 +2779,6 @@ again:
                        break;
 
                src = path->nodes[0];
-               size = btrfs_item_size_nr(src, path->slots[0]);
                if (ins_nr && ins_start_slot + ins_nr == path->slots[0]) {
                        ins_nr++;
                        goto next_slot;
index e25e46a8b4e2540639f5d1dbcfbbb71c955f01e6..cc04dc1445d64da8694401c2cbc2fde27105b8f9 100644 (file)
@@ -1898,7 +1898,6 @@ int btrfs_balance(struct btrfs_root *dev_root)
        u64 size_to_free;
        struct btrfs_path *path;
        struct btrfs_key key;
-       struct btrfs_chunk *chunk;
        struct btrfs_root *chunk_root = dev_root->fs_info->chunk_root;
        struct btrfs_trans_handle *trans;
        struct btrfs_key found_key;
@@ -1962,9 +1961,6 @@ int btrfs_balance(struct btrfs_root *dev_root)
                if (found_key.objectid != key.objectid)
                        break;
 
-               chunk = btrfs_item_ptr(path->nodes[0],
-                                      path->slots[0],
-                                      struct btrfs_chunk);
                /* chunk zero is special */
                if (found_key.offset == 0)
                        break;
@@ -3031,8 +3027,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
                }
                bio->bi_sector = multi->stripes[dev_nr].physical >> 9;
                dev = multi->stripes[dev_nr].dev;
-               BUG_ON(rw == WRITE && !dev->writeable);
-               if (dev && dev->bdev) {
+               if (dev && dev->bdev && (rw != WRITE || dev->writeable)) {
                        bio->bi_bdev = dev->bdev;
                        if (async_submit)
                                schedule_bio(root, dev, rw, bio);
index 88ecbb215878ae3573a5bbedfc4afadc6ef0a73d..698fdd2c739c9286e549c290983ed1f08138ef39 100644 (file)
@@ -178,7 +178,6 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
        struct inode *inode = dentry->d_inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_path *path;
-       struct btrfs_item *item;
        struct extent_buffer *leaf;
        struct btrfs_dir_item *di;
        int ret = 0, slot, advance;
@@ -234,7 +233,6 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
                }
                advance = 1;
 
-               item = btrfs_item_nr(leaf, slot);
                btrfs_item_key_to_cpu(leaf, &found_key, slot);
 
                /* check to make sure this item is what we want */
index 3e2b90eaa23945415d56cbd0edfec6848e5dd2d6..b9cd5445f71cac0c6b2d565f80d065091d65fa4b 100644 (file)
@@ -199,8 +199,6 @@ int btrfs_zlib_compress_pages(struct address_space *mapping,
        int nr_pages = 0;
        struct page *in_page = NULL;
        struct page *out_page = NULL;
-       int out_written = 0;
-       int in_read = 0;
        unsigned long bytes_left;
 
        *out_pages = 0;
@@ -233,9 +231,6 @@ int btrfs_zlib_compress_pages(struct address_space *mapping,
        workspace->def_strm.avail_out = PAGE_CACHE_SIZE;
        workspace->def_strm.avail_in = min(len, PAGE_CACHE_SIZE);
 
-       out_written = 0;
-       in_read = 0;
-
        while (workspace->def_strm.total_in < len) {
                ret = zlib_deflate(&workspace->def_strm, Z_SYNC_FLUSH);
                if (ret != Z_OK) {
index d6e0e042189184183b4ccf82da8787622e7f7d11..08b460ae05395311f833d54d39c2bf95c3c89667 100644 (file)
@@ -635,7 +635,7 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
 /*
  * mount: join the ceph cluster, and open root directory.
  */
-static int ceph_mount(struct ceph_fs_client *fsc, struct vfsmount *mnt,
+static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
                      const char *path)
 {
        int err;
@@ -678,16 +678,14 @@ static int ceph_mount(struct ceph_fs_client *fsc, struct vfsmount *mnt,
                }
        }
 
-       mnt->mnt_root = root;
-       mnt->mnt_sb = fsc->sb;
-
        fsc->mount_state = CEPH_MOUNT_MOUNTED;
        dout("mount success\n");
-       err = 0;
+       mutex_unlock(&fsc->client->mount_mutex);
+       return root;
 
 out:
        mutex_unlock(&fsc->client->mount_mutex);
-       return err;
+       return ERR_PTR(err);
 
 fail:
        if (first) {
@@ -777,41 +775,45 @@ static int ceph_register_bdi(struct super_block *sb,
        return err;
 }
 
-static int ceph_get_sb(struct file_system_type *fs_type,
-                      int flags, const char *dev_name, void *data,
-                      struct vfsmount *mnt)
+static struct dentry *ceph_mount(struct file_system_type *fs_type,
+                      int flags, const char *dev_name, void *data)
 {
        struct super_block *sb;
        struct ceph_fs_client *fsc;
+       struct dentry *res;
        int err;
        int (*compare_super)(struct super_block *, void *) = ceph_compare_super;
        const char *path = NULL;
        struct ceph_mount_options *fsopt = NULL;
        struct ceph_options *opt = NULL;
 
-       dout("ceph_get_sb\n");
+       dout("ceph_mount\n");
        err = parse_mount_options(&fsopt, &opt, flags, data, dev_name, &path);
-       if (err < 0)
+       if (err < 0) {
+               res = ERR_PTR(err);
                goto out_final;
+       }
 
        /* create client (which we may/may not use) */
        fsc = create_fs_client(fsopt, opt);
        if (IS_ERR(fsc)) {
-               err = PTR_ERR(fsc);
+               res = ERR_CAST(fsc);
                kfree(fsopt);
                kfree(opt);
                goto out_final;
        }
 
        err = ceph_mdsc_init(fsc);
-       if (err < 0)
+       if (err < 0) {
+               res = ERR_PTR(err);
                goto out;
+       }
 
        if (ceph_test_opt(fsc->client, NOSHARE))
                compare_super = NULL;
        sb = sget(fs_type, compare_super, ceph_set_super, fsc);
        if (IS_ERR(sb)) {
-               err = PTR_ERR(sb);
+               res = ERR_CAST(sb);
                goto out;
        }
 
@@ -823,16 +825,18 @@ static int ceph_get_sb(struct file_system_type *fs_type,
        } else {
                dout("get_sb using new client %p\n", fsc);
                err = ceph_register_bdi(sb, fsc);
-               if (err < 0)
+               if (err < 0) {
+                       res = ERR_PTR(err);
                        goto out_splat;
+               }
        }
 
-       err = ceph_mount(fsc, mnt, path);
-       if (err < 0)
+       res = ceph_real_mount(fsc, path);
+       if (IS_ERR(res))
                goto out_splat;
-       dout("root %p inode %p ino %llx.%llx\n", mnt->mnt_root,
-            mnt->mnt_root->d_inode, ceph_vinop(mnt->mnt_root->d_inode));
-       return 0;
+       dout("root %p inode %p ino %llx.%llx\n", res,
+            res->d_inode, ceph_vinop(res->d_inode));
+       return res;
 
 out_splat:
        ceph_mdsc_close_sessions(fsc->mdsc);
@@ -843,8 +847,8 @@ out:
        ceph_mdsc_destroy(fsc);
        destroy_fs_client(fsc);
 out_final:
-       dout("ceph_get_sb fail %d\n", err);
-       return err;
+       dout("ceph_mount fail %ld\n", PTR_ERR(res));
+       return res;
 }
 
 static void ceph_kill_sb(struct super_block *s)
@@ -860,7 +864,7 @@ static void ceph_kill_sb(struct super_block *s)
 static struct file_system_type ceph_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ceph",
-       .get_sb         = ceph_get_sb,
+       .mount          = ceph_mount,
        .kill_sb        = ceph_kill_sb,
        .fs_flags       = FS_RENAME_DOES_D_MOVE,
 };
index 917b7d449bb2a6248c28c23284cf82d9c032f285..0ed213970cede228e097a04eec99c94ce97a6146 100644 (file)
@@ -2,6 +2,9 @@ config CIFS
        tristate "CIFS support (advanced network filesystem, SMBFS successor)"
        depends on INET
        select NLS
+       select CRYPTO
+       select CRYPTO_MD5
+       select CRYPTO_ARC4
        help
          This is the client VFS module for the Common Internet File System
          (CIFS) protocol which is the successor to the Server Message Block
index 5aff46c61e521cbaef027b92d1a4bdd7bb86c547..355abcdcda980acfcd70dcb54d4bb798edf6fcae 100644 (file)
@@ -81,7 +81,7 @@ u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for
 
 v) mount check for unmatched uids
 
-w) Add support for new vfs entry points for setlease and fallocate 
+w) Add support for new vfs entry point for fallocate
 
 x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of 
 processes can proceed better in parallel (on the server)
index 525ba59a41058a6d13f4311fb841eb2604a00140..e9a393c9c2ca4ddb8ec3d75cfcf0766234ec1789 100644 (file)
@@ -15,7 +15,7 @@
  *   the GNU Lesser General Public License for more details.
  *
  */
-#include <linux/radix-tree.h>
+#include <linux/rbtree.h>
 
 #ifndef _CIFS_FS_SB_H
 #define _CIFS_FS_SB_H
@@ -42,9 +42,9 @@
 #define CIFS_MOUNT_MULTIUSER   0x20000 /* multiuser mount */
 
 struct cifs_sb_info {
-       struct radix_tree_root tlink_tree;
-#define CIFS_TLINK_MASTER_TAG          0       /* is "master" (mount) tcon */
+       struct rb_root tlink_tree;
        spinlock_t tlink_tree_lock;
+       struct tcon_link *master_tlink;
        struct nls_table *local_nls;
        unsigned int rsize;
        unsigned int wsize;
index 7ac0056294cf65357d6c45b0c3409e69d4110931..f856732161aba416234842ed8d5a496df6336823 100644 (file)
@@ -43,18 +43,32 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
                       unsigned char *p24);
 
 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
-                               const struct session_key *key, char *signature)
+                               struct TCP_Server_Info *server, char *signature)
 {
-       struct  MD5Context context;
+       int rc;
 
-       if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL))
+       if (cifs_pdu == NULL || signature == NULL || server == NULL)
                return -EINVAL;
 
-       cifs_MD5_init(&context);
-       cifs_MD5_update(&context, (char *)&key->data, key->len);
-       cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
+       if (!server->secmech.sdescmd5) {
+               cERROR(1, "%s: Can't generate signature\n", __func__);
+               return -1;
+       }
+
+       rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
+       if (rc) {
+               cERROR(1, "%s: Oould not init md5\n", __func__);
+               return rc;
+       }
+
+       crypto_shash_update(&server->secmech.sdescmd5->shash,
+               server->session_key.response, server->session_key.len);
+
+       crypto_shash_update(&server->secmech.sdescmd5->shash,
+               cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
+
+       rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
 
-       cifs_MD5_final(signature, &context);
        return 0;
 }
 
@@ -79,8 +93,7 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
        server->sequence_number++;
        spin_unlock(&GlobalMid_Lock);
 
-       rc = cifs_calculate_signature(cifs_pdu, &server->session_key,
-                                     smb_signature);
+       rc = cifs_calculate_signature(cifs_pdu, server, smb_signature);
        if (rc)
                memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
        else
@@ -90,16 +103,28 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
 }
 
 static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
-                               const struct session_key *key, char *signature)
+                               struct TCP_Server_Info *server, char *signature)
 {
-       struct  MD5Context context;
        int i;
+       int rc;
 
-       if ((iov == NULL) || (signature == NULL) || (key == NULL))
+       if (iov == NULL || signature == NULL || server == NULL)
                return -EINVAL;
 
-       cifs_MD5_init(&context);
-       cifs_MD5_update(&context, (char *)&key->data, key->len);
+       if (!server->secmech.sdescmd5) {
+               cERROR(1, "%s: Can't generate signature\n", __func__);
+               return -1;
+       }
+
+       rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
+       if (rc) {
+               cERROR(1, "%s: Oould not init md5\n", __func__);
+               return rc;
+       }
+
+       crypto_shash_update(&server->secmech.sdescmd5->shash,
+               server->session_key.response, server->session_key.len);
+
        for (i = 0; i < n_vec; i++) {
                if (iov[i].iov_len == 0)
                        continue;
@@ -112,18 +137,18 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
                if (i == 0) {
                        if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
                                break; /* nothing to sign or corrupt header */
-                       cifs_MD5_update(&context, iov[0].iov_base+4,
-                                 iov[0].iov_len-4);
+                       crypto_shash_update(&server->secmech.sdescmd5->shash,
+                               iov[i].iov_base + 4, iov[i].iov_len - 4);
                } else
-                       cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len);
+                       crypto_shash_update(&server->secmech.sdescmd5->shash,
+                               iov[i].iov_base, iov[i].iov_len);
        }
 
-       cifs_MD5_final(signature, &context);
+       rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
 
-       return 0;
+       return rc;
 }
 
-
 int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
                   __u32 *pexpected_response_sequence_number)
 {
@@ -146,8 +171,7 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
        server->sequence_number++;
        spin_unlock(&GlobalMid_Lock);
 
-       rc = cifs_calc_signature2(iov, n_vec, &server->session_key,
-                                     smb_signature);
+       rc = cifs_calc_signature2(iov, n_vec, server, smb_signature);
        if (rc)
                memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
        else
@@ -157,14 +181,14 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
 }
 
 int cifs_verify_signature(struct smb_hdr *cifs_pdu,
-                         const struct session_key *session_key,
+                         struct TCP_Server_Info *server,
                          __u32 expected_sequence_number)
 {
        unsigned int rc;
        char server_response_sig[8];
        char what_we_think_sig_should_be[20];
 
-       if (cifs_pdu == NULL || session_key == NULL)
+       if (cifs_pdu == NULL || server == NULL)
                return -EINVAL;
 
        if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
@@ -193,7 +217,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
                                        cpu_to_le32(expected_sequence_number);
        cifs_pdu->Signature.Sequence.Reserved = 0;
 
-       rc = cifs_calculate_signature(cifs_pdu, session_key,
+       rc = cifs_calculate_signature(cifs_pdu, server,
                what_we_think_sig_should_be);
 
        if (rc)
@@ -209,18 +233,28 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
 
 }
 
-/* We fill in key by putting in 40 byte array which was allocated by caller */
-int cifs_calculate_session_key(struct session_key *key, const char *rn,
-                          const char *password)
+/* first calculate 24 bytes ntlm response and then 16 byte session key */
+int setup_ntlm_response(struct cifsSesInfo *ses)
 {
-       char temp_key[16];
-       if ((key == NULL) || (rn == NULL))
+       unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
+       char temp_key[CIFS_SESS_KEY_SIZE];
+
+       if (!ses)
                return -EINVAL;
 
-       E_md4hash(password, temp_key);
-       mdfour(key->data.ntlm, temp_key, 16);
-       memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE);
-       key->len = 40;
+       ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
+       if (!ses->auth_key.response) {
+               cERROR(1, "NTLM can't allocate (%u bytes) memory", temp_len);
+               return -ENOMEM;
+       }
+       ses->auth_key.len = temp_len;
+
+       SMBNTencrypt(ses->password, ses->server->cryptkey,
+                       ses->auth_key.response + CIFS_SESS_KEY_SIZE);
+
+       E_md4hash(ses->password, temp_key);
+       mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
+
        return 0;
 }
 
@@ -294,15 +328,15 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
         * two times the unicode length of a server name +
         * size of a timestamp (which is 8 bytes).
         */
-       ses->tilen = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
-       ses->tiblob = kzalloc(ses->tilen, GFP_KERNEL);
-       if (!ses->tiblob) {
-               ses->tilen = 0;
+       ses->auth_key.len = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
+       ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
+       if (!ses->auth_key.response) {
+               ses->auth_key.len = 0;
                cERROR(1, "Challenge target info allocation failure");
                return -ENOMEM;
        }
 
-       blobptr = ses->tiblob;
+       blobptr = ses->auth_key.response;
        attrptr = (struct ntlmssp2_name *) blobptr;
 
        attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
@@ -357,7 +391,7 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
  * about target string i.e. for some, just user name might suffice.
  */
 static int
-find_domain_name(struct cifsSesInfo *ses)
+find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
 {
        unsigned int attrsize;
        unsigned int type;
@@ -366,11 +400,11 @@ find_domain_name(struct cifsSesInfo *ses)
        unsigned char *blobend;
        struct ntlmssp2_name *attrptr;
 
-       if (!ses->tilen || !ses->tiblob)
+       if (!ses->auth_key.len || !ses->auth_key.response)
                return 0;
 
-       blobptr = ses->tiblob;
-       blobend = ses->tiblob + ses->tilen;
+       blobptr = ses->auth_key.response;
+       blobend = blobptr + ses->auth_key.len;
 
        while (blobptr + onesize < blobend) {
                attrptr = (struct ntlmssp2_name *) blobptr;
@@ -386,16 +420,13 @@ find_domain_name(struct cifsSesInfo *ses)
                        if (!attrsize)
                                break;
                        if (!ses->domainName) {
-                               struct nls_table *default_nls;
                                ses->domainName =
                                        kmalloc(attrsize + 1, GFP_KERNEL);
                                if (!ses->domainName)
                                                return -ENOMEM;
-                               default_nls = load_nls_default();
                                cifs_from_ucs2(ses->domainName,
                                        (__le16 *)blobptr, attrsize, attrsize,
-                                       default_nls, false);
-                               unload_nls(default_nls);
+                                       nls_cp, false);
                                break;
                        }
                }
@@ -405,82 +436,136 @@ find_domain_name(struct cifsSesInfo *ses)
        return 0;
 }
 
-static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
+static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash,
                            const struct nls_table *nls_cp)
 {
        int rc = 0;
        int len;
-       char nt_hash[16];
-       struct HMACMD5Context *pctxt;
+       char nt_hash[CIFS_NTHASH_SIZE];
        wchar_t *user;
        wchar_t *domain;
+       wchar_t *server;
 
-       pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL);
-
-       if (pctxt == NULL)
-               return -ENOMEM;
+       if (!ses->server->secmech.sdeschmacmd5) {
+               cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
+               return -1;
+       }
 
        /* calculate md4 hash of password */
        E_md4hash(ses->password, nt_hash);
 
-       /* convert Domainname to unicode and uppercase */
-       hmac_md5_init_limK_to_64(nt_hash, 16, pctxt);
+       crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
+                               CIFS_NTHASH_SIZE);
+
+       rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
+       if (rc) {
+               cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n");
+               return rc;
+       }
 
        /* convert ses->userName to unicode and uppercase */
        len = strlen(ses->userName);
        user = kmalloc(2 + (len * 2), GFP_KERNEL);
-       if (user == NULL)
+       if (user == NULL) {
+               cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
+               rc = -ENOMEM;
                goto calc_exit_2;
+       }
        len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
        UniStrupr(user);
-       hmac_md5_update((char *)user, 2*len, pctxt);
+
+       crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
+                               (char *)user, 2 * len);
 
        /* convert ses->domainName to unicode and uppercase */
        if (ses->domainName) {
                len = strlen(ses->domainName);
 
                domain = kmalloc(2 + (len * 2), GFP_KERNEL);
-               if (domain == NULL)
+               if (domain == NULL) {
+                       cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
+                       rc = -ENOMEM;
                        goto calc_exit_1;
+               }
                len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
                                        nls_cp);
-               /* the following line was removed since it didn't work well
-                  with lower cased domain name that passed as an option.
-                  Maybe converting the domain name earlier makes sense */
-               /* UniStrupr(domain); */
-
-               hmac_md5_update((char *)domain, 2*len, pctxt);
-
+               crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
+                                       (char *)domain, 2 * len);
                kfree(domain);
+       } else if (ses->serverName) {
+               len = strlen(ses->serverName);
+
+               server = kmalloc(2 + (len * 2), GFP_KERNEL);
+               if (server == NULL) {
+                       cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
+                       rc = -ENOMEM;
+                       goto calc_exit_1;
+               }
+               len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
+                                       nls_cp);
+               crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
+                                       (char *)server, 2 * len);
+               kfree(server);
        }
+
+       rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
+                                       ntlmv2_hash);
+
 calc_exit_1:
        kfree(user);
 calc_exit_2:
-       /* BB FIXME what about bytes 24 through 40 of the signing key?
-          compare with the NTLM example */
-       hmac_md5_final(ses->ntlmv2_hash, pctxt);
+       return rc;
+}
+
+static int
+CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
+{
+       int rc;
+       unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
+
+       if (!ses->server->secmech.sdeschmacmd5) {
+               cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
+               return -1;
+       }
+
+       crypto_shash_setkey(ses->server->secmech.hmacmd5,
+                               ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
+
+       rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
+       if (rc) {
+               cERROR(1, "CalcNTLMv2_response: could not init hmacmd5");
+               return rc;
+       }
+
+       if (ses->server->secType == RawNTLMSSP)
+               memcpy(ses->auth_key.response + offset,
+                       ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
+       else
+               memcpy(ses->auth_key.response + offset,
+                       ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
+       crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
+               ses->auth_key.response + offset, ses->auth_key.len - offset);
+
+       rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
+               ses->auth_key.response + CIFS_SESS_KEY_SIZE);
 
-       kfree(pctxt);
        return rc;
 }
 
+
 int
-setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
-                     const struct nls_table *nls_cp)
+setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
 {
        int rc;
-       struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf;
-       struct HMACMD5Context context;
-
-       buf->blob_signature = cpu_to_le32(0x00000101);
-       buf->reserved = 0;
-       buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
-       get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
-       buf->reserved2 = 0;
+       int baselen;
+       unsigned int tilen;
+       struct ntlmv2_resp *buf;
+       char ntlmv2_hash[16];
+       unsigned char *tiblob = NULL; /* target info blob */
 
        if (ses->server->secType == RawNTLMSSP) {
                if (!ses->domainName) {
-                       rc = find_domain_name(ses);
+                       rc = find_domain_name(ses, nls_cp);
                        if (rc) {
                                cERROR(1, "error %d finding domain name", rc);
                                goto setup_ntlmv2_rsp_ret;
@@ -490,51 +575,179 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
                rc = build_avpair_blob(ses, nls_cp);
                if (rc) {
                        cERROR(1, "error %d building av pair blob", rc);
-                       return rc;
+                       goto setup_ntlmv2_rsp_ret;
                }
        }
 
-       /* calculate buf->ntlmv2_hash */
-       rc = calc_ntlmv2_hash(ses, nls_cp);
+       baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
+       tilen = ses->auth_key.len;
+       tiblob = ses->auth_key.response;
+
+       ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
+       if (!ses->auth_key.response) {
+               rc = ENOMEM;
+               ses->auth_key.len = 0;
+               cERROR(1, "%s: Can't allocate auth blob", __func__);
+               goto setup_ntlmv2_rsp_ret;
+       }
+       ses->auth_key.len += baselen;
+
+       buf = (struct ntlmv2_resp *)
+                       (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
+       buf->blob_signature = cpu_to_le32(0x00000101);
+       buf->reserved = 0;
+       buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
+       get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
+       buf->reserved2 = 0;
+
+       memcpy(ses->auth_key.response + baselen, tiblob, tilen);
+
+       /* calculate ntlmv2_hash */
+       rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
        if (rc) {
                cERROR(1, "could not get v2 hash rc %d", rc);
                goto setup_ntlmv2_rsp_ret;
        }
-       CalcNTLMv2_response(ses, resp_buf);
+
+       /* calculate first part of the client response (CR1) */
+       rc = CalcNTLMv2_response(ses, ntlmv2_hash);
+       if (rc) {
+               cERROR(1, "Could not calculate CR1  rc: %d", rc);
+               goto setup_ntlmv2_rsp_ret;
+       }
 
        /* now calculate the session key for NTLMv2 */
-       hmac_md5_init_limK_to_64(ses->ntlmv2_hash, 16, &context);
-       hmac_md5_update(resp_buf, 16, &context);
-       hmac_md5_final(ses->auth_key.data.ntlmv2.key, &context);
+       crypto_shash_setkey(ses->server->secmech.hmacmd5,
+               ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
+
+       rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
+       if (rc) {
+               cERROR(1, "%s: Could not init hmacmd5\n", __func__);
+               goto setup_ntlmv2_rsp_ret;
+       }
 
-       memcpy(&ses->auth_key.data.ntlmv2.resp, resp_buf,
-              sizeof(struct ntlmv2_resp));
-       ses->auth_key.len = 16 + sizeof(struct ntlmv2_resp);
+       crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
+               ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+               CIFS_HMAC_MD5_HASH_SIZE);
 
-       return 0;
+       rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
+               ses->auth_key.response);
 
 setup_ntlmv2_rsp_ret:
-       kfree(ses->tiblob);
-       ses->tiblob = NULL;
-       ses->tilen = 0;
+       kfree(tiblob);
 
        return rc;
 }
 
-void CalcNTLMv2_response(const struct cifsSesInfo *ses,
-                        char *v2_session_response)
+int
+calc_seckey(struct cifsSesInfo *ses)
 {
-       struct HMACMD5Context context;
-       /* rest of v2 struct already generated */
-       memcpy(v2_session_response + 8, ses->cryptKey, 8);
-       hmac_md5_init_limK_to_64(ses->ntlmv2_hash, 16, &context);
+       int rc;
+       struct crypto_blkcipher *tfm_arc4;
+       struct scatterlist sgin, sgout;
+       struct blkcipher_desc desc;
+       unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */
+
+       get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
+
+       tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
+       if (!tfm_arc4 || IS_ERR(tfm_arc4)) {
+               cERROR(1, "could not allocate crypto API arc4\n");
+               return PTR_ERR(tfm_arc4);
+       }
 
-       hmac_md5_update(v2_session_response+8,
-                       sizeof(struct ntlmv2_resp) - 8, &context);
+       desc.tfm = tfm_arc4;
 
-       if (ses->tilen)
-               hmac_md5_update(ses->tiblob, ses->tilen, &context);
+       crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response,
+                                       CIFS_SESS_KEY_SIZE);
 
-       hmac_md5_final(v2_session_response, &context);
-/*     cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */
+       sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE);
+       sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
+
+       rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
+       if (rc) {
+               cERROR(1, "could not encrypt session key rc: %d\n", rc);
+               crypto_free_blkcipher(tfm_arc4);
+               return rc;
+       }
+
+       /* make secondary_key/nonce as session key */
+       memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
+       /* and make len as that of session key only */
+       ses->auth_key.len = CIFS_SESS_KEY_SIZE;
+
+       crypto_free_blkcipher(tfm_arc4);
+
+       return 0;
+}
+
+void
+cifs_crypto_shash_release(struct TCP_Server_Info *server)
+{
+       if (server->secmech.md5)
+               crypto_free_shash(server->secmech.md5);
+
+       if (server->secmech.hmacmd5)
+               crypto_free_shash(server->secmech.hmacmd5);
+
+       kfree(server->secmech.sdeschmacmd5);
+
+       kfree(server->secmech.sdescmd5);
+}
+
+int
+cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
+{
+       int rc;
+       unsigned int size;
+
+       server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
+       if (!server->secmech.hmacmd5 ||
+                       IS_ERR(server->secmech.hmacmd5)) {
+               cERROR(1, "could not allocate crypto hmacmd5\n");
+               return PTR_ERR(server->secmech.hmacmd5);
+       }
+
+       server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
+       if (!server->secmech.md5 || IS_ERR(server->secmech.md5)) {
+               cERROR(1, "could not allocate crypto md5\n");
+               rc = PTR_ERR(server->secmech.md5);
+               goto crypto_allocate_md5_fail;
+       }
+
+       size = sizeof(struct shash_desc) +
+                       crypto_shash_descsize(server->secmech.hmacmd5);
+       server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
+       if (!server->secmech.sdeschmacmd5) {
+               cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n");
+               rc = -ENOMEM;
+               goto crypto_allocate_hmacmd5_sdesc_fail;
+       }
+       server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
+       server->secmech.sdeschmacmd5->shash.flags = 0x0;
+
+
+       size = sizeof(struct shash_desc) +
+                       crypto_shash_descsize(server->secmech.md5);
+       server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
+       if (!server->secmech.sdescmd5) {
+               cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n");
+               rc = -ENOMEM;
+               goto crypto_allocate_md5_sdesc_fail;
+       }
+       server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
+       server->secmech.sdescmd5->shash.flags = 0x0;
+
+       return 0;
+
+crypto_allocate_md5_sdesc_fail:
+       kfree(server->secmech.sdeschmacmd5);
+
+crypto_allocate_hmacmd5_sdesc_fail:
+       crypto_free_shash(server->secmech.md5);
+
+crypto_allocate_md5_fail:
+       crypto_free_shash(server->secmech.hmacmd5);
+
+       return rc;
 }
index 34371637f210b496d54e291863b23ee619db9b8f..9c3789762ab7c4c92a7d67859c34b32cb196f1ab 100644 (file)
@@ -116,7 +116,7 @@ cifs_read_super(struct super_block *sb, void *data,
                return -ENOMEM;
 
        spin_lock_init(&cifs_sb->tlink_tree_lock);
-       INIT_RADIX_TREE(&cifs_sb->tlink_tree, GFP_KERNEL);
+       cifs_sb->tlink_tree = RB_ROOT;
 
        rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
        if (rc) {
@@ -318,12 +318,10 @@ cifs_alloc_inode(struct super_block *sb)
                return NULL;
        cifs_inode->cifsAttrs = 0x20;   /* default */
        cifs_inode->time = 0;
-       cifs_inode->write_behind_rc = 0;
        /* Until the file is open and we have gotten oplock
        info back from the server, can not assume caching of
        file data or metadata */
-       cifs_inode->clientCanCacheRead = false;
-       cifs_inode->clientCanCacheAll = false;
+       cifs_set_oplock_level(cifs_inode, 0);
        cifs_inode->delete_pending = false;
        cifs_inode->invalid_mapping = false;
        cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
@@ -545,9 +543,9 @@ static const struct super_operations cifs_super_ops = {
 #endif
 };
 
-static int
-cifs_get_sb(struct file_system_type *fs_type,
-           int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *
+cifs_do_mount(struct file_system_type *fs_type,
+           int flags, const char *dev_name, void *data)
 {
        int rc;
        struct super_block *sb;
@@ -557,18 +555,17 @@ cifs_get_sb(struct file_system_type *fs_type,
        cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
 
        if (IS_ERR(sb))
-               return PTR_ERR(sb);
+               return ERR_CAST(sb);
 
        sb->s_flags = flags;
 
        rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
        if (rc) {
                deactivate_locked_super(sb);
-               return rc;
+               return ERR_PTR(rc);
        }
        sb->s_flags |= MS_ACTIVE;
-       simple_set_mnt(mnt, sb);
-       return 0;
+       return dget(sb->s_root);
 }
 
 static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
@@ -634,7 +631,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
 struct file_system_type cifs_fs_type = {
        .owner = THIS_MODULE,
        .name = "cifs",
-       .get_sb = cifs_get_sb,
+       .mount = cifs_do_mount,
        .kill_sb = kill_anon_super,
        /*  .fs_flags */
 };
index f35795a16b425b4c3b6fa84c6c9ff9030338a239..897b2b2b28b539cb0c74847a1690d6e84929ab84 100644 (file)
@@ -112,5 +112,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* EXPERIMENTAL */
 
-#define CIFS_VERSION   "1.67"
+#define CIFS_VERSION   "1.68"
 #endif                         /* _CIFSFS_H */
index 3365e77f6f240825a68ff3f577c11e064d691620..b577bf0a1bb3622491ed0a885ca30b9e7684d24e 100644 (file)
@@ -25,6 +25,9 @@
 #include <linux/workqueue.h>
 #include "cifs_fs_sb.h"
 #include "cifsacl.h"
+#include <crypto/internal/hash.h>
+#include <linux/scatterlist.h>
+
 /*
  * The sizes of various internal tables and strings
  */
@@ -74,7 +77,7 @@
  * CIFS vfs client Status information (based on what we know.)
  */
 
- /* associated with each tcp and smb session */
+/* associated with each tcp and smb session */
 enum statusEnum {
        CifsNew = 0,
        CifsGood,
@@ -99,14 +102,29 @@ enum protocolEnum {
 
 struct session_key {
        unsigned int len;
-       union {
-               char ntlm[CIFS_SESS_KEY_SIZE + 16];
-               char krb5[CIFS_SESS_KEY_SIZE + 16]; /* BB: length correct? */
-               struct {
-                       char key[16];
-                       struct ntlmv2_resp resp;
-               } ntlmv2;
-       } data;
+       char *response;
+};
+
+/* crypto security descriptor definition */
+struct sdesc {
+       struct shash_desc shash;
+       char ctx[];
+};
+
+/* crypto hashing related structure/fields, not specific to a sec mech */
+struct cifs_secmech {
+       struct crypto_shash *hmacmd5; /* hmac-md5 hash function */
+       struct crypto_shash *md5; /* md5 hash function */
+       struct sdesc *sdeschmacmd5;  /* ctxt to generate ntlmv2 hash, CR1 */
+       struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */
+};
+
+/* per smb session structure/fields */
+struct ntlmssp_auth {
+       __u32 client_flags; /* sent by client in type 1 ntlmsssp exchange */
+       __u32 server_flags; /* sent by server in type 2 ntlmssp exchange */
+       unsigned char ciphertext[CIFS_CPHTXT_SIZE]; /* sent to server */
+       char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlmssp */
 };
 
 struct cifs_cred {
@@ -179,12 +197,14 @@ struct TCP_Server_Info {
        int capabilities; /* allow selective disabling of caps by smb sess */
        int timeAdj;  /* Adjust for difference in server time zone in sec */
        __u16 CurrentMid;         /* multiplex id - rotating counter */
+       char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
        /* 16th byte of RFC1001 workstation name is always null */
        char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
        __u32 sequence_number; /* needed for CIFS PDU signature */
        struct session_key session_key;
        unsigned long lstrp; /* when we got last response from this server */
        u16 dialect; /* dialect index that server chose */
+       struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */
        /* extended security flavors that server supports */
        bool    sec_kerberos;           /* supports plain Kerberos */
        bool    sec_mskerberos;         /* supports legacy MS Kerberos */
@@ -222,11 +242,8 @@ struct cifsSesInfo {
        char userName[MAX_USERNAME_SIZE + 1];
        char *domainName;
        char *password;
-       char cryptKey[CIFS_CRYPTO_KEY_SIZE];
        struct session_key auth_key;
-       char ntlmv2_hash[16];
-       unsigned int tilen; /* length of the target info blob */
-       unsigned char *tiblob; /* target info blob in challenge response */
+       struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */
        bool need_reconnect:1; /* connection reset, uid now invalid */
 };
 /* no more than one of the following three session flags may be set */
@@ -319,7 +336,8 @@ struct cifsTconInfo {
  * "get" on the container.
  */
 struct tcon_link {
-       unsigned long           tl_index;
+       struct rb_node          tl_rbnode;
+       uid_t                   tl_uid;
        unsigned long           tl_flags;
 #define TCON_LINK_MASTER       0
 #define TCON_LINK_PENDING      1
@@ -395,16 +413,19 @@ struct cifsFileInfo {
        struct list_head llist; /* list of byte range locks we have. */
        bool invalidHandle:1;   /* file closed via session abend */
        bool oplock_break_cancelled:1;
-       atomic_t count;         /* reference count */
+       int count;              /* refcount protected by cifs_file_list_lock */
        struct mutex fh_mutex; /* prevents reopen race after dead ses*/
        struct cifs_search_info srch_inf;
        struct work_struct oplock_break; /* work for oplock breaks */
 };
 
-/* Take a reference on the file private data */
+/*
+ * Take a reference on the file private data. Must be called with
+ * cifs_file_list_lock held.
+ */
 static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file)
 {
-       atomic_inc(&cifs_file->count);
+       ++cifs_file->count;
 }
 
 void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
@@ -417,7 +438,6 @@ struct cifsInodeInfo {
        struct list_head lockList;
        /* BB add in lists for dirty pages i.e. write caching info for oplock */
        struct list_head openFileList;
-       int write_behind_rc;
        __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
        unsigned long time;     /* jiffies of last update/check of inode */
        bool clientCanCacheRead:1;      /* read oplock */
@@ -668,7 +688,7 @@ require use of the stronger protocol */
  *  GlobalMid_Lock protects:
  *     list operations on pending_mid_q and oplockQ
  *      updates to XID counters, multiplex id  and SMB sequence numbers
- *  GlobalSMBSesLock protects:
+ *  cifs_file_list_lock protects:
  *     list operations on tcp and SMB session lists and tCon lists
  *  f_owner.lock protects certain per file struct operations
  *  mapping->page_lock protects certain per page operations
index b0f4b5656d4c2008379f720194e2a294350a06bc..de36b09763a84e7fb6016b93222fc74ee263d540 100644 (file)
  */
 #define CIFS_CRYPTO_KEY_SIZE (8)
 
+/*
+ * Size of the ntlm client response
+ */
+#define CIFS_AUTH_RESP_SIZE (24)
+
 /*
  * Size of the session key (crypto key encrypted with the password
  */
-#define CIFS_SESS_KEY_SIZE (24)
+#define CIFS_SESS_KEY_SIZE (16)
+
+#define CIFS_CLIENT_CHALLENGE_SIZE (8)
+#define CIFS_SERVER_CHALLENGE_SIZE (8)
+#define CIFS_HMAC_MD5_HASH_SIZE (16)
+#define CIFS_CPHTXT_SIZE (16)
+#define CIFS_NTHASH_SIZE (16)
 
 /*
  * Maximum user name length
index e593c40ba7baf925f447f9d246f663fcc1c498aa..7ed69b6b5fe6719f66ed5af0a0b38d2cda1aa352 100644 (file)
@@ -104,6 +104,7 @@ extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
 extern u64 cifs_UnixTimeToNT(struct timespec);
 extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
                                      int offset);
+extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
 
 extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle,
                                struct file *file, struct tcon_link *tlink,
@@ -362,13 +363,15 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
                          __u32 *);
 extern int cifs_verify_signature(struct smb_hdr *,
-                                const struct session_key *session_key,
+                                struct TCP_Server_Info *server,
                                __u32 expected_sequence_number);
-extern int cifs_calculate_session_key(struct session_key *key, const char *rn,
-                                const char *pass);
-extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
-extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
-                            const struct nls_table *);
+extern void SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
+extern int setup_ntlm_response(struct cifsSesInfo *);
+extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *);
+extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
+extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
+extern int calc_seckey(struct cifsSesInfo *);
+
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 extern void calc_lanman_hash(const char *password, const char *cryptkey,
                                bool encrypt, char *lnm_session_key);
index e98f1f317b159f56fe39f7dda35a9ab15881e32d..2f2632b6df5a1efd960bf44502d280e0e9499908 100644 (file)
@@ -503,7 +503,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 
                if (rsp->EncryptionKeyLength ==
                                cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
-                       memcpy(ses->cryptKey, rsp->EncryptionKey,
+                       memcpy(ses->server->cryptkey, rsp->EncryptionKey,
                                CIFS_CRYPTO_KEY_SIZE);
                } else if (server->secMode & SECMODE_PW_ENCRYPT) {
                        rc = -EIO; /* need cryptkey unless plain text */
@@ -574,7 +574,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
        server->timeAdj *= 60;
        if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
-               memcpy(ses->cryptKey, pSMBr->u.EncryptionKey,
+               memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
                       CIFS_CRYPTO_KEY_SIZE);
        } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
                        && (pSMBr->EncryptionKeyLength == 0)) {
index 7e73176acb58d700a73ef41de51f1aec45a8b945..251a17c03545dfc35e8ab37e1ea5a612e94f7536 100644 (file)
@@ -116,6 +116,7 @@ struct smb_vol {
 
 static int ipv4_connect(struct TCP_Server_Info *server);
 static int ipv6_connect(struct TCP_Server_Info *server);
+static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
 static void cifs_prune_tlinks(struct work_struct *work);
 
 /*
@@ -175,6 +176,9 @@ cifs_reconnect(struct TCP_Server_Info *server)
        }
        server->sequence_number = 0;
        server->session_estab = false;
+       kfree(server->session_key.response);
+       server->session_key.response = NULL;
+       server->session_key.len = 0;
 
        spin_lock(&GlobalMid_Lock);
        list_for_each(tmp, &server->pending_mid_q) {
@@ -1064,7 +1068,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        }
                        i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
                                                 value, strlen(value));
-                       if (i < 0) {
+                       if (i == 0) {
                                printk(KERN_WARNING "CIFS:  Could not parse"
                                       " srcaddr: %s\n",
                                       value);
@@ -1560,8 +1564,13 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
        server->tcpStatus = CifsExiting;
        spin_unlock(&GlobalMid_Lock);
 
+       cifs_crypto_shash_release(server);
        cifs_fscache_release_client_cookie(server);
 
+       kfree(server->session_key.response);
+       server->session_key.response = NULL;
+       server->session_key.len = 0;
+
        task = xchg(&server->tsk, NULL);
        if (task)
                force_sig(SIGKILL, task);
@@ -1614,10 +1623,16 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
                goto out_err;
        }
 
+       rc = cifs_crypto_shash_allocate(tcp_ses);
+       if (rc) {
+               cERROR(1, "could not setup hash structures rc %d", rc);
+               goto out_err;
+       }
+
        tcp_ses->hostname = extract_hostname(volume_info->UNC);
        if (IS_ERR(tcp_ses->hostname)) {
                rc = PTR_ERR(tcp_ses->hostname);
-               goto out_err;
+               goto out_err_crypto_release;
        }
 
        tcp_ses->noblocksnd = volume_info->noblocksnd;
@@ -1661,7 +1676,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
        }
        if (rc < 0) {
                cERROR(1, "Error connecting to socket. Aborting operation");
-               goto out_err;
+               goto out_err_crypto_release;
        }
 
        /*
@@ -1675,7 +1690,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
                rc = PTR_ERR(tcp_ses->tsk);
                cERROR(1, "error %d create cifsd thread", rc);
                module_put(THIS_MODULE);
-               goto out_err;
+               goto out_err_crypto_release;
        }
 
        /* thread spawned, put it on the list */
@@ -1687,6 +1702,9 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
 
        return tcp_ses;
 
+out_err_crypto_release:
+       cifs_crypto_shash_release(tcp_ses);
+
 out_err:
        if (tcp_ses) {
                if (!IS_ERR(tcp_ses->hostname))
@@ -1801,8 +1819,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
        if (ses == NULL)
                goto get_ses_fail;
 
-       ses->tilen = 0;
-       ses->tiblob = NULL;
        /* new SMB session uses our server ref */
        ses->server = server;
        if (server->addr.sockAddr6.sin6_family == AF_INET6)
@@ -1823,10 +1839,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
                        goto get_ses_fail;
        }
        if (volume_info->domainname) {
-               int len = strlen(volume_info->domainname);
-               ses->domainName = kmalloc(len + 1, GFP_KERNEL);
-               if (ses->domainName)
-                       strcpy(ses->domainName, volume_info->domainname);
+               ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
+               if (!ses->domainName)
+                       goto get_ses_fail;
        }
        ses->cred_uid = volume_info->cred_uid;
        ses->linux_uid = volume_info->linux_uid;
@@ -2886,24 +2901,16 @@ remote_path_check:
                goto mount_fail_check;
        }
 
-       tlink->tl_index = pSesInfo->linux_uid;
+       tlink->tl_uid = pSesInfo->linux_uid;
        tlink->tl_tcon = tcon;
        tlink->tl_time = jiffies;
        set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
        set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
 
-       rc = radix_tree_preload(GFP_KERNEL);
-       if (rc == -ENOMEM) {
-               kfree(tlink);
-               goto mount_fail_check;
-       }
-
+       cifs_sb->master_tlink = tlink;
        spin_lock(&cifs_sb->tlink_tree_lock);
-       radix_tree_insert(&cifs_sb->tlink_tree, pSesInfo->linux_uid, tlink);
-       radix_tree_tag_set(&cifs_sb->tlink_tree, pSesInfo->linux_uid,
-                          CIFS_TLINK_MASTER_TAG);
+       tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
        spin_unlock(&cifs_sb->tlink_tree_lock);
-       radix_tree_preload_end();
 
        queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
                                TLINK_IDLE_EXPIRE);
@@ -2985,13 +2992,13 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
                if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
                    (ses->server->secType == LANMAN))
-                       calc_lanman_hash(tcon->password, ses->cryptKey,
+                       calc_lanman_hash(tcon->password, ses->server->cryptkey,
                                         ses->server->secMode &
                                            SECMODE_PW_ENCRYPT ? true : false,
                                         bcc_ptr);
                else
 #endif /* CIFS_WEAK_PW_HASH */
-               SMBNTencrypt(tcon->password, ses->cryptKey, bcc_ptr);
+               SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr);
 
                bcc_ptr += CIFS_SESS_KEY_SIZE;
                if (ses->capabilities & CAP_UNICODE) {
@@ -3093,32 +3100,25 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
 int
 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
 {
-       int i, ret;
+       struct rb_root *root = &cifs_sb->tlink_tree;
+       struct rb_node *node;
+       struct tcon_link *tlink;
        char *tmp;
-       struct tcon_link *tlink[8];
-       unsigned long index = 0;
 
        cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
 
-       do {
-               spin_lock(&cifs_sb->tlink_tree_lock);
-               ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree,
-                                            (void **)tlink, index,
-                                            ARRAY_SIZE(tlink));
-               /* increment index for next pass */
-               if (ret > 0)
-                       index = tlink[ret - 1]->tl_index + 1;
-               for (i = 0; i < ret; i++) {
-                       cifs_get_tlink(tlink[i]);
-                       clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags);
-                       radix_tree_delete(&cifs_sb->tlink_tree,
-                                                       tlink[i]->tl_index);
-               }
-               spin_unlock(&cifs_sb->tlink_tree_lock);
+       spin_lock(&cifs_sb->tlink_tree_lock);
+       while ((node = rb_first(root))) {
+               tlink = rb_entry(node, struct tcon_link, tl_rbnode);
+               cifs_get_tlink(tlink);
+               clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
+               rb_erase(node, root);
 
-               for (i = 0; i < ret; i++)
-                       cifs_put_tlink(tlink[i]);
-       } while (ret != 0);
+               spin_unlock(&cifs_sb->tlink_tree_lock);
+               cifs_put_tlink(tlink);
+               spin_lock(&cifs_sb->tlink_tree_lock);
+       }
+       spin_unlock(&cifs_sb->tlink_tree_lock);
 
        tmp = cifs_sb->prepath;
        cifs_sb->prepathlen = 0;
@@ -3178,10 +3178,11 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
        } else {
                mutex_lock(&ses->server->srv_mutex);
                if (!server->session_estab) {
-                       memcpy(&server->session_key.data,
-                               &ses->auth_key.data, ses->auth_key.len);
+                       server->session_key.response = ses->auth_key.response;
                        server->session_key.len = ses->auth_key.len;
-                       ses->server->session_estab = true;
+                       server->sequence_number = 0x2;
+                       server->session_estab = true;
+                       ses->auth_key.response = NULL;
                }
                mutex_unlock(&server->srv_mutex);
 
@@ -3192,6 +3193,12 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
                spin_unlock(&GlobalMid_Lock);
        }
 
+       kfree(ses->auth_key.response);
+       ses->auth_key.response = NULL;
+       ses->auth_key.len = 0;
+       kfree(ses->ntlmssp);
+       ses->ntlmssp = NULL;
+
        return rc;
 }
 
@@ -3250,22 +3257,10 @@ out:
        return tcon;
 }
 
-static struct tcon_link *
+static inline struct tcon_link *
 cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
 {
-       struct tcon_link *tlink;
-       unsigned int ret;
-
-       spin_lock(&cifs_sb->tlink_tree_lock);
-       ret = radix_tree_gang_lookup_tag(&cifs_sb->tlink_tree, (void **)&tlink,
-                                       0, 1, CIFS_TLINK_MASTER_TAG);
-       spin_unlock(&cifs_sb->tlink_tree_lock);
-
-       /* the master tcon should always be present */
-       if (ret == 0)
-               BUG();
-
-       return tlink;
+       return cifs_sb->master_tlink;
 }
 
 struct cifsTconInfo *
@@ -3281,6 +3276,47 @@ cifs_sb_tcon_pending_wait(void *unused)
        return signal_pending(current) ? -ERESTARTSYS : 0;
 }
 
+/* find and return a tlink with given uid */
+static struct tcon_link *
+tlink_rb_search(struct rb_root *root, uid_t uid)
+{
+       struct rb_node *node = root->rb_node;
+       struct tcon_link *tlink;
+
+       while (node) {
+               tlink = rb_entry(node, struct tcon_link, tl_rbnode);
+
+               if (tlink->tl_uid > uid)
+                       node = node->rb_left;
+               else if (tlink->tl_uid < uid)
+                       node = node->rb_right;
+               else
+                       return tlink;
+       }
+       return NULL;
+}
+
+/* insert a tcon_link into the tree */
+static void
+tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
+{
+       struct rb_node **new = &(root->rb_node), *parent = NULL;
+       struct tcon_link *tlink;
+
+       while (*new) {
+               tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
+               parent = *new;
+
+               if (tlink->tl_uid > new_tlink->tl_uid)
+                       new = &((*new)->rb_left);
+               else
+                       new = &((*new)->rb_right);
+       }
+
+       rb_link_node(&new_tlink->tl_rbnode, parent, new);
+       rb_insert_color(&new_tlink->tl_rbnode, root);
+}
+
 /*
  * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
  * current task.
@@ -3288,7 +3324,7 @@ cifs_sb_tcon_pending_wait(void *unused)
  * If the superblock doesn't refer to a multiuser mount, then just return
  * the master tcon for the mount.
  *
- * First, search the radix tree for an existing tcon for this fsuid. If one
+ * First, search the rbtree for an existing tcon for this fsuid. If one
  * exists, then check to see if it's pending construction. If it is then wait
  * for construction to complete. Once it's no longer pending, check to see if
  * it failed and either return an error or retry construction, depending on
@@ -3301,14 +3337,14 @@ struct tcon_link *
 cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
 {
        int ret;
-       unsigned long fsuid = (unsigned long) current_fsuid();
+       uid_t fsuid = current_fsuid();
        struct tcon_link *tlink, *newtlink;
 
        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
                return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
 
        spin_lock(&cifs_sb->tlink_tree_lock);
-       tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
+       tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
        if (tlink)
                cifs_get_tlink(tlink);
        spin_unlock(&cifs_sb->tlink_tree_lock);
@@ -3317,36 +3353,24 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
                newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
                if (newtlink == NULL)
                        return ERR_PTR(-ENOMEM);
-               newtlink->tl_index = fsuid;
+               newtlink->tl_uid = fsuid;
                newtlink->tl_tcon = ERR_PTR(-EACCES);
                set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
                set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
                cifs_get_tlink(newtlink);
 
-               ret = radix_tree_preload(GFP_KERNEL);
-               if (ret != 0) {
-                       kfree(newtlink);
-                       return ERR_PTR(ret);
-               }
-
                spin_lock(&cifs_sb->tlink_tree_lock);
                /* was one inserted after previous search? */
-               tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
+               tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
                if (tlink) {
                        cifs_get_tlink(tlink);
                        spin_unlock(&cifs_sb->tlink_tree_lock);
-                       radix_tree_preload_end();
                        kfree(newtlink);
                        goto wait_for_construction;
                }
-               ret = radix_tree_insert(&cifs_sb->tlink_tree, fsuid, newtlink);
-               spin_unlock(&cifs_sb->tlink_tree_lock);
-               radix_tree_preload_end();
-               if (ret) {
-                       kfree(newtlink);
-                       return ERR_PTR(ret);
-               }
                tlink = newtlink;
+               tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
+               spin_unlock(&cifs_sb->tlink_tree_lock);
        } else {
 wait_for_construction:
                ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
@@ -3392,39 +3416,39 @@ cifs_prune_tlinks(struct work_struct *work)
 {
        struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
                                                    prune_tlinks.work);
-       struct tcon_link *tlink[8];
-       unsigned long now = jiffies;
-       unsigned long index = 0;
-       int i, ret;
+       struct rb_root *root = &cifs_sb->tlink_tree;
+       struct rb_node *node = rb_first(root);
+       struct rb_node *tmp;
+       struct tcon_link *tlink;
 
-       do {
-               spin_lock(&cifs_sb->tlink_tree_lock);
-               ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree,
-                                            (void **)tlink, index,
-                                            ARRAY_SIZE(tlink));
-               /* increment index for next pass */
-               if (ret > 0)
-                       index = tlink[ret - 1]->tl_index + 1;
-               for (i = 0; i < ret; i++) {
-                       if (test_bit(TCON_LINK_MASTER, &tlink[i]->tl_flags) ||
-                           atomic_read(&tlink[i]->tl_count) != 0 ||
-                           time_after(tlink[i]->tl_time + TLINK_IDLE_EXPIRE,
-                                      now)) {
-                               tlink[i] = NULL;
-                               continue;
-                       }
-                       cifs_get_tlink(tlink[i]);
-                       clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags);
-                       radix_tree_delete(&cifs_sb->tlink_tree,
-                                         tlink[i]->tl_index);
-               }
-               spin_unlock(&cifs_sb->tlink_tree_lock);
+       /*
+        * Because we drop the spinlock in the loop in order to put the tlink
+        * it's not guarded against removal of links from the tree. The only
+        * places that remove entries from the tree are this function and
+        * umounts. Because this function is non-reentrant and is canceled
+        * before umount can proceed, this is safe.
+        */
+       spin_lock(&cifs_sb->tlink_tree_lock);
+       node = rb_first(root);
+       while (node != NULL) {
+               tmp = node;
+               node = rb_next(tmp);
+               tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);
+
+               if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
+                   atomic_read(&tlink->tl_count) != 0 ||
+                   time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
+                       continue;
 
-               for (i = 0; i < ret; i++) {
-                       if (tlink[i] != NULL)
-                               cifs_put_tlink(tlink[i]);
-               }
-       } while (ret != 0);
+               cifs_get_tlink(tlink);
+               clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
+               rb_erase(tmp, root);
+
+               spin_unlock(&cifs_sb->tlink_tree_lock);
+               cifs_put_tlink(tlink);
+               spin_lock(&cifs_sb->tlink_tree_lock);
+       }
+       spin_unlock(&cifs_sb->tlink_tree_lock);
 
        queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
                                TLINK_IDLE_EXPIRE);
index 45af003865d2607da7eb0f9ffdc43eed18f82b4d..06c3e83fa387fecf63b93e33a0455dac6da45f6d 100644 (file)
@@ -131,8 +131,7 @@ static inline int cifs_open_inode_helper(struct inode *inode,
                        /* BB no need to lock inode until after invalidate
                        since namei code should already have it locked? */
                        rc = filemap_write_and_wait(inode->i_mapping);
-                       if (rc != 0)
-                               pCifsInode->write_behind_rc = rc;
+                       mapping_set_error(inode->i_mapping, rc);
                }
                cFYI(1, "invalidating remote inode since open detected it "
                         "changed");
@@ -147,12 +146,7 @@ client_can_cache:
                rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
                                         xid, NULL);
 
-       if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-               pCifsInode->clientCanCacheAll = true;
-               pCifsInode->clientCanCacheRead = true;
-               cFYI(1, "Exclusive Oplock granted on inode %p", inode);
-       } else if ((oplock & 0xF) == OPLOCK_READ)
-               pCifsInode->clientCanCacheRead = true;
+       cifs_set_oplock_level(pCifsInode, oplock);
 
        return rc;
 }
@@ -232,6 +226,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
        if (pCifsFile == NULL)
                return pCifsFile;
 
+       pCifsFile->count = 1;
        pCifsFile->netfid = fileHandle;
        pCifsFile->pid = current->tgid;
        pCifsFile->uid = current_fsuid();
@@ -242,7 +237,6 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
        mutex_init(&pCifsFile->fh_mutex);
        mutex_init(&pCifsFile->lock_mutex);
        INIT_LIST_HEAD(&pCifsFile->llist);
-       atomic_set(&pCifsFile->count, 1);
        INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
 
        spin_lock(&cifs_file_list_lock);
@@ -254,12 +248,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
                list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList);
        spin_unlock(&cifs_file_list_lock);
 
-       if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-               pCifsInode->clientCanCacheAll = true;
-               pCifsInode->clientCanCacheRead = true;
-               cFYI(1, "Exclusive Oplock inode %p", inode);
-       } else if ((oplock & 0xF) == OPLOCK_READ)
-               pCifsInode->clientCanCacheRead = true;
+       cifs_set_oplock_level(pCifsInode, oplock);
 
        file->private_data = pCifsFile;
        return pCifsFile;
@@ -267,16 +256,18 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
 
 /*
  * Release a reference on the file private data. This may involve closing
- * the filehandle out on the server.
+ * the filehandle out on the server. Must be called without holding
+ * cifs_file_list_lock.
  */
 void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
 {
+       struct inode *inode = cifs_file->dentry->d_inode;
        struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink);
-       struct cifsInodeInfo *cifsi = CIFS_I(cifs_file->dentry->d_inode);
+       struct cifsInodeInfo *cifsi = CIFS_I(inode);
        struct cifsLockInfo *li, *tmp;
 
        spin_lock(&cifs_file_list_lock);
-       if (!atomic_dec_and_test(&cifs_file->count)) {
+       if (--cifs_file->count > 0) {
                spin_unlock(&cifs_file_list_lock);
                return;
        }
@@ -288,8 +279,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
        if (list_empty(&cifsi->openFileList)) {
                cFYI(1, "closing last open instance for inode %p",
                        cifs_file->dentry->d_inode);
-               cifsi->clientCanCacheRead = false;
-               cifsi->clientCanCacheAll  = false;
+               cifs_set_oplock_level(cifsi, 0);
        }
        spin_unlock(&cifs_file_list_lock);
 
@@ -605,11 +595,8 @@ reopen_success:
 
        if (can_flush) {
                rc = filemap_write_and_wait(inode->i_mapping);
-               if (rc != 0)
-                       CIFS_I(inode)->write_behind_rc = rc;
+               mapping_set_error(inode->i_mapping, rc);
 
-               pCifsInode->clientCanCacheAll = false;
-               pCifsInode->clientCanCacheRead = false;
                if (tcon->unix_ext)
                        rc = cifs_get_inode_info_unix(&inode,
                                full_path, inode->i_sb, xid);
@@ -623,18 +610,9 @@ reopen_success:
             invalidate the current end of file on the server
             we can not go to the server to get the new inod
             info */
-       if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-               pCifsInode->clientCanCacheAll = true;
-               pCifsInode->clientCanCacheRead = true;
-               cFYI(1, "Exclusive Oplock granted on inode %p",
-                        pCifsFile->dentry->d_inode);
-       } else if ((oplock & 0xF) == OPLOCK_READ) {
-               pCifsInode->clientCanCacheRead = true;
-               pCifsInode->clientCanCacheAll = false;
-       } else {
-               pCifsInode->clientCanCacheRead = false;
-               pCifsInode->clientCanCacheAll = false;
-       }
+
+       cifs_set_oplock_level(pCifsInode, oplock);
+
        cifs_relock_file(pCifsFile);
 
 reopen_error_exit:
@@ -776,12 +754,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
 
        cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink);
-
-       if (file->private_data == NULL) {
-               rc = -EBADF;
-               FreeXid(xid);
-               return rc;
-       }
        netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
 
        if ((tcon->ses->capabilities & CAP_UNIX) &&
@@ -957,6 +929,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
 ssize_t cifs_user_write(struct file *file, const char __user *write_data,
        size_t write_size, loff_t *poffset)
 {
+       struct inode *inode = file->f_path.dentry->d_inode;
        int rc = 0;
        unsigned int bytes_written = 0;
        unsigned int total_written;
@@ -964,7 +937,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
        struct cifsTconInfo *pTcon;
        int xid, long_op;
        struct cifsFileInfo *open_file;
-       struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode);
+       struct cifsInodeInfo *cifsi = CIFS_I(inode);
 
        cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
 
@@ -1030,21 +1003,17 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
 
        cifs_stats_bytes_written(pTcon, total_written);
 
-       /* since the write may have blocked check these pointers again */
-       if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) {
-               struct inode *inode = file->f_path.dentry->d_inode;
 /* Do not update local mtime - server will set its actual value on write
- *             inode->i_ctime = inode->i_mtime =
- *                     current_fs_time(inode->i_sb);*/
-               if (total_written > 0) {
-                       spin_lock(&inode->i_lock);
-                       if (*poffset > file->f_path.dentry->d_inode->i_size)
-                               i_size_write(file->f_path.dentry->d_inode,
-                                       *poffset);
-                       spin_unlock(&inode->i_lock);
-               }
-               mark_inode_dirty_sync(file->f_path.dentry->d_inode);
+ *     inode->i_ctime = inode->i_mtime =
+ *             current_fs_time(inode->i_sb);*/
+       if (total_written > 0) {
+               spin_lock(&inode->i_lock);
+               if (*poffset > inode->i_size)
+                       i_size_write(inode, *poffset);
+               spin_unlock(&inode->i_lock);
        }
+       mark_inode_dirty_sync(inode);
+
        FreeXid(xid);
        return total_written;
 }
@@ -1179,7 +1148,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
                                        bool fsuid_only)
 {
        struct cifsFileInfo *open_file;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
+       struct cifs_sb_info *cifs_sb;
        bool any_available = false;
        int rc;
 
@@ -1193,6 +1162,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
                return NULL;
        }
 
+       cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
+
        /* only filter by fsuid on multiuser mounts */
        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
                fsuid_only = false;
@@ -1353,6 +1324,7 @@ static int cifs_writepages(struct address_space *mapping,
        if (!experimEnabled && tcon->ses->server->secMode &
                        (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
                cifsFileInfo_put(open_file);
+               kfree(iov);
                return generic_writepages(mapping, wbc);
        }
        cifsFileInfo_put(open_file);
@@ -1478,12 +1450,7 @@ retry:
                        if (rc || bytes_written < bytes_to_write) {
                                cERROR(1, "Write2 ret %d, wrote %d",
                                          rc, bytes_written);
-                               /* BB what if continued retry is
-                                  requested via mount flags? */
-                               if (rc == -ENOSPC)
-                                       set_bit(AS_ENOSPC, &mapping->flags);
-                               else
-                                       set_bit(AS_EIO, &mapping->flags);
+                               mapping_set_error(mapping, rc);
                        } else {
                                cifs_stats_bytes_written(tcon, bytes_written);
                        }
@@ -1628,11 +1595,10 @@ int cifs_fsync(struct file *file, int datasync)
 
        rc = filemap_write_and_wait(inode->i_mapping);
        if (rc == 0) {
-               rc = CIFS_I(inode)->write_behind_rc;
-               CIFS_I(inode)->write_behind_rc = 0;
+               struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+
                tcon = tlink_tcon(smbfile->tlink);
-               if (!rc && tcon && smbfile &&
-                  !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
+               if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
                        rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
        }
 
@@ -1677,21 +1643,8 @@ int cifs_flush(struct file *file, fl_owner_t id)
        struct inode *inode = file->f_path.dentry->d_inode;
        int rc = 0;
 
-       /* Rather than do the steps manually:
-          lock the inode for writing
-          loop through pages looking for write behind data (dirty pages)
-          coalesce into contiguous 16K (or smaller) chunks to write to server
-          send to server (prefer in parallel)
-          deal with writebehind errors
-          unlock inode for writing
-          filemapfdatawrite appears easier for the time being */
-
-       rc = filemap_fdatawrite(inode->i_mapping);
-       /* reset wb rc if we were able to write out dirty pages */
-       if (!rc) {
-               rc = CIFS_I(inode)->write_behind_rc;
-               CIFS_I(inode)->write_behind_rc = 0;
-       }
+       if (file->f_mode & FMODE_WRITE)
+               rc = filemap_write_and_wait(inode->i_mapping);
 
        cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc);
 
@@ -2270,7 +2223,7 @@ void cifs_oplock_break(struct work_struct *work)
                                                  oplock_break);
        struct inode *inode = cfile->dentry->d_inode;
        struct cifsInodeInfo *cinode = CIFS_I(inode);
-       int rc, waitrc = 0;
+       int rc = 0;
 
        if (inode && S_ISREG(inode->i_mode)) {
                if (cinode->clientCanCacheRead)
@@ -2279,13 +2232,10 @@ void cifs_oplock_break(struct work_struct *work)
                        break_lease(inode, O_WRONLY);
                rc = filemap_fdatawrite(inode->i_mapping);
                if (cinode->clientCanCacheRead == 0) {
-                       waitrc = filemap_fdatawait(inode->i_mapping);
+                       rc = filemap_fdatawait(inode->i_mapping);
+                       mapping_set_error(inode->i_mapping, rc);
                        invalidate_remote_inode(inode);
                }
-               if (!rc)
-                       rc = waitrc;
-               if (rc)
-                       cinode->write_behind_rc = rc;
                cFYI(1, "Oplock flush inode %p rc %d", inode, rc);
        }
 
@@ -2304,7 +2254,7 @@ void cifs_oplock_break(struct work_struct *work)
        /*
         * We might have kicked in before is_valid_oplock_break()
         * finished grabbing reference for us.  Make sure it's done by
-        * waiting for GlobalSMSSeslock.
+        * waiting for cifs_file_list_lock.
         */
        spin_lock(&cifs_file_list_lock);
        spin_unlock(&cifs_file_list_lock);
@@ -2312,6 +2262,7 @@ void cifs_oplock_break(struct work_struct *work)
        cifs_oplock_break_put(cfile);
 }
 
+/* must be called while holding cifs_file_list_lock */
 void cifs_oplock_break_get(struct cifsFileInfo *cfile)
 {
        cifs_sb_active(cfile->dentry->d_sb);
index 94979309698a1a2459c765153d80277886826c74..ef3a55bf86b6d3700c521e074954548c6f53223f 100644 (file)
@@ -1682,8 +1682,7 @@ cifs_invalidate_mapping(struct inode *inode)
        /* write back any cached data */
        if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
                rc = filemap_write_and_wait(inode->i_mapping);
-               if (rc)
-                       cifs_i->write_behind_rc = rc;
+               mapping_set_error(inode->i_mapping, rc);
        }
        invalidate_remote_inode(inode);
        cifs_fscache_reset_inode_cookie(inode);
@@ -1943,10 +1942,8 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
         * the flush returns error?
         */
        rc = filemap_write_and_wait(inode->i_mapping);
-       if (rc != 0) {
-               cifsInode->write_behind_rc = rc;
-               rc = 0;
-       }
+       mapping_set_error(inode->i_mapping, rc);
+       rc = 0;
 
        if (attrs->ia_valid & ATTR_SIZE) {
                rc = cifs_set_file_size(inode, attrs, xid, full_path);
@@ -2087,10 +2084,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
         * the flush returns error?
         */
        rc = filemap_write_and_wait(inode->i_mapping);
-       if (rc != 0) {
-               cifsInode->write_behind_rc = rc;
-               rc = 0;
-       }
+       mapping_set_error(inode->i_mapping, rc);
+       rc = 0;
 
        if (attrs->ia_valid & ATTR_SIZE) {
                rc = cifs_set_file_size(inode, attrs, xid, full_path);
@@ -2182,7 +2177,6 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 
        setattr_copy(inode, attrs);
        mark_inode_dirty(inode);
-       return 0;
 
 cifs_setattr_exit:
        kfree(full_path);
index 077bf756f34231300c6b0d7fdae7cedf6023bd08..0c98672d01225ccadb67bb09705e7c21922332c7 100644 (file)
@@ -38,10 +38,10 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
        struct cifs_sb_info *cifs_sb;
 #ifdef CONFIG_CIFS_POSIX
        struct cifsFileInfo *pSMBFile = filep->private_data;
-       struct cifsTconInfo *tcon = tlink_tcon(pSMBFile->tlink);
+       struct cifsTconInfo *tcon;
        __u64   ExtAttrBits = 0;
        __u64   ExtAttrMask = 0;
-       __u64   caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
+       __u64   caps;
 #endif /* CONFIG_CIFS_POSIX */
 
        xid = GetXid();
@@ -62,9 +62,11 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
                        break;
 #ifdef CONFIG_CIFS_POSIX
                case FS_IOC_GETFLAGS:
+                       if (pSMBFile == NULL)
+                               break;
+                       tcon = tlink_tcon(pSMBFile->tlink);
+                       caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
                        if (CIFS_UNIX_EXTATTR_CAP & caps) {
-                               if (pSMBFile == NULL)
-                                       break;
                                rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,
                                        &ExtAttrBits, &ExtAttrMask);
                                if (rc == 0)
@@ -75,13 +77,15 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
                        break;
 
                case FS_IOC_SETFLAGS:
+                       if (pSMBFile == NULL)
+                               break;
+                       tcon = tlink_tcon(pSMBFile->tlink);
+                       caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
                        if (CIFS_UNIX_EXTATTR_CAP & caps) {
                                if (get_user(ExtAttrBits, (int __user *)arg)) {
                                        rc = -EFAULT;
                                        break;
                                }
-                               if (pSMBFile == NULL)
-                                       break;
                                /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,
                                        extAttrBits, &ExtAttrMask);*/
                        }
index 1c681f6a68039ce14f2ac832c90eb17226198247..43f10281bc19e80be48303e1bd9c974b4882cb37 100644 (file)
@@ -569,15 +569,14 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
 
                                cFYI(1, "file id match, oplock break");
                                pCifsInode = CIFS_I(netfile->dentry->d_inode);
-                               pCifsInode->clientCanCacheAll = false;
-                               if (pSMB->OplockLevel == 0)
-                                       pCifsInode->clientCanCacheRead = false;
 
+                               cifs_set_oplock_level(pCifsInode,
+                                                     pSMB->OplockLevel);
                                /*
                                 * cifs_oplock_break_put() can't be called
                                 * from here.  Get reference after queueing
                                 * succeeded.  cifs_oplock_break() will
-                                * synchronize using GlobalSMSSeslock.
+                                * synchronize using cifs_file_list_lock.
                                 */
                                if (queue_work(system_nrt_wq,
                                               &netfile->oplock_break))
@@ -722,3 +721,23 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
                           cifs_sb_master_tcon(cifs_sb)->treeName);
        }
 }
+
+void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
+{
+       oplock &= 0xF;
+
+       if (oplock == OPLOCK_EXCLUSIVE) {
+               cinode->clientCanCacheAll = true;
+               cinode->clientCanCacheRead = true;
+               cFYI(1, "Exclusive Oplock granted on inode %p",
+                    &cinode->vfs_inode);
+       } else if (oplock == OPLOCK_READ) {
+               cinode->clientCanCacheAll = false;
+               cinode->clientCanCacheRead = true;
+               cFYI(1, "Level II Oplock granted on inode %p",
+                   &cinode->vfs_inode);
+       } else {
+               cinode->clientCanCacheAll = false;
+               cinode->clientCanCacheRead = false;
+       }
+}
index 2a11efd965928964adbedf57e8eb3dd6a33b2830..7b01d3f6eed6e76cff6317f16c43b366c1af595d 100644 (file)
@@ -32,9 +32,6 @@
 #include <linux/slab.h>
 #include "cifs_spnego.h"
 
-extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
-                        unsigned char *p24);
-
 /*
  * Checks if this is the first smb session to be reconnected after
  * the socket has been reestablished (so we know whether to use vc 0).
@@ -402,23 +399,22 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
                return -EINVAL;
        }
 
-       memcpy(ses->cryptKey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
+       memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
        /* BB we could decode pblob->NegotiateFlags; some may be useful */
        /* In particular we can examine sign flags */
        /* BB spec says that if AvId field of MsvAvTimestamp is populated then
                we must set the MIC field of the AUTHENTICATE_MESSAGE */
-
+       ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
        tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset);
        tilen = cpu_to_le16(pblob->TargetInfoArray.Length);
-       ses->tilen = tilen;
-       if (ses->tilen) {
-               ses->tiblob = kmalloc(tilen, GFP_KERNEL);
-               if (!ses->tiblob) {
+       if (tilen) {
+               ses->auth_key.response = kmalloc(tilen, GFP_KERNEL);
+               if (!ses->auth_key.response) {
                        cERROR(1, "Challenge target info allocation failure");
-                       ses->tilen = 0;
                        return -ENOMEM;
                }
-               memcpy(ses->tiblob,  bcc_ptr + tioffset, ses->tilen);
+               memcpy(ses->auth_key.response, bcc_ptr + tioffset, tilen);
+               ses->auth_key.len = tilen;
        }
 
        return 0;
@@ -443,10 +439,12 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
                NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
                NTLMSSP_NEGOTIATE_NTLM;
        if (ses->server->secMode &
-          (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+                       (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
                flags |= NTLMSSP_NEGOTIATE_SIGN;
-       if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
-               flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+               if (!ses->server->session_estab)
+                       flags |= NTLMSSP_NEGOTIATE_KEY_XCH |
+                               NTLMSSP_NEGOTIATE_EXTENDED_SEC;
+       }
 
        sec_blob->NegotiateFlags |= cpu_to_le32(flags);
 
@@ -469,11 +467,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
                                   const struct nls_table *nls_cp)
 {
        int rc;
-       unsigned int size;
        AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
        __u32 flags;
        unsigned char *tmp;
-       struct ntlmv2_resp ntlmv2_response = {};
 
        memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
        sec_blob->MessageType = NtLmAuthenticate;
@@ -497,25 +493,19 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
        sec_blob->LmChallengeResponse.MaximumLength = 0;
 
        sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
-       rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp);
+       rc = setup_ntlmv2_rsp(ses, nls_cp);
        if (rc) {
                cERROR(1, "Error %d during NTLMSSP authentication", rc);
                goto setup_ntlmv2_ret;
        }
-       size =  sizeof(struct ntlmv2_resp);
-       memcpy(tmp, (char *)&ntlmv2_response, size);
-       tmp += size;
-       if (ses->tilen > 0) {
-               memcpy(tmp, ses->tiblob, ses->tilen);
-               tmp += ses->tilen;
-       }
+       memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+                       ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+       tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
 
-       sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + ses->tilen);
+       sec_blob->NtChallengeResponse.Length =
+                       cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
        sec_blob->NtChallengeResponse.MaximumLength =
-                               cpu_to_le16(size + ses->tilen);
-       kfree(ses->tiblob);
-       ses->tiblob = NULL;
-       ses->tilen = 0;
+                       cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
 
        if (ses->domainName == NULL) {
                sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
@@ -554,9 +544,19 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
        sec_blob->WorkstationName.MaximumLength = 0;
        tmp += 2;
 
-       sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
-       sec_blob->SessionKey.Length = 0;
-       sec_blob->SessionKey.MaximumLength = 0;
+       if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
+                       !calc_seckey(ses)) {
+               memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
+               sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
+               sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
+               sec_blob->SessionKey.MaximumLength =
+                               cpu_to_le16(CIFS_CPHTXT_SIZE);
+               tmp += CIFS_CPHTXT_SIZE;
+       } else {
+               sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
+               sec_blob->SessionKey.Length = 0;
+               sec_blob->SessionKey.MaximumLength = 0;
+       }
 
 setup_ntlmv2_ret:
        *buflen = tmp - pbuffer;
@@ -600,8 +600,16 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
                return -EINVAL;
 
        type = ses->server->secType;
-
        cFYI(1, "sess setup type %d", type);
+       if (type == RawNTLMSSP) {
+               /* if memory allocation is successful, caller of this function
+                * frees it.
+                */
+               ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
+               if (!ses->ntlmssp)
+                       return -ENOMEM;
+       }
+
 ssetup_ntlmssp_authenticate:
        if (phase == NtLmChallenge)
                phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
@@ -666,10 +674,14 @@ ssetup_ntlmssp_authenticate:
                /* no capabilities flags in old lanman negotiation */
 
                pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
-               /* BB calculate hash with password */
-               /* and copy into bcc */
 
-               calc_lanman_hash(ses->password, ses->cryptKey,
+               /* Calculate hash with password and copy into bcc_ptr.
+                * Encryption Key (stored as in cryptkey) gets used if the
+                * security mode bit in Negottiate Protocol response states
+                * to use challenge/response method (i.e. Password bit is 1).
+                */
+
+               calc_lanman_hash(ses->password, ses->server->cryptkey,
                                 ses->server->secMode & SECMODE_PW_ENCRYPT ?
                                        true : false, lnm_session_key);
 
@@ -687,24 +699,27 @@ ssetup_ntlmssp_authenticate:
                ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
 #endif
        } else if (type == NTLM) {
-               char ntlm_session_key[CIFS_SESS_KEY_SIZE];
-
                pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
                pSMB->req_no_secext.CaseInsensitivePasswordLength =
-                       cpu_to_le16(CIFS_SESS_KEY_SIZE);
+                       cpu_to_le16(CIFS_AUTH_RESP_SIZE);
                pSMB->req_no_secext.CaseSensitivePasswordLength =
-                       cpu_to_le16(CIFS_SESS_KEY_SIZE);
+                       cpu_to_le16(CIFS_AUTH_RESP_SIZE);
+
+               /* calculate ntlm response and session key */
+               rc = setup_ntlm_response(ses);
+               if (rc) {
+                       cERROR(1, "Error %d during NTLM authentication", rc);
+                       goto ssetup_exit;
+               }
 
-               /* calculate session key */
-               SMBNTencrypt(ses->password, ses->cryptKey, ntlm_session_key);
+               /* copy ntlm response */
+               memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+                               CIFS_AUTH_RESP_SIZE);
+               bcc_ptr += CIFS_AUTH_RESP_SIZE;
+               memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+                               CIFS_AUTH_RESP_SIZE);
+               bcc_ptr += CIFS_AUTH_RESP_SIZE;
 
-               cifs_calculate_session_key(&ses->auth_key,
-                                       ntlm_session_key, ses->password);
-               /* copy session key */
-               memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
-               bcc_ptr += CIFS_SESS_KEY_SIZE;
-               memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
-               bcc_ptr += CIFS_SESS_KEY_SIZE;
                if (ses->capabilities & CAP_UNICODE) {
                        /* unicode strings must be word aligned */
                        if (iov[0].iov_len % 2) {
@@ -715,47 +730,26 @@ ssetup_ntlmssp_authenticate:
                } else
                        ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
        } else if (type == NTLMv2) {
-               char *v2_sess_key =
-                       kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
-
-               /* BB FIXME change all users of v2_sess_key to
-                  struct ntlmv2_resp */
-
-               if (v2_sess_key == NULL) {
-                       rc = -ENOMEM;
-                       goto ssetup_exit;
-               }
-
                pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
 
                /* LM2 password would be here if we supported it */
                pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
-               /*      cpu_to_le16(LM2_SESS_KEY_SIZE); */
 
-               /* calculate session key */
-               rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
+               /* calculate nlmv2 response and session key */
+               rc = setup_ntlmv2_rsp(ses, nls_cp);
                if (rc) {
                        cERROR(1, "Error %d during NTLMv2 authentication", rc);
-                       kfree(v2_sess_key);
                        goto ssetup_exit;
                }
-               memcpy(bcc_ptr, (char *)v2_sess_key,
-                               sizeof(struct ntlmv2_resp));
-               bcc_ptr += sizeof(struct ntlmv2_resp);
-               kfree(v2_sess_key);
+               memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+                               ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+               bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
+
                /* set case sensitive password length after tilen may get
                 * assigned, tilen is 0 otherwise.
                 */
                pSMB->req_no_secext.CaseSensitivePasswordLength =
-                       cpu_to_le16(sizeof(struct ntlmv2_resp) + ses->tilen);
-               if (ses->tilen > 0) {
-                       memcpy(bcc_ptr, ses->tiblob, ses->tilen);
-                       bcc_ptr += ses->tilen;
-                       /* we never did allocate ses->domainName to free */
-                       kfree(ses->tiblob);
-                       ses->tiblob = NULL;
-                       ses->tilen = 0;
-               }
+                       cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
 
                if (ses->capabilities & CAP_UNICODE) {
                        if (iov[0].iov_len % 2) {
@@ -768,6 +762,7 @@ ssetup_ntlmssp_authenticate:
        } else if (type == Kerberos) {
 #ifdef CONFIG_CIFS_UPCALL
                struct cifs_spnego_msg *msg;
+
                spnego_key = cifs_get_spnego_key(ses);
                if (IS_ERR(spnego_key)) {
                        rc = PTR_ERR(spnego_key);
@@ -785,16 +780,17 @@ ssetup_ntlmssp_authenticate:
                        rc = -EKEYREJECTED;
                        goto ssetup_exit;
                }
-               /* bail out if key is too long */
-               if (msg->sesskey_len >
-                   sizeof(ses->auth_key.data.krb5)) {
-                       cERROR(1, "Kerberos signing key too long (%u bytes)",
-                               msg->sesskey_len);
-                       rc = -EOVERFLOW;
+
+               ses->auth_key.response = kmalloc(msg->sesskey_len, GFP_KERNEL);
+               if (!ses->auth_key.response) {
+                       cERROR(1, "Kerberos can't allocate (%u bytes) memory",
+                                       msg->sesskey_len);
+                       rc = -ENOMEM;
                        goto ssetup_exit;
                }
+               memcpy(ses->auth_key.response, msg->data, msg->sesskey_len);
                ses->auth_key.len = msg->sesskey_len;
-               memcpy(ses->auth_key.data.krb5, msg->data, msg->sesskey_len);
+
                pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
                capabilities |= CAP_EXTENDED_SECURITY;
                pSMB->req.Capabilities = cpu_to_le32(capabilities);
@@ -897,8 +893,6 @@ ssetup_ntlmssp_authenticate:
                          CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
        /* SMB request buf freed in SendReceive2 */
 
-       cFYI(1, "ssetup rc from sendrecv2 is %d", rc);
-
        pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
        smb_buf = (struct smb_hdr *)iov[0].iov_base;
 
index a66c91eb6eb4e13cdc611786ad44dae2172ede1a..e0588cdf4cc5d5a1e8a73c1190c21f2d6cbe4986 100644 (file)
@@ -543,7 +543,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                    (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
                                             SECMODE_SIGN_ENABLED))) {
                        rc = cifs_verify_signature(midQ->resp_buf,
-                                               &ses->server->session_key,
+                                               ses->server,
                                                midQ->sequence_number+1);
                        if (rc) {
                                cERROR(1, "Unexpected SMB signature");
@@ -731,7 +731,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                    (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
                                             SECMODE_SIGN_ENABLED))) {
                        rc = cifs_verify_signature(out_buf,
-                                               &ses->server->session_key,
+                                               ses->server,
                                                midQ->sequence_number+1);
                        if (rc) {
                                cERROR(1, "Unexpected SMB signature");
@@ -981,7 +981,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
            (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
                                     SECMODE_SIGN_ENABLED))) {
                rc = cifs_verify_signature(out_buf,
-                                          &ses->server->session_key,
+                                          ses->server,
                                           midQ->sequence_number+1);
                if (rc) {
                        cERROR(1, "Unexpected SMB signature");
index 7993b96ca348cdf6910fc60e048b61847c8d7097..5ea57c8c7f97032abe286dc97c9e3b5dc041f4a6 100644 (file)
@@ -306,16 +306,16 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 /* init_coda: used by filesystems.c to register coda */
 
-static int coda_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *coda_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, coda_fill_super, mnt);
+       return mount_nodev(fs_type, flags, data, coda_fill_super);
 }
 
 struct file_system_type coda_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "coda",
-       .get_sb         = coda_get_sb,
+       .mount          = coda_mount,
        .kill_sb        = kill_anon_super,
        .fs_flags       = FS_BINARY_MOUNTDATA,
 };
index 52cfeb61da77c14ce7d3838db7517b5b6f88b213..c580c322fa6b1bab00a8b949cd3284f691bc366a 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/eventpoll.h>
 #include <linux/fs_struct.h>
 #include <linux/slab.h>
+#include <linux/pagemap.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -606,14 +607,14 @@ ssize_t compat_rw_copy_check_uvector(int type,
        /*
         * Single unix specification:
         * We should -EINVAL if an element length is not >= 0 and fitting an
-        * ssize_t.  The total length is fitting an ssize_t
+        * ssize_t.
         *
-        * Be careful here because iov_len is a size_t not an ssize_t
+        * In Linux, the total length is limited to MAX_RW_COUNT, there is
+        * no overflow possibility.
         */
        tot_len = 0;
        ret = -EINVAL;
        for (seg = 0; seg < nr_segs; seg++) {
-               compat_ssize_t tmp = tot_len;
                compat_uptr_t buf;
                compat_ssize_t len;
 
@@ -624,13 +625,13 @@ ssize_t compat_rw_copy_check_uvector(int type,
                }
                if (len < 0)    /* size_t not fitting in compat_ssize_t .. */
                        goto out;
-               tot_len += len;
-               if (tot_len < tmp) /* maths overflow on the compat_ssize_t */
-                       goto out;
                if (!access_ok(vrfy_dir(type), compat_ptr(buf), len)) {
                        ret = -EFAULT;
                        goto out;
                }
+               if (len > MAX_RW_COUNT - tot_len)
+                       len = MAX_RW_COUNT - tot_len;
+               tot_len += len;
                iov->iov_base = compat_ptr(buf);
                iov->iov_len = (compat_size_t) len;
                uvector++;
index 8c8d64230c2d040d1946444eb33c6533288f6019..7d3607febe1c7f8878912ab3a389933cda932aaa 100644 (file)
@@ -104,16 +104,16 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 }
 
-static int configfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *configfs_do_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, configfs_fill_super, mnt);
+       return mount_single(fs_type, flags, data, configfs_fill_super);
 }
 
 static struct file_system_type configfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "configfs",
-       .get_sb         = configfs_get_sb,
+       .mount          = configfs_do_mount,
        .kill_sb        = kill_litter_super,
 };
 
index 1e7a33028d33908807d776d05840637cfd7e4f22..32fd5fe9ca0e5b8cd13a4a25c4c7a194e235bf1f 100644 (file)
@@ -533,17 +533,16 @@ static const struct super_operations cramfs_ops = {
        .statfs         = cramfs_statfs,
 };
 
-static int cramfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *cramfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, cramfs_fill_super);
 }
 
 static struct file_system_type cramfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "cramfs",
-       .get_sb         = cramfs_get_sb,
+       .mount          = cramfs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index a4ed8380e98a630197edf4c556b8f4067a1c872f..37a8ca7c12228442022a75f6735bb65cb5930209 100644 (file)
@@ -135,17 +135,17 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent)
        return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
 }
 
-static int debug_get_sb(struct file_system_type *fs_type,
+static struct dentry *debug_mount(struct file_system_type *fs_type,
                        int flags, const char *dev_name,
-                       void *data, struct vfsmount *mnt)
+                       void *data)
 {
-       return get_sb_single(fs_type, flags, data, debug_fill_super, mnt);
+       return mount_single(fs_type, flags, data, debug_fill_super);
 }
 
 static struct file_system_type debug_fs_type = {
        .owner =        THIS_MODULE,
        .name =         "debugfs",
-       .get_sb =       debug_get_sb,
+       .mount =        debug_mount,
        .kill_sb =      kill_litter_super,
 };
 
index 8b3ffd5b5235eebf6e5f711efa1673776f80e6e9..1bb547c9cad6d98d5c2816a3bf01d46481a72224 100644 (file)
@@ -331,7 +331,7 @@ static int compare_init_pts_sb(struct super_block *s, void *p)
 }
 
 /*
- * devpts_get_sb()
+ * devpts_mount()
  *
  *     If the '-o newinstance' mount option was specified, mount a new
  *     (private) instance of devpts.  PTYs created in this instance are
@@ -345,20 +345,20 @@ static int compare_init_pts_sb(struct super_block *s, void *p)
  *     semantics in devpts while preserving backward compatibility of the
  *     current 'single-namespace' semantics. i.e all mounts of devpts
  *     without the 'newinstance' mount option should bind to the initial
- *     kernel mount, like get_sb_single().
+ *     kernel mount, like mount_single().
  *
  *     Mounts with 'newinstance' option create a new, private namespace.
  *
  *     NOTE:
  *
- *     For single-mount semantics, devpts cannot use get_sb_single(),
- *     because get_sb_single()/sget() find and use the super-block from
+ *     For single-mount semantics, devpts cannot use mount_single(),
+ *     because mount_single()/sget() find and use the super-block from
  *     the most recent mount of devpts. But that recent mount may be a
- *     'newinstance' mount and get_sb_single() would pick the newinstance
+ *     'newinstance' mount and mount_single() would pick the newinstance
  *     super-block instead of the initial super-block.
  */
-static int devpts_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *devpts_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
        int error;
        struct pts_mount_opts opts;
@@ -366,7 +366,7 @@ static int devpts_get_sb(struct file_system_type *fs_type,
 
        error = parse_mount_options(data, PARSE_MOUNT, &opts);
        if (error)
-               return error;
+               return ERR_PTR(error);
 
        if (opts.newinstance)
                s = sget(fs_type, NULL, set_anon_super, NULL);
@@ -374,7 +374,7 @@ static int devpts_get_sb(struct file_system_type *fs_type,
                s = sget(fs_type, compare_init_pts_sb, set_anon_super, NULL);
 
        if (IS_ERR(s))
-               return PTR_ERR(s);
+               return ERR_CAST(s);
 
        if (!s->s_root) {
                s->s_flags = flags;
@@ -390,13 +390,11 @@ static int devpts_get_sb(struct file_system_type *fs_type,
        if (error)
                goto out_undo_sget;
 
-       simple_set_mnt(mnt, s);
-
-       return 0;
+       return dget(s->s_root);
 
 out_undo_sget:
        deactivate_locked_super(s);
-       return error;
+       return ERR_PTR(error);
 }
 
 #else
@@ -404,10 +402,10 @@ out_undo_sget:
  * This supports only the legacy single-instance semantics (no
  * multiple-instance semantics)
  */
-static int devpts_get_sb(struct file_system_type *fs_type, int flags,
-               const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *devpts_mount(struct file_system_type *fs_type, int flags,
+               const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, devpts_fill_super, mnt);
+       return mount_single(fs_type, flags, data, devpts_fill_super);
 }
 #endif
 
@@ -421,7 +419,7 @@ static void devpts_kill_sb(struct super_block *sb)
 
 static struct file_system_type devpts_fs_type = {
        .name           = "devpts",
-       .get_sb         = devpts_get_sb,
+       .mount          = devpts_mount,
        .kill_sb        = devpts_kill_sb,
 };
 
index 40186b9594296f5152119e43d3ade4092a17d07f..413a3c48f0bb8a539f2dd09c72cdc8c972db83c1 100644 (file)
@@ -377,6 +377,7 @@ struct ecryptfs_mount_crypt_stat {
 #define ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES      0x00000010
 #define ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK   0x00000020
 #define ECRYPTFS_GLOBAL_ENCFN_USE_FEK          0x00000040
+#define ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY    0x00000080
        u32 flags;
        struct list_head global_auth_tok_list;
        struct mutex global_auth_tok_list_mutex;
index 3fbc94203380acf8e6095627ee610ff058df5f38..9d1a22d62765af487333005a58e7c60230362a44 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/crypto.h>
 #include <linux/fs_stack.h>
 #include <linux/slab.h>
+#include <linux/xattr.h>
 #include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
@@ -70,15 +71,19 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
        struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
        struct dentry *dentry_save;
        struct vfsmount *vfsmount_save;
+       unsigned int flags_save;
        int rc;
 
        dentry_save = nd->path.dentry;
        vfsmount_save = nd->path.mnt;
+       flags_save = nd->flags;
        nd->path.dentry = lower_dentry;
        nd->path.mnt = lower_mnt;
+       nd->flags &= ~LOOKUP_OPEN;
        rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
        nd->path.dentry = dentry_save;
        nd->path.mnt = vfsmount_save;
+       nd->flags = flags_save;
        return rc;
 }
 
@@ -1108,10 +1113,8 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
                rc = -EOPNOTSUPP;
                goto out;
        }
-       mutex_lock(&lower_dentry->d_inode->i_mutex);
-       rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry, name, value,
-                                                  size, flags);
-       mutex_unlock(&lower_dentry->d_inode->i_mutex);
+
+       rc = vfs_setxattr(lower_dentry, name, value, size, flags);
 out:
        return rc;
 }
index 73811cfa2ea4369766a99a251c614ddb091bc8f4..b1f6858a5223323c43708b62b6ab2d9c139dc376 100644 (file)
@@ -446,6 +446,7 @@ out:
  */
 static int
 ecryptfs_find_auth_tok_for_sig(
+       struct key **auth_tok_key,
        struct ecryptfs_auth_tok **auth_tok,
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
        char *sig)
@@ -453,12 +454,21 @@ ecryptfs_find_auth_tok_for_sig(
        struct ecryptfs_global_auth_tok *global_auth_tok;
        int rc = 0;
 
+       (*auth_tok_key) = NULL;
        (*auth_tok) = NULL;
        if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,
                                                  mount_crypt_stat, sig)) {
-               struct key *auth_tok_key;
 
-               rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok,
+               /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the
+                * mount_crypt_stat structure, we prevent to use auth toks that
+                * are not inserted through the ecryptfs_add_global_auth_tok
+                * function.
+                */
+               if (mount_crypt_stat->flags
+                               & ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY)
+                       return -EINVAL;
+
+               rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok,
                                                       sig);
        } else
                (*auth_tok) = global_auth_tok->global_auth_tok;
@@ -509,6 +519,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
                             char *filename, size_t filename_size)
 {
        struct ecryptfs_write_tag_70_packet_silly_stack *s;
+       struct key *auth_tok_key = NULL;
        int rc = 0;
 
        s = kmalloc(sizeof(*s), GFP_KERNEL);
@@ -606,6 +617,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
        }
        dest[s->i++] = s->cipher_code;
        rc = ecryptfs_find_auth_tok_for_sig(
+               &auth_tok_key,
                &s->auth_tok, mount_crypt_stat,
                mount_crypt_stat->global_default_fnek_sig);
        if (rc) {
@@ -753,6 +765,8 @@ out_free_unlock:
 out_unlock:
        mutex_unlock(s->tfm_mutex);
 out:
+       if (auth_tok_key)
+               key_put(auth_tok_key);
        kfree(s);
        return rc;
 }
@@ -798,6 +812,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
                             char *data, size_t max_packet_size)
 {
        struct ecryptfs_parse_tag_70_packet_silly_stack *s;
+       struct key *auth_tok_key = NULL;
        int rc = 0;
 
        (*packet_size) = 0;
@@ -910,7 +925,8 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
         * >= ECRYPTFS_MAX_IV_BYTES. */
        memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES);
        s->desc.info = s->iv;
-       rc = ecryptfs_find_auth_tok_for_sig(&s->auth_tok, mount_crypt_stat,
+       rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key,
+                                           &s->auth_tok, mount_crypt_stat,
                                            s->fnek_sig_hex);
        if (rc) {
                printk(KERN_ERR "%s: Error attempting to find auth tok for "
@@ -986,6 +1002,8 @@ out:
                (*filename_size) = 0;
                (*filename) = NULL;
        }
+       if (auth_tok_key)
+               key_put(auth_tok_key);
        kfree(s);
        return rc;
 }
@@ -1557,14 +1575,19 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
                       ECRYPTFS_VERSION_MAJOR,
                       ECRYPTFS_VERSION_MINOR);
                rc = -EINVAL;
-               goto out;
+               goto out_release_key;
        }
        if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD
            && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) {
                printk(KERN_ERR "Invalid auth_tok structure "
                       "returned from key query\n");
                rc = -EINVAL;
-               goto out;
+               goto out_release_key;
+       }
+out_release_key:
+       if (rc) {
+               key_put(*auth_tok_key);
+               (*auth_tok_key) = NULL;
        }
 out:
        return rc;
@@ -1688,6 +1711,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
        struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
        size_t tag_11_contents_size;
        size_t tag_11_packet_size;
+       struct key *auth_tok_key = NULL;
        int rc = 0;
 
        INIT_LIST_HEAD(&auth_tok_list);
@@ -1784,6 +1808,10 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
         * just one will be sufficient to decrypt to get the FEK. */
 find_next_matching_auth_tok:
        found_auth_tok = 0;
+       if (auth_tok_key) {
+               key_put(auth_tok_key);
+               auth_tok_key = NULL;
+       }
        list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) {
                candidate_auth_tok = &auth_tok_list_item->auth_tok;
                if (unlikely(ecryptfs_verbosity > 0)) {
@@ -1800,10 +1828,11 @@ find_next_matching_auth_tok:
                        rc = -EINVAL;
                        goto out_wipe_list;
                }
-               ecryptfs_find_auth_tok_for_sig(&matching_auth_tok,
+               rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key,
+                                              &matching_auth_tok,
                                               crypt_stat->mount_crypt_stat,
                                               candidate_auth_tok_sig);
-               if (matching_auth_tok) {
+               if (!rc) {
                        found_auth_tok = 1;
                        goto found_matching_auth_tok;
                }
@@ -1866,6 +1895,8 @@ found_matching_auth_tok:
 out_wipe_list:
        wipe_auth_tok_list(&auth_tok_list);
 out:
+       if (auth_tok_key)
+               key_put(auth_tok_key);
        return rc;
 }
 
index cbd4e18adb204438d45b865469d38b7af97a9904..a9dbd62518e6a875abee7da0e0698ac0ed7ba4ff 100644 (file)
@@ -208,7 +208,8 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig,
        ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata,
        ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig,
        ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes,
-       ecryptfs_opt_unlink_sigs, ecryptfs_opt_err };
+       ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only,
+       ecryptfs_opt_err };
 
 static const match_table_t tokens = {
        {ecryptfs_opt_sig, "sig=%s"},
@@ -223,6 +224,7 @@ static const match_table_t tokens = {
        {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"},
        {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"},
        {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"},
+       {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"},
        {ecryptfs_opt_err, NULL}
 };
 
@@ -406,6 +408,10 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options)
                case ecryptfs_opt_unlink_sigs:
                        mount_crypt_stat->flags |= ECRYPTFS_UNLINK_SIGS;
                        break;
+               case ecryptfs_opt_mount_auth_tok_only:
+                       mount_crypt_stat->flags |=
+                               ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY;
+                       break;
                case ecryptfs_opt_err:
                default:
                        printk(KERN_WARNING
@@ -540,9 +546,8 @@ out:
  *                        ecryptfs_interpose to perform most of the linking
  * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c)
  */
-static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
-                       const char *dev_name, void *raw_data,
-                       struct vfsmount *mnt)
+static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags,
+                       const char *dev_name, void *raw_data)
 {
        struct super_block *s;
        struct ecryptfs_sb_info *sbi;
@@ -607,8 +612,7 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
                err = "Reading sb failed";
                goto out;
        }
-       simple_set_mnt(mnt, s);
-       return 0;
+       return dget(s->s_root);
 
 out:
        if (sbi) {
@@ -616,7 +620,7 @@ out:
                kmem_cache_free(ecryptfs_sb_info_cache, sbi);
        }
        printk(KERN_ERR "%s; rc = [%d]\n", err, rc);
-       return rc;
+       return ERR_PTR(rc);
 }
 
 /**
@@ -639,7 +643,7 @@ static void ecryptfs_kill_block_super(struct super_block *sb)
 static struct file_system_type ecryptfs_fs_type = {
        .owner = THIS_MODULE,
        .name = "ecryptfs",
-       .get_sb = ecryptfs_get_sb,
+       .mount = ecryptfs_mount,
        .kill_sb = ecryptfs_kill_block_super,
        .fs_flags = 0
 };
index f7fc286a3aa9a7353ab7ca1bd0ba56e7cbb821e2..253732382d375e848edc61ca40a3eaadb60f80c7 100644 (file)
@@ -180,6 +180,8 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
                seq_printf(m, ",ecryptfs_encrypted_view");
        if (mount_crypt_stat->flags & ECRYPTFS_UNLINK_SIGS)
                seq_printf(m, ",ecryptfs_unlink_sigs");
+       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY)
+               seq_printf(m, ",ecryptfs_mount_auth_tok_only");
 
        return 0;
 }
index f04942810818ade709f8f7cfa416b21f87c6736a..5073a07652cc78724cfdd537bf365e17e139ac2f 100644 (file)
 static int efs_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int efs_fill_super(struct super_block *s, void *d, int silent);
 
-static int efs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *efs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, efs_fill_super, mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, efs_fill_super);
 }
 
 static struct file_system_type efs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "efs",
-       .get_sb         = efs_get_sb,
+       .mount          = efs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 047e92fa3af8aaf56350fbb2ca99fd56e45d7dd3..79c3ae6e045693ec5e7e8f91cf031309be175242 100644 (file)
@@ -659,19 +659,19 @@ free_bdi:
 /*
  * Set up the superblock (calls exofs_fill_super eventually)
  */
-static int exofs_get_sb(struct file_system_type *type,
+static struct dentry *exofs_mount(struct file_system_type *type,
                          int flags, const char *dev_name,
-                         void *data, struct vfsmount *mnt)
+                         void *data)
 {
        struct exofs_mountopt opts;
        int ret;
 
        ret = parse_options(data, &opts);
        if (ret)
-               return ret;
+               return ERR_PTR(ret);
 
        opts.dev_name = dev_name;
-       return get_sb_nodev(type, flags, &opts, exofs_fill_super, mnt);
+       return mount_nodev(type, flags, &opts, exofs_fill_super);
 }
 
 /*
@@ -809,7 +809,7 @@ static const struct export_operations exofs_export_ops = {
 static struct file_system_type exofs_type = {
        .owner          = THIS_MODULE,
        .name           = "exofs",
-       .get_sb         = exofs_get_sb,
+       .mount          = exofs_mount,
        .kill_sb        = generic_shutdown_super,
 };
 
index 0901320671da20631092a1cc57113e9a0ef46d8d..d89e0b6a2d78d86f7e74772b58b98291bba3aa4a 100644 (file)
@@ -1356,10 +1356,10 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
        return 0;
 }
 
-static int ext2_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *ext2_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super, mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, ext2_fill_super);
 }
 
 #ifdef CONFIG_QUOTA
@@ -1473,7 +1473,7 @@ out:
 static struct file_system_type ext2_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ext2",
-       .get_sb         = ext2_get_sb,
+       .mount          = ext2_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index db87413d3479c15ecc36223ad4b02c8c6c06f07e..2fedaf8b50125bf65ad9b550537742de3109ecd4 100644 (file)
@@ -3020,16 +3020,16 @@ out:
 
 #endif
 
-static int ext3_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *ext3_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super, mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, ext3_fill_super);
 }
 
 static struct file_system_type ext3_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ext3",
-       .get_sb         = ext3_get_sb,
+       .mount          = ext3_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 8b5dd6369f82c19d5ba28dea07018e4fb13a025f..6a5edea2d70b3ac7c56e8b272686b5a799eabbcf 100644 (file)
@@ -177,7 +177,7 @@ struct mpage_da_data {
 
 struct ext4_io_page {
        struct page     *p_page;
-       int             p_count;
+       atomic_t        p_count;
 };
 
 #define MAX_IO_PAGES 128
@@ -858,6 +858,7 @@ struct ext4_inode_info {
        spinlock_t i_completed_io_lock;
        /* current io_end structure for async DIO write*/
        ext4_io_end_t *cur_aio_dio;
+       atomic_t i_ioend_count; /* Number of outstanding io_end structs */
 
        /*
         * Transactions that contain inode's metadata needed to complete
@@ -2060,6 +2061,7 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp,
 /* page-io.c */
 extern int __init ext4_init_pageio(void);
 extern void ext4_exit_pageio(void);
+extern void ext4_ioend_wait(struct inode *);
 extern void ext4_free_io_end(ext4_io_end_t *io);
 extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags);
 extern int ext4_end_io_nolock(ext4_io_end_t *io);
index 1916164704667dc3c190ab327781933fa7c5f4b8..bdbe69902207c151df025d98690c4c016cf0b0e9 100644 (file)
@@ -53,6 +53,7 @@
 static inline int ext4_begin_ordered_truncate(struct inode *inode,
                                              loff_t new_size)
 {
+       trace_ext4_begin_ordered_truncate(inode, new_size);
        return jbd2_journal_begin_ordered_truncate(
                                        EXT4_SB(inode->i_sb)->s_journal,
                                        &EXT4_I(inode)->jinode,
@@ -178,6 +179,7 @@ void ext4_evict_inode(struct inode *inode)
        handle_t *handle;
        int err;
 
+       trace_ext4_evict_inode(inode);
        if (inode->i_nlink) {
                truncate_inode_pages(&inode->i_data, 0);
                goto no_delete;
@@ -5410,9 +5412,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
         * will return the blocks that include the delayed allocation
         * blocks for this file.
         */
-       spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
        delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks;
-       spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
 
        stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9;
        return 0;
@@ -5649,6 +5649,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
        int err, ret;
 
        might_sleep();
+       trace_ext4_mark_inode_dirty(inode, _RET_IP_);
        err = ext4_reserve_inode_write(handle, inode, &iloc);
        if (ext4_handle_valid(handle) &&
            EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&
index c58eba34724a4281f1cb8bb405ab607ef09b49ff..5b4d4e3a4d58e3506c15e891e7b8df394bc0838f 100644 (file)
@@ -4640,8 +4640,6 @@ do_more:
                 * with group lock held. generate_buddy look at
                 * them with group lock_held
                 */
-               if (test_opt(sb, DISCARD))
-                       ext4_issue_discard(sb, block_group, bit, count);
                ext4_lock_group(sb, block_group);
                mb_clear_bits(bitmap_bh->b_data, bit, count);
                mb_free_blocks(inode, &e4b, bit, count);
index 46a7d6a9d9764b82075071c94f661cc65c3675fc..7f5451cd1d38bff2399471750618fc7429ce5c5e 100644 (file)
 
 static struct kmem_cache *io_page_cachep, *io_end_cachep;
 
+#define WQ_HASH_SZ             37
+#define to_ioend_wq(v) (&ioend_wq[((unsigned long)v) % WQ_HASH_SZ])
+static wait_queue_head_t ioend_wq[WQ_HASH_SZ];
+
 int __init ext4_init_pageio(void)
 {
+       int i;
+
        io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT);
        if (io_page_cachep == NULL)
                return -ENOMEM;
@@ -42,6 +48,8 @@ int __init ext4_init_pageio(void)
                kmem_cache_destroy(io_page_cachep);
                return -ENOMEM;
        }
+       for (i = 0; i < WQ_HASH_SZ; i++)
+               init_waitqueue_head(&ioend_wq[i]);
 
        return 0;
 }
@@ -52,24 +60,37 @@ void ext4_exit_pageio(void)
        kmem_cache_destroy(io_page_cachep);
 }
 
+void ext4_ioend_wait(struct inode *inode)
+{
+       wait_queue_head_t *wq = to_ioend_wq(inode);
+
+       wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0));
+}
+
+static void put_io_page(struct ext4_io_page *io_page)
+{
+       if (atomic_dec_and_test(&io_page->p_count)) {
+               end_page_writeback(io_page->p_page);
+               put_page(io_page->p_page);
+               kmem_cache_free(io_page_cachep, io_page);
+       }
+}
+
 void ext4_free_io_end(ext4_io_end_t *io)
 {
        int i;
+       wait_queue_head_t *wq;
 
        BUG_ON(!io);
        if (io->page)
                put_page(io->page);
-       for (i = 0; i < io->num_io_pages; i++) {
-               if (--io->pages[i]->p_count == 0) {
-                       struct page *page = io->pages[i]->p_page;
-
-                       end_page_writeback(page);
-                       put_page(page);
-                       kmem_cache_free(io_page_cachep, io->pages[i]);
-               }
-       }
+       for (i = 0; i < io->num_io_pages; i++)
+               put_io_page(io->pages[i]);
        io->num_io_pages = 0;
-       iput(io->inode);
+       wq = to_ioend_wq(io->inode);
+       if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count) &&
+           waitqueue_active(wq))
+               wake_up_all(wq);
        kmem_cache_free(io_end_cachep, io);
 }
 
@@ -142,8 +163,8 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
        io = kmem_cache_alloc(io_end_cachep, flags);
        if (io) {
                memset(io, 0, sizeof(*io));
-               io->inode = igrab(inode);
-               BUG_ON(!io->inode);
+               atomic_inc(&EXT4_I(inode)->i_ioend_count);
+               io->inode = inode;
                INIT_WORK(&io->work, ext4_end_io_work);
                INIT_LIST_HEAD(&io->list);
        }
@@ -171,35 +192,15 @@ static void ext4_end_bio(struct bio *bio, int error)
        struct workqueue_struct *wq;
        struct inode *inode;
        unsigned long flags;
-       ext4_fsblk_t err_block;
        int i;
 
        BUG_ON(!io_end);
-       inode = io_end->inode;
        bio->bi_private = NULL;
        bio->bi_end_io = NULL;
        if (test_bit(BIO_UPTODATE, &bio->bi_flags))
                error = 0;
-       err_block = bio->bi_sector >> (inode->i_blkbits - 9);
        bio_put(bio);
 
-       if (!(inode->i_sb->s_flags & MS_ACTIVE)) {
-               pr_err("sb umounted, discard end_io request for inode %lu\n",
-                       io_end->inode->i_ino);
-               ext4_free_io_end(io_end);
-               return;
-       }
-
-       if (error) {
-               io_end->flag |= EXT4_IO_END_ERROR;
-               ext4_warning(inode->i_sb, "I/O error writing to inode %lu "
-                            "(offset %llu size %ld starting block %llu)",
-                            inode->i_ino,
-                            (unsigned long long) io_end->offset,
-                            (long) io_end->size,
-                            (unsigned long long) err_block);
-       }
-
        for (i = 0; i < io_end->num_io_pages; i++) {
                struct page *page = io_end->pages[i]->p_page;
                struct buffer_head *bh, *head;
@@ -236,13 +237,7 @@ static void ext4_end_bio(struct bio *bio, int error)
                        } while (bh != head);
                }
 
-               if (--io_end->pages[i]->p_count == 0) {
-                       struct page *page = io_end->pages[i]->p_page;
-
-                       end_page_writeback(page);
-                       put_page(page);
-                       kmem_cache_free(io_page_cachep, io_end->pages[i]);
-               }
+               put_io_page(io_end->pages[i]);
 
                /*
                 * If this is a partial write which happened to make
@@ -254,8 +249,19 @@ static void ext4_end_bio(struct bio *bio, int error)
                if (!partial_write)
                        SetPageUptodate(page);
        }
-
        io_end->num_io_pages = 0;
+       inode = io_end->inode;
+
+       if (error) {
+               io_end->flag |= EXT4_IO_END_ERROR;
+               ext4_warning(inode->i_sb, "I/O error writing to inode %lu "
+                            "(offset %llu size %ld starting block %llu)",
+                            inode->i_ino,
+                            (unsigned long long) io_end->offset,
+                            (long) io_end->size,
+                            (unsigned long long)
+                            bio->bi_sector >> (inode->i_blkbits - 9));
+       }
 
        /* Add the io_end to per-inode completed io list*/
        spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
@@ -305,7 +311,6 @@ static int io_submit_init(struct ext4_io_submit *io,
        bio->bi_private = io->io_end = io_end;
        bio->bi_end_io = ext4_end_bio;
 
-       io_end->inode = inode;
        io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh);
 
        io->io_bio = bio;
@@ -360,7 +365,7 @@ submit_and_retry:
        if ((io_end->num_io_pages == 0) ||
            (io_end->pages[io_end->num_io_pages-1] != io_page)) {
                io_end->pages[io_end->num_io_pages++] = io_page;
-               io_page->p_count++;
+               atomic_inc(&io_page->p_count);
        }
        return 0;
 }
@@ -389,7 +394,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
                return -ENOMEM;
        }
        io_page->p_page = page;
-       io_page->p_count = 0;
+       atomic_set(&io_page->p_count, 1);
        get_page(page);
 
        for (bh = head = page_buffers(page), block_start = 0;
@@ -421,10 +426,6 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
         * PageWriteback bit from the page to prevent the system from
         * wedging later on.
         */
-       if (io_page->p_count == 0) {
-               put_page(page);
-               end_page_writeback(page);
-               kmem_cache_free(io_page_cachep, io_page);
-       }
+       put_io_page(io_page);
        return ret;
 }
index 0348ce0665929f45933bb04fa538d2c18fe863f8..61182fe6254e94ad606a6c67fed1b30ef289ad38 100644 (file)
@@ -73,8 +73,8 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int ext4_unfreeze(struct super_block *sb);
 static void ext4_write_super(struct super_block *sb);
 static int ext4_freeze(struct super_block *sb);
-static int ext4_get_sb(struct file_system_type *fs_type, int flags,
-                      const char *dev_name, void *data, struct vfsmount *mnt);
+static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
+                      const char *dev_name, void *data);
 static void ext4_destroy_lazyinit_thread(void);
 static void ext4_unregister_li_request(struct super_block *sb);
 
@@ -82,7 +82,7 @@ static void ext4_unregister_li_request(struct super_block *sb);
 static struct file_system_type ext3_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ext3",
-       .get_sb         = ext4_get_sb,
+       .mount          = ext4_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
@@ -828,12 +828,22 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
        ei->cur_aio_dio = NULL;
        ei->i_sync_tid = 0;
        ei->i_datasync_tid = 0;
+       atomic_set(&ei->i_ioend_count, 0);
 
        return &ei->vfs_inode;
 }
 
+static int ext4_drop_inode(struct inode *inode)
+{
+       int drop = generic_drop_inode(inode);
+
+       trace_ext4_drop_inode(inode, drop);
+       return drop;
+}
+
 static void ext4_destroy_inode(struct inode *inode)
 {
+       ext4_ioend_wait(inode);
        if (!list_empty(&(EXT4_I(inode)->i_orphan))) {
                ext4_msg(inode->i_sb, KERN_ERR,
                         "Inode %lu (%p): orphan list check failed!",
@@ -1173,6 +1183,7 @@ static const struct super_operations ext4_sops = {
        .destroy_inode  = ext4_destroy_inode,
        .write_inode    = ext4_write_inode,
        .dirty_inode    = ext4_dirty_inode,
+       .drop_inode     = ext4_drop_inode,
        .evict_inode    = ext4_evict_inode,
        .put_super      = ext4_put_super,
        .sync_fs        = ext4_sync_fs,
@@ -1194,6 +1205,7 @@ static const struct super_operations ext4_nojournal_sops = {
        .destroy_inode  = ext4_destroy_inode,
        .write_inode    = ext4_write_inode,
        .dirty_inode    = ext4_dirty_inode,
+       .drop_inode     = ext4_drop_inode,
        .evict_inode    = ext4_evict_inode,
        .write_super    = ext4_write_super,
        .put_super      = ext4_put_super,
@@ -2699,7 +2711,6 @@ static int ext4_lazyinit_thread(void *arg)
        struct ext4_li_request *elr;
        unsigned long next_wakeup;
        DEFINE_WAIT(wait);
-       int ret;
 
        BUG_ON(NULL == eli);
 
@@ -2723,13 +2734,12 @@ cont_thread:
                        elr = list_entry(pos, struct ext4_li_request,
                                         lr_request);
 
-                       if (time_after_eq(jiffies, elr->lr_next_sched))
-                               ret = ext4_run_li_request(elr);
-
-                       if (ret) {
-                               ret = 0;
-                               ext4_remove_li_request(elr);
-                               continue;
+                       if (time_after_eq(jiffies, elr->lr_next_sched)) {
+                               if (ext4_run_li_request(elr) != 0) {
+                                       /* error, remove the lazy_init job */
+                                       ext4_remove_li_request(elr);
+                                       continue;
+                               }
                        }
 
                        if (time_before(elr->lr_next_sched, next_wakeup))
@@ -2740,7 +2750,8 @@ cont_thread:
                if (freezing(current))
                        refrigerator();
 
-               if (time_after_eq(jiffies, next_wakeup)) {
+               if ((time_after_eq(jiffies, next_wakeup)) ||
+                   (MAX_JIFFY_OFFSET == next_wakeup)) {
                        cond_resched();
                        continue;
                }
@@ -3348,6 +3359,24 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        get_random_bytes(&sbi->s_next_generation, sizeof(u32));
        spin_lock_init(&sbi->s_next_gen_lock);
 
+       err = percpu_counter_init(&sbi->s_freeblocks_counter,
+                       ext4_count_free_blocks(sb));
+       if (!err) {
+               err = percpu_counter_init(&sbi->s_freeinodes_counter,
+                               ext4_count_free_inodes(sb));
+       }
+       if (!err) {
+               err = percpu_counter_init(&sbi->s_dirs_counter,
+                               ext4_count_dirs(sb));
+       }
+       if (!err) {
+               err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0);
+       }
+       if (err) {
+               ext4_msg(sb, KERN_ERR, "insufficient memory");
+               goto failed_mount3;
+       }
+
        sbi->s_stripe = ext4_get_stripe_size(sbi);
        sbi->s_max_writeback_mb_bump = 128;
 
@@ -3446,22 +3475,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        }
        set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
 
-no_journal:
-       err = percpu_counter_init(&sbi->s_freeblocks_counter,
-                                 ext4_count_free_blocks(sb));
-       if (!err)
-               err = percpu_counter_init(&sbi->s_freeinodes_counter,
-                                         ext4_count_free_inodes(sb));
-       if (!err)
-               err = percpu_counter_init(&sbi->s_dirs_counter,
-                                         ext4_count_dirs(sb));
-       if (!err)
-               err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0);
-       if (err) {
-               ext4_msg(sb, KERN_ERR, "insufficient memory");
-               goto failed_mount_wq;
-       }
+       /*
+        * The journal may have updated the bg summary counts, so we
+        * need to update the global counters.
+        */
+       percpu_counter_set(&sbi->s_freeblocks_counter,
+                          ext4_count_free_blocks(sb));
+       percpu_counter_set(&sbi->s_freeinodes_counter,
+                          ext4_count_free_inodes(sb));
+       percpu_counter_set(&sbi->s_dirs_counter,
+                          ext4_count_dirs(sb));
+       percpu_counter_set(&sbi->s_dirtyblocks_counter, 0);
 
+no_journal:
        EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten");
        if (!EXT4_SB(sb)->dio_unwritten_wq) {
                printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n");
@@ -3611,10 +3637,6 @@ failed_mount_wq:
                jbd2_journal_destroy(sbi->s_journal);
                sbi->s_journal = NULL;
        }
-       percpu_counter_destroy(&sbi->s_freeblocks_counter);
-       percpu_counter_destroy(&sbi->s_freeinodes_counter);
-       percpu_counter_destroy(&sbi->s_dirs_counter);
-       percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
 failed_mount3:
        if (sbi->s_flex_groups) {
                if (is_vmalloc_addr(sbi->s_flex_groups))
@@ -3622,6 +3644,10 @@ failed_mount3:
                else
                        kfree(sbi->s_flex_groups);
        }
+       percpu_counter_destroy(&sbi->s_freeblocks_counter);
+       percpu_counter_destroy(&sbi->s_freeinodes_counter);
+       percpu_counter_destroy(&sbi->s_dirs_counter);
+       percpu_counter_destroy(&sbi->s_dirtyblocks_counter);
 failed_mount2:
        for (i = 0; i < db_count; i++)
                brelse(sbi->s_group_desc[i]);
@@ -3949,13 +3975,11 @@ static int ext4_commit_super(struct super_block *sb, int sync)
        else
                es->s_kbytes_written =
                        cpu_to_le64(EXT4_SB(sb)->s_kbytes_written);
-       if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeblocks_counter))
-               ext4_free_blocks_count_set(es, percpu_counter_sum_positive(
-                                       &EXT4_SB(sb)->s_freeblocks_counter));
-       if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeinodes_counter))
-               es->s_free_inodes_count =
-                       cpu_to_le32(percpu_counter_sum_positive(
-                                       &EXT4_SB(sb)->s_freeinodes_counter));
+       ext4_free_blocks_count_set(es, percpu_counter_sum_positive(
+                                          &EXT4_SB(sb)->s_freeblocks_counter));
+       es->s_free_inodes_count =
+               cpu_to_le32(percpu_counter_sum_positive(
+                               &EXT4_SB(sb)->s_freeinodes_counter));
        sb->s_dirt = 0;
        BUFFER_TRACE(sbh, "marking dirty");
        mark_buffer_dirty(sbh);
@@ -4556,12 +4580,10 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
 
 static int ext4_quota_off(struct super_block *sb, int type)
 {
-       /* Force all delayed allocation blocks to be allocated */
-       if (test_opt(sb, DELALLOC)) {
-               down_read(&sb->s_umount);
+       /* Force all delayed allocation blocks to be allocated.
+        * Caller already holds s_umount sem */
+       if (test_opt(sb, DELALLOC))
                sync_filesystem(sb);
-               up_read(&sb->s_umount);
-       }
 
        return dquot_quota_off(sb, type);
 }
@@ -4667,17 +4689,17 @@ out:
 
 #endif
 
-static int ext4_get_sb(struct file_system_type *fs_type, int flags,
-                      const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
+                      const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, ext4_fill_super);
 }
 
 #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
 static struct file_system_type ext2_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ext2",
-       .get_sb         = ext4_get_sb,
+       .mount          = ext4_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
@@ -4722,7 +4744,7 @@ static inline void unregister_as_ext3(void) { }
 static struct file_system_type ext4_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ext4",
-       .get_sb         = ext4_get_sb,
+       .mount          = ext4_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index bbca5c186ae7654d69025a2cbb214c1fc1f96a3d..3345aabd1dd7e32585b18956175265ec3fdda011 100644 (file)
@@ -675,18 +675,17 @@ static int msdos_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 }
 
-static int msdos_get_sb(struct file_system_type *fs_type,
+static struct dentry *msdos_mount(struct file_system_type *fs_type,
                        int flags, const char *dev_name,
-                       void *data, struct vfsmount *mnt)
+                       void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, msdos_fill_super);
 }
 
 static struct file_system_type msdos_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "msdos",
-       .get_sb         = msdos_get_sb,
+       .mount          = msdos_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 6f0f6c9a0152263d61081e436641fb9a0300db6c..b936703b8924491a2671b8432c67570d18e9a810 100644 (file)
@@ -1071,18 +1071,17 @@ static int vfat_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 }
 
-static int vfat_get_sb(struct file_system_type *fs_type,
+static struct dentry *vfat_mount(struct file_system_type *fs_type,
                       int flags, const char *dev_name,
-                      void *data, struct vfsmount *mnt)
+                      void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, vfat_fill_super);
 }
 
 static struct file_system_type vfat_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "vfat",
-       .get_sb         = vfat_get_sb,
+       .mount          = vfat_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 71b0148b878415795d984528c02679d45ee218e4..9d1c99558389dabd0b11329ddcb51bcd4d9711f6 100644 (file)
@@ -246,17 +246,16 @@ out:
 /*
  * The usual module blurb.
  */
-static int vxfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *vxfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, vxfs_fill_super);
 }
 
 static struct file_system_type vxfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "vxfs",
-       .get_sb         = vxfs_get_sb,
+       .mount          = vxfs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index aed881a76b229602ece291fb8c55fbd5ec45ee90..3d06ccc953aafaa8f590528015953e2e53a2c0c9 100644 (file)
@@ -707,6 +707,17 @@ get_next_work_item(struct backing_dev_info *bdi)
        return work;
 }
 
+/*
+ * Add in the number of potentially dirty inodes, because each inode
+ * write can dirty pagecache in the underlying blockdev.
+ */
+static unsigned long get_nr_dirty_pages(void)
+{
+       return global_page_state(NR_FILE_DIRTY) +
+               global_page_state(NR_UNSTABLE_NFS) +
+               get_nr_dirty_inodes();
+}
+
 static long wb_check_old_data_flush(struct bdi_writeback *wb)
 {
        unsigned long expired;
@@ -724,13 +735,7 @@ static long wb_check_old_data_flush(struct bdi_writeback *wb)
                return 0;
 
        wb->last_old_flush = jiffies;
-       /*
-        * Add in the number of potentially dirty inodes, because each inode
-        * write can dirty pagecache in the underlying blockdev.
-        */
-       nr_pages = global_page_state(NR_FILE_DIRTY) +
-                       global_page_state(NR_UNSTABLE_NFS) +
-                       get_nr_dirty_inodes();
+       nr_pages = get_nr_dirty_pages();
 
        if (nr_pages) {
                struct wb_writeback_work work = {
@@ -1076,32 +1081,42 @@ static void wait_sb_inodes(struct super_block *sb)
 }
 
 /**
- * writeback_inodes_sb -       writeback dirty inodes from given super_block
+ * writeback_inodes_sb_nr -    writeback dirty inodes from given super_block
  * @sb: the superblock
+ * @nr: the number of pages to write
  *
  * Start writeback on some inodes on this super_block. No guarantees are made
  * on how many (if any) will be written, and this function does not wait
- * for IO completion of submitted IO. The number of pages submitted is
- * returned.
+ * for IO completion of submitted IO.
  */
-void writeback_inodes_sb(struct super_block *sb)
+void writeback_inodes_sb_nr(struct super_block *sb, unsigned long nr)
 {
-       unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
-       unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
        DECLARE_COMPLETION_ONSTACK(done);
        struct wb_writeback_work work = {
                .sb             = sb,
                .sync_mode      = WB_SYNC_NONE,
                .done           = &done,
+               .nr_pages       = nr,
        };
 
        WARN_ON(!rwsem_is_locked(&sb->s_umount));
-
-       work.nr_pages = nr_dirty + nr_unstable + get_nr_dirty_inodes();
-
        bdi_queue_work(sb->s_bdi, &work);
        wait_for_completion(&done);
 }
+EXPORT_SYMBOL(writeback_inodes_sb_nr);
+
+/**
+ * writeback_inodes_sb -       writeback dirty inodes from given super_block
+ * @sb: the superblock
+ *
+ * Start writeback on some inodes on this super_block. No guarantees are made
+ * on how many (if any) will be written, and this function does not wait
+ * for IO completion of submitted IO.
+ */
+void writeback_inodes_sb(struct super_block *sb)
+{
+       return writeback_inodes_sb_nr(sb, get_nr_dirty_pages());
+}
 EXPORT_SYMBOL(writeback_inodes_sb);
 
 /**
@@ -1123,6 +1138,27 @@ int writeback_inodes_sb_if_idle(struct super_block *sb)
 }
 EXPORT_SYMBOL(writeback_inodes_sb_if_idle);
 
+/**
+ * writeback_inodes_sb_if_idle -       start writeback if none underway
+ * @sb: the superblock
+ * @nr: the number of pages to write
+ *
+ * Invoke writeback_inodes_sb if no writeback is currently underway.
+ * Returns 1 if writeback was started, 0 if not.
+ */
+int writeback_inodes_sb_nr_if_idle(struct super_block *sb,
+                                  unsigned long nr)
+{
+       if (!writeback_in_progress(sb->s_bdi)) {
+               down_read(&sb->s_umount);
+               writeback_inodes_sb_nr(sb, nr);
+               up_read(&sb->s_umount);
+               return 1;
+       } else
+               return 0;
+}
+EXPORT_SYMBOL(writeback_inodes_sb_nr_if_idle);
+
 /**
  * sync_inodes_sb      -       sync sb inode pages
  * @sb: the superblock
index 4eba07661e5c562b50462d8feee6982e39fe2c4b..85542a7daf4012d2dffb7b7d4c86e0b6b917cb72 100644 (file)
@@ -322,12 +322,10 @@ static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 }
 
-static int fuse_ctl_get_sb(struct file_system_type *fs_type, int flags,
-                       const char *dev_name, void *raw_data,
-                       struct vfsmount *mnt)
+static struct dentry *fuse_ctl_mount(struct file_system_type *fs_type,
+                       int flags, const char *dev_name, void *raw_data)
 {
-       return get_sb_single(fs_type, flags, raw_data,
-                               fuse_ctl_fill_super, mnt);
+       return mount_single(fs_type, flags, raw_data, fuse_ctl_fill_super);
 }
 
 static void fuse_ctl_kill_sb(struct super_block *sb)
@@ -346,7 +344,7 @@ static void fuse_ctl_kill_sb(struct super_block *sb)
 static struct file_system_type fuse_ctl_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "fusectl",
-       .get_sb         = fuse_ctl_get_sb,
+       .mount          = fuse_ctl_mount,
        .kill_sb        = fuse_ctl_kill_sb,
 };
 
index da9e6e11374c402d63145dd2da7b0e8fdf72deca..cfce3ad86a9253c8f82f793da306979357f4df6f 100644 (file)
@@ -1041,11 +1041,11 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
        return err;
 }
 
-static int fuse_get_sb(struct file_system_type *fs_type,
+static struct dentry *fuse_mount(struct file_system_type *fs_type,
                       int flags, const char *dev_name,
-                      void *raw_data, struct vfsmount *mnt)
+                      void *raw_data)
 {
-       return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super, mnt);
+       return mount_nodev(fs_type, flags, raw_data, fuse_fill_super);
 }
 
 static void fuse_kill_sb_anon(struct super_block *sb)
@@ -1065,17 +1065,16 @@ static struct file_system_type fuse_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "fuse",
        .fs_flags       = FS_HAS_SUBTYPE,
-       .get_sb         = fuse_get_sb,
+       .mount          = fuse_mount,
        .kill_sb        = fuse_kill_sb_anon,
 };
 
 #ifdef CONFIG_BLOCK
-static int fuse_get_sb_blk(struct file_system_type *fs_type,
+static struct dentry *fuse_mount_blk(struct file_system_type *fs_type,
                           int flags, const char *dev_name,
-                          void *raw_data, struct vfsmount *mnt)
+                          void *raw_data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super);
 }
 
 static void fuse_kill_sb_blk(struct super_block *sb)
@@ -1094,7 +1093,7 @@ static void fuse_kill_sb_blk(struct super_block *sb)
 static struct file_system_type fuseblk_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "fuseblk",
-       .get_sb         = fuse_get_sb_blk,
+       .mount          = fuse_mount_blk,
        .kill_sb        = fuse_kill_sb_blk,
        .fs_flags       = FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
 };
index 06d582732d3427a058864d03ca6cb667c5063481..5ab3839dfcb97719d3b9e2f96e99062eef3b3c5f 100644 (file)
@@ -138,10 +138,8 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
                                      struct gfs2_inum_host *inum)
 {
        struct gfs2_sbd *sdp = sb->s_fs_info;
-       struct gfs2_holder i_gh;
        struct inode *inode;
        struct dentry *dentry;
-       int error;
 
        inode = gfs2_ilookup(sb, inum->no_addr);
        if (inode) {
@@ -152,52 +150,16 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
                goto out_inode;
        }
 
-       error = gfs2_glock_nq_num(sdp, inum->no_addr, &gfs2_inode_glops,
-                                 LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
-       if (error)
-               return ERR_PTR(error);
-
-       error = gfs2_check_blk_type(sdp, inum->no_addr, GFS2_BLKST_DINODE);
-       if (error)
-               goto fail;
-
-       inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0);
-       if (IS_ERR(inode)) {
-               error = PTR_ERR(inode);
-               goto fail;
-       }
-
-       error = gfs2_inode_refresh(GFS2_I(inode));
-       if (error) {
-               iput(inode);
-               goto fail;
-       }
-
-       /* Pick up the works we bypass in gfs2_inode_lookup */
-       if (inode->i_state & I_NEW) 
-               gfs2_set_iop(inode);
-
-       if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) {
-               iput(inode);
-               goto fail;
-       }
-
-       error = -EIO;
-       if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) {
-               iput(inode);
-               goto fail;
-       }
-
-       gfs2_glock_dq_uninit(&i_gh);
+       inode = gfs2_lookup_by_inum(sdp, inum->no_addr, &inum->no_formal_ino,
+                                   GFS2_BLKST_DINODE);
+       if (IS_ERR(inode))
+               return ERR_CAST(inode);
 
 out_inode:
        dentry = d_obtain_alias(inode);
        if (!IS_ERR(dentry))
                dentry->d_op = &gfs2_dops;
        return dentry;
-fail:
-       gfs2_glock_dq_uninit(&i_gh);
-       return ERR_PTR(error);
 }
 
 static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
index 87778857f0994fa504224d93c7c5611d10bc1e8c..f92c1770416981df8b625b6f918bac6c061c6e5e 100644 (file)
@@ -686,21 +686,20 @@ static void delete_work_func(struct work_struct *work)
 {
        struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_delete);
        struct gfs2_sbd *sdp = gl->gl_sbd;
-       struct gfs2_inode *ip = NULL;
+       struct gfs2_inode *ip;
        struct inode *inode;
-       u64 no_addr = 0;
+       u64 no_addr = gl->gl_name.ln_number;
+
+       ip = gl->gl_object;
+       /* Note: Unsafe to dereference ip as we don't hold right refs/locks */
 
-       spin_lock(&gl->gl_spin);
-       ip = (struct gfs2_inode *)gl->gl_object;
        if (ip)
-               no_addr = ip->i_no_addr;
-       spin_unlock(&gl->gl_spin);
-       if (ip) {
                inode = gfs2_ilookup(sdp->sd_vfs, no_addr);
-               if (inode) {
-                       d_prune_aliases(inode);
-                       iput(inode);
-               }
+       else
+               inode = gfs2_lookup_by_inum(sdp, no_addr, NULL, GFS2_BLKST_UNLINKED);
+       if (inode && !IS_ERR(inode)) {
+               d_prune_aliases(inode);
+               iput(inode);
        }
        gfs2_glock_put(gl);
 }
index 06370f8bd8cf4aafa95fd4df64e93ec8d657328d..e1213f7f92179aa2472304ff0db4294be66040d8 100644 (file)
@@ -73,49 +73,6 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
        return iget5_locked(sb, hash, iget_test, iget_set, &no_addr);
 }
 
-struct gfs2_skip_data {
-       u64     no_addr;
-       int     skipped;
-};
-
-static int iget_skip_test(struct inode *inode, void *opaque)
-{
-       struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_skip_data *data = opaque;
-
-       if (ip->i_no_addr == data->no_addr) {
-               if (inode->i_state & (I_FREEING|I_WILL_FREE)){
-                       data->skipped = 1;
-                       return 0;
-               }
-               return 1;
-       }
-       return 0;
-}
-
-static int iget_skip_set(struct inode *inode, void *opaque)
-{
-       struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_skip_data *data = opaque;
-
-       if (data->skipped)
-               return 1;
-       inode->i_ino = (unsigned long)(data->no_addr);
-       ip->i_no_addr = data->no_addr;
-       return 0;
-}
-
-static struct inode *gfs2_iget_skip(struct super_block *sb,
-                                   u64 no_addr)
-{
-       struct gfs2_skip_data data;
-       unsigned long hash = (unsigned long)no_addr;
-
-       data.no_addr = no_addr;
-       data.skipped = 0;
-       return iget5_locked(sb, hash, iget_skip_test, iget_skip_set, &data);
-}
-
 /**
  * GFS2 lookup code fills in vfs inode contents based on info obtained
  * from directory entry inside gfs2_inode_lookup(). This has caused issues
@@ -243,93 +200,54 @@ fail:
        return ERR_PTR(error);
 }
 
-/**
- * gfs2_process_unlinked_inode - Lookup an unlinked inode for reclamation
- *                               and try to reclaim it by doing iput.
- *
- * This function assumes no rgrp locks are currently held.
- *
- * @sb: The super block
- * no_addr: The inode number
- *
- */
-
-void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
+struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
+                                 u64 *no_formal_ino, unsigned int blktype)
 {
-       struct gfs2_sbd *sdp;
-       struct gfs2_inode *ip;
-       struct gfs2_glock *io_gl = NULL;
-       int error;
-       struct gfs2_holder gh;
+       struct super_block *sb = sdp->sd_vfs;
+       struct gfs2_holder i_gh;
        struct inode *inode;
+       int error;
 
-       inode = gfs2_iget_skip(sb, no_addr);
-
-       if (!inode)
-               return;
-
-       /* If it's not a new inode, someone's using it, so leave it alone. */
-       if (!(inode->i_state & I_NEW)) {
-               iput(inode);
-               return;
-       }
-
-       ip = GFS2_I(inode);
-       sdp = GFS2_SB(inode);
-       ip->i_no_formal_ino = -1;
+       error = gfs2_glock_nq_num(sdp, no_addr, &gfs2_inode_glops,
+                                 LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
+       if (error)
+               return ERR_PTR(error);
 
-       error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
-       if (unlikely(error))
+       error = gfs2_check_blk_type(sdp, no_addr, blktype);
+       if (error)
                goto fail;
-       ip->i_gl->gl_object = ip;
 
-       error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
-       if (unlikely(error))
-               goto fail_put;
-
-       set_bit(GIF_INVALID, &ip->i_flags);
-       error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT,
-                                  &ip->i_iopen_gh);
-       if (unlikely(error))
-               goto fail_iopen;
+       inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0);
+       if (IS_ERR(inode))
+               goto fail;
 
-       ip->i_iopen_gh.gh_gl->gl_object = ip;
-       gfs2_glock_put(io_gl);
-       io_gl = NULL;
+       error = gfs2_inode_refresh(GFS2_I(inode));
+       if (error)
+               goto fail_iput;
 
-       inode->i_mode = DT2IF(DT_UNKNOWN);
+       /* Pick up the works we bypass in gfs2_inode_lookup */
+       if (inode->i_state & I_NEW) 
+               gfs2_set_iop(inode);
 
-       /*
-        * We must read the inode in order to work out its type in
-        * this case. Note that this doesn't happen often as we normally
-        * know the type beforehand. This code path only occurs during
-        * unlinked inode recovery (where it is safe to do this glock,
-        * which is not true in the general case).
-        */
-       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY,
-                                  &gh);
-       if (unlikely(error))
-               goto fail_glock;
+       /* Two extra checks for NFS only */
+       if (no_formal_ino) {
+               error = -ESTALE;
+               if (GFS2_I(inode)->i_no_formal_ino != *no_formal_ino)
+                       goto fail_iput;
 
-       /* Inode is now uptodate */
-       gfs2_glock_dq_uninit(&gh);
-       gfs2_set_iop(inode);
+               error = -EIO;
+               if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM)
+                       goto fail_iput;
 
-       /* The iput will cause it to be deleted. */
-       iput(inode);
-       return;
+               error = 0;
+       }
 
-fail_glock:
-       gfs2_glock_dq(&ip->i_iopen_gh);
-fail_iopen:
-       if (io_gl)
-               gfs2_glock_put(io_gl);
-fail_put:
-       ip->i_gl->gl_object = NULL;
-       gfs2_glock_put(ip->i_gl);
 fail:
-       iget_failed(inode);
-       return;
+       gfs2_glock_dq_uninit(&i_gh);
+       return error ? ERR_PTR(error) : inode;
+fail_iput:
+       iput(inode);
+       goto fail;
 }
 
 static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
index 6720d7d5fbc6aac91083b399b95ba6c978922c67..d8499fadcc53915837a8ae7e7bdcc77213f825cc 100644 (file)
@@ -99,7 +99,9 @@ err:
 extern void gfs2_set_iop(struct inode *inode);
 extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, 
                                       u64 no_addr, u64 no_formal_ino);
-extern void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr);
+extern struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
+                                        u64 *no_formal_ino,
+                                        unsigned int blktype);
 extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
 
 extern int gfs2_inode_refresh(struct gfs2_inode *ip);
index cade1acbcea9420dc7c69622888d820af24eea99..3eb1393f7b81ba80f0e56ff58a92748ca68b708e 100644 (file)
@@ -1250,12 +1250,11 @@ static int test_gfs2_super(struct super_block *s, void *ptr)
 }
 
 /**
- * gfs2_get_sb - Get the GFS2 superblock
+ * gfs2_mount - Get the GFS2 superblock
  * @fs_type: The GFS2 filesystem type
  * @flags: Mount flags
  * @dev_name: The name of the device
  * @data: The mount arguments
- * @mnt: The vfsmnt for this mount
  *
  * Q. Why not use get_sb_bdev() ?
  * A. We need to select one of two root directories to mount, independent
@@ -1264,8 +1263,8 @@ static int test_gfs2_super(struct super_block *s, void *ptr)
  * Returns: 0 or -ve on error
  */
 
-static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
-                      const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
+                      const char *dev_name, void *data)
 {
        struct block_device *bdev;
        struct super_block *s;
@@ -1279,7 +1278,7 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
 
        bdev = open_bdev_exclusive(dev_name, mode, fs_type);
        if (IS_ERR(bdev))
-               return PTR_ERR(bdev);
+               return ERR_CAST(bdev);
 
        /*
         * once the super is inserted into the list by sget, s_umount
@@ -1298,6 +1297,9 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
        if (IS_ERR(s))
                goto error_bdev;
 
+       if (s->s_root)
+               close_bdev_exclusive(bdev, mode);
+
        memset(&args, 0, sizeof(args));
        args.ar_quota = GFS2_QUOTA_DEFAULT;
        args.ar_data = GFS2_DATA_DEFAULT;
@@ -1309,17 +1311,13 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
        error = gfs2_mount_args(&args, data);
        if (error) {
                printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
-               if (s->s_root)
-                       goto error_super;
-               deactivate_locked_super(s);
-               return error;
+               goto error_super;
        }
 
        if (s->s_root) {
                error = -EBUSY;
                if ((flags ^ s->s_flags) & MS_RDONLY)
                        goto error_super;
-               close_bdev_exclusive(bdev, mode);
        } else {
                char b[BDEVNAME_SIZE];
 
@@ -1328,27 +1326,24 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
                strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
                sb_set_blocksize(s, block_size(bdev));
                error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0);
-               if (error) {
-                       deactivate_locked_super(s);
-                       return error;
-               }
+               if (error)
+                       goto error_super;
                s->s_flags |= MS_ACTIVE;
                bdev->bd_super = s;
        }
 
        sdp = s->s_fs_info;
-       mnt->mnt_sb = s;
        if (args.ar_meta)
-               mnt->mnt_root = dget(sdp->sd_master_dir);
+               return dget(sdp->sd_master_dir);
        else
-               mnt->mnt_root = dget(sdp->sd_root_dir);
-       return 0;
+               return dget(sdp->sd_root_dir);
 
 error_super:
        deactivate_locked_super(s);
+       return ERR_PTR(error);
 error_bdev:
        close_bdev_exclusive(bdev, mode);
-       return error;
+       return ERR_PTR(error);
 }
 
 static int set_meta_super(struct super_block *s, void *ptr)
@@ -1356,8 +1351,8 @@ static int set_meta_super(struct super_block *s, void *ptr)
        return -EINVAL;
 }
 
-static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
-                           const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type,
+                       int flags, const char *dev_name, void *data)
 {
        struct super_block *s;
        struct gfs2_sbd *sdp;
@@ -1368,23 +1363,21 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
        if (error) {
                printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n",
                       dev_name, error);
-               return error;
+               return ERR_PTR(error);
        }
        s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super,
                 path.dentry->d_inode->i_sb->s_bdev);
        path_put(&path);
        if (IS_ERR(s)) {
                printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
-               return PTR_ERR(s);
+               return ERR_CAST(s);
        }
        if ((flags ^ s->s_flags) & MS_RDONLY) {
                deactivate_locked_super(s);
-               return -EBUSY;
+               return ERR_PTR(-EBUSY);
        }
        sdp = s->s_fs_info;
-       mnt->mnt_sb = s;
-       mnt->mnt_root = dget(sdp->sd_master_dir);
-       return 0;
+       return dget(sdp->sd_master_dir);
 }
 
 static void gfs2_kill_sb(struct super_block *sb)
@@ -1410,7 +1403,7 @@ static void gfs2_kill_sb(struct super_block *sb)
 struct file_system_type gfs2_fs_type = {
        .name = "gfs2",
        .fs_flags = FS_REQUIRES_DEV,
-       .get_sb = gfs2_get_sb,
+       .mount = gfs2_mount,
        .kill_sb = gfs2_kill_sb,
        .owner = THIS_MODULE,
 };
@@ -1418,7 +1411,7 @@ struct file_system_type gfs2_fs_type = {
 struct file_system_type gfs2meta_fs_type = {
        .name = "gfs2meta",
        .fs_flags = FS_REQUIRES_DEV,
-       .get_sb = gfs2_get_sb_meta,
+       .mount = gfs2_mount_meta,
        .owner = THIS_MODULE,
 };
 
index bef3ab6cf5c1aeb2d0f28d7955e4e62c8cb34be2..33c8407b876f00ceef0741221ebae4ba46ecb426 100644 (file)
@@ -963,17 +963,18 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
  *          The inode, if one has been found, in inode.
  */
 
-static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
-                          u64 skip)
+static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip)
 {
        u32 goal = 0, block;
        u64 no_addr;
        struct gfs2_sbd *sdp = rgd->rd_sbd;
        unsigned int n;
+       struct gfs2_glock *gl;
+       struct gfs2_inode *ip;
+       int error;
+       int found = 0;
 
-       for(;;) {
-               if (goal >= rgd->rd_data)
-                       break;
+       while (goal < rgd->rd_data) {
                down_write(&sdp->sd_log_flush_lock);
                n = 1;
                block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
@@ -990,11 +991,32 @@ static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
                if (no_addr == skip)
                        continue;
                *last_unlinked = no_addr;
-               return no_addr;
+
+               error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &gl);
+               if (error)
+                       continue;
+
+               /* If the inode is already in cache, we can ignore it here
+                * because the existing inode disposal code will deal with
+                * it when all refs have gone away. Accessing gl_object like
+                * this is not safe in general. Here it is ok because we do
+                * not dereference the pointer, and we only need an approx
+                * answer to whether it is NULL or not.
+                */
+               ip = gl->gl_object;
+
+               if (ip || queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
+                       gfs2_glock_put(gl);
+               else
+                       found++;
+
+               /* Limit reclaim to sensible number of tasks */
+               if (found > 2*NR_CPUS)
+                       return;
        }
 
        rgd->rd_flags &= ~GFS2_RDF_CHECK;
-       return 0;
+       return;
 }
 
 /**
@@ -1075,11 +1097,9 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd)
  * Try to acquire rgrp in way which avoids contending with others.
  *
  * Returns: errno
- *          unlinked: the block address of an unlinked block to be reclaimed
  */
 
-static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked,
-                         u64 *last_unlinked)
+static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_rgrpd *rgd, *begin = NULL;
@@ -1089,7 +1109,6 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked,
        int loops = 0;
        int error, rg_locked;
 
-       *unlinked = 0;
        rgd = gfs2_blk2rgrpd(sdp, ip->i_goal);
 
        while (rgd) {
@@ -1106,17 +1125,10 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked,
                case 0:
                        if (try_rgrp_fit(rgd, al))
                                goto out;
-                       /* If the rg came in already locked, there's no
-                          way we can recover from a failed try_rgrp_unlink
-                          because that would require an iput which can only
-                          happen after the rgrp is unlocked. */
-                       if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK)
-                               *unlinked = try_rgrp_unlink(rgd, last_unlinked,
-                                                          ip->i_no_addr);
+                       if (rgd->rd_flags & GFS2_RDF_CHECK)
+                               try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr);
                        if (!rg_locked)
                                gfs2_glock_dq_uninit(&al->al_rgd_gh);
-                       if (*unlinked)
-                               return -EAGAIN;
                        /* fall through */
                case GLR_TRYFAILED:
                        rgd = recent_rgrp_next(rgd);
@@ -1145,13 +1157,10 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked,
                case 0:
                        if (try_rgrp_fit(rgd, al))
                                goto out;
-                       if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK)
-                               *unlinked = try_rgrp_unlink(rgd, last_unlinked,
-                                                           ip->i_no_addr);
+                       if (rgd->rd_flags & GFS2_RDF_CHECK)
+                               try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr);
                        if (!rg_locked)
                                gfs2_glock_dq_uninit(&al->al_rgd_gh);
-                       if (*unlinked)
-                               return -EAGAIN;
                        break;
 
                case GLR_TRYFAILED:
@@ -1204,12 +1213,12 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex,
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_alloc *al = ip->i_alloc;
        int error = 0;
-       u64 last_unlinked = NO_BLOCK, unlinked;
+       u64 last_unlinked = NO_BLOCK;
+       int tries = 0;
 
        if (gfs2_assert_warn(sdp, al->al_requested))
                return -EINVAL;
 
-try_again:
        if (hold_rindex) {
                /* We need to hold the rindex unless the inode we're using is
                   the rindex itself, in which case it's already held. */
@@ -1218,31 +1227,23 @@ try_again:
                else if (!sdp->sd_rgrps) /* We may not have the rindex read
                                            in, so: */
                        error = gfs2_ri_update_special(ip);
+               if (error)
+                       return error;
        }
 
-       if (error)
-               return error;
+       do {
+               error = get_local_rgrp(ip, &last_unlinked);
+               /* If there is no space, flushing the log may release some */
+               if (error)
+                       gfs2_log_flush(sdp, NULL);
+       } while (error && tries++ < 3);
 
-       /* Find an rgrp suitable for allocation.  If it encounters any unlinked
-          dinodes along the way, error will equal -EAGAIN and unlinked will
-          contains it block address. We then need to look up that inode and
-          try to free it, and try the allocation again. */
-       error = get_local_rgrp(ip, &unlinked, &last_unlinked);
        if (error) {
                if (hold_rindex && ip != GFS2_I(sdp->sd_rindex))
                        gfs2_glock_dq_uninit(&al->al_ri_gh);
-               if (error != -EAGAIN)
-                       return error;
-
-               gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked);
-               /* regardless of whether or not gfs2_process_unlinked_inode
-                  was successful, we don't want to repeat it again. */
-               last_unlinked = unlinked;
-               gfs2_log_flush(sdp, NULL);
-               error = 0;
-
-               goto try_again;
+               return error;
        }
+
        /* no error, so we have the rgrp set in the inode's allocation. */
        al->al_file = file;
        al->al_line = line;
index 6ee1586f2334f0c05be1dd8a5305dc96be12674a..4824c27cebb8c2e49aa61edc33f2ec94f984ceab 100644 (file)
@@ -441,17 +441,16 @@ bail:
        return res;
 }
 
-static int hfs_get_sb(struct file_system_type *fs_type,
-                     int flags, const char *dev_name, void *data,
-                     struct vfsmount *mnt)
+static struct dentry *hfs_mount(struct file_system_type *fs_type,
+                     int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, hfs_fill_super, mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, hfs_fill_super);
 }
 
 static struct file_system_type hfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "hfs",
-       .get_sb         = hfs_get_sb,
+       .mount          = hfs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 9a88d7536103e2c1c70f3824b42d367d3eac848f..52cc746d3ba36dd7a6ae8c2ab366d8469131456f 100644 (file)
@@ -495,18 +495,16 @@ static void hfsplus_destroy_inode(struct inode *inode)
 
 #define HFSPLUS_INODE_SIZE     sizeof(struct hfsplus_inode_info)
 
-static int hfsplus_get_sb(struct file_system_type *fs_type,
-                         int flags, const char *dev_name, void *data,
-                         struct vfsmount *mnt)
+static struct dentry *hfsplus_mount(struct file_system_type *fs_type,
+                         int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, hfsplus_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, hfsplus_fill_super);
 }
 
 static struct file_system_type hfsplus_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "hfsplus",
-       .get_sb         = hfsplus_get_sb,
+       .mount          = hfsplus_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index cd7c93917cc7c29636ee7c87a8846177e4098d23..2c0f148a49e65e9cb01016249a76dfd7985aeb25 100644 (file)
@@ -962,11 +962,11 @@ out:
        return err;
 }
 
-static int hostfs_read_sb(struct file_system_type *type,
+static struct dentry *hostfs_read_sb(struct file_system_type *type,
                          int flags, const char *dev_name,
-                         void *data, struct vfsmount *mnt)
+                         void *data)
 {
-       return get_sb_nodev(type, flags, data, hostfs_fill_sb_common, mnt);
+       return mount_nodev(type, flags, data, hostfs_fill_sb_common);
 }
 
 static void hostfs_kill_sb(struct super_block *s)
@@ -978,7 +978,7 @@ static void hostfs_kill_sb(struct super_block *s)
 static struct file_system_type hostfs_type = {
        .owner          = THIS_MODULE,
        .name           = "hostfs",
-       .get_sb         = hostfs_read_sb,
+       .mount          = hostfs_read_sb,
        .kill_sb        = hostfs_kill_sb,
        .fs_flags       = 0,
 };
index eac5f96323e3d9640a197ee5eb10acdbf6046591..793cb9d943d21a70584958c27fba6b2f97b37f93 100644 (file)
@@ -14,7 +14,7 @@ void hpfs_lock_creation(struct super_block *s)
 #ifdef DEBUG_LOCKS
        printk("lock creation\n");
 #endif
-       down(&hpfs_sb(s)->hpfs_creation_de);
+       mutex_lock(&hpfs_sb(s)->hpfs_creation_de);
 }
 
 void hpfs_unlock_creation(struct super_block *s)
@@ -22,7 +22,7 @@ void hpfs_unlock_creation(struct super_block *s)
 #ifdef DEBUG_LOCKS
        printk("unlock creation\n");
 #endif
-       up(&hpfs_sb(s)->hpfs_creation_de);
+       mutex_unlock(&hpfs_sb(s)->hpfs_creation_de);
 }
 
 /* Map a sector into a buffer and return pointers to it and to the buffer. */
index b59eac0232a0f057063fac03d747a8b627560056..2fee17d0d9ab37ac67602007b0ab556f9e9eb22d 100644 (file)
@@ -87,7 +87,7 @@ struct hpfs_sb_info {
        unsigned *sb_bmp_dir;           /* main bitmap directory */
        unsigned sb_c_bitmap;           /* current bitmap */
        unsigned sb_max_fwd_alloc;      /* max forwad allocation */
-       struct semaphore hpfs_creation_de; /* when creating dirents, nobody else
+       struct mutex hpfs_creation_de;  /* when creating dirents, nobody else
                                           can alloc blocks */
        /*unsigned sb_mounting : 1;*/
        int sb_timeshift;
index c969a1aa163a7cd3fb0b48094edf1ac90f63816c..6c5f01597c3af07a21ec162b996437545c6e13af 100644 (file)
@@ -491,7 +491,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
        sbi->sb_bmp_dir = NULL;
        sbi->sb_cp_table = NULL;
 
-       init_MUTEX(&sbi->hpfs_creation_de);
+       mutex_init(&sbi->hpfs_creation_de);
 
        uid = current_uid();
        gid = current_gid();
@@ -686,17 +686,16 @@ bail0:
        return -EINVAL;
 }
 
-static int hpfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *hpfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, hpfs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, hpfs_fill_super);
 }
 
 static struct file_system_type hpfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "hpfs",
-       .get_sb         = hpfs_get_sb,
+       .mount          = hpfs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 4e2a45ea6140ddde677446d52f022eadbe020395..f702b5f713fc40805a37ce173c505ea569d04628 100644 (file)
@@ -748,17 +748,17 @@ static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
        return(err);
 }
 
-static int hppfs_read_super(struct file_system_type *type,
+static struct dentry *hppfs_read_super(struct file_system_type *type,
                            int flags, const char *dev_name,
-                           void *data, struct vfsmount *mnt)
+                           void *data)
 {
-       return get_sb_nodev(type, flags, data, hppfs_fill_super, mnt);
+       return mount_nodev(type, flags, data, hppfs_fill_super);
 }
 
 static struct file_system_type hppfs_type = {
        .owner          = THIS_MODULE,
        .name           = "hppfs",
-       .get_sb         = hppfs_read_super,
+       .mount          = hppfs_read_super,
        .kill_sb        = kill_anon_super,
        .fs_flags       = 0,
 };
index b14be3f781c714129d4fafbd17a7ff9874193b3f..a5fe68189eed00d76e0d3027fead3edc648c9aff 100644 (file)
@@ -896,15 +896,15 @@ void hugetlb_put_quota(struct address_space *mapping, long delta)
        }
 }
 
-static int hugetlbfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *hugetlbfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, hugetlbfs_fill_super, mnt);
+       return mount_nodev(fs_type, flags, data, hugetlbfs_fill_super);
 }
 
 static struct file_system_type hugetlbfs_fs_type = {
        .name           = "hugetlbfs",
-       .get_sb         = hugetlbfs_get_sb,
+       .mount          = hugetlbfs_mount,
        .kill_sb        = kill_litter_super,
 };
 
@@ -932,8 +932,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
        if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) {
                *user = current_user();
                if (user_shm_lock(size, *user)) {
-                       WARN_ONCE(1,
-                         "Using mlock ulimits for SHM_HUGETLB deprecated\n");
+                       printk_once(KERN_WARNING "Using mlock ulimits for SHM_HUGETLB is deprecated\n");
                } else {
                        *user = NULL;
                        return ERR_PTR(-EPERM);
index ebad3b90752dae0b37838734293ee36864af2c02..e43b9a4dbf4e602e39f9ca4e85a77f364798980b 100644 (file)
@@ -106,5 +106,5 @@ extern void release_open_intent(struct nameidata *);
  * inode.c
  */
 extern int get_nr_dirty_inodes(void);
-extern int evict_inodes(struct super_block *);
+extern void evict_inodes(struct super_block *);
 extern int invalidate_inodes(struct super_block *);
index 748cfb92dcc6203897c62d87ee113876f197a28b..2f7d05c899220e06d99ac9ecc9f8047903faa3a0 100644 (file)
@@ -111,12 +111,14 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
        read_lock(&tasklist_lock);
        switch (which) {
                case IOPRIO_WHO_PROCESS:
+                       rcu_read_lock();
                        if (!who)
                                p = current;
                        else
                                p = find_task_by_vpid(who);
                        if (p)
                                ret = set_task_ioprio(p, ioprio);
+                       rcu_read_unlock();
                        break;
                case IOPRIO_WHO_PGRP:
                        if (!who)
@@ -139,7 +141,12 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
                                break;
 
                        do_each_thread(g, p) {
-                               if (__task_cred(p)->uid != who)
+                               int match;
+
+                               rcu_read_lock();
+                               match = __task_cred(p)->uid == who;
+                               rcu_read_unlock();
+                               if (!match)
                                        continue;
                                ret = set_task_ioprio(p, ioprio);
                                if (ret)
@@ -200,12 +207,14 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
        read_lock(&tasklist_lock);
        switch (which) {
                case IOPRIO_WHO_PROCESS:
+                       rcu_read_lock();
                        if (!who)
                                p = current;
                        else
                                p = find_task_by_vpid(who);
                        if (p)
                                ret = get_task_ioprio(p);
+                       rcu_read_unlock();
                        break;
                case IOPRIO_WHO_PGRP:
                        if (!who)
@@ -232,7 +241,12 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
                                break;
 
                        do_each_thread(g, p) {
-                               if (__task_cred(p)->uid != user->uid)
+                               int match;
+
+                               rcu_read_lock();
+                               match = __task_cred(p)->uid == user->uid;
+                               rcu_read_unlock();
+                               if (!match)
                                        continue;
                                tmpio = get_task_ioprio(p);
                                if (tmpio < 0)
index 79cf7f616bbe8fdb9f84a90e92bf4f6717ae22cb..bfdeb82a53be09e848a74b75bbb3178a9881b352 100644 (file)
@@ -1507,17 +1507,16 @@ struct inode *isofs_iget(struct super_block *sb,
        return inode;
 }
 
-static int isofs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *isofs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super,
-                               mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super);
 }
 
 static struct file_system_type iso9660_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "iso9660",
-       .get_sb         = isofs_get_sb,
+       .mount          = isofs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 538417c1fdbbcbb630cbcdb885c74ebe5f433844..c590d155c0959bfbe1f8ce2f6be9702afd2904f4 100644 (file)
@@ -1838,7 +1838,6 @@ size_t journal_tag_bytes(journal_t *journal)
  */
 #define JBD2_MAX_SLABS 8
 static struct kmem_cache *jbd2_slab[JBD2_MAX_SLABS];
-static DECLARE_MUTEX(jbd2_slab_create_sem);
 
 static const char *jbd2_slab_names[JBD2_MAX_SLABS] = {
        "jbd2_1k", "jbd2_2k", "jbd2_4k", "jbd2_8k",
@@ -1859,6 +1858,7 @@ static void jbd2_journal_destroy_slabs(void)
 
 static int jbd2_journal_create_slab(size_t size)
 {
+       static DEFINE_MUTEX(jbd2_slab_create_mutex);
        int i = order_base_2(size) - 10;
        size_t slab_size;
 
@@ -1870,16 +1870,16 @@ static int jbd2_journal_create_slab(size_t size)
 
        if (unlikely(i < 0))
                i = 0;
-       down(&jbd2_slab_create_sem);
+       mutex_lock(&jbd2_slab_create_mutex);
        if (jbd2_slab[i]) {
-               up(&jbd2_slab_create_sem);
+               mutex_unlock(&jbd2_slab_create_mutex);
                return 0;       /* Already created */
        }
 
        slab_size = 1 << (i+10);
        jbd2_slab[i] = kmem_cache_create(jbd2_slab_names[i], slab_size,
                                         slab_size, 0, NULL);
-       up(&jbd2_slab_create_sem);
+       mutex_unlock(&jbd2_slab_create_mutex);
        if (!jbd2_slab[i]) {
                printk(KERN_EMERG "JBD2: no memory for jbd2_slab cache\n");
                return -ENOMEM;
index a906f538d11ce33d0f9c81e38cbaf95528030638..85c6be2db02f7fc5c9b0152cc723ec39e6c25584 100644 (file)
@@ -23,7 +23,7 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *,
 static inline struct jffs2_inode_cache *
 first_inode_chain(int *i, struct jffs2_sb_info *c)
 {
-       for (; *i < INOCACHE_HASHSIZE; (*i)++) {
+       for (; *i < c->inocache_hashsize; (*i)++) {
                if (c->inocache_list[*i])
                        return c->inocache_list[*i];
        }
index 617a1e5694c1bf8598ca6b5f4c03d4eb65a79d48..de4247021d25a0dae391d4c2e93f16f8b882d41e 100644 (file)
@@ -103,7 +103,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
                        spin_unlock(&jffs2_compressor_list_lock);
                        *datalen  = orig_slen;
                        *cdatalen = orig_dlen;
-                       compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL);
+                       compr_ret = this->compress(data_in, output_buf, datalen, cdatalen);
                        spin_lock(&jffs2_compressor_list_lock);
                        this->usecount--;
                        if (!compr_ret) {
@@ -152,7 +152,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
                        spin_unlock(&jffs2_compressor_list_lock);
                        *datalen  = orig_slen;
                        *cdatalen = orig_dlen;
-                       compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL);
+                       compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen);
                        spin_lock(&jffs2_compressor_list_lock);
                        this->usecount--;
                        if (!compr_ret) {
@@ -220,7 +220,7 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
                        if (comprtype == this->compr) {
                                this->usecount++;
                                spin_unlock(&jffs2_compressor_list_lock);
-                               ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL);
+                               ret = this->decompress(cdata_in, data_out, cdatalen, datalen);
                                spin_lock(&jffs2_compressor_list_lock);
                                if (ret) {
                                        printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret);
index e471a9106fd942515fb8af1d52a22a7cc1f8bb92..13bb7597ab3987b5da405d5bd857e50b64dce4ab 100644 (file)
@@ -49,9 +49,9 @@ struct jffs2_compressor {
        char *name;
        char compr;                     /* JFFS2_COMPR_XXX */
        int (*compress)(unsigned char *data_in, unsigned char *cpage_out,
-                       uint32_t *srclen, uint32_t *destlen, void *model);
+                       uint32_t *srclen, uint32_t *destlen);
        int (*decompress)(unsigned char *cdata_in, unsigned char *data_out,
-                         uint32_t cdatalen, uint32_t datalen, void *model);
+                         uint32_t cdatalen, uint32_t datalen);
        int usecount;
        int disabled;           /* if set the compressor won't compress */
        unsigned char *compr_buf;       /* used by size compr. mode */
index ed25ae7c98eba0935d10ef3ba20ce4dd2607be86..af186ee674d8f79ddda691a86e59af88fa29bd24 100644 (file)
@@ -42,7 +42,7 @@ static int __init alloc_workspace(void)
 }
 
 static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out,
-                             uint32_t *sourcelen, uint32_t *dstlen, void *model)
+                             uint32_t *sourcelen, uint32_t *dstlen)
 {
        size_t compress_size;
        int ret;
@@ -67,7 +67,7 @@ static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out,
 }
 
 static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
-                                uint32_t srclen, uint32_t destlen, void *model)
+                                uint32_t srclen, uint32_t destlen)
 {
        size_t dl = destlen;
        int ret;
index 9696ad9ef5f77675dddebd17705a36059de6fc78..16a5047903a6ef3a89e031e61e4a9044fa9b99c9 100644 (file)
@@ -31,8 +31,7 @@
 /* _compress returns the compressed size, -1 if bigger */
 static int jffs2_rtime_compress(unsigned char *data_in,
                                unsigned char *cpage_out,
-                               uint32_t *sourcelen, uint32_t *dstlen,
-                               void *model)
+                               uint32_t *sourcelen, uint32_t *dstlen)
 {
        short positions[256];
        int outpos = 0;
@@ -73,8 +72,7 @@ static int jffs2_rtime_compress(unsigned char *data_in,
 
 static int jffs2_rtime_decompress(unsigned char *data_in,
                                  unsigned char *cpage_out,
-                                 uint32_t srclen, uint32_t destlen,
-                                 void *model)
+                                 uint32_t srclen, uint32_t destlen)
 {
        short positions[256];
        int outpos = 0;
index a12b4f763373ff60f8af242f6eec1110ad8eda4c..9e7cec808c4c97c7f1530b10c2f16fd512464ea6 100644 (file)
@@ -298,7 +298,7 @@ static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
 #if 0
 /* _compress returns the compressed size, -1 if bigger */
 int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
-                  uint32_t *sourcelen, uint32_t *dstlen, void *model)
+                  uint32_t *sourcelen, uint32_t *dstlen)
 {
        return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in,
                                 cpage_out, sourcelen, dstlen);
@@ -306,8 +306,7 @@ int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
 #endif
 static int jffs2_dynrubin_compress(unsigned char *data_in,
                                   unsigned char *cpage_out,
-                                  uint32_t *sourcelen, uint32_t *dstlen,
-                                  void *model)
+                                  uint32_t *sourcelen, uint32_t *dstlen)
 {
        int bits[8];
        unsigned char histo[256];
@@ -387,8 +386,7 @@ static void rubin_do_decompress(int bit_divider, int *bits,
 
 static int jffs2_rubinmips_decompress(unsigned char *data_in,
                                      unsigned char *cpage_out,
-                                     uint32_t sourcelen, uint32_t dstlen,
-                                     void *model)
+                                     uint32_t sourcelen, uint32_t dstlen)
 {
        rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in,
                            cpage_out, sourcelen, dstlen);
@@ -397,8 +395,7 @@ static int jffs2_rubinmips_decompress(unsigned char *data_in,
 
 static int jffs2_dynrubin_decompress(unsigned char *data_in,
                                     unsigned char *cpage_out,
-                                    uint32_t sourcelen, uint32_t dstlen,
-                                    void *model)
+                                    uint32_t sourcelen, uint32_t dstlen)
 {
        int bits[8];
        int c;
index 97fc45de6f81eace3538ae22e9e8239834d9856f..fd05a0b9431df3e2bb37ed3b4bed29a131c37ffd 100644 (file)
@@ -68,8 +68,7 @@ static void free_workspaces(void)
 
 static int jffs2_zlib_compress(unsigned char *data_in,
                               unsigned char *cpage_out,
-                              uint32_t *sourcelen, uint32_t *dstlen,
-                              void *model)
+                              uint32_t *sourcelen, uint32_t *dstlen)
 {
        int ret;
 
@@ -136,8 +135,7 @@ static int jffs2_zlib_compress(unsigned char *data_in,
 
 static int jffs2_zlib_decompress(unsigned char *data_in,
                                 unsigned char *cpage_out,
-                                uint32_t srclen, uint32_t destlen,
-                                void *model)
+                                uint32_t srclen, uint32_t destlen)
 {
        int ret;
        int wbits = MAX_WBITS;
index 79121aa5858b8a4aa02861ba57cf17d9a8dfe13b..92978658ed1803bc289840500e8a220cbf032ffa 100644 (file)
@@ -367,7 +367,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
        }
 
        /* We use f->target field to store the target path. */
-       f->target = kmalloc(targetlen + 1, GFP_KERNEL);
+       f->target = kmemdup(target, targetlen + 1, GFP_KERNEL);
        if (!f->target) {
                printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
                mutex_unlock(&f->sem);
@@ -376,7 +376,6 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
                goto fail;
        }
 
-       memcpy(f->target, target, targetlen + 1);
        D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->target));
 
        /* No data here. Only a metadata node, which will be
index abac961f617b88a739ad3bfbaa49233d45d9e6d4..e513f1913c1522a8e9e8dbc4f501a4804507d182 100644 (file)
@@ -151,7 +151,7 @@ int jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
                }
 
                /* Be nice */
-               yield();
+               cond_resched();
                mutex_lock(&c->erase_free_sem);
                spin_lock(&c->erase_completion_lock);
        }
index d9beb06e6fcaf55c7fdc2f46367ce2f280bff859..e896e67767eb9e10515f37a7608fd7bdcc2d330d 100644 (file)
@@ -474,6 +474,25 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
        return inode;
 }
 
+static int calculate_inocache_hashsize(uint32_t flash_size)
+{
+       /*
+        * Pick a inocache hash size based on the size of the medium.
+        * Count how many megabytes we're dealing with, apply a hashsize twice
+        * that size, but rounding down to the usual big powers of 2. And keep
+        * to sensible bounds.
+        */
+
+       int size_mb = flash_size / 1024 / 1024;
+       int hashsize = (size_mb * 2) & ~0x3f;
+
+       if (hashsize < INOCACHE_HASHSIZE_MIN)
+               return INOCACHE_HASHSIZE_MIN;
+       if (hashsize > INOCACHE_HASHSIZE_MAX)
+               return INOCACHE_HASHSIZE_MAX;
+
+       return hashsize;
+}
 
 int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
 {
@@ -520,7 +539,8 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
        if (ret)
                return ret;
 
-       c->inocache_list = kcalloc(INOCACHE_HASHSIZE, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
+       c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size);
+       c->inocache_list = kcalloc(c->inocache_hashsize, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
        if (!c->inocache_list) {
                ret = -ENOMEM;
                goto out_wbuf;
index 846a79452497b9adcb20b831a8e12c6037038d9d..31dce611337cffcf67e8330bb2f6b6e8608bde1e 100644 (file)
@@ -219,13 +219,14 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
        if (!list_empty(&c->erase_complete_list) ||
            !list_empty(&c->erase_pending_list)) {
                spin_unlock(&c->erase_completion_lock);
+               mutex_unlock(&c->alloc_sem);
                D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() erasing pending blocks\n"));
-               if (jffs2_erase_pending_blocks(c, 1)) {
-                       mutex_unlock(&c->alloc_sem);
+               if (jffs2_erase_pending_blocks(c, 1))
                        return 0;
-               }
+
                D1(printk(KERN_DEBUG "No progress from erasing blocks; doing GC anyway\n"));
                spin_lock(&c->erase_completion_lock);
+               mutex_lock(&c->alloc_sem);
        }
 
        /* First, work out which block we're garbage-collecting */
index 6784bc89add1da39222a5c0c3cfbf4943462332f..f864005de64ccbd367b03c5985a7fd11782ab996 100644 (file)
@@ -100,6 +100,7 @@ struct jffs2_sb_info {
        wait_queue_head_t erase_wait;           /* For waiting for erases to complete */
 
        wait_queue_head_t inocache_wq;
+       int inocache_hashsize;
        struct jffs2_inode_cache **inocache_list;
        spinlock_t inocache_lock;
 
index af02bd13846967a8d9288358e1e3979c89520fe7..5e03233c2363e2476998a473edb989f21c50f752 100644 (file)
@@ -420,7 +420,7 @@ struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t
 {
        struct jffs2_inode_cache *ret;
 
-       ret = c->inocache_list[ino % INOCACHE_HASHSIZE];
+       ret = c->inocache_list[ino % c->inocache_hashsize];
        while (ret && ret->ino < ino) {
                ret = ret->next;
        }
@@ -441,7 +441,7 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
 
        dbg_inocache("add %p (ino #%u)\n", new, new->ino);
 
-       prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
+       prev = &c->inocache_list[new->ino % c->inocache_hashsize];
 
        while ((*prev) && (*prev)->ino < new->ino) {
                prev = &(*prev)->next;
@@ -462,7 +462,7 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
        dbg_inocache("del %p (ino #%u)\n", old, old->ino);
        spin_lock(&c->inocache_lock);
 
-       prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
+       prev = &c->inocache_list[old->ino % c->inocache_hashsize];
 
        while ((*prev) && (*prev)->ino < old->ino) {
                prev = &(*prev)->next;
@@ -487,7 +487,7 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
        int i;
        struct jffs2_inode_cache *this, *next;
 
-       for (i=0; i<INOCACHE_HASHSIZE; i++) {
+       for (i=0; i < c->inocache_hashsize; i++) {
                this = c->inocache_list[i];
                while (this) {
                        next = this->next;
index 523a91691052065e3bf03bec79c59ae309b2398f..5a53d9bdb2b584a3e1cb737ed028183d99f527e2 100644 (file)
@@ -199,7 +199,8 @@ struct jffs2_inode_cache {
 #define RAWNODE_CLASS_XATTR_DATUM      1
 #define RAWNODE_CLASS_XATTR_REF                2
 
-#define INOCACHE_HASHSIZE 128
+#define INOCACHE_HASHSIZE_MIN 128
+#define INOCACHE_HASHSIZE_MAX 1024
 
 #define write_ofs(c) ((c)->nextblock->offset + (c)->sector_size - (c)->nextblock->free_size)
 
index 46f870d1cc36ffaca178be3e62c600186e23d7f6..b632dddcb482821122918bd1673391ff34d51e4c 100644 (file)
@@ -20,7 +20,7 @@
 #include "summary.h"
 #include "debug.h"
 
-#define DEFAULT_EMPTY_SCAN_SIZE 1024
+#define DEFAULT_EMPTY_SCAN_SIZE 256
 
 #define noisy_printk(noise, args...) do { \
        if (*(noise)) { \
@@ -435,7 +435,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
                                  unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {
        struct jffs2_unknown_node *node;
        struct jffs2_unknown_node crcnode;
-       uint32_t ofs, prevofs;
+       uint32_t ofs, prevofs, max_ofs;
        uint32_t hdr_crc, buf_ofs, buf_len;
        int err;
        int noise = 0;
@@ -550,12 +550,12 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
 
        /* We temporarily use 'ofs' as a pointer into the buffer/jeb */
        ofs = 0;
-
-       /* Scan only 4KiB of 0xFF before declaring it's empty */
-       while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
+       max_ofs = EMPTY_SCAN_SIZE(c->sector_size);
+       /* Scan only EMPTY_SCAN_SIZE of 0xFF before declaring it's empty */
+       while(ofs < max_ofs && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
                ofs += 4;
 
-       if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) {
+       if (ofs == max_ofs) {
 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
                if (jffs2_cleanmarker_oob(c)) {
                        /* scan oob, take care of cleanmarker */
index d1ae5dfc22b97cd04c29fa9c901ac88ba31f0670..c86041b866a4810d4ebb66f16dd137521470294f 100644 (file)
@@ -179,12 +179,11 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
        return ret;
 }
 
-static int jffs2_get_sb(struct file_system_type *fs_type,
+static struct dentry *jffs2_mount(struct file_system_type *fs_type,
                        int flags, const char *dev_name,
-                       void *data, struct vfsmount *mnt)
+                       void *data)
 {
-       return get_sb_mtd(fs_type, flags, dev_name, data, jffs2_fill_super,
-                         mnt);
+       return mount_mtd(fs_type, flags, dev_name, data, jffs2_fill_super);
 }
 
 static void jffs2_put_super (struct super_block *sb)
@@ -229,7 +228,7 @@ static void jffs2_kill_sb(struct super_block *sb)
 static struct file_system_type jffs2_fs_type = {
        .owner =        THIS_MODULE,
        .name =         "jffs2",
-       .get_sb =       jffs2_get_sb,
+       .mount =        jffs2_mount,
        .kill_sb =      jffs2_kill_sb,
 };
 
index 68eee2bf629ee4ba6d5d6ad326012aca03d09c4f..0669fc1cc3bf25b69121cb2c34cd216e1a7a9966 100644 (file)
@@ -583,11 +583,10 @@ static int jfs_unfreeze(struct super_block *sb)
        return 0;
 }
 
-static int jfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *jfs_do_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, jfs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, jfs_fill_super);
 }
 
 static int jfs_sync_fs(struct super_block *sb, int wait)
@@ -770,7 +769,7 @@ static const struct export_operations jfs_export_operations = {
 static struct file_system_type jfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "jfs",
-       .get_sb         = jfs_get_sb,
+       .mount          = jfs_do_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 304a5132ca270d018799d3003170bd813c23dd9b..a3accdf528add9161bd6dccfb84f7c08ccb28437 100644 (file)
@@ -201,9 +201,8 @@ static const struct super_operations simple_super_operations = {
  * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that
  * will never be mountable)
  */
-int get_sb_pseudo(struct file_system_type *fs_type, char *name,
-       const struct super_operations *ops, unsigned long magic,
-       struct vfsmount *mnt)
+struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
+       const struct super_operations *ops, unsigned long magic)
 {
        struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
        struct dentry *dentry;
@@ -211,7 +210,7 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name,
        struct qstr d_name = {.name = name, .len = strlen(name)};
 
        if (IS_ERR(s))
-               return PTR_ERR(s);
+               return ERR_CAST(s);
 
        s->s_flags = MS_NOUSER;
        s->s_maxbytes = MAX_LFS_FILESIZE;
@@ -241,12 +240,11 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name,
        d_instantiate(dentry, root);
        s->s_root = dentry;
        s->s_flags |= MS_ACTIVE;
-       simple_set_mnt(mnt, s);
-       return 0;
+       return dget(s->s_root);
 
 Enomem:
        deactivate_locked_super(s);
-       return -ENOMEM;
+       return ERR_PTR(-ENOMEM);
 }
 
 int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
@@ -951,7 +949,7 @@ EXPORT_SYMBOL(dcache_dir_lseek);
 EXPORT_SYMBOL(dcache_dir_open);
 EXPORT_SYMBOL(dcache_readdir);
 EXPORT_SYMBOL(generic_read_dir);
-EXPORT_SYMBOL(get_sb_pseudo);
+EXPORT_SYMBOL(mount_pseudo);
 EXPORT_SYMBOL(simple_write_begin);
 EXPORT_SYMBOL(simple_write_end);
 EXPORT_SYMBOL(simple_dir_inode_operations);
index 50ec15927aab3164a456875e6c11b1f4fa2f8bef..0e62dd35d088486ee2c04c62f312ffb2b0ca5149 100644 (file)
@@ -186,7 +186,7 @@ void locks_release_private(struct file_lock *fl)
 EXPORT_SYMBOL_GPL(locks_release_private);
 
 /* Free a lock which is not in use. */
-static void locks_free_lock(struct file_lock *fl)
+void locks_free_lock(struct file_lock *fl)
 {
        BUG_ON(waitqueue_active(&fl->fl_wait));
        BUG_ON(!list_empty(&fl->fl_block));
@@ -195,6 +195,7 @@ static void locks_free_lock(struct file_lock *fl)
        locks_release_private(fl);
        kmem_cache_free(filelock_cache, fl);
 }
+EXPORT_SYMBOL(locks_free_lock);
 
 void locks_init_lock(struct file_lock *fl)
 {
@@ -234,11 +235,8 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
                        fl->fl_ops->fl_copy_lock(new, fl);
                new->fl_ops = fl->fl_ops;
        }
-       if (fl->fl_lmops) {
-               if (fl->fl_lmops->fl_copy_lock)
-                       fl->fl_lmops->fl_copy_lock(new, fl);
+       if (fl->fl_lmops)
                new->fl_lmops = fl->fl_lmops;
-       }
 }
 
 /*
@@ -1371,20 +1369,22 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
        struct inode *inode = dentry->d_inode;
        int error, rdlease_count = 0, wrlease_count = 0;
 
+       lease = *flp;
+
+       error = -EACCES;
        if ((current_fsuid() != inode->i_uid) && !capable(CAP_LEASE))
-               return -EACCES;
+               goto out;
+       error = -EINVAL;
        if (!S_ISREG(inode->i_mode))
-               return -EINVAL;
+               goto out;
        error = security_file_lock(filp, arg);
        if (error)
-               return error;
+               goto out;
 
        time_out_leases(inode);
 
        BUG_ON(!(*flp)->fl_lmops->fl_break);
 
-       lease = *flp;
-
        if (arg != F_UNLCK) {
                error = -EAGAIN;
                if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
@@ -1425,8 +1425,9 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
                goto out;
 
        if (my_before != NULL) {
-               *flp = *my_before;
                error = lease->fl_lmops->fl_change(my_before, arg);
+               if (!error)
+                       *flp = *my_before;
                goto out;
        }
 
@@ -1441,7 +1442,6 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
        return 0;
 
 out:
-       locks_free_lock(lease);
        return error;
 }
 EXPORT_SYMBOL(generic_setlease);
@@ -1493,21 +1493,19 @@ int vfs_setlease(struct file *filp, long arg, struct file_lock **lease)
 }
 EXPORT_SYMBOL_GPL(vfs_setlease);
 
-/**
- *     fcntl_setlease  -       sets a lease on an open file
- *     @fd: open file descriptor
- *     @filp: file pointer
- *     @arg: type of lease to obtain
- *
- *     Call this fcntl to establish a lease on the file.
- *     Note that you also need to call %F_SETSIG to
- *     receive a signal when the lease is broken.
- */
-int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
+static int do_fcntl_delete_lease(struct file *filp)
 {
-       struct file_lock *fl;
+       struct file_lock fl, *flp = &fl;
+
+       lease_init(filp, F_UNLCK, flp);
+
+       return vfs_setlease(filp, F_UNLCK, &flp);
+}
+
+static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
+{
+       struct file_lock *fl, *ret;
        struct fasync_struct *new;
-       struct inode *inode = filp->f_path.dentry->d_inode;
        int error;
 
        fl = lease_alloc(filp, arg);
@@ -1519,10 +1517,16 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
                locks_free_lock(fl);
                return -ENOMEM;
        }
+       ret = fl;
        lock_flocks();
-       error = __vfs_setlease(filp, arg, &fl);
-       if (error || arg == F_UNLCK)
-               goto out_unlock;
+       error = __vfs_setlease(filp, arg, &ret);
+       if (error) {
+               unlock_flocks();
+               locks_free_lock(fl);
+               goto out_free_fasync;
+       }
+       if (ret != fl)
+               locks_free_lock(fl);
 
        /*
         * fasync_insert_entry() returns the old entry if any.
@@ -1530,25 +1534,35 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
         * inserted it into the fasync list. Clear new so that
         * we don't release it here.
         */
-       if (!fasync_insert_entry(fd, filp, &fl->fl_fasync, new))
+       if (!fasync_insert_entry(fd, filp, &ret->fl_fasync, new))
                new = NULL;
 
-       if (error < 0) {
-               /* remove lease just inserted by setlease */
-               fl->fl_type = F_UNLCK | F_INPROGRESS;
-               fl->fl_break_time = jiffies - 10;
-               time_out_leases(inode);
-               goto out_unlock;
-       }
-
        error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
-out_unlock:
        unlock_flocks();
+
+out_free_fasync:
        if (new)
                fasync_free(new);
        return error;
 }
 
+/**
+ *     fcntl_setlease  -       sets a lease on an open file
+ *     @fd: open file descriptor
+ *     @filp: file pointer
+ *     @arg: type of lease to obtain
+ *
+ *     Call this fcntl to establish a lease on the file.
+ *     Note that you also need to call %F_SETSIG to
+ *     receive a signal when the lease is broken.
+ */
+int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
+{
+       if (arg == F_UNLCK)
+               return do_fcntl_delete_lease(filp);
+       return do_fcntl_add_lease(fd, filp, arg);
+}
+
 /**
  * flock_lock_file_wait - Apply a FLOCK-style lock to a file
  * @filp: The file to apply the lock to
index 9bd2ce2a30407897557b32a2fa9f97708695593e..92ca6fbe09bd2254eb9cbbd3d23b487ee4d4f9a8 100644 (file)
@@ -298,9 +298,9 @@ static int bdev_write_sb(struct super_block *sb, struct page *page)
        return sync_request(page, bdev, WRITE);
 }
 
-static void bdev_put_device(struct super_block *sb)
+static void bdev_put_device(struct logfs_super *s)
 {
-       close_bdev_exclusive(logfs_super(sb)->s_bdev, FMODE_READ|FMODE_WRITE);
+       close_bdev_exclusive(s->s_bdev, FMODE_READ|FMODE_WRITE);
 }
 
 static int bdev_can_write_buf(struct super_block *sb, u64 ofs)
@@ -320,8 +320,8 @@ static const struct logfs_device_ops bd_devops = {
        .put_device     = bdev_put_device,
 };
 
-int logfs_get_sb_bdev(struct file_system_type *type, int flags,
-               const char *devname, struct vfsmount *mnt)
+int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type,
+               const char *devname)
 {
        struct block_device *bdev;
 
@@ -332,8 +332,11 @@ int logfs_get_sb_bdev(struct file_system_type *type, int flags,
        if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
                int mtdnr = MINOR(bdev->bd_dev);
                close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE);
-               return logfs_get_sb_mtd(type, flags, mtdnr, mnt);
+               return logfs_get_sb_mtd(p, mtdnr);
        }
 
-       return logfs_get_sb_device(type, flags, NULL, bdev, &bd_devops, mnt);
+       p->s_bdev = bdev;
+       p->s_mtd = NULL;
+       p->s_devops = &bd_devops;
+       return 0;
 }
index a85d47d13e4b04623dff3d873c66cc107b7f8599..7466e9dcc8c537c532b92241bd9684bfd3b26481 100644 (file)
@@ -230,9 +230,9 @@ static void mtd_writeseg(struct super_block *sb, u64 ofs, size_t len)
        __mtd_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT);
 }
 
-static void mtd_put_device(struct super_block *sb)
+static void mtd_put_device(struct logfs_super *s)
 {
-       put_mtd_device(logfs_super(sb)->s_mtd);
+       put_mtd_device(s->s_mtd);
 }
 
 static int mtd_can_write_buf(struct super_block *sb, u64 ofs)
@@ -265,14 +265,14 @@ static const struct logfs_device_ops mtd_devops = {
        .put_device     = mtd_put_device,
 };
 
-int logfs_get_sb_mtd(struct file_system_type *type, int flags,
-               int mtdnr, struct vfsmount *mnt)
+int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr)
 {
-       struct mtd_info *mtd;
-       const struct logfs_device_ops *devops = &mtd_devops;
-
-       mtd = get_mtd_device(NULL, mtdnr);
+       struct mtd_info *mtd = get_mtd_device(NULL, mtdnr);
        if (IS_ERR(mtd))
                return PTR_ERR(mtd);
-       return logfs_get_sb_device(type, flags, mtd, NULL, devops, mnt);
+
+       s->s_bdev = NULL;
+       s->s_mtd = mtd;
+       s->s_devops = &mtd_devops;
+       return 0;
 }
index b8786264d243fcd49d31f9d3fe670657264e46d4..57afd4a6fabbb992b0b08ea9bb5399071ea576c2 100644 (file)
@@ -136,6 +136,7 @@ struct logfs_area_ops {
        int     (*erase_segment)(struct logfs_area *area);
 };
 
+struct logfs_super;    /* forward */
 /**
  * struct logfs_device_ops - device access operations
  *
@@ -156,7 +157,7 @@ struct logfs_device_ops {
                        int ensure_write);
        int (*can_write_buf)(struct super_block *sb, u64 ofs);
        void (*sync)(struct super_block *sb);
-       void (*put_device)(struct super_block *sb);
+       void (*put_device)(struct logfs_super *s);
 };
 
 /**
@@ -471,11 +472,13 @@ void logfs_compr_exit(void);
 
 /* dev_bdev.c */
 #ifdef CONFIG_BLOCK
-int logfs_get_sb_bdev(struct file_system_type *type, int flags,
-               const char *devname, struct vfsmount *mnt);
+int logfs_get_sb_bdev(struct logfs_super *s,
+               struct file_system_type *type,
+               const char *devname);
 #else
-static inline int logfs_get_sb_bdev(struct file_system_type *type, int flags,
-               const char *devname, struct vfsmount *mnt)
+static inline int logfs_get_sb_bdev(struct logfs_super *s,
+               struct file_system_type *type,
+               const char *devname)
 {
        return -ENODEV;
 }
@@ -483,11 +486,9 @@ static inline int logfs_get_sb_bdev(struct file_system_type *type, int flags,
 
 /* dev_mtd.c */
 #ifdef CONFIG_MTD
-int logfs_get_sb_mtd(struct file_system_type *type, int flags,
-               int mtdnr, struct vfsmount *mnt);
+int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr);
 #else
-static inline int logfs_get_sb_mtd(struct file_system_type *type, int flags,
-               int mtdnr, struct vfsmount *mnt)
+static inline int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr)
 {
        return -ENODEV;
 }
@@ -619,9 +620,6 @@ void emergency_read_end(struct page *page);
 void logfs_crash_dump(struct super_block *sb);
 void *memchr_inv(const void *s, int c, size_t n);
 int logfs_statfs(struct dentry *dentry, struct kstatfs *stats);
-int logfs_get_sb_device(struct file_system_type *type, int flags,
-               struct mtd_info *mtd, struct block_device *bdev,
-               const struct logfs_device_ops *devops, struct vfsmount *mnt);
 int logfs_check_ds(struct logfs_disk_super *ds);
 int logfs_write_sb(struct super_block *sb);
 
index 5336155c5d8189c2d6f4f78d73bd1abb3056ff36..33435e4b14d24aaad89bfab57da526870bbfa797 100644 (file)
@@ -325,7 +325,7 @@ static int logfs_make_writeable(struct super_block *sb)
        return 0;
 }
 
-static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt)
+static int logfs_get_sb_final(struct super_block *sb)
 {
        struct logfs_super *super = logfs_super(sb);
        struct inode *rootdir;
@@ -356,7 +356,6 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt)
        }
 
        log_super("LogFS: Finished mounting\n");
-       simple_set_mnt(mnt, sb);
        return 0;
 
 fail:
@@ -529,43 +528,37 @@ static void logfs_kill_sb(struct super_block *sb)
        logfs_cleanup_rw(sb);
        if (super->s_erase_page)
                __free_page(super->s_erase_page);
-       super->s_devops->put_device(sb);
+       super->s_devops->put_device(super);
        logfs_mempool_destroy(super->s_btree_pool);
        logfs_mempool_destroy(super->s_alias_pool);
        kfree(super);
        log_super("LogFS: Finished unmounting\n");
 }
 
-int logfs_get_sb_device(struct file_system_type *type, int flags,
-               struct mtd_info *mtd, struct block_device *bdev,
-               const struct logfs_device_ops *devops, struct vfsmount *mnt)
+static struct dentry *logfs_get_sb_device(struct logfs_super *super,
+               struct file_system_type *type, int flags)
 {
-       struct logfs_super *super;
        struct super_block *sb;
        int err = -ENOMEM;
        static int mount_count;
 
        log_super("LogFS: Start mount %x\n", mount_count++);
-       super = kzalloc(sizeof(*super), GFP_KERNEL);
-       if (!super)
-               goto err0;
 
-       super->s_mtd    = mtd;
-       super->s_bdev   = bdev;
        err = -EINVAL;
        sb = sget(type, logfs_sb_test, logfs_sb_set, super);
-       if (IS_ERR(sb))
-               goto err0;
+       if (IS_ERR(sb)) {
+               super->s_devops->put_device(super);
+               kfree(super);
+               return ERR_CAST(sb);
+       }
 
        if (sb->s_root) {
                /* Device is already in use */
-               err = 0;
-               simple_set_mnt(mnt, sb);
-               goto err0;
+               super->s_devops->put_device(super);
+               kfree(super);
+               return dget(sb->s_root);
        }
 
-       super->s_devops = devops;
-
        /*
         * sb->s_maxbytes is limited to 8TB.  On 32bit systems, the page cache
         * only covers 16TB and the upper 8TB are used for indirect blocks.
@@ -581,10 +574,12 @@ int logfs_get_sb_device(struct file_system_type *type, int flags,
                goto err1;
 
        sb->s_flags |= MS_ACTIVE;
-       err = logfs_get_sb_final(sb, mnt);
-       if (err)
+       err = logfs_get_sb_final(sb);
+       if (err) {
                deactivate_locked_super(sb);
-       return err;
+               return ERR_PTR(err);
+       }
+       return dget(sb->s_root);
 
 err1:
        /* no ->s_root, no ->put_super() */
@@ -592,37 +587,45 @@ err1:
        iput(super->s_segfile_inode);
        iput(super->s_mapping_inode);
        deactivate_locked_super(sb);
-       return err;
-err0:
-       kfree(super);
-       //devops->put_device(sb);
-       return err;
+       return ERR_PTR(err);
 }
 
-static int logfs_get_sb(struct file_system_type *type, int flags,
-               const char *devname, void *data, struct vfsmount *mnt)
+static struct dentry *logfs_mount(struct file_system_type *type, int flags,
+               const char *devname, void *data)
 {
        ulong mtdnr;
+       struct logfs_super *super;
+       int err;
 
-       if (!devname)
-               return logfs_get_sb_bdev(type, flags, devname, mnt);
-       if (strncmp(devname, "mtd", 3))
-               return logfs_get_sb_bdev(type, flags, devname, mnt);
+       super = kzalloc(sizeof(*super), GFP_KERNEL);
+       if (!super)
+               return ERR_PTR(-ENOMEM);
 
-       {
+       if (!devname)
+               err = logfs_get_sb_bdev(super, type, devname);
+       else if (strncmp(devname, "mtd", 3))
+               err = logfs_get_sb_bdev(super, type, devname);
+       else {
                char *garbage;
                mtdnr = simple_strtoul(devname+3, &garbage, 0);
                if (*garbage)
-                       return -EINVAL;
+                       err = -EINVAL;
+               else
+                       err = logfs_get_sb_mtd(super, mtdnr);
+       }
+
+       if (err) {
+               kfree(super);
+               return ERR_PTR(err);
        }
 
-       return logfs_get_sb_mtd(type, flags, mtdnr, mnt);
+       return logfs_get_sb_device(super, type, flags);
 }
 
 static struct file_system_type logfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "logfs",
-       .get_sb         = logfs_get_sb,
+       .mount          = logfs_mount,
        .kill_sb        = logfs_kill_sb,
        .fs_flags       = FS_REQUIRES_DEV,
 
index e39d6bf2e8fbcf3ccbc36117aca4fd03a67c862e..fb2020858a34cfde663938f5c42503c952d01d48 100644 (file)
@@ -614,17 +614,16 @@ void minix_truncate(struct inode * inode)
                V2_minix_truncate(inode);
 }
 
-static int minix_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *minix_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, minix_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, minix_fill_super);
 }
 
 static struct file_system_type minix_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "minix",
-       .get_sb         = minix_get_sb,
+       .mount          = minix_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index f7dbc06857abfe6e1959654f7fd66b393dd161d0..5362af9b73729905817a76b5c24a5b33c48d5ce7 100644 (file)
@@ -1574,6 +1574,7 @@ static struct file *finish_open(struct nameidata *nd,
         */
        if (will_truncate)
                mnt_drop_write(nd->path.mnt);
+       path_put(&nd->path);
        return filp;
 
 exit:
@@ -1675,6 +1676,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
                }
                filp = nameidata_to_filp(nd);
                mnt_drop_write(nd->path.mnt);
+               path_put(&nd->path);
                if (!IS_ERR(filp)) {
                        error = ima_file_check(filp, acc_mode);
                        if (error) {
index 985fabb26aca44edcacc889af0a8d2c5c47e8f04..d290545aa0c4b98c932e316c7dd4fcf3961b1126 100644 (file)
@@ -1020,16 +1020,16 @@ out:
        return result;
 }
 
-static int ncp_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *ncp_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, ncp_fill_super, mnt);
+       return mount_nodev(fs_type, flags, data, ncp_fill_super);
 }
 
 static struct file_system_type ncp_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ncpfs",
-       .get_sb         = ncp_get_sb,
+       .mount          = ncp_mount,
        .kill_sb        = kill_anon_super,
        .fs_flags       = FS_BINARY_MOUNTDATA,
 };
index e756075637b005ba1937b275c2d77ed3ff8ad676..60677f9f13110d1a98774595de819fddf2c0ccdf 100644 (file)
@@ -884,6 +884,5 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
        dprintk("NFS: setlease(%s/%s, arg=%ld)\n",
                        file->f_path.dentry->d_parent->d_name.name,
                        file->f_path.dentry->d_name.name, arg);
-
        return -EINVAL;
 }
index 3600ec700d583356d7e765db1c3a7035d3b2355c..0a42e8f4adcbc1723b57a7dac93c78b0a34b975e 100644 (file)
@@ -260,8 +260,8 @@ static int  nfs_statfs(struct dentry *, struct kstatfs *);
 static int  nfs_show_options(struct seq_file *, struct vfsmount *);
 static int  nfs_show_stats(struct seq_file *, struct vfsmount *);
 static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *);
-static int nfs_xdev_get_sb(struct file_system_type *fs_type,
-               int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
+static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type,
+               int flags, const char *dev_name, void *raw_data);
 static void nfs_put_super(struct super_block *);
 static void nfs_kill_super(struct super_block *);
 static int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
@@ -277,7 +277,7 @@ static struct file_system_type nfs_fs_type = {
 struct file_system_type nfs_xdev_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "nfs",
-       .get_sb         = nfs_xdev_get_sb,
+       .mount          = nfs_xdev_mount,
        .kill_sb        = nfs_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
@@ -302,14 +302,14 @@ static int nfs4_try_mount(int flags, const char *dev_name,
        struct nfs_parsed_mount_data *data, struct vfsmount *mnt);
 static int nfs4_get_sb(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
-static int nfs4_remote_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
-static int nfs4_xdev_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
+static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *raw_data);
+static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *raw_data);
 static int nfs4_referral_get_sb(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
-static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
+static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *raw_data);
 static void nfs4_kill_super(struct super_block *sb);
 
 static struct file_system_type nfs4_fs_type = {
@@ -323,7 +323,7 @@ static struct file_system_type nfs4_fs_type = {
 static struct file_system_type nfs4_remote_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "nfs4",
-       .get_sb         = nfs4_remote_get_sb,
+       .mount          = nfs4_remote_mount,
        .kill_sb        = nfs4_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
@@ -331,7 +331,7 @@ static struct file_system_type nfs4_remote_fs_type = {
 struct file_system_type nfs4_xdev_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "nfs4",
-       .get_sb         = nfs4_xdev_get_sb,
+       .mount          = nfs4_xdev_mount,
        .kill_sb        = nfs4_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
@@ -339,7 +339,7 @@ struct file_system_type nfs4_xdev_fs_type = {
 static struct file_system_type nfs4_remote_referral_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "nfs4",
-       .get_sb         = nfs4_remote_referral_get_sb,
+       .mount          = nfs4_remote_referral_mount,
        .kill_sb        = nfs4_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
@@ -2397,9 +2397,9 @@ static void nfs_kill_super(struct super_block *s)
 /*
  * Clone an NFS2/3 server record on xdev traversal (FSID-change)
  */
-static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
-                          const char *dev_name, void *raw_data,
-                          struct vfsmount *mnt)
+static struct dentry *
+nfs_xdev_mount(struct file_system_type *fs_type, int flags,
+               const char *dev_name, void *raw_data)
 {
        struct nfs_clone_mount *data = raw_data;
        struct super_block *s;
@@ -2411,7 +2411,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
        };
        int error;
 
-       dprintk("--> nfs_xdev_get_sb()\n");
+       dprintk("--> nfs_xdev_mount()\n");
 
        /* create a new volume representation */
        server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
@@ -2458,28 +2458,26 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
        }
 
        s->s_flags |= MS_ACTIVE;
-       mnt->mnt_sb = s;
-       mnt->mnt_root = mntroot;
 
        /* clone any lsm security options from the parent to the new sb */
        security_sb_clone_mnt_opts(data->sb, s);
 
-       dprintk("<-- nfs_xdev_get_sb() = 0\n");
-       return 0;
+       dprintk("<-- nfs_xdev_mount() = 0\n");
+       return mntroot;
 
 out_err_nosb:
        nfs_free_server(server);
 out_err_noserver:
-       dprintk("<-- nfs_xdev_get_sb() = %d [error]\n", error);
-       return error;
+       dprintk("<-- nfs_xdev_mount() = %d [error]\n", error);
+       return ERR_PTR(error);
 
 error_splat_super:
        if (server && !s->s_root)
                bdi_unregister(&server->backing_dev_info);
 error_splat_bdi:
        deactivate_locked_super(s);
-       dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
-       return error;
+       dprintk("<-- nfs_xdev_mount() = %d [splat]\n", error);
+       return ERR_PTR(error);
 }
 
 #ifdef CONFIG_NFS_V4
@@ -2649,8 +2647,9 @@ out_no_address:
 /*
  * Get the superblock for the NFS4 root partition
  */
-static int nfs4_remote_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
+static struct dentry *
+nfs4_remote_mount(struct file_system_type *fs_type, int flags,
+                 const char *dev_name, void *raw_data)
 {
        struct nfs_parsed_mount_data *data = raw_data;
        struct super_block *s;
@@ -2714,15 +2713,16 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
                goto error_splat_root;
 
        s->s_flags |= MS_ACTIVE;
-       mnt->mnt_sb = s;
-       mnt->mnt_root = mntroot;
-       error = 0;
+
+       security_free_mnt_opts(&data->lsm_opts);
+       nfs_free_fhandle(mntfh);
+       return mntroot;
 
 out:
        security_free_mnt_opts(&data->lsm_opts);
 out_free_fh:
        nfs_free_fhandle(mntfh);
-       return error;
+       return ERR_PTR(error);
 
 out_free:
        nfs_free_server(server);
@@ -2968,9 +2968,9 @@ static void nfs4_kill_super(struct super_block *sb)
 /*
  * Clone an NFS4 server record on xdev traversal (FSID-change)
  */
-static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
-                           const char *dev_name, void *raw_data,
-                           struct vfsmount *mnt)
+static struct dentry *
+nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
+                const char *dev_name, void *raw_data)
 {
        struct nfs_clone_mount *data = raw_data;
        struct super_block *s;
@@ -2982,7 +2982,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
        };
        int error;
 
-       dprintk("--> nfs4_xdev_get_sb()\n");
+       dprintk("--> nfs4_xdev_mount()\n");
 
        /* create a new volume representation */
        server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
@@ -3029,32 +3029,30 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
        }
 
        s->s_flags |= MS_ACTIVE;
-       mnt->mnt_sb = s;
-       mnt->mnt_root = mntroot;
 
        security_sb_clone_mnt_opts(data->sb, s);
 
-       dprintk("<-- nfs4_xdev_get_sb() = 0\n");
-       return 0;
+       dprintk("<-- nfs4_xdev_mount() = 0\n");
+       return mntroot;
 
 out_err_nosb:
        nfs_free_server(server);
 out_err_noserver:
-       dprintk("<-- nfs4_xdev_get_sb() = %d [error]\n", error);
-       return error;
+       dprintk("<-- nfs4_xdev_mount() = %d [error]\n", error);
+       return ERR_PTR(error);
 
 error_splat_super:
        if (server && !s->s_root)
                bdi_unregister(&server->backing_dev_info);
 error_splat_bdi:
        deactivate_locked_super(s);
-       dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
-       return error;
+       dprintk("<-- nfs4_xdev_mount() = %d [splat]\n", error);
+       return ERR_PTR(error);
 }
 
-static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
-               int flags, const char *dev_name, void *raw_data,
-               struct vfsmount *mnt)
+static struct dentry *
+nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
+                          const char *dev_name, void *raw_data)
 {
        struct nfs_clone_mount *data = raw_data;
        struct super_block *s;
@@ -3118,14 +3116,12 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
        }
 
        s->s_flags |= MS_ACTIVE;
-       mnt->mnt_sb = s;
-       mnt->mnt_root = mntroot;
 
        security_sb_clone_mnt_opts(data->sb, s);
 
        nfs_free_fhandle(mntfh);
        dprintk("<-- nfs4_referral_get_sb() = 0\n");
-       return 0;
+       return mntroot;
 
 out_err_nosb:
        nfs_free_server(server);
@@ -3133,7 +3129,7 @@ out_err_noserver:
        nfs_free_fhandle(mntfh);
 out_err_nofh:
        dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);
-       return error;
+       return ERR_PTR(error);
 
 error_splat_super:
        if (server && !s->s_root)
@@ -3142,7 +3138,7 @@ error_splat_bdi:
        deactivate_locked_super(s);
        nfs_free_fhandle(mntfh);
        dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
-       return error;
+       return ERR_PTR(error);
 }
 
 /*
index 9a16bad5d2eaf4dad7d99e8b89d83576a3f163a1..7bdec8531400a8955d2292221debb83004bcd29f 100644 (file)
@@ -444,9 +444,9 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
 
        /* set up nfs_renamedata */
        data->old_dir = old_dir;
-       atomic_inc(&old_dir->i_count);
+       ihold(old_dir);
        data->new_dir = new_dir;
-       atomic_inc(&new_dir->i_count);
+       ihold(new_dir);
        data->old_dentry = dget(old_dentry);
        data->new_dentry = dget(new_dentry);
        nfs_fattr_init(&data->old_fattr);
index 56347e0ac88da33f1fd655809a90c1509f0cb389..ad2bfa68d534d28531c3788b955734b5d9a76985 100644 (file)
@@ -673,16 +673,17 @@ static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses)
        spin_unlock(&clp->cl_lock);
 }
 
-static void nfsd4_register_conn(struct nfsd4_conn *conn)
+static int nfsd4_register_conn(struct nfsd4_conn *conn)
 {
        conn->cn_xpt_user.callback = nfsd4_conn_lost;
-       register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
+       return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
 }
 
 static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
 {
        struct nfsd4_conn *conn;
        u32 flags = NFS4_CDFC4_FORE;
+       int ret;
 
        if (ses->se_flags & SESSION4_BACK_CHAN)
                flags |= NFS4_CDFC4_BACK;
@@ -690,7 +691,10 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
        if (!conn)
                return nfserr_jukebox;
        nfsd4_hash_conn(conn, ses);
-       nfsd4_register_conn(conn);
+       ret = nfsd4_register_conn(conn);
+       if (ret)
+               /* oops; xprt is already down: */
+               nfsd4_conn_lost(&conn->cn_xpt_user);
        return nfs_ok;
 }
 
@@ -1644,6 +1648,7 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi
 {
        struct nfs4_client *clp = ses->se_client;
        struct nfsd4_conn *c;
+       int ret;
 
        spin_lock(&clp->cl_lock);
        c = __nfsd4_find_conn(new->cn_xprt, ses);
@@ -1654,7 +1659,10 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi
        }
        __nfsd4_hash_conn(new, ses);
        spin_unlock(&clp->cl_lock);
-       nfsd4_register_conn(new);
+       ret = nfsd4_register_conn(new);
+       if (ret)
+               /* oops; xprt is already down: */
+               nfsd4_conn_lost(&new->cn_xpt_user);
        return;
 }
 
@@ -2309,22 +2317,6 @@ void nfsd_release_deleg_cb(struct file_lock *fl)
        dp->dl_flock = NULL;
 }
 
-/*
- * Set the delegation file_lock back pointer.
- *
- * Called from setlease() with lock_kernel() held.
- */
-static
-void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl)
-{
-       struct nfs4_delegation *dp = (struct nfs4_delegation *)new->fl_owner;
-
-       dprintk("NFSD: nfsd_copy_lock_deleg_cb: new fl %p dp %p\n", new, dp);
-       if (!dp)
-               return;
-       dp->dl_flock = new;
-}
-
 /*
  * Called from setlease() with lock_kernel() held
  */
@@ -2355,7 +2347,6 @@ int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
 static const struct lock_manager_operations nfsd_lease_mng_ops = {
        .fl_break = nfsd_break_deleg_cb,
        .fl_release_private = nfsd_release_deleg_cb,
-       .fl_copy_lock = nfsd_copy_lock_deleg_cb,
        .fl_mylease = nfsd_same_client_deleg_cb,
        .fl_change = nfsd_change_deleg_cb,
 };
@@ -2661,12 +2652,15 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
        fl->fl_file = find_readable_file(stp->st_file);
        BUG_ON(!fl->fl_file);
        fl->fl_pid = current->tgid;
+       dp->dl_flock = fl;
 
        /* vfs_setlease checks to see if delegation should be handed out.
         * the lock_manager callbacks fl_mylease and fl_change are used
         */
        if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) {
                dprintk("NFSD: setlease failed [%d], no delegation\n", status);
+               dp->dl_flock = NULL;
+               locks_free_lock(fl);
                unhash_delegation(dp);
                flag = NFS4_OPEN_DELEGATE_NONE;
                goto out;
index d6dc3f61f8bafdd77e3a592b26a543e42ae7d1a9..4514ebbee4d6246aac28086ecbb90a0568a01d16 100644 (file)
@@ -1405,16 +1405,16 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
        return simple_fill_super(sb, 0x6e667364, nfsd_files);
 }
 
-static int nfsd_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *nfsd_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, nfsd_fill_super, mnt);
+       return mount_single(fs_type, flags, data, nfsd_fill_super);
 }
 
 static struct file_system_type nfsd_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "nfsd",
-       .get_sb         = nfsd_get_sb,
+       .mount          = nfsd_mount,
        .kill_sb        = kill_litter_super,
 };
 
index 35ae03c0db8601a2709d71b8ed29b42cb1f211e6..f804d41ec9d3b2e253972beed4ecda1fc2daf2b9 100644 (file)
@@ -1141,9 +1141,9 @@ static int nilfs_test_bdev_super(struct super_block *s, void *data)
        return (void *)s->s_bdev == data;
 }
 
-static int
-nilfs_get_sb(struct file_system_type *fs_type, int flags,
-            const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *
+nilfs_mount(struct file_system_type *fs_type, int flags,
+            const char *dev_name, void *data)
 {
        struct nilfs_super_data sd;
        struct super_block *s;
@@ -1156,7 +1156,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
 
        sd.bdev = open_bdev_exclusive(dev_name, mode, fs_type);
        if (IS_ERR(sd.bdev))
-               return PTR_ERR(sd.bdev);
+               return ERR_CAST(sd.bdev);
 
        sd.cno = 0;
        sd.flags = flags;
@@ -1235,9 +1235,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
        if (!s_new)
                close_bdev_exclusive(sd.bdev, mode);
 
-       mnt->mnt_sb = s;
-       mnt->mnt_root = root_dentry;
-       return 0;
+       return root_dentry;
 
  failed_super:
        deactivate_locked_super(s);
@@ -1245,13 +1243,13 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
  failed:
        if (!s_new)
                close_bdev_exclusive(sd.bdev, mode);
-       return err;
+       return ERR_PTR(err);
 }
 
 struct file_system_type nilfs_fs_type = {
        .owner    = THIS_MODULE,
        .name     = "nilfs2",
-       .get_sb   = nilfs_get_sb,
+       .mount    = nilfs_mount,
        .kill_sb  = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV,
 };
index b388443c3a09b01574b78befaabbf7fe03f9eeb4..22c629eedd82d70425704ee86b4ddf816b7bd174 100644 (file)
@@ -3,4 +3,4 @@ config FSNOTIFY
 
 source "fs/notify/dnotify/Kconfig"
 source "fs/notify/inotify/Kconfig"
-#source "fs/notify/fanotify/Kconfig"
+source "fs/notify/fanotify/Kconfig"
index 85366c78cc3759b1a0027e1a3d5d0598e2f2fdec..b04f88eed09e98b6134f275cb7ba530a06e7f998 100644 (file)
@@ -131,6 +131,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
        BUILD_BUG_ON(FAN_Q_OVERFLOW != FS_Q_OVERFLOW);
        BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM);
        BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM);
+       BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR);
 
        pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
@@ -160,20 +161,21 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
                                       __u32 event_mask, void *data, int data_type)
 {
        __u32 marks_mask, marks_ignored_mask;
+       struct path *path = data;
 
        pr_debug("%s: group=%p to_tell=%p inode_mark=%p vfsmnt_mark=%p "
                 "mask=%x data=%p data_type=%d\n", __func__, group, to_tell,
                 inode_mark, vfsmnt_mark, event_mask, data, data_type);
 
-       /* sorry, fanotify only gives a damn about files and dirs */
-       if (!S_ISREG(to_tell->i_mode) &&
-           !S_ISDIR(to_tell->i_mode))
-               return false;
-
        /* if we don't have enough info to send an event to userspace say no */
        if (data_type != FSNOTIFY_EVENT_PATH)
                return false;
 
+       /* sorry, fanotify only gives a damn about files and dirs */
+       if (!S_ISREG(path->dentry->d_inode->i_mode) &&
+           !S_ISDIR(path->dentry->d_inode->i_mode))
+               return false;
+
        if (inode_mark && vfsmnt_mark) {
                marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
                marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);
@@ -194,16 +196,29 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
                BUG();
        }
 
+       if (S_ISDIR(path->dentry->d_inode->i_mode) &&
+           (marks_ignored_mask & FS_ISDIR))
+               return false;
+
        if (event_mask & marks_mask & ~marks_ignored_mask)
                return true;
 
        return false;
 }
 
+static void fanotify_free_group_priv(struct fsnotify_group *group)
+{
+       struct user_struct *user;
+
+       user = group->fanotify_data.user;
+       atomic_dec(&user->fanotify_listeners);
+       free_uid(user);
+}
+
 const struct fsnotify_ops fanotify_fsnotify_ops = {
        .handle_event = fanotify_handle_event,
        .should_send_event = fanotify_should_send_event,
-       .free_group_priv = NULL,
+       .free_group_priv = fanotify_free_group_priv,
        .free_event_priv = NULL,
        .freeing_mark = NULL,
 };
index bbcb98e7fcc611d692e9d85c4c74dd742d417507..063224812b7e607879bffeedd5b90f9c4967346f 100644 (file)
 
 #include <asm/ioctls.h>
 
+#define FANOTIFY_DEFAULT_MAX_EVENTS    16384
+#define FANOTIFY_DEFAULT_MAX_MARKS     8192
+#define FANOTIFY_DEFAULT_MAX_LISTENERS 128
+
 extern const struct fsnotify_ops fanotify_fsnotify_ops;
 
 static struct kmem_cache *fanotify_mark_cache __read_mostly;
@@ -326,7 +330,7 @@ static ssize_t fanotify_read(struct file *file, char __user *buf,
                ret = -EAGAIN;
                if (file->f_flags & O_NONBLOCK)
                        break;
-               ret = -EINTR;
+               ret = -ERESTARTSYS;
                if (signal_pending(current))
                        break;
 
@@ -372,11 +376,10 @@ static ssize_t fanotify_write(struct file *file, const char __user *buf, size_t
 static int fanotify_release(struct inode *ignored, struct file *file)
 {
        struct fsnotify_group *group = file->private_data;
-       struct fanotify_response_event *re, *lre;
-
-       pr_debug("%s: file=%p group=%p\n", __func__, file, group);
 
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
+       struct fanotify_response_event *re, *lre;
+
        mutex_lock(&group->fanotify_data.access_mutex);
 
        group->fanotify_data.bypass_perm = true;
@@ -554,18 +557,24 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
                                       __u32 mask,
                                       unsigned int flags)
 {
-       __u32 oldmask;
+       __u32 oldmask = -1;
 
        spin_lock(&fsn_mark->lock);
        if (!(flags & FAN_MARK_IGNORED_MASK)) {
                oldmask = fsn_mark->mask;
                fsnotify_set_mark_mask_locked(fsn_mark, (oldmask | mask));
        } else {
-               oldmask = fsn_mark->ignored_mask;
-               fsnotify_set_mark_ignored_mask_locked(fsn_mark, (oldmask | mask));
+               __u32 tmask = fsn_mark->ignored_mask | mask;
+               fsnotify_set_mark_ignored_mask_locked(fsn_mark, tmask);
                if (flags & FAN_MARK_IGNORED_SURV_MODIFY)
                        fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY;
        }
+
+       if (!(flags & FAN_MARK_ONDIR)) {
+               __u32 tmask = fsn_mark->ignored_mask | FAN_ONDIR;
+               fsnotify_set_mark_ignored_mask_locked(fsn_mark, tmask);
+       }
+
        spin_unlock(&fsn_mark->lock);
 
        return mask & ~oldmask;
@@ -582,6 +591,9 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
        if (!fsn_mark) {
                int ret;
 
+               if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
+                       return -ENOSPC;
+
                fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
                if (!fsn_mark)
                        return -ENOMEM;
@@ -610,10 +622,23 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 
        pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
 
+       /*
+        * If some other task has this inode open for write we should not add
+        * an ignored mark, unless that ignored mark is supposed to survive
+        * modification changes anyway.
+        */
+       if ((flags & FAN_MARK_IGNORED_MASK) &&
+           !(flags & FAN_MARK_IGNORED_SURV_MODIFY) &&
+           (atomic_read(&inode->i_writecount) > 0))
+               return 0;
+
        fsn_mark = fsnotify_find_inode_mark(group, inode);
        if (!fsn_mark) {
                int ret;
 
+               if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
+                       return -ENOSPC;
+
                fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
                if (!fsn_mark)
                        return -ENOMEM;
@@ -637,6 +662,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 {
        struct fsnotify_group *group;
        int f_flags, fd;
+       struct user_struct *user;
 
        pr_debug("%s: flags=%d event_f_flags=%d\n",
                __func__, flags, event_f_flags);
@@ -647,6 +673,12 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
        if (flags & ~FAN_ALL_INIT_FLAGS)
                return -EINVAL;
 
+       user = get_current_user();
+       if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) {
+               free_uid(user);
+               return -EMFILE;
+       }
+
        f_flags = O_RDWR | FMODE_NONOTIFY;
        if (flags & FAN_CLOEXEC)
                f_flags |= O_CLOEXEC;
@@ -658,12 +690,47 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
        if (IS_ERR(group))
                return PTR_ERR(group);
 
+       group->fanotify_data.user = user;
+       atomic_inc(&user->fanotify_listeners);
+
        group->fanotify_data.f_flags = event_f_flags;
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
        mutex_init(&group->fanotify_data.access_mutex);
        init_waitqueue_head(&group->fanotify_data.access_waitq);
        INIT_LIST_HEAD(&group->fanotify_data.access_list);
 #endif
+       switch (flags & FAN_ALL_CLASS_BITS) {
+       case FAN_CLASS_NOTIF:
+               group->priority = FS_PRIO_0;
+               break;
+       case FAN_CLASS_CONTENT:
+               group->priority = FS_PRIO_1;
+               break;
+       case FAN_CLASS_PRE_CONTENT:
+               group->priority = FS_PRIO_2;
+               break;
+       default:
+               fd = -EINVAL;
+               goto out_put_group;
+       }
+
+       if (flags & FAN_UNLIMITED_QUEUE) {
+               fd = -EPERM;
+               if (!capable(CAP_SYS_ADMIN))
+                       goto out_put_group;
+               group->max_events = UINT_MAX;
+       } else {
+               group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
+       }
+
+       if (flags & FAN_UNLIMITED_MARKS) {
+               fd = -EPERM;
+               if (!capable(CAP_SYS_ADMIN))
+                       goto out_put_group;
+               group->fanotify_data.max_marks = UINT_MAX;
+       } else {
+               group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS;
+       }
 
        fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
        if (fd < 0)
@@ -704,6 +771,12 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
        default:
                return -EINVAL;
        }
+
+       if (mask & FAN_ONDIR) {
+               flags |= FAN_MARK_ONDIR;
+               mask &= ~FAN_ONDIR;
+       }
+
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
        if (mask & ~(FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_EVENT_ON_CHILD))
 #else
@@ -719,6 +792,16 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
        ret = -EINVAL;
        if (unlikely(filp->f_op != &fanotify_fops))
                goto fput_and_out;
+       group = filp->private_data;
+
+       /*
+        * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF.  These are not
+        * allowed to set permissions events.
+        */
+       ret = -EINVAL;
+       if (mask & FAN_ALL_PERM_EVENTS &&
+           group->priority == FS_PRIO_0)
+               goto fput_and_out;
 
        ret = fanotify_find_path(dfd, pathname, &path, flags);
        if (ret)
@@ -729,7 +812,6 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
                inode = path.dentry->d_inode;
        else
                mnt = path.mnt;
-       group = filp->private_data;
 
        /* create/update an inode mark */
        switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
index 4498a208df940b92117323dcad6cb355969fd164..20dc218707ca59afc4c5b42de6cd7d614ca49340 100644 (file)
@@ -84,16 +84,17 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
 }
 
 /* Notify this dentry's parent about a child's events. */
-void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
+int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
 {
        struct dentry *parent;
        struct inode *p_inode;
+       int ret = 0;
 
        if (!dentry)
                dentry = path->dentry;
 
        if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
-               return;
+               return 0;
 
        parent = dget_parent(dentry);
        p_inode = parent->d_inode;
@@ -106,14 +107,16 @@ void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
                mask |= FS_EVENT_ON_CHILD;
 
                if (path)
-                       fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
-                                dentry->d_name.name, 0);
+                       ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
+                                      dentry->d_name.name, 0);
                else
-                       fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
-                                dentry->d_name.name, 0);
+                       ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
+                                      dentry->d_name.name, 0);
        }
 
        dput(parent);
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(__fsnotify_parent);
 
@@ -252,20 +255,23 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
 
                if (inode_group > vfsmount_group) {
                        /* handle inode */
-                       send_to_group(to_tell, NULL, inode_mark, NULL, mask, data,
-                                     data_is, cookie, file_name, &event);
+                       ret = send_to_group(to_tell, NULL, inode_mark, NULL, mask, data,
+                                           data_is, cookie, file_name, &event);
                        /* we didn't use the vfsmount_mark */
                        vfsmount_group = NULL;
                } else if (vfsmount_group > inode_group) {
-                       send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data,
-                                     data_is, cookie, file_name, &event);
+                       ret = send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data,
+                                           data_is, cookie, file_name, &event);
                        inode_group = NULL;
                } else {
-                       send_to_group(to_tell, mnt, inode_mark, vfsmount_mark,
-                                     mask, data, data_is, cookie, file_name,
-                                     &event);
+                       ret = send_to_group(to_tell, mnt, inode_mark, vfsmount_mark,
+                                           mask, data, data_is, cookie, file_name,
+                                           &event);
                }
 
+               if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
+                       goto out;
+
                if (inode_group)
                        inode_node = srcu_dereference(inode_node->next,
                                                      &fsnotify_mark_srcu);
@@ -273,7 +279,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
                        vfsmount_node = srcu_dereference(vfsmount_node->next,
                                                         &fsnotify_mark_srcu);
        }
-
+       ret = 0;
+out:
        srcu_read_unlock(&fsnotify_mark_srcu, idx);
        /*
         * fsnotify_create_event() took a reference so the event can't be cleaned
index 21ed10660b80770c34eb136a311254330568fac2..4c29fcf557d13d21100030c31ab98aa44b555a62 100644 (file)
@@ -177,7 +177,8 @@ void fsnotify_set_inode_mark_mask_locked(struct fsnotify_mark *mark,
  * Attach an initialized mark to a given inode.
  * These marks may be used for the fsnotify backend to determine which
  * event types should be delivered to which group and for which inodes.  These
- * marks are ordered according to the group's location in memory.
+ * marks are ordered according to priority, highest number first, and then by
+ * the group's location in memory.
  */
 int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
                            struct fsnotify_group *group, struct inode *inode,
@@ -211,7 +212,11 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
                        goto out;
                }
 
-               if (mark->group < lmark->group)
+               if (mark->group->priority < lmark->group->priority)
+                       continue;
+
+               if ((mark->group->priority == lmark->group->priority) &&
+                   (mark->group < lmark->group))
                        continue;
 
                hlist_add_before_rcu(&mark->i.i_list, &lmark->i.i_list);
index 24edc1185d53fd1b2a0d61e646d02f4bd7fc0afb..444c305a468c531b7e9e8dda803a2d650a257c58 100644 (file)
@@ -862,7 +862,7 @@ static int __init inotify_user_setup(void)
        BUILD_BUG_ON(IN_Q_OVERFLOW != FS_Q_OVERFLOW);
        BUILD_BUG_ON(IN_IGNORED != FS_IN_IGNORED);
        BUILD_BUG_ON(IN_EXCL_UNLINK != FS_EXCL_UNLINK);
-       BUILD_BUG_ON(IN_ISDIR != FS_IN_ISDIR);
+       BUILD_BUG_ON(IN_ISDIR != FS_ISDIR);
        BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT);
 
        BUG_ON(hweight32(ALL_INOTIFY_BITS) != 21);
index 56772b578fbd546d62a199ad25f6b1dec859e660..85eebff6d0d7de00928c5281e7418688c2265907 100644 (file)
@@ -169,7 +169,11 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
                        goto out;
                }
 
-               if (mark->group < lmark->group)
+               if (mark->group->priority < lmark->group->priority)
+                       continue;
+
+               if ((mark->group->priority == lmark->group->priority) &&
+                   (mark->group < lmark->group))
                        continue;
 
                hlist_add_before_rcu(&mark->m.m_list, &lmark->m.m_list);
index d3fbe5730bfc1bb1c1264e9e3923c9425321fea0..a30ecacc01f2b1e45323517e3a01b1bbada8c05e 100644 (file)
@@ -3059,17 +3059,16 @@ struct kmem_cache *ntfs_index_ctx_cache;
 /* Driver wide mutex. */
 DEFINE_MUTEX(ntfs_lock);
 
-static int ntfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *ntfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ntfs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, ntfs_fill_super);
 }
 
 static struct file_system_type ntfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ntfs",
-       .get_sb         = ntfs_get_sb,
+       .mount          = ntfs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 75e115f1bd730d2b12d4e1d924d203a5864d5150..b2df490a19edda212a399891a7402060dbdcaf7b 100644 (file)
@@ -643,16 +643,16 @@ static const struct inode_operations dlmfs_file_inode_operations = {
        .setattr        = dlmfs_file_setattr,
 };
 
-static int dlmfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *dlmfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, dlmfs_fill_super, mnt);
+       return mount_nodev(fs_type, flags, data, dlmfs_fill_super);
 }
 
 static struct file_system_type dlmfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ocfs2_dlmfs",
-       .get_sb         = dlmfs_get_sb,
+       .mount          = dlmfs_mount,
        .kill_sb        = kill_litter_super,
 };
 
index d8408217e3bd0657a3446f77a56833a20f03ad52..1efea3615589ae1d5c30509d73cd03c09ccc973e 100644 (file)
@@ -159,7 +159,9 @@ struct ocfs2_lock_res {
        char                     l_name[OCFS2_LOCK_ID_MAX_LEN];
        unsigned int             l_ro_holders;
        unsigned int             l_ex_holders;
-       unsigned char            l_level;
+       char                     l_level;
+       char                     l_requested;
+       char                     l_blocking;
 
        /* Data packed - type enum ocfs2_lock_type */
        unsigned char            l_type;
@@ -169,8 +171,6 @@ struct ocfs2_lock_res {
        unsigned char            l_action;
        /* Data packed - enum type ocfs2_unlock_action */
        unsigned char            l_unlock_action;
-       unsigned char            l_requested;
-       unsigned char            l_blocking;
        unsigned int             l_pending_gen;
 
        spinlock_t               l_lock;
index 56f0cb3958209b944ecb07a3a8262efc3b9aa75d..f02c0ef315788427e1f8b51e964f9b9dec513a10 100644 (file)
@@ -1236,14 +1236,12 @@ read_super_error:
        return status;
 }
 
-static int ocfs2_get_sb(struct file_system_type *fs_type,
+static struct dentry *ocfs2_mount(struct file_system_type *fs_type,
                        int flags,
                        const char *dev_name,
-                       void *data,
-                       struct vfsmount *mnt)
+                       void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super);
 }
 
 static void ocfs2_kill_sb(struct super_block *sb)
@@ -1267,8 +1265,7 @@ out:
 static struct file_system_type ocfs2_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ocfs2",
-       .get_sb         = ocfs2_get_sb, /* is this called when we mount
-                                       * the fs? */
+       .mount          = ocfs2_mount,
        .kill_sb        = ocfs2_kill_sb,
 
        .fs_flags       = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE,
index 14a22863291a6dedb60336d571c2d1b2dc069561..e043c4cb9a9729895bfd2561105f622dba9966c8 100644 (file)
@@ -557,17 +557,16 @@ end:
        return ret;
 }
 
-static int omfs_get_sb(struct file_system_type *fs_type,
-                       int flags, const char *dev_name,
-                       void *data, struct vfsmount *m)
+static struct dentry *omfs_mount(struct file_system_type *fs_type,
+                       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, omfs_fill_super, m);
+       return mount_bdev(fs_type, flags, dev_name, data, omfs_fill_super);
 }
 
 static struct file_system_type omfs_fs_type = {
        .owner = THIS_MODULE,
        .name = "omfs",
-       .get_sb = omfs_get_sb,
+       .mount = omfs_mount,
        .kill_sb = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV,
 };
index d74e1983e8dc478145dc8da369c0479bb947d8c2..4197b9ed023d8d1b1831ddf8f706d2a34a934aa6 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -786,11 +786,11 @@ struct file *nameidata_to_filp(struct nameidata *nd)
        /* Pick up the filp from the open intent */
        filp = nd->intent.open.file;
        /* Has the filesystem initialised the file for us? */
-       if (filp->f_path.dentry == NULL)
+       if (filp->f_path.dentry == NULL) {
+               path_get(&nd->path);
                filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp,
                                     NULL, cred);
-       else
-               path_put(&nd->path);
+       }
        return filp;
 }
 
index ffcd04f0012c6aa67dcf2fa5990d4d162f835f5a..911e61f348fc0fecb5dd748e96153c0c21974c10 100644 (file)
@@ -415,16 +415,16 @@ out_no_root:
        return ret;
 }
 
-static int openprom_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *openprom_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, openprom_fill_super, mnt);
+       return mount_single(fs_type, flags, data, openprom_fill_super);
 }
 
 static struct file_system_type openprom_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "openpromfs",
-       .get_sb         = openprom_get_sb,
+       .mount          = openprom_mount,
        .kill_sb        = kill_anon_super,
 };
 
index d2d7566ce68e5cb4fc9713e531670d8f05d52d02..a8012a955720418eb059b237ac68bd98760891bb 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1247,16 +1247,15 @@ out:
  * any operations on the root directory. However, we need a non-trivial
  * d_name - pipe: will go nicely and kill the special-casing in procfs.
  */
-static int pipefs_get_sb(struct file_system_type *fs_type,
-                        int flags, const char *dev_name, void *data,
-                        struct vfsmount *mnt)
+static struct dentry *pipefs_mount(struct file_system_type *fs_type,
+                        int flags, const char *dev_name, void *data)
 {
-       return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC, mnt);
+       return mount_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC);
 }
 
 static struct file_system_type pipe_fs_type = {
        .name           = "pipefs",
-       .get_sb         = pipefs_get_sb,
+       .mount          = pipefs_mount,
        .kill_sb        = kill_anon_super,
 };
 
index 93d99b316325164758ed1d48a740f65ef9a59e9b..ef9fa8e24ad65f9b13a2a4cb989a14466ac3db8b 100644 (file)
@@ -35,8 +35,8 @@ static int proc_set_super(struct super_block *sb, void *data)
        return set_anon_super(sb, NULL);
 }
 
-static int proc_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *proc_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
        int err;
        struct super_block *sb;
@@ -61,14 +61,14 @@ static int proc_get_sb(struct file_system_type *fs_type,
 
        sb = sget(fs_type, proc_test_super, proc_set_super, ns);
        if (IS_ERR(sb))
-               return PTR_ERR(sb);
+               return ERR_CAST(sb);
 
        if (!sb->s_root) {
                sb->s_flags = flags;
                err = proc_fill_super(sb);
                if (err) {
                        deactivate_locked_super(sb);
-                       return err;
+                       return ERR_PTR(err);
                }
 
                ei = PROC_I(sb->s_root->d_inode);
@@ -79,11 +79,9 @@ static int proc_get_sb(struct file_system_type *fs_type,
                }
 
                sb->s_flags |= MS_ACTIVE;
-               ns->proc_mnt = mnt;
        }
 
-       simple_set_mnt(mnt, sb);
-       return 0;
+       return dget(sb->s_root);
 }
 
 static void proc_kill_sb(struct super_block *sb)
@@ -97,7 +95,7 @@ static void proc_kill_sb(struct super_block *sb)
 
 static struct file_system_type proc_fs_type = {
        .name           = "proc",
-       .get_sb         = proc_get_sb,
+       .mount          = proc_mount,
        .kill_sb        = proc_kill_sb,
 };
 
@@ -115,6 +113,7 @@ void __init proc_root_init(void)
                return;
        }
 
+       init_pid_ns.proc_mnt = proc_mnt;
        proc_symlink("mounts", NULL, "self/mounts");
 
        proc_net_init();
@@ -213,6 +212,7 @@ int pid_ns_prepare_proc(struct pid_namespace *ns)
        if (IS_ERR(mnt))
                return PTR_ERR(mnt);
 
+       ns->proc_mnt = mnt;
        return 0;
 }
 
index 01bad30026fc7ea1026da00bba7bd3f507e1d468..fcada42f1aa35ad472daeb910cf8b5f0ffe2ea13 100644 (file)
@@ -454,17 +454,16 @@ static void destroy_inodecache(void)
        kmem_cache_destroy(qnx4_inode_cachep);
 }
 
-static int qnx4_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *qnx4_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, qnx4_fill_super);
 }
 
 static struct file_system_type qnx4_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "qnx4",
-       .get_sb         = qnx4_get_sb,
+       .mount          = qnx4_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 67fadb1ad2c11a6428480aad801ee616d90eebac..eacb166fb25916eb1f460e99f2ad1b67f15ac4ea 100644 (file)
@@ -255,17 +255,16 @@ fail:
        return err;
 }
 
-int ramfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+struct dentry *ramfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, ramfs_fill_super, mnt);
+       return mount_nodev(fs_type, flags, data, ramfs_fill_super);
 }
 
-static int rootfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *rootfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super,
-                           mnt);
+       return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
 }
 
 static void ramfs_kill_sb(struct super_block *sb)
@@ -276,12 +275,12 @@ static void ramfs_kill_sb(struct super_block *sb)
 
 static struct file_system_type ramfs_fs_type = {
        .name           = "ramfs",
-       .get_sb         = ramfs_get_sb,
+       .mount          = ramfs_mount,
        .kill_sb        = ramfs_kill_sb,
 };
 static struct file_system_type rootfs_fs_type = {
        .name           = "rootfs",
-       .get_sb         = rootfs_get_sb,
+       .mount          = rootfs_mount,
        .kill_sb        = kill_litter_super,
 };
 
index 9cd9d148105d287b55c9f60af4034f300cc6d1af..431a0ed610c83a8750592e516ff23ac35ffbe524 100644 (file)
@@ -243,8 +243,6 @@ bad:
  * them to something that fits in "int" so that others
  * won't have to do range checks all the time.
  */
-#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
-
 int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count)
 {
        struct inode *inode;
@@ -584,65 +582,71 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
                              unsigned long nr_segs, unsigned long fast_segs,
                              struct iovec *fast_pointer,
                              struct iovec **ret_pointer)
-  {
+{
        unsigned long seg;
-       ssize_t ret;
+       ssize_t ret;
        struct iovec *iov = fast_pointer;
 
-       /*
-        * SuS says "The readv() function *may* fail if the iovcnt argument
-        * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
-        * traditionally returned zero for zero segments, so...
-        */
+       /*
+        * SuS says "The readv() function *may* fail if the iovcnt argument
+        * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
+        * traditionally returned zero for zero segments, so...
+        */
        if (nr_segs == 0) {
                ret = 0;
-               goto out;
+               goto out;
        }
 
-       /*
-        * First get the "struct iovec" from user memory and
-        * verify all the pointers
-        */
+       /*
+        * First get the "struct iovec" from user memory and
+        * verify all the pointers
+        */
        if (nr_segs > UIO_MAXIOV) {
                ret = -EINVAL;
-               goto out;
+               goto out;
        }
        if (nr_segs > fast_segs) {
-               iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
+               iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
                if (iov == NULL) {
                        ret = -ENOMEM;
-                       goto out;
+                       goto out;
                }
-       }
+       }
        if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) {
                ret = -EFAULT;
-               goto out;
+               goto out;
        }
 
-       /*
+       /*
         * According to the Single Unix Specification we should return EINVAL
         * if an element length is < 0 when cast to ssize_t or if the
         * total length would overflow the ssize_t return value of the
         * system call.
-        */
+        *
+        * Linux caps all read/write calls to MAX_RW_COUNT, and avoids the
+        * overflow case.
+        */
        ret = 0;
-       for (seg = 0; seg < nr_segs; seg++) {
-               void __user *buf = iov[seg].iov_base;
-               ssize_t len = (ssize_t)iov[seg].iov_len;
+       for (seg = 0; seg < nr_segs; seg++) {
+               void __user *buf = iov[seg].iov_base;
+               ssize_t len = (ssize_t)iov[seg].iov_len;
 
                /* see if we we're about to use an invalid len or if
                 * it's about to overflow ssize_t */
-               if (len < 0 || (ret + len < ret)) {
+               if (len < 0) {
                        ret = -EINVAL;
-                       goto out;
+                       goto out;
                }
                if (unlikely(!access_ok(vrfy_dir(type), buf, len))) {
                        ret = -EFAULT;
-                       goto out;
+                       goto out;
+               }
+               if (len > MAX_RW_COUNT - ret) {
+                       len = MAX_RW_COUNT - ret;
+                       iov[seg].iov_len = len;
                }
-
                ret += len;
-       }
+       }
 out:
        *ret_pointer = iov;
        return ret;
index e15ff612002d314ee0191d5f718bc1686a80ef3d..3bf7a6457f4d3f021db9d561a34ab7fb07bf1e01 100644 (file)
@@ -2213,12 +2213,11 @@ out:
 
 #endif
 
-static int get_super_block(struct file_system_type *fs_type,
+static struct dentry *get_super_block(struct file_system_type *fs_type,
                           int flags, const char *dev_name,
-                          void *data, struct vfsmount *mnt)
+                          void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super);
 }
 
 static int __init init_reiserfs_fs(void)
@@ -2253,7 +2252,7 @@ static void __exit exit_reiserfs_fs(void)
 struct file_system_type reiserfs_fs_type = {
        .owner = THIS_MODULE,
        .name = "reiserfs",
-       .get_sb = get_super_block,
+       .mount = get_super_block,
        .kill_sb = reiserfs_kill_sb,
        .fs_flags = FS_REQUIRES_DEV,
 };
index 268580535c92ba462a1af5983618ab0d11a321a7..6647f90e55cdcb7b96fdc41f9d63ae86a3f5e00c 100644 (file)
@@ -552,20 +552,19 @@ error_rsb:
 /*
  * get a superblock for mounting
  */
-static int romfs_get_sb(struct file_system_type *fs_type,
+static struct dentry *romfs_mount(struct file_system_type *fs_type,
                        int flags, const char *dev_name,
-                       void *data, struct vfsmount *mnt)
+                       void *data)
 {
-       int ret = -EINVAL;
+       struct dentry *ret = ERR_PTR(-EINVAL);
 
 #ifdef CONFIG_ROMFS_ON_MTD
-       ret = get_sb_mtd(fs_type, flags, dev_name, data, romfs_fill_super,
-                        mnt);
+       ret = mount_mtd(fs_type, flags, dev_name, data, romfs_fill_super);
 #endif
 #ifdef CONFIG_ROMFS_ON_BLOCK
-       if (ret == -EINVAL)
-               ret = get_sb_bdev(fs_type, flags, dev_name, data,
-                                 romfs_fill_super, mnt);
+       if (ret == ERR_PTR(-EINVAL))
+               ret = mount_bdev(fs_type, flags, dev_name, data,
+                                 romfs_fill_super);
 #endif
        return ret;
 }
@@ -592,7 +591,7 @@ static void romfs_kill_sb(struct super_block *sb)
 static struct file_system_type romfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "romfs",
-       .get_sb         = romfs_get_sb,
+       .mount          = romfs_mount,
        .kill_sb        = romfs_kill_sb,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 07a4f115604850d77191baed3a7fd96c7d161661..24de30ba34c18ba4b194ff030a4ec591f25aa75d 100644 (file)
@@ -370,12 +370,10 @@ static void squashfs_put_super(struct super_block *sb)
 }
 
 
-static int squashfs_get_sb(struct file_system_type *fs_type, int flags,
-                               const char *dev_name, void *data,
-                               struct vfsmount *mnt)
+static struct dentry *squashfs_mount(struct file_system_type *fs_type, int flags,
+                               const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super,
-                               mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super);
 }
 
 
@@ -451,7 +449,7 @@ static void squashfs_destroy_inode(struct inode *inode)
 static struct file_system_type squashfs_fs_type = {
        .owner = THIS_MODULE,
        .name = "squashfs",
-       .get_sb = squashfs_get_sb,
+       .mount = squashfs_mount,
        .kill_sb = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV
 };
index 652b8541f9c6dc5bf2b2246f753a795b92481cdb..3876c36699a1ca5a8d8303c11e9a5d99ab4c0492 100644 (file)
@@ -158,17 +158,18 @@ static int squashfs_xattr_get(struct inode *inode, int name_index,
                                        strncmp(target, name, name_size) == 0) {
                        /* found xattr */
                        if (type & SQUASHFS_XATTR_VALUE_OOL) {
-                               __le64 xattr;
+                               __le64 xattr_val;
+                               u64 xattr;
                                /* val is a reference to the real location */
                                err = squashfs_read_metadata(sb, &val, &start,
                                                &offset, sizeof(val));
                                if (err < 0)
                                        goto failed;
-                               err = squashfs_read_metadata(sb, &xattr, &start,
-                                        &offset, sizeof(xattr));
+                               err = squashfs_read_metadata(sb, &xattr_val,
+                                       &start, &offset, sizeof(xattr_val));
                                if (err < 0)
                                        goto failed;
-                               xattr = le64_to_cpu(xattr);
+                               xattr = le64_to_cpu(xattr_val);
                                start = SQUASHFS_XATTR_BLK(xattr) +
                                                        msblk->xattr_table;
                                offset = SQUASHFS_XATTR_OFFSET(xattr);
index 49fe0d719fbfd7bf114a39a6c152d87937828957..b634efce4bded85e487849738af0cda27650048c 100644 (file)
@@ -25,7 +25,7 @@
 extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64,
                u64 *, int *);
 extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *,
-               int *, unsigned long long *);
+               unsigned int *, unsigned long long *);
 #else
 static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb,
                u64 start, u64 *xattr_table_start, int *xattr_ids)
@@ -35,7 +35,7 @@ static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb,
 }
 
 static inline int squashfs_xattr_lookup(struct super_block *sb,
-               unsigned int index, int *count, int *size,
+               unsigned int index, int *count, unsigned int *size,
                unsigned long long *xattr)
 {
        return 0;
index cfb41106098fbbe2faef42bc2392c02479539479..d33be5dd6c32564fbe8ff4768b8d2f96a6175252 100644 (file)
@@ -34,6 +34,7 @@
 #include "squashfs_fs_sb.h"
 #include "squashfs_fs_i.h"
 #include "squashfs.h"
+#include "xattr.h"
 
 /*
  * Map xattr id using the xattr id look up table
index b9c9869165db359d018134e99e0a39e2738e6dba..ca696155cd9aea65d527af3e8d25a8bdc9cc40f0 100644 (file)
@@ -715,15 +715,14 @@ static int ns_set_super(struct super_block *sb, void *data)
        return set_anon_super(sb, NULL);
 }
 
-int get_sb_ns(struct file_system_type *fs_type, int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt)
+struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
+       void *data, int (*fill_super)(struct super_block *, void *, int))
 {
        struct super_block *sb;
 
        sb = sget(fs_type, ns_test_super, ns_set_super, data);
        if (IS_ERR(sb))
-               return PTR_ERR(sb);
+               return ERR_CAST(sb);
 
        if (!sb->s_root) {
                int err;
@@ -731,17 +730,16 @@ int get_sb_ns(struct file_system_type *fs_type, int flags, void *data,
                err = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
                if (err) {
                        deactivate_locked_super(sb);
-                       return err;
+                       return ERR_PTR(err);
                }
 
                sb->s_flags |= MS_ACTIVE;
        }
 
-       simple_set_mnt(mnt, sb);
-       return 0;
+       return dget(sb->s_root);
 }
 
-EXPORT_SYMBOL(get_sb_ns);
+EXPORT_SYMBOL(mount_ns);
 
 #ifdef CONFIG_BLOCK
 static int set_bdev_super(struct super_block *s, void *data)
@@ -762,10 +760,9 @@ static int test_bdev_super(struct super_block *s, void *data)
        return (void *)s->s_bdev == data;
 }
 
-int get_sb_bdev(struct file_system_type *fs_type,
+struct dentry *mount_bdev(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt)
+       int (*fill_super)(struct super_block *, void *, int))
 {
        struct block_device *bdev;
        struct super_block *s;
@@ -777,7 +774,7 @@ int get_sb_bdev(struct file_system_type *fs_type,
 
        bdev = open_bdev_exclusive(dev_name, mode, fs_type);
        if (IS_ERR(bdev))
-               return PTR_ERR(bdev);
+               return ERR_CAST(bdev);
 
        /*
         * once the super is inserted into the list by sget, s_umount
@@ -829,15 +826,30 @@ int get_sb_bdev(struct file_system_type *fs_type,
                bdev->bd_super = s;
        }
 
-       simple_set_mnt(mnt, s);
-       return 0;
+       return dget(s->s_root);
 
 error_s:
        error = PTR_ERR(s);
 error_bdev:
        close_bdev_exclusive(bdev, mode);
 error:
-       return error;
+       return ERR_PTR(error);
+}
+EXPORT_SYMBOL(mount_bdev);
+
+int get_sb_bdev(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data,
+       int (*fill_super)(struct super_block *, void *, int),
+       struct vfsmount *mnt)
+{
+       struct dentry *root;
+
+       root = mount_bdev(fs_type, flags, dev_name, data, fill_super);
+       if (IS_ERR(root))
+               return PTR_ERR(root);
+       mnt->mnt_root = root;
+       mnt->mnt_sb = root->d_sb;
+       return 0;
 }
 
 EXPORT_SYMBOL(get_sb_bdev);
@@ -856,29 +868,42 @@ void kill_block_super(struct super_block *sb)
 EXPORT_SYMBOL(kill_block_super);
 #endif
 
-int get_sb_nodev(struct file_system_type *fs_type,
+struct dentry *mount_nodev(struct file_system_type *fs_type,
        int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt)
+       int (*fill_super)(struct super_block *, void *, int))
 {
        int error;
        struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
 
        if (IS_ERR(s))
-               return PTR_ERR(s);
+               return ERR_CAST(s);
 
        s->s_flags = flags;
 
        error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
        if (error) {
                deactivate_locked_super(s);
-               return error;
+               return ERR_PTR(error);
        }
        s->s_flags |= MS_ACTIVE;
-       simple_set_mnt(mnt, s);
-       return 0;
+       return dget(s->s_root);
 }
+EXPORT_SYMBOL(mount_nodev);
 
+int get_sb_nodev(struct file_system_type *fs_type,
+       int flags, void *data,
+       int (*fill_super)(struct super_block *, void *, int),
+       struct vfsmount *mnt)
+{
+       struct dentry *root;
+
+       root = mount_nodev(fs_type, flags, data, fill_super);
+       if (IS_ERR(root))
+               return PTR_ERR(root);
+       mnt->mnt_root = root;
+       mnt->mnt_sb = root->d_sb;
+       return 0;
+}
 EXPORT_SYMBOL(get_sb_nodev);
 
 static int compare_single(struct super_block *s, void *p)
@@ -886,29 +911,42 @@ static int compare_single(struct super_block *s, void *p)
        return 1;
 }
 
-int get_sb_single(struct file_system_type *fs_type,
+struct dentry *mount_single(struct file_system_type *fs_type,
        int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt)
+       int (*fill_super)(struct super_block *, void *, int))
 {
        struct super_block *s;
        int error;
 
        s = sget(fs_type, compare_single, set_anon_super, NULL);
        if (IS_ERR(s))
-               return PTR_ERR(s);
+               return ERR_CAST(s);
        if (!s->s_root) {
                s->s_flags = flags;
                error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
                if (error) {
                        deactivate_locked_super(s);
-                       return error;
+                       return ERR_PTR(error);
                }
                s->s_flags |= MS_ACTIVE;
        } else {
                do_remount_sb(s, flags, data, 0);
        }
-       simple_set_mnt(mnt, s);
+       return dget(s->s_root);
+}
+EXPORT_SYMBOL(mount_single);
+
+int get_sb_single(struct file_system_type *fs_type,
+       int flags, void *data,
+       int (*fill_super)(struct super_block *, void *, int),
+       struct vfsmount *mnt)
+{
+       struct dentry *root;
+       root = mount_single(fs_type, flags, data, fill_super);
+       if (IS_ERR(root))
+               return PTR_ERR(root);
+       mnt->mnt_root = root;
+       mnt->mnt_sb = root->d_sb;
        return 0;
 }
 
@@ -918,6 +956,7 @@ struct vfsmount *
 vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
 {
        struct vfsmount *mnt;
+       struct dentry *root;
        char *secdata = NULL;
        int error;
 
@@ -942,9 +981,19 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
                        goto out_free_secdata;
        }
 
-       error = type->get_sb(type, flags, name, data, mnt);
-       if (error < 0)
-               goto out_free_secdata;
+       if (type->mount) {
+               root = type->mount(type, flags, name, data);
+               if (IS_ERR(root)) {
+                       error = PTR_ERR(root);
+                       goto out_free_secdata;
+               }
+               mnt->mnt_root = root;
+               mnt->mnt_sb = root->d_sb;
+       } else {
+               error = type->get_sb(type, flags, name, data, mnt);
+               if (error < 0)
+                       goto out_free_secdata;
+       }
        BUG_ON(!mnt->mnt_sb);
        WARN_ON(!mnt->mnt_sb->s_bdi);
        mnt->mnt_sb->s_flags |= MS_BORN;
index f2af22574c50978865afc939d6d9a3a853ebdf3c..266895783b477a94e64248217483ec52f02c75fb 100644 (file)
@@ -23,7 +23,7 @@
 #include "sysfs.h"
 
 
-static struct vfsmount *sysfs_mount;
+static struct vfsmount *sysfs_mnt;
 struct kmem_cache *sysfs_dir_cachep;
 
 static const struct super_operations sysfs_ops = {
@@ -95,18 +95,17 @@ static int sysfs_set_super(struct super_block *sb, void *data)
        return error;
 }
 
-static int sysfs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *sysfs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
        struct sysfs_super_info *info;
        enum kobj_ns_type type;
        struct super_block *sb;
        int error;
 
-       error = -ENOMEM;
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
-               goto out;
+               return ERR_PTR(-ENOMEM);
 
        for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
                info->ns[type] = kobj_ns_current(type);
@@ -114,24 +113,19 @@ static int sysfs_get_sb(struct file_system_type *fs_type,
        sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info);
        if (IS_ERR(sb) || sb->s_fs_info != info)
                kfree(info);
-       if (IS_ERR(sb)) {
-               error = PTR_ERR(sb);
-               goto out;
-       }
+       if (IS_ERR(sb))
+               return ERR_CAST(sb);
        if (!sb->s_root) {
                sb->s_flags = flags;
                error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
                if (error) {
                        deactivate_locked_super(sb);
-                       goto out;
+                       return ERR_PTR(error);
                }
                sb->s_flags |= MS_ACTIVE;
        }
 
-       simple_set_mnt(mnt, sb);
-       error = 0;
-out:
-       return error;
+       return dget(sb->s_root);
 }
 
 static void sysfs_kill_sb(struct super_block *sb)
@@ -147,7 +141,7 @@ static void sysfs_kill_sb(struct super_block *sb)
 
 static struct file_system_type sysfs_fs_type = {
        .name           = "sysfs",
-       .get_sb         = sysfs_get_sb,
+       .mount          = sysfs_mount,
        .kill_sb        = sysfs_kill_sb,
 };
 
@@ -189,11 +183,11 @@ int __init sysfs_init(void)
 
        err = register_filesystem(&sysfs_fs_type);
        if (!err) {
-               sysfs_mount = kern_mount(&sysfs_fs_type);
-               if (IS_ERR(sysfs_mount)) {
+               sysfs_mnt = kern_mount(&sysfs_fs_type);
+               if (IS_ERR(sysfs_mnt)) {
                        printk(KERN_ERR "sysfs: could not mount!\n");
-                       err = PTR_ERR(sysfs_mount);
-                       sysfs_mount = NULL;
+                       err = PTR_ERR(sysfs_mnt);
+                       sysfs_mnt = NULL;
                        unregister_filesystem(&sysfs_fs_type);
                        goto out_err;
                }
index a0b0cda6927ea467a7ccf73c94bbe9b80a04d004..3d9c62be0c10ebc051d64951836ba366a3586018 100644 (file)
@@ -526,23 +526,22 @@ failed:
 
 /* Every kernel module contains stuff like this. */
 
-static int sysv_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *sysv_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, sysv_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, sysv_fill_super);
 }
 
-static int v7_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *v7_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, v7_fill_super, mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, v7_fill_super);
 }
 
 static struct file_system_type sysv_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "sysv",
-       .get_sb         = sysv_get_sb,
+       .mount          = sysv_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
@@ -550,7 +549,7 @@ static struct file_system_type sysv_fs_type = {
 static struct file_system_type v7_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "v7",
-       .get_sb         = v7_get_sb,
+       .mount          = v7_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 9a47c9f0ad07e69fddc57f5debc488982aab9429..91fac54c70e32b3a304c5060fbaa3de68995f5e4 100644 (file)
@@ -2038,8 +2038,8 @@ static int sb_test(struct super_block *sb, void *data)
        return c->vi.cdev == *dev;
 }
 
-static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
-                       const char *name, void *data, struct vfsmount *mnt)
+static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags,
+                       const char *name, void *data)
 {
        struct ubi_volume_desc *ubi;
        struct ubi_volume_info vi;
@@ -2057,7 +2057,7 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
        if (IS_ERR(ubi)) {
                dbg_err("cannot open \"%s\", error %d",
                        name, (int)PTR_ERR(ubi));
-               return PTR_ERR(ubi);
+               return ERR_CAST(ubi);
        }
        ubi_get_volume_info(ubi, &vi);
 
@@ -2095,20 +2095,19 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
        /* 'fill_super()' opens ubi again so we must close it here */
        ubi_close_volume(ubi);
 
-       simple_set_mnt(mnt, sb);
-       return 0;
+       return dget(sb->s_root);
 
 out_deact:
        deactivate_locked_super(sb);
 out_close:
        ubi_close_volume(ubi);
-       return err;
+       return ERR_PTR(err);
 }
 
 static struct file_system_type ubifs_fs_type = {
        .name    = "ubifs",
        .owner   = THIS_MODULE,
-       .get_sb  = ubifs_get_sb,
+       .mount   = ubifs_mount,
        .kill_sb = kill_anon_super,
 };
 
index 76f3d6d97b402ea14c391c46b8a924af9888cc6c..4a5c7c61836aaf6a1224740eefe607b886929c9e 100644 (file)
@@ -107,17 +107,16 @@ struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi)
 }
 
 /* UDF filesystem type */
-static int udf_get_sb(struct file_system_type *fs_type,
-                     int flags, const char *dev_name, void *data,
-                     struct vfsmount *mnt)
+static struct dentry *udf_mount(struct file_system_type *fs_type,
+                     int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super, mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, udf_fill_super);
 }
 
 static struct file_system_type udf_fstype = {
        .owner          = THIS_MODULE,
        .name           = "udf",
-       .get_sb         = udf_get_sb,
+       .mount          = udf_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index 6b9be90dae7dd7affc1ccba35c02bd9fac193570..2c47daed56dac7f2ad789a41a2d1e19fc929a49b 100644 (file)
@@ -1454,16 +1454,16 @@ static const struct super_operations ufs_super_ops = {
        .show_options   = ufs_show_options,
 };
 
-static int ufs_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *ufs_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super, mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, ufs_fill_super);
 }
 
 static struct file_system_type ufs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ufs",
-       .get_sb         = ufs_get_sb,
+       .mount          = ufs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
index c9af48fffcd77fc559f73d5d97317e22ec4d3413..7d287afccde58ac16c854ee5dc2eb31f2f7b1637 100644 (file)
@@ -1111,11 +1111,12 @@ xfs_vm_writepage(
                        uptodate = 0;
 
                /*
-                * A hole may still be marked uptodate because discard_buffer
-                * leaves the flag set.
+                * set_page_dirty dirties all buffers in a page, independent
+                * of their state.  The dirty state however is entirely
+                * meaningless for holes (!mapped && uptodate), so skip
+                * buffers covering holes here.
                 */
                if (!buffer_mapped(bh) && buffer_uptodate(bh)) {
-                       ASSERT(!buffer_dirty(bh));
                        imap_valid = 0;
                        continue;
                }
index 63fd2c07cb57d861837bf463d9ad7b3aa5392088..aa1d353def29c64903cf02db9af159d612259b87 100644 (file)
@@ -1781,7 +1781,6 @@ xfs_buf_delwri_split(
        INIT_LIST_HEAD(list);
        spin_lock(dwlk);
        list_for_each_entry_safe(bp, n, dwq, b_list) {
-               trace_xfs_buf_delwri_split(bp, _RET_IP_);
                ASSERT(bp->b_flags & XBF_DELWRI);
 
                if (!XFS_BUF_ISPINNED(bp) && !xfs_buf_cond_lock(bp)) {
@@ -1795,6 +1794,7 @@ xfs_buf_delwri_split(
                                         _XBF_RUN_QUEUES);
                        bp->b_flags |= XBF_WRITE;
                        list_move_tail(&bp->b_list, list);
+                       trace_xfs_buf_delwri_split(bp, _RET_IP_);
                } else
                        skipped++;
        }
index 2ea238f6d38eb0504187d674a70c57d9acc5b382..ad442d9e392e480ab242f5d13922ee3ec0feab2e 100644 (file)
@@ -416,7 +416,7 @@ xfs_attrlist_by_handle(
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
 
-       kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL);
+       kbuf = kzalloc(al_hreq.buflen, GFP_KERNEL);
        if (!kbuf)
                goto out_dput;
 
index 96107efc0c61908c3f1a94a646604836fc2131e1..94d5fd6a2973042239bd22f19047947494f57581 100644 (file)
@@ -762,7 +762,8 @@ xfs_setup_inode(
        inode->i_state = I_NEW;
 
        inode_sb_list_add(inode);
-       insert_inode_hash(inode);
+       /* make the inode look hashed for the writeback code */
+       hlist_add_fake(&inode->i_hash);
 
        inode->i_mode   = ip->i_d.di_mode;
        inode->i_nlink  = ip->i_d.di_nlink;
index cf808782c0650d86e967e149a8fac2baf80dd093..064f964d4f3c201ce52bf6bb42e7dbbd3c0526bd 100644 (file)
@@ -353,9 +353,6 @@ xfs_parseargs(
                        mp->m_qflags &= ~XFS_OQUOTA_ENFD;
                } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) {
                        mp->m_flags |= XFS_MOUNT_DELAYLOG;
-                       cmn_err(CE_WARN,
-                               "Enabling EXPERIMENTAL delayed logging feature "
-                               "- use at your own risk.\n");
                } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) {
                        mp->m_flags &= ~XFS_MOUNT_DELAYLOG;
                } else if (!strcmp(this_char, "ihashsize")) {
@@ -1609,16 +1606,14 @@ xfs_fs_fill_super(
        goto out_free_sb;
 }
 
-STATIC int
-xfs_fs_get_sb(
+STATIC struct dentry *
+xfs_fs_mount(
        struct file_system_type *fs_type,
        int                     flags,
        const char              *dev_name,
-       void                    *data,
-       struct vfsmount         *mnt)
+       void                    *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super,
-                          mnt);
+       return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super);
 }
 
 static const struct super_operations xfs_super_operations = {
@@ -1639,7 +1634,7 @@ static const struct super_operations xfs_super_operations = {
 static struct file_system_type xfs_fs_type = {
        .owner                  = THIS_MODULE,
        .name                   = "xfs",
-       .get_sb                 = xfs_fs_get_sb,
+       .mount                  = xfs_fs_mount,
        .kill_sb                = kill_block_super,
        .fs_flags               = FS_REQUIRES_DEV,
 };
index 37d33254981da7026cffb7e586f072c1a93eae9d..afb0d7cfad1cceafef852098d955cd8dfb42bee3 100644 (file)
@@ -853,6 +853,7 @@ restart:
                if (trylock) {
                        if (!mutex_trylock(&pag->pag_ici_reclaim_lock)) {
                                skipped++;
+                               xfs_perag_put(pag);
                                continue;
                        }
                        first_index = pag->pag_ici_reclaim_cursor;
index 9b715dce5699df0833ea92058683a5b9f30f8868..9124425b7f2fe9a07c3479047e7c3ea7c3a74693 100644 (file)
@@ -744,9 +744,15 @@ xfs_filestream_new_ag(
         * If the file's parent directory is known, take its iolock in exclusive
         * mode to prevent two sibling files from racing each other to migrate
         * themselves and their parent to different AGs.
+        *
+        * Note that we lock the parent directory iolock inside the child
+        * iolock here.  That's fine as we never hold both parent and child
+        * iolock in any other place.  This is different from the ilock,
+        * which requires locking of the child after the parent for namespace
+        * operations.
         */
        if (pip)
-               xfs_ilock(pip, XFS_IOLOCK_EXCL);
+               xfs_ilock(pip, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
 
        /*
         * A new AG needs to be found for the file.  If the file's parent
index b1498ab5a399b627b3f7b643e2bca6256ae5a49f..19e9dfa1c2543e3a47c05ea1a25cb954b47d9736 100644 (file)
@@ -275,6 +275,7 @@ xfs_free_perag(
                pag = radix_tree_delete(&mp->m_perag_tree, agno);
                spin_unlock(&mp->m_perag_lock);
                ASSERT(pag);
+               ASSERT(atomic_read(&pag->pag_ref) == 0);
                call_rcu(&pag->rcu_head, __xfs_free_perag);
        }
 }
index e0e64b113bd66e91b22933ab6eaf8192e67e936a..9bb6eda4cd215903077612233bf3b6c0d1577327 100644 (file)
@@ -346,8 +346,17 @@ xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid,
 #define xfs_trans_mod_dquot_byino(tp, ip, fields, delta)
 #define xfs_trans_apply_dquot_deltas(tp)
 #define xfs_trans_unreserve_and_mod_dquots(tp)
-#define xfs_trans_reserve_quota_nblks(tp, ip, nblks, ninos, flags)     (0)
-#define xfs_trans_reserve_quota_bydquots(tp, mp, u, g, nb, ni, fl)     (0)
+static inline int xfs_trans_reserve_quota_nblks(struct xfs_trans *tp,
+               struct xfs_inode *ip, long nblks, long ninos, uint flags)
+{
+       return 0;
+}
+static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp,
+               struct xfs_mount *mp, struct xfs_dquot *udqp,
+               struct xfs_dquot *gdqp, long nblks, long nions, uint flags)
+{
+       return 0;
+}
 #define xfs_qm_vop_create_dqattach(tp, ip, u, g)
 #define xfs_qm_vop_rename_dqattach(it)                                 (0)
 #define xfs_qm_vop_chown(tp, ip, old, new)                             (NULL)
@@ -357,11 +366,14 @@ xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid,
 #define xfs_qm_dqdetach(ip)
 #define xfs_qm_dqrele(d)
 #define xfs_qm_statvfs(ip, s)
-#define xfs_qm_sync(mp, fl)                                            (0)
+static inline int xfs_qm_sync(struct xfs_mount *mp, int flags)
+{
+       return 0;
+}
 #define xfs_qm_newmount(mp, a, b)                                      (0)
 #define xfs_qm_mount_quotas(mp)
 #define xfs_qm_unmount(mp)
-#define xfs_qm_unmount_quotas(mp)                                      (0)
+#define xfs_qm_unmount_quotas(mp)
 #endif /* CONFIG_XFS_QUOTA */
 
 #define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \
index 50764550a60c388d858293e3395a68f1d87e4ffb..bcbab3e4a3be6c802698fe0d1419f02b54a1eba3 100644 (file)
@@ -20,3 +20,7 @@ __NR_chown32,
 __NR_fchown32,
 __NR_lchown32,
 #endif
+__NR_link,
+#ifdef __NR_linkat
+__NR_linkat,
+#endif
index 47e64170305d8f862e2f67d73420eb3e0a8ed9e4..bd8cad21998e0e41ac88435b55ae9f3d275c0283 100644 (file)
@@ -33,18 +33,18 @@ struct stat {
        int             st_blksize;     /* Optimal block size for I/O.  */
        int             __pad2;
        long            st_blocks;      /* Number 512-byte blocks allocated. */
-       int             st_atime;       /* Time of last access.  */
-       unsigned int    st_atime_nsec;
-       int             st_mtime;       /* Time of last modification.  */
-       unsigned int    st_mtime_nsec;
-       int             st_ctime;       /* Time of last status change.  */
-       unsigned int    st_ctime_nsec;
+       long            st_atime;       /* Time of last access.  */
+       unsigned long   st_atime_nsec;
+       long            st_mtime;       /* Time of last modification.  */
+       unsigned long   st_mtime_nsec;
+       long            st_ctime;       /* Time of last status change.  */
+       unsigned long   st_ctime_nsec;
        unsigned int    __unused4;
        unsigned int    __unused5;
 };
 
-#if __BITS_PER_LONG != 64
 /* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
+#if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64)
 struct stat64 {
        unsigned long long st_dev;      /* Device.  */
        unsigned long long st_ino;      /* File serial number.  */
index 5afa5b52063e6d385926de88ec49faf1324a185a..beafc156a5353259d6b077ca57b2dd13af39f48d 100644 (file)
@@ -432,6 +432,10 @@ extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo);
  * together with the @destroy function,
  * enables driver-specific objects derived from a ttm_buffer_object.
  * On successful return, the object kref and list_kref are set to 1.
+ * If a failure occurs, the function will call the @destroy function, or
+ * kfree() if @destroy is NULL. Thus, after a failure, dereferencing @bo is
+ * illegal and will likely cause memory corruption.
+ *
  * Returns
  * -ENOMEM: Out of memory.
  * -EINVAL: Invalid placement flags.
index d01b4ddbdc56acb88fd1064b0e4580f82aa03b76..8e0c848326b6df5ccc95fc4ae16b965d81bfa0c8 100644 (file)
@@ -206,14 +206,84 @@ struct ttm_tt {
 struct ttm_mem_type_manager;
 
 struct ttm_mem_type_manager_func {
+       /**
+        * struct ttm_mem_type_manager member init
+        *
+        * @man: Pointer to a memory type manager.
+        * @p_size: Implementation dependent, but typically the size of the
+        * range to be managed in pages.
+        *
+        * Called to initialize a private range manager. The function is
+        * expected to initialize the man::priv member.
+        * Returns 0 on success, negative error code on failure.
+        */
        int  (*init)(struct ttm_mem_type_manager *man, unsigned long p_size);
+
+       /**
+        * struct ttm_mem_type_manager member takedown
+        *
+        * @man: Pointer to a memory type manager.
+        *
+        * Called to undo the setup done in init. All allocated resources
+        * should be freed.
+        */
        int  (*takedown)(struct ttm_mem_type_manager *man);
+
+       /**
+        * struct ttm_mem_type_manager member get_node
+        *
+        * @man: Pointer to a memory type manager.
+        * @bo: Pointer to the buffer object we're allocating space for.
+        * @placement: Placement details.
+        * @mem: Pointer to a struct ttm_mem_reg to be filled in.
+        *
+        * This function should allocate space in the memory type managed
+        * by @man. Placement details if
+        * applicable are given by @placement. If successful,
+        * @mem::mm_node should be set to a non-null value, and
+        * @mem::start should be set to a value identifying the beginning
+        * of the range allocated, and the function should return zero.
+        * If the memory region accomodate the buffer object, @mem::mm_node
+        * should be set to NULL, and the function should return 0.
+        * If a system error occured, preventing the request to be fulfilled,
+        * the function should return a negative error code.
+        *
+        * Note that @mem::mm_node will only be dereferenced by
+        * struct ttm_mem_type_manager functions and optionally by the driver,
+        * which has knowledge of the underlying type.
+        *
+        * This function may not be called from within atomic context, so
+        * an implementation can and must use either a mutex or a spinlock to
+        * protect any data structures managing the space.
+        */
        int  (*get_node)(struct ttm_mem_type_manager *man,
                         struct ttm_buffer_object *bo,
                         struct ttm_placement *placement,
                         struct ttm_mem_reg *mem);
+
+       /**
+        * struct ttm_mem_type_manager member put_node
+        *
+        * @man: Pointer to a memory type manager.
+        * @mem: Pointer to a struct ttm_mem_reg to be filled in.
+        *
+        * This function frees memory type resources previously allocated
+        * and that are identified by @mem::mm_node and @mem::start. May not
+        * be called from within atomic context.
+        */
        void (*put_node)(struct ttm_mem_type_manager *man,
                         struct ttm_mem_reg *mem);
+
+       /**
+        * struct ttm_mem_type_manager member debug
+        *
+        * @man: Pointer to a memory type manager.
+        * @prefix: Prefix to be used in printout to identify the caller.
+        *
+        * This function is called to print out the state of the memory
+        * type manager to aid debugging of out-of-memory conditions.
+        * It may not be called from within atomic context.
+        */
        void (*debug)(struct ttm_mem_type_manager *man, const char *prefix);
 };
 
@@ -231,14 +301,13 @@ struct ttm_mem_type_manager {
        uint64_t size;
        uint32_t available_caching;
        uint32_t default_caching;
+       const struct ttm_mem_type_manager_func *func;
+       void *priv;
 
        /*
-        * Protected by the bdev->lru_lock.
-        * TODO: Consider one lru_lock per ttm_mem_type_manager.
-        * Plays ill with list removal, though.
+        * Protected by the global->lru_lock.
         */
-       const struct ttm_mem_type_manager_func *func;
-       void *priv;
+
        struct list_head lru;
 };
 
index 90e3ed3a314494ef69cc3cd9e86274f703f2c8b7..97319a8fc1e08e9af7a63177272fe4e4671e1b8d 100644 (file)
@@ -118,6 +118,7 @@ header-y += eventpoll.h
 header-y += ext2_fs.h
 header-y += fadvise.h
 header-y += falloc.h
+header-y += fanotify.h
 header-y += fb.h
 header-y += fcntl.h
 header-y += fd.h
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
new file mode 100644 (file)
index 0000000..96c038e
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _LINUX_ATOMIC_H
+#define _LINUX_ATOMIC_H
+#include <asm/atomic.h>
+
+/**
+ * atomic_inc_not_zero_hint - increment if not null
+ * @v: pointer of type atomic_t
+ * @hint: probable value of the atomic before the increment
+ *
+ * This version of atomic_inc_not_zero() gives a hint of probable
+ * value of the atomic. This helps processor to not read the memory
+ * before doing the atomic read/modify/write cycle, lowering
+ * number of bus transactions on some arches.
+ *
+ * Returns: 0 if increment was not done, 1 otherwise.
+ */
+#ifndef atomic_inc_not_zero_hint
+static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint)
+{
+       int val, c = hint;
+
+       /* sanity test, should be removed by compiler if hint is a constant */
+       if (!hint)
+               return atomic_inc_not_zero(v);
+
+       do {
+               val = atomic_cmpxchg(v, c, c + 1);
+               if (val == c)
+                       return 1;
+               c = val;
+       } while (c);
+
+       return 0;
+}
+#endif
+
+#endif /* _LINUX_ATOMIC_H */
index e24afabc548f136bdaf736bb867432d05ba48667..8b5c0620abf95ba50223ced24c2e558eaaf73d54 100644 (file)
 #define AUDIT_EOE              1320    /* End of multi-record event */
 #define AUDIT_BPRM_FCAPS       1321    /* Information about fcaps increasing perms */
 #define AUDIT_CAPSET           1322    /* Record showing argument to sys_capset */
+#define AUDIT_MMAP             1323    /* Record showing descriptor and flags in mmap */
 
 #define AUDIT_AVC              1400    /* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR      1401    /* Internal SE Linux Errors */
@@ -478,6 +479,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
                                  const struct cred *new,
                                  const struct cred *old);
 extern void __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
+extern void __audit_mmap_fd(int fd, int flags);
 
 static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
 {
@@ -531,6 +533,12 @@ static inline void audit_log_capset(pid_t pid, const struct cred *new,
                __audit_log_capset(pid, new, old);
 }
 
+static inline void audit_mmap_fd(int fd, int flags)
+{
+       if (unlikely(!audit_dummy_context()))
+               __audit_mmap_fd(fd, flags);
+}
+
 extern int audit_n_rules;
 extern int audit_signals;
 #else
@@ -564,6 +572,7 @@ extern int audit_signals;
 #define audit_mq_getsetattr(d,s) ((void)0)
 #define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; })
 #define audit_log_capset(pid, ncr, ocr) ((void)0)
+#define audit_mmap_fd(fd, flags) ((void)0)
 #define audit_ptrace(t) ((void)0)
 #define audit_n_rules 0
 #define audit_signals 0
index ba679992d39b4e08ebf0314b784a72a80dd41506..35dcdb3589bc9a59047a58e166efc540c22a3105 100644 (file)
 #define bio_offset(bio)                bio_iovec((bio))->bv_offset
 #define bio_segments(bio)      ((bio)->bi_vcnt - (bio)->bi_idx)
 #define bio_sectors(bio)       ((bio)->bi_size >> 9)
-#define bio_empty_barrier(bio) \
-       ((bio->bi_rw & REQ_HARDBARRIER) && \
-        !bio_has_data(bio) && \
-        !(bio->bi_rw & REQ_DISCARD))
 
 static inline unsigned int bio_cur_bytes(struct bio *bio)
 {
index 0437ab6bb54c0b2265c39bb961e88eda09d38739..46ad5197537af19697396a4e43179e6322a255aa 100644 (file)
@@ -122,7 +122,6 @@ enum rq_flag_bits {
        __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */
        __REQ_FAILFAST_DRIVER,  /* no driver retries of driver errors */
 
-       __REQ_HARDBARRIER,      /* may not be passed by drive either */
        __REQ_SYNC,             /* request is sync (sync write or read) */
        __REQ_META,             /* metadata io request */
        __REQ_DISCARD,          /* request to discard sectors */
@@ -159,7 +158,6 @@ enum rq_flag_bits {
 #define REQ_FAILFAST_DEV       (1 << __REQ_FAILFAST_DEV)
 #define REQ_FAILFAST_TRANSPORT (1 << __REQ_FAILFAST_TRANSPORT)
 #define REQ_FAILFAST_DRIVER    (1 << __REQ_FAILFAST_DRIVER)
-#define REQ_HARDBARRIER                (1 << __REQ_HARDBARRIER)
 #define REQ_SYNC               (1 << __REQ_SYNC)
 #define REQ_META               (1 << __REQ_META)
 #define REQ_DISCARD            (1 << __REQ_DISCARD)
@@ -168,8 +166,8 @@ enum rq_flag_bits {
 #define REQ_FAILFAST_MASK \
        (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
 #define REQ_COMMON_MASK \
-       (REQ_WRITE | REQ_FAILFAST_MASK | REQ_HARDBARRIER | REQ_SYNC | \
-        REQ_META | REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
+       (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_DISCARD | \
+        REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
 #define REQ_CLONE_MASK         REQ_COMMON_MASK
 
 #define REQ_UNPLUG             (1 << __REQ_UNPLUG)
index 5027a599077d89cd72aa5c09aaaa56254b971886..aae86fd10c4f5dcea0eaf43cf6c39667a805dae4 100644 (file)
@@ -552,8 +552,7 @@ static inline void blk_clear_queue_full(struct request_queue *q, int sync)
  * it already be started by driver.
  */
 #define RQ_NOMERGE_FLAGS       \
-       (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER | \
-        REQ_FLUSH | REQ_FUA)
+       (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
 #define rq_mergeable(rq)       \
        (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \
         (((rq)->cmd_flags & REQ_DISCARD) || \
index 7187bd8a75f62c23b13ac73f4416488a0e42a0c7..749f01ccd26ef4ea23e06241b6f0c51f84efbd65 100644 (file)
@@ -462,7 +462,8 @@ struct dccp_ackvec;
  * @dccps_hc_rx_insert_options - receiver wants to add options when acking
  * @dccps_hc_tx_insert_options - sender wants to add options when sending
  * @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3)
- * @dccps_xmit_timer - timer for when CCID is not ready to send
+ * @dccps_xmitlet - tasklet scheduled by the TX CCID to dequeue data packets
+ * @dccps_xmit_timer - used by the TX CCID to delay sending (rate-based pacing)
  * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs)
  */
 struct dccp_sock {
@@ -502,6 +503,7 @@ struct dccp_sock {
        __u8                            dccps_hc_rx_insert_options:1;
        __u8                            dccps_hc_tx_insert_options:1;
        __u8                            dccps_server_timewait:1;
+       struct tasklet_struct           dccps_xmitlet;
        struct timer_list               dccps_xmit_timer;
 };
 
index 9b2a0158f399af00af84e4e65805df81f5b935c6..ef44c7a0638cdaaf087a65e01476aca73d29239b 100644 (file)
@@ -53,7 +53,7 @@
 
 
 extern const char *drbd_buildtag(void);
-#define REL_VERSION "8.3.9rc2"
+#define REL_VERSION "8.3.9"
 #define API_VERSION 88
 #define PRO_VERSION_MIN 86
 #define PRO_VERSION_MAX 95
index 63531a6b4d2a0e42759dbe1a224a103afec1327a..0f0121467fc4b8cf261cbb06a9ff6347b3596474 100644 (file)
@@ -6,18 +6,19 @@
 /* the following events that user-space can register for */
 #define FAN_ACCESS             0x00000001      /* File was accessed */
 #define FAN_MODIFY             0x00000002      /* File was modified */
-#define FAN_CLOSE_WRITE                0x00000008      /* Unwrittable file closed */
-#define FAN_CLOSE_NOWRITE      0x00000010      /* Writtable file closed */
+#define FAN_CLOSE_WRITE                0x00000008      /* Writtable file closed */
+#define FAN_CLOSE_NOWRITE      0x00000010      /* Unwrittable file closed */
 #define FAN_OPEN               0x00000020      /* File was opened */
 
-#define FAN_EVENT_ON_CHILD     0x08000000      /* interested in child events */
-
-/* FIXME currently Q's have no limit.... */
 #define FAN_Q_OVERFLOW         0x00004000      /* Event queued overflowed */
 
 #define FAN_OPEN_PERM          0x00010000      /* File open in perm check */
 #define FAN_ACCESS_PERM                0x00020000      /* File accessed in perm check */
 
+#define FAN_ONDIR              0x40000000      /* event occurred against dir */
+
+#define FAN_EVENT_ON_CHILD     0x08000000      /* interested in child events */
+
 /* helper events */
 #define FAN_CLOSE              (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */
 
 #define FAN_CLOEXEC            0x00000001
 #define FAN_NONBLOCK           0x00000002
 
-#define FAN_ALL_INIT_FLAGS     (FAN_CLOEXEC | FAN_NONBLOCK)
+/* These are NOT bitwise flags.  Both bits are used togther.  */
+#define FAN_CLASS_NOTIF                0x00000000
+#define FAN_CLASS_CONTENT      0x00000004
+#define FAN_CLASS_PRE_CONTENT  0x00000008
+#define FAN_ALL_CLASS_BITS     (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \
+                                FAN_CLASS_PRE_CONTENT)
+
+#define FAN_UNLIMITED_QUEUE    0x00000010
+#define FAN_UNLIMITED_MARKS    0x00000020
+
+#define FAN_ALL_INIT_FLAGS     (FAN_CLOEXEC | FAN_NONBLOCK | \
+                                FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\
+                                FAN_UNLIMITED_MARKS)
 
 /* flags used for fanotify_modify_mark() */
 #define FAN_MARK_ADD           0x00000001
 #define FAN_MARK_IGNORED_MASK  0x00000020
 #define FAN_MARK_IGNORED_SURV_MODIFY   0x00000040
 #define FAN_MARK_FLUSH         0x00000080
+#ifdef __KERNEL__
+/* not valid from userspace, only kernel internal */
+#define FAN_MARK_ONDIR         0x00000100
+#endif
 
 #define FAN_ALL_MARK_FLAGS     (FAN_MARK_ADD |\
                                 FAN_MARK_REMOVE |\
@@ -43,7 +60,8 @@
                                 FAN_MARK_ONLYDIR |\
                                 FAN_MARK_MOUNT |\
                                 FAN_MARK_IGNORED_MASK |\
-                                FAN_MARK_IGNORED_SURV_MODIFY)
+                                FAN_MARK_IGNORED_SURV_MODIFY |\
+                                FAN_MARK_FLUSH)
 
 /*
  * All of the events - we build the list by hand so that we can add flags in
 struct fanotify_event_metadata {
        __u32 event_len;
        __u32 vers;
-       __u64 mask;
+       __aligned_u64 mask;
        __s32 fd;
        __s32 pid;
-} __attribute__ ((packed));
+};
 
 struct fanotify_response {
        __s32 fd;
index 1c73b50e81ffbb2f67014e93fdbc0143a414b7ff..334d68a171081472a25f98baa510bc7eb4cfeb8e 100644 (file)
@@ -1056,7 +1056,6 @@ struct lock_manager_operations {
        int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
        void (*fl_notify)(struct file_lock *);  /* unblock callback */
        int (*fl_grant)(struct file_lock *, struct file_lock *, int);
-       void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
        void (*fl_release_private)(struct file_lock *);
        void (*fl_break)(struct file_lock *);
        int (*fl_mylease)(struct file_lock *, struct file_lock *);
@@ -1129,6 +1128,7 @@ extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg);
 extern int fcntl_getlease(struct file *filp);
 
 /* fs/locks.c */
+void locks_free_lock(struct file_lock *fl);
 extern void locks_init_lock(struct file_lock *);
 extern struct file_lock * locks_alloc_lock(void);
 extern void locks_copy_lock(struct file_lock *, struct file_lock *);
@@ -1772,6 +1772,8 @@ struct file_system_type {
        int fs_flags;
        int (*get_sb) (struct file_system_type *, int,
                       const char *, void *, struct vfsmount *);
+       struct dentry *(*mount) (struct file_system_type *, int,
+                      const char *, void *);
        void (*kill_sb) (struct super_block *);
        struct module *owner;
        struct file_system_type * next;
@@ -1787,17 +1789,25 @@ struct file_system_type {
        struct lock_class_key i_alloc_sem_key;
 };
 
-extern int get_sb_ns(struct file_system_type *fs_type, int flags, void *data,
-       int (*fill_super)(struct super_block *, void *, int),
-       struct vfsmount *mnt);
+extern struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
+       void *data, int (*fill_super)(struct super_block *, void *, int));
+extern struct dentry *mount_bdev(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data,
+       int (*fill_super)(struct super_block *, void *, int));
 extern int get_sb_bdev(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data,
        int (*fill_super)(struct super_block *, void *, int),
        struct vfsmount *mnt);
+extern struct dentry *mount_single(struct file_system_type *fs_type,
+       int flags, void *data,
+       int (*fill_super)(struct super_block *, void *, int));
 extern int get_sb_single(struct file_system_type *fs_type,
        int flags, void *data,
        int (*fill_super)(struct super_block *, void *, int),
        struct vfsmount *mnt);
+extern struct dentry *mount_nodev(struct file_system_type *fs_type,
+       int flags, void *data,
+       int (*fill_super)(struct super_block *, void *, int));
 extern int get_sb_nodev(struct file_system_type *fs_type,
        int flags, void *data,
        int (*fill_super)(struct super_block *, void *, int),
@@ -1813,9 +1823,8 @@ struct super_block *sget(struct file_system_type *type,
                        int (*test)(struct super_block *,void *),
                        int (*set)(struct super_block *,void *),
                        void *data);
-extern int get_sb_pseudo(struct file_system_type *, char *,
-       const struct super_operations *ops, unsigned long,
-       struct vfsmount *mnt);
+extern struct dentry *mount_pseudo(struct file_system_type *, char *,
+       const struct super_operations *ops, unsigned long);
 extern void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb);
 
 static inline void sb_mark_dirty(struct super_block *sb)
@@ -1858,6 +1867,7 @@ extern int current_umask(void);
 /* /sys/fs */
 extern struct kobject *fs_kobj;
 
+#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
 extern int rw_verify_area(int, struct file *, loff_t *, size_t);
 
 #define FLOCK_VERIFY_READ  1
index fc295d7ea4632ad9c1c0cef1905699feabb979d2..781d4671415f9c5f25aaa50250a06190ea91f0bb 100644 (file)
@@ -54,7 +54,6 @@ struct aoi_display_offset {
 };
 
 #define MFB_SET_CHROMA_KEY     _IOW('M', 1, struct mfb_chroma_key)
-#define MFB_WAIT_FOR_VSYNC     _IOW('F', 0x20, u_int32_t)
 #define MFB_SET_BRIGHTNESS     _IOW('M', 3, __u8)
 
 #define MFB_SET_ALPHA          0x80014d00
index 59d0df43ff9d5ef649fd109228ded45f37579d84..5c185fa27089f03b4e9194445ee7bfd842f125c6 100644 (file)
@@ -26,12 +26,12 @@ static inline void fsnotify_d_instantiate(struct dentry *dentry,
 }
 
 /* Notify this dentry's parent about a child's events. */
-static inline void fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
+static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
 {
        if (!dentry)
                dentry = path->dentry;
 
-       __fsnotify_parent(path, dentry, mask);
+       return __fsnotify_parent(path, dentry, mask);
 }
 
 /* simple call site for access decisions */
@@ -40,6 +40,7 @@ static inline int fsnotify_perm(struct file *file, int mask)
        struct path *path = &file->f_path;
        struct inode *inode = path->dentry->d_inode;
        __u32 fsnotify_mask = 0;
+       int ret;
 
        if (file->f_mode & FMODE_NONOTIFY)
                return 0;
@@ -52,6 +53,10 @@ static inline int fsnotify_perm(struct file *file, int mask)
        else
                BUG();
 
+       ret = fsnotify_parent(path, NULL, fsnotify_mask);
+       if (ret)
+               return ret;
+
        return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
 }
 
@@ -93,8 +98,8 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
                old_dir_mask |= FS_DN_RENAME;
 
        if (isdir) {
-               old_dir_mask |= FS_IN_ISDIR;
-               new_dir_mask |= FS_IN_ISDIR;
+               old_dir_mask |= FS_ISDIR;
+               new_dir_mask |= FS_ISDIR;
        }
 
        fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE, old_name, fs_cookie);
@@ -132,7 +137,7 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
        __u32 mask = FS_DELETE;
 
        if (isdir)
-               mask |= FS_IN_ISDIR;
+               mask |= FS_ISDIR;
 
        fsnotify_parent(NULL, dentry, mask);
 }
@@ -174,7 +179,7 @@ static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct
  */
 static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
 {
-       __u32 mask = (FS_CREATE | FS_IN_ISDIR);
+       __u32 mask = (FS_CREATE | FS_ISDIR);
        struct inode *d_inode = dentry->d_inode;
 
        audit_inode_child(dentry, inode);
@@ -192,7 +197,7 @@ static inline void fsnotify_access(struct file *file)
        __u32 mask = FS_ACCESS;
 
        if (S_ISDIR(inode->i_mode))
-               mask |= FS_IN_ISDIR;
+               mask |= FS_ISDIR;
 
        if (!(file->f_mode & FMODE_NONOTIFY)) {
                fsnotify_parent(path, NULL, mask);
@@ -210,7 +215,7 @@ static inline void fsnotify_modify(struct file *file)
        __u32 mask = FS_MODIFY;
 
        if (S_ISDIR(inode->i_mode))
-               mask |= FS_IN_ISDIR;
+               mask |= FS_ISDIR;
 
        if (!(file->f_mode & FMODE_NONOTIFY)) {
                fsnotify_parent(path, NULL, mask);
@@ -228,12 +233,13 @@ static inline void fsnotify_open(struct file *file)
        __u32 mask = FS_OPEN;
 
        if (S_ISDIR(inode->i_mode))
-               mask |= FS_IN_ISDIR;
+               mask |= FS_ISDIR;
 
-       if (!(file->f_mode & FMODE_NONOTIFY)) {
-               fsnotify_parent(path, NULL, mask);
-               fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
-       }
+       /* FMODE_NONOTIFY must never be set from user */
+       file->f_mode &= ~FMODE_NONOTIFY;
+
+       fsnotify_parent(path, NULL, mask);
+       fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
 }
 
 /*
@@ -247,7 +253,7 @@ static inline void fsnotify_close(struct file *file)
        __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
 
        if (S_ISDIR(inode->i_mode))
-               mask |= FS_IN_ISDIR;
+               mask |= FS_ISDIR;
 
        if (!(file->f_mode & FMODE_NONOTIFY)) {
                fsnotify_parent(path, NULL, mask);
@@ -264,7 +270,7 @@ static inline void fsnotify_xattr(struct dentry *dentry)
        __u32 mask = FS_ATTRIB;
 
        if (S_ISDIR(inode->i_mode))
-               mask |= FS_IN_ISDIR;
+               mask |= FS_ISDIR;
 
        fsnotify_parent(NULL, dentry, mask);
        fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
@@ -299,7 +305,7 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
 
        if (mask) {
                if (S_ISDIR(inode->i_mode))
-                       mask |= FS_IN_ISDIR;
+                       mask |= FS_ISDIR;
 
                fsnotify_parent(NULL, dentry, mask);
                fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
index e40190d1687813d5c86e2a1b9e414e48fcf22595..0a68f924f06fcf3f6f75727f382971bc16e5608f 100644 (file)
@@ -45,7 +45,7 @@
 #define FS_ACCESS_PERM         0x00020000      /* access event in a permissions hook */
 
 #define FS_EXCL_UNLINK         0x04000000      /* do not send events if object is unlinked */
-#define FS_IN_ISDIR            0x40000000      /* event occurred against dir */
+#define FS_ISDIR               0x40000000      /* event occurred against dir */
 #define FS_IN_ONESHOT          0x80000000      /* only send event once */
 
 #define FS_DN_RENAME           0x10000000      /* file renamed */
 
 #define FS_MOVE                        (FS_MOVED_FROM | FS_MOVED_TO)
 
+#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM)
+
 #define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
                             FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
                             FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
                             FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \
                             FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
                             FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \
-                            FS_IN_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \
+                            FS_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \
                             FS_DN_MULTISHOT | FS_EVENT_ON_CHILD)
 
 struct fsnotify_group;
@@ -129,6 +131,14 @@ struct fsnotify_group {
        wait_queue_head_t notification_waitq;   /* read() on the notification file blocks on this waitq */
        unsigned int q_len;                     /* events on the queue */
        unsigned int max_events;                /* maximum events allowed on the list */
+       /*
+        * Valid fsnotify group priorities.  Events are send in order from highest
+        * priority to lowest priority.  We default to the lowest priority.
+        */
+       #define FS_PRIO_0       0 /* normal notifiers, no permissions */
+       #define FS_PRIO_1       1 /* fanotify content based access control */
+       #define FS_PRIO_2       2 /* fanotify pre-content access */
+       unsigned int priority;
 
        /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */
        spinlock_t mark_lock;           /* protect marks_list */
@@ -159,6 +169,8 @@ struct fsnotify_group {
                        bool bypass_perm; /* protected by access_mutex */
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
                        int f_flags;
+                       unsigned int max_marks;
+                       struct user_struct *user;
                } fanotify_data;
 #endif /* CONFIG_FANOTIFY */
        };
@@ -275,8 +287,8 @@ struct fsnotify_mark {
                struct fsnotify_inode_mark i;
                struct fsnotify_vfsmount_mark m;
        };
-       __u32 ignored_mask;             /* events types to ignore */
        struct list_head free_g_list;   /* tmp list used when freeing this mark */
+       __u32 ignored_mask;             /* events types to ignore */
 #define FSNOTIFY_MARK_FLAG_INODE               0x01
 #define FSNOTIFY_MARK_FLAG_VFSMOUNT            0x02
 #define FSNOTIFY_MARK_FLAG_OBJECT_PINNED       0x04
@@ -294,7 +306,7 @@ struct fsnotify_mark {
 /* main fsnotify call to send events */
 extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
                    const unsigned char *name, u32 cookie);
-extern void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
+extern int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
 extern void __fsnotify_inode_delete(struct inode *inode);
 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
 extern u32 fsnotify_get_cookie(void);
@@ -423,8 +435,10 @@ static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int da
        return 0;
 }
 
-static inline void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
-{}
+static inline int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
+{
+       return 0;
+}
 
 static inline void __fsnotify_inode_delete(struct inode *inode)
 {}
index 8a389b608ce3b568e85d14dcbfb71f8f98cf0c13..41cb31f14ee3068cd3c232fb07e385676f2f9ba0 100644 (file)
  */
 #define in_nmi()       (preempt_count() & NMI_MASK)
 
-#if defined(CONFIG_PREEMPT)
+#if defined(CONFIG_PREEMPT) && defined(CONFIG_BKL)
 # define PREEMPT_INATOMIC_BASE kernel_locked()
-# define PREEMPT_CHECK_OFFSET 1
 #else
 # define PREEMPT_INATOMIC_BASE 0
+#endif
+
+#if defined(CONFIG_PREEMPT)
+# define PREEMPT_CHECK_OFFSET 1
+#else
 # define PREEMPT_CHECK_OFFSET 0
 #endif
 
index e9138198e8239d878ba04e069112e45eef0d519a..b676c585574e1723a50fbb7bddf0b96d43706dbe 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/hardirq.h>
 
 #include <asm/cacheflush.h>
 
index e844a0b186957c3fd49a7b0b2ff3578bea75e3e6..4bef5c55716014a15e3b49e049514d8040f77b3c 100644 (file)
  */
 
 /* --- Bit algorithm adapters                                          */
-#define I2C_HW_B_BT848         0x010005 /* BT848 video boards */
-#define I2C_HW_B_RIVA          0x010010 /* Riva based graphics cards */
-#define I2C_HW_B_ZR36067       0x010019 /* Zoran-36057/36067 based boards */
 #define I2C_HW_B_CX2388x       0x01001b /* connexant 2388x based tv cards */
-#define I2C_HW_B_EM28XX                0x01001f /* em28xx video capture cards */
-#define I2C_HW_B_CX2341X       0x010020 /* Conexant CX2341X MPEG encoder cards */
-#define I2C_HW_B_CX23885       0x010022 /* conexant 23885 based tv cards (bus1) */
-#define I2C_HW_B_AU0828                0x010023 /* auvitek au0828 usb bridge */
-#define I2C_HW_B_CX231XX       0x010024 /* Conexant CX231XX USB based cards */
-#define I2C_HW_B_HDPVR         0x010025 /* Hauppauge HD PVR */
-
-/* --- SGI adapters                                                    */
-#define I2C_HW_SGI_VINO                0x160000
-
-/* --- SMBus only adapters                                             */
-#define I2C_HW_SMBUS_W9968CF   0x04000d
-#define I2C_HW_SMBUS_OV511     0x04000e /* OV511(+) USB 1.1 webcam ICs */
-#define I2C_HW_SMBUS_OV518     0x04000f /* OV518(+) USB 1.1 webcam ICs */
-#define I2C_HW_SMBUS_CAFE      0x040012 /* Marvell 88ALP01 "CAFE" cam  */
-
-/* --- Miscellaneous adapters */
-#define I2C_HW_SAA7146         0x060000 /* SAA7146 video decoder bus */
-#define I2C_HW_SAA7134         0x090000 /* SAA7134 video decoder bus */
 
 #endif /* LINUX_I2C_ID_H */
index 1f66fa06a97cae66e39d3ad6f6cef8fc221ea955..56cfe23ffb39b5f600fd0aa5bb9616d150b4e2f0 100644 (file)
@@ -353,7 +353,7 @@ struct i2c_algorithm {
  */
 struct i2c_adapter {
        struct module *owner;
-       unsigned int id;
+       unsigned int id __deprecated;
        unsigned int class;               /* classes to allow probing for */
        const struct i2c_algorithm *algo; /* the algorithm to access the bus */
        void *algo_data;
@@ -407,8 +407,6 @@ void i2c_unlock_adapter(struct i2c_adapter *);
 
 /* i2c adapter classes (bitmask) */
 #define I2C_CLASS_HWMON                (1<<0)  /* lm_sensors, ... */
-#define I2C_CLASS_TV_ANALOG    (1<<1)  /* bttv + friends */
-#define I2C_CLASS_TV_DIGITAL   (1<<2)  /* dvb cards */
 #define I2C_CLASS_DDC          (1<<3)  /* DDC bus on graphics adapters */
 #define I2C_CLASS_SPD          (1<<7)  /* SPD EEPROMs and similar */
 
index 3c5d6b6e765c22b06f6125a606eef9b5107958aa..cec17cf6cac2b6044d820066419164d2faeccabc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Analog Devices ADP5588 I/O Expander and QWERTY Keypad Controller
  *
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2010 Analog Devices Inc.
  *
  * Licensed under the GPL-2 or later.
  */
  /* Configuration Register1 */
 #define ADP5588_AUTO_INC       (1 << 7)
 #define ADP5588_GPIEM_CFG      (1 << 6)
+#define ADP5588_OVR_FLOW_M     (1 << 5)
 #define ADP5588_INT_CFG                (1 << 4)
+#define ADP5588_OVR_FLOW_IEN   (1 << 3)
+#define ADP5588_K_LCK_IM       (1 << 2)
 #define ADP5588_GPI_IEN                (1 << 1)
+#define ADP5588_KE_IEN         (1 << 0)
 
 /* Interrupt Status Register */
+#define ADP5588_CMP2_INT       (1 << 5)
+#define ADP5588_CMP1_INT       (1 << 4)
+#define ADP5588_OVR_FLOW_INT   (1 << 3)
+#define ADP5588_K_LCK_INT      (1 << 2)
 #define ADP5588_GPI_INT                (1 << 1)
 #define ADP5588_KE_INT         (1 << 0)
 
+/* Key Lock and Event Counter Register */
+#define ADP5588_K_LCK_EN       (1 << 6)
+#define ADP5588_LCK21          0x30
+#define ADP5588_KEC            0xF
+
 #define ADP5588_MAXGPIO                18
 #define ADP5588_BANK(offs)     ((offs) >> 3)
 #define ADP5588_BIT(offs)      (1u << ((offs) & 0x7))
index c2f3a72712cec86a63699690096b928f1a1db6a2..635e1faec412db465a429a626da4c373510f2d98 100644 (file)
@@ -339,6 +339,31 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
        }
 }
 
+/**
+ * vlan_get_protocol - get protocol EtherType.
+ * @skb: skbuff to query
+ *
+ * Returns the EtherType of the packet, regardless of whether it is
+ * vlan encapsulated (normal or hardware accelerated) or not.
+ */
+static inline __be16 vlan_get_protocol(const struct sk_buff *skb)
+{
+       __be16 protocol = 0;
+
+       if (vlan_tx_tag_present(skb) ||
+            skb->protocol != cpu_to_be16(ETH_P_8021Q))
+               protocol = skb->protocol;
+       else {
+               __be16 proto, *protop;
+               protop = skb_header_pointer(skb, offsetof(struct vlan_ethhdr,
+                                               h_vlan_encapsulated_proto),
+                                               sizeof(proto), &proto);
+               if (likely(protop))
+                       protocol = *protop;
+       }
+
+       return protocol;
+}
 #endif /* __KERNEL__ */
 
 /* VLAN IOCTLs are found in sockios.h */
index 51af441f3a21268fe40f8b78810d801cdc5b6416..6ef44465db8ddc31c41be1de00eeef38c53b5fa5 100644 (file)
@@ -1406,6 +1406,8 @@ static inline void input_set_drvdata(struct input_dev *dev, void *data)
 int __must_check input_register_device(struct input_dev *);
 void input_unregister_device(struct input_dev *);
 
+void input_reset_device(struct input_dev *);
+
 int __must_check input_register_handler(struct input_handler *);
 void input_unregister_handler(struct input_handler *);
 
@@ -1421,7 +1423,7 @@ void input_release_device(struct input_handle *);
 int input_open_device(struct input_handle *);
 void input_close_device(struct input_handle *);
 
-int input_flush_device(struct input_handle* handle, struct file* file);
+int input_flush_device(struct input_handle *handle, struct file *file);
 
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
 void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value);
index 3e70b21884a948880f90e28684e5d5778e7a3d35..b2eee896dcbc7506f528be8b06a1fe3728aca141 100644 (file)
@@ -76,7 +76,6 @@ int put_io_context(struct io_context *ioc);
 void exit_io_context(struct task_struct *task);
 struct io_context *get_io_context(gfp_t gfp_flags, int node);
 struct io_context *alloc_io_context(gfp_t gfp_flags, int node);
-void copy_io_context(struct io_context **pdst, struct io_context **psrc);
 #else
 static inline void exit_io_context(struct task_struct *task)
 {
index e9639115dff1b920095b79b92202767cd0ed0537..abde2527c699684f78cf029b82c740af751c26a2 100644 (file)
@@ -412,6 +412,11 @@ static inline void irq_free_desc(unsigned int irq)
        irq_free_descs(irq, 1);
 }
 
+static inline int irq_reserve_irq(unsigned int irq)
+{
+       return irq_reserve_irqs(irq, 1);
+}
+
 #endif /* CONFIG_GENERIC_HARDIRQS */
 
 #endif /* !CONFIG_S390 */
index 05aa8c23483ff502bdf94e76365236fa44ff9721..3bc4dcab6e828a16b6113c1aa1f3de08bb062c46 100644 (file)
@@ -43,7 +43,7 @@ unsigned int irq_get_next_irq(unsigned int offset);
                else
 
 #ifdef CONFIG_SMP
-#define irq_node(irq)  (irq_to_desc(irq)->node)
+#define irq_node(irq)  (irq_get_irq_data(irq)->node)
 #else
 #define irq_node(irq)  0
 #endif
index b67cb180e6e943ffef4f70577c0a8f503b496cee..7880f18e4b863b7d0ad6a84a0b55a06452ad0990 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _LINUX_JUMP_LABEL_H
 #define _LINUX_JUMP_LABEL_H
 
-#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_HAVE_ARCH_JUMP_LABEL)
+#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL)
 # include <asm/jump_label.h>
 # define HAVE_JUMP_LABEL
 #endif
@@ -18,6 +18,8 @@ struct module;
 extern struct jump_entry __start___jump_table[];
 extern struct jump_entry __stop___jump_table[];
 
+extern void jump_label_lock(void);
+extern void jump_label_unlock(void);
 extern void arch_jump_label_transform(struct jump_entry *entry,
                                 enum jump_label_type type);
 extern void arch_jump_label_text_poke_early(jump_label_t addr);
@@ -59,6 +61,9 @@ static inline int jump_label_text_reserved(void *start, void *end)
        return 0;
 }
 
+static inline void jump_label_lock(void) {}
+static inline void jump_label_unlock(void) {}
+
 #endif
 
 #define COND_STMT(key, stmt)                                   \
index 450092c1e35f459f6db7dba29dbb94ec1a2c683c..b6de9a6f7018b6132de91c7142bafefdd1e68962 100644 (file)
 #include <linux/bitops.h>
 #include <linux/log2.h>
 #include <linux/typecheck.h>
+#include <linux/printk.h>
 #include <linux/dynamic_debug.h>
 #include <asm/byteorder.h>
 #include <asm/bug.h>
 
-extern const char linux_banner[];
-extern const char linux_proc_banner[];
-
 #define USHRT_MAX      ((u16)(~0U))
 #define SHRT_MAX       ((s16)(USHRT_MAX>>1))
 #define SHRT_MIN       ((s16)(-SHRT_MAX - 1))
@@ -60,7 +58,7 @@ extern const char linux_proc_banner[];
 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
 #define roundup(x, y) (                                        \
 {                                                      \
-       typeof(y) __y = y;                              \
+       const typeof(y) __y = y;                        \
        (((x) + (__y - 1)) / __y) * __y;                \
 }                                                      \
 )
@@ -110,31 +108,6 @@ extern const char linux_proc_banner[];
  */
 #define lower_32_bits(n) ((u32)(n))
 
-#define        KERN_EMERG      "<0>"   /* system is unusable                   */
-#define        KERN_ALERT      "<1>"   /* action must be taken immediately     */
-#define        KERN_CRIT       "<2>"   /* critical conditions                  */
-#define        KERN_ERR        "<3>"   /* error conditions                     */
-#define        KERN_WARNING    "<4>"   /* warning conditions                   */
-#define        KERN_NOTICE     "<5>"   /* normal but significant condition     */
-#define        KERN_INFO       "<6>"   /* informational                        */
-#define        KERN_DEBUG      "<7>"   /* debug-level messages                 */
-
-/* Use the default kernel loglevel */
-#define KERN_DEFAULT   "<d>"
-/*
- * Annotation for a "continued" line of log printout (only done after a
- * line that had no enclosing \n). Only to be used by core/arch code
- * during early bootup (a continued line is not SMP-safe otherwise).
- */
-#define        KERN_CONT       "<c>"
-
-extern int console_printk[];
-
-#define console_loglevel (console_printk[0])
-#define default_message_loglevel (console_printk[1])
-#define minimum_console_loglevel (console_printk[2])
-#define default_console_loglevel (console_printk[3])
-
 struct completion;
 struct pt_regs;
 struct user;
@@ -187,11 +160,6 @@ static inline void might_fault(void)
 }
 #endif
 
-struct va_format {
-       const char *fmt;
-       va_list *va;
-};
-
 extern struct atomic_notifier_head panic_notifier_list;
 extern long (*panic_blink)(int state);
 NORET_TYPE void panic(const char * fmt, ...)
@@ -245,114 +213,8 @@ extern int func_ptr_is_kernel_text(void *ptr);
 struct pid;
 extern struct pid *session_of_pgrp(struct pid *pgrp);
 
-/*
- * FW_BUG
- * Add this to a message where you are sure the firmware is buggy or behaves
- * really stupid or out of spec. Be aware that the responsible BIOS developer
- * should be able to fix this issue or at least get a concrete idea of the
- * problem by reading your message without the need of looking at the kernel
- * code.
- * 
- * Use it for definite and high priority BIOS bugs.
- *
- * FW_WARN
- * Use it for not that clear (e.g. could the kernel messed up things already?)
- * and medium priority BIOS bugs.
- *
- * FW_INFO
- * Use this one if you want to tell the user or vendor about something
- * suspicious, but generally harmless related to the firmware.
- *
- * Use it for information or very low priority BIOS bugs.
- */
-#define FW_BUG         "[Firmware Bug]: "
-#define FW_WARN                "[Firmware Warn]: "
-#define FW_INFO                "[Firmware Info]: "
-
-/*
- * HW_ERR
- * Add this to a message for hardware errors, so that user can report
- * it to hardware vendor instead of LKML or software vendor.
- */
-#define HW_ERR         "[Hardware Error]: "
-
-#ifdef CONFIG_PRINTK
-asmlinkage int vprintk(const char *fmt, va_list args)
-       __attribute__ ((format (printf, 1, 0)));
-asmlinkage int printk(const char * fmt, ...)
-       __attribute__ ((format (printf, 1, 2))) __cold;
-
-/*
- * Please don't use printk_ratelimit(), because it shares ratelimiting state
- * with all other unrelated printk_ratelimit() callsites.  Instead use
- * printk_ratelimited() or plain old __ratelimit().
- */
-extern int __printk_ratelimit(const char *func);
-#define printk_ratelimit() __printk_ratelimit(__func__)
-extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
-                                  unsigned int interval_msec);
-
-extern int printk_delay_msec;
-
-/*
- * Print a one-time message (analogous to WARN_ONCE() et al):
- */
-#define printk_once(x...) ({                   \
-       static bool __print_once;               \
-                                               \
-       if (!__print_once) {                    \
-               __print_once = true;            \
-               printk(x);                      \
-       }                                       \
-})
-
-void log_buf_kexec_setup(void);
-#else
-static inline int vprintk(const char *s, va_list args)
-       __attribute__ ((format (printf, 1, 0)));
-static inline int vprintk(const char *s, va_list args) { return 0; }
-static inline int printk(const char *s, ...)
-       __attribute__ ((format (printf, 1, 2)));
-static inline int __cold printk(const char *s, ...) { return 0; }
-static inline int printk_ratelimit(void) { return 0; }
-static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \
-                                         unsigned int interval_msec)   \
-               { return false; }
-
-/* No effect, but we still get type checking even in the !PRINTK case: */
-#define printk_once(x...) printk(x)
-
-static inline void log_buf_kexec_setup(void)
-{
-}
-#endif
-
-/*
- * Dummy printk for disabled debugging statements to use whilst maintaining
- * gcc's format and side-effect checking.
- */
-static inline __attribute__ ((format (printf, 1, 2)))
-int no_printk(const char *s, ...) { return 0; }
-
-extern int printk_needs_cpu(int cpu);
-extern void printk_tick(void);
-
-extern void asmlinkage __attribute__((format(printf, 1, 2)))
-       early_printk(const char *fmt, ...);
-
 unsigned long int_sqrt(unsigned long);
 
-static inline void console_silent(void)
-{
-       console_loglevel = 0;
-}
-
-static inline void console_verbose(void)
-{
-       if (console_loglevel)
-               console_loglevel = 15;
-}
-
 extern void bust_spinlocks(int yes);
 extern void wake_up_klogd(void);
 extern int oops_in_progress;           /* If set, an oops, panic(), BUG() or die() is in progress */
@@ -389,22 +251,6 @@ extern enum system_states {
 #define TAINT_CRAP                     10
 #define TAINT_FIRMWARE_WORKAROUND      11
 
-extern void dump_stack(void) __cold;
-
-enum {
-       DUMP_PREFIX_NONE,
-       DUMP_PREFIX_ADDRESS,
-       DUMP_PREFIX_OFFSET
-};
-extern void hex_dump_to_buffer(const void *buf, size_t len,
-                               int rowsize, int groupsize,
-                               char *linebuf, size_t linebuflen, bool ascii);
-extern void print_hex_dump(const char *level, const char *prefix_str,
-                               int prefix_type, int rowsize, int groupsize,
-                               const void *buf, size_t len, bool ascii);
-extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
-                       const void *buf, size_t len);
-
 extern const char hex_asc[];
 #define hex_asc_lo(x)  hex_asc[((x) & 0x0f)]
 #define hex_asc_hi(x)  hex_asc[((x) & 0xf0) >> 4]
@@ -418,94 +264,6 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
 
 extern int hex_to_bin(char ch);
 
-#ifndef pr_fmt
-#define pr_fmt(fmt) fmt
-#endif
-
-#define pr_emerg(fmt, ...) \
-        printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_alert(fmt, ...) \
-        printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_crit(fmt, ...) \
-        printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_err(fmt, ...) \
-        printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_warning(fmt, ...) \
-        printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_warn pr_warning
-#define pr_notice(fmt, ...) \
-        printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_info(fmt, ...) \
-        printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_cont(fmt, ...) \
-       printk(KERN_CONT fmt, ##__VA_ARGS__)
-
-/* pr_devel() should produce zero code unless DEBUG is defined */
-#ifdef DEBUG
-#define pr_devel(fmt, ...) \
-       printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
-#else
-#define pr_devel(fmt, ...) \
-       ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; })
-#endif
-
-/* If you are writing a driver, please use dev_dbg instead */
-#if defined(DEBUG)
-#define pr_debug(fmt, ...) \
-       printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
-#elif defined(CONFIG_DYNAMIC_DEBUG)
-/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
-#define pr_debug(fmt, ...) \
-       dynamic_pr_debug(fmt, ##__VA_ARGS__)
-#else
-#define pr_debug(fmt, ...) \
-       ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; })
-#endif
-
-/*
- * ratelimited messages with local ratelimit_state,
- * no local ratelimit_state used in the !PRINTK case
- */
-#ifdef CONFIG_PRINTK
-#define printk_ratelimited(fmt, ...)  ({                               \
-       static DEFINE_RATELIMIT_STATE(_rs,                              \
-                                     DEFAULT_RATELIMIT_INTERVAL,       \
-                                     DEFAULT_RATELIMIT_BURST);         \
-                                                                       \
-       if (__ratelimit(&_rs))                                          \
-               printk(fmt, ##__VA_ARGS__);                             \
-})
-#else
-/* No effect, but we still get type checking even in the !PRINTK case: */
-#define printk_ratelimited printk
-#endif
-
-#define pr_emerg_ratelimited(fmt, ...) \
-       printk_ratelimited(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_alert_ratelimited(fmt, ...) \
-       printk_ratelimited(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_crit_ratelimited(fmt, ...) \
-       printk_ratelimited(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_err_ratelimited(fmt, ...) \
-       printk_ratelimited(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_warning_ratelimited(fmt, ...) \
-       printk_ratelimited(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_warn_ratelimited pr_warning_ratelimited
-#define pr_notice_ratelimited(fmt, ...) \
-       printk_ratelimited(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_info_ratelimited(fmt, ...) \
-       printk_ratelimited(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
-/* no pr_cont_ratelimited, don't do that... */
-/* If you are writing a driver, please use dev_dbg instead */
-#if defined(DEBUG)
-#define pr_debug_ratelimited(fmt, ...) \
-       printk_ratelimited(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
-#else
-#define pr_debug_ratelimited(fmt, ...) \
-       ({ if (0) printk_ratelimited(KERN_DEBUG pr_fmt(fmt), \
-                                    ##__VA_ARGS__); 0; })
-#endif
-
 /*
  * General tracing related utility functions - trace_printk(),
  * tracing_on/tracing_off and tracing_start()/tracing_stop
index cc96f0f23e04a545ffd3dfc7faff7d27fb7d61f1..092e4250a4583f735140221d5f4dd7a4667d3d69 100644 (file)
@@ -35,16 +35,6 @@ struct pt_regs;
  */
 extern int kgdb_skipexception(int exception, struct pt_regs *regs);
 
-/**
- *     kgdb_disable_hw_debug - (optional) Disable hardware debugging hook
- *     @regs: Current &struct pt_regs.
- *
- *     This function will be called if the particular architecture must
- *     disable hardware debugging while it is processing gdb packets or
- *     handling exception.
- */
-extern void kgdb_disable_hw_debug(struct pt_regs *regs);
-
 struct tasklet_struct;
 struct task_struct;
 struct uart_port;
@@ -243,6 +233,8 @@ extern void kgdb_arch_late(void);
  * breakpoint.
  * @remove_hw_breakpoint: Allow an architecture to specify how to remove a
  * hardware breakpoint.
+ * @disable_hw_break: Allow an architecture to specify how to disable
+ * hardware breakpoints for a single cpu.
  * @remove_all_hw_break: Allow an architecture to specify how to remove all
  * hardware breakpoints.
  * @correct_hw_break: Allow an architecture to specify how to correct the
@@ -256,6 +248,7 @@ struct kgdb_arch {
        int     (*remove_breakpoint)(unsigned long, char *);
        int     (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype);
        int     (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype);
+       void    (*disable_hw_break)(struct pt_regs *regs);
        void    (*remove_all_hw_break)(void);
        void    (*correct_hw_break)(void);
 };
diff --git a/include/linux/leds-lp5521.h b/include/linux/leds-lp5521.h
new file mode 100644 (file)
index 0000000..38368d7
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * LP5521 LED chip driver.
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 __LINUX_LP5521_H
+#define __LINUX_LP5521_H
+
+/* See Documentation/leds/leds-lp5521.txt */
+
+struct lp5521_led_config {
+       u8              chan_nr;
+       u8              led_current; /* mA x10, 0 if led is not connected */
+       u8              max_current;
+};
+
+#define LP5521_CLOCK_AUTO      0
+#define LP5521_CLOCK_INT       1
+#define LP5521_CLOCK_EXT       2
+
+struct lp5521_platform_data {
+       struct lp5521_led_config *led_config;
+       u8      num_channels;
+       u8      clock_mode;
+       int     (*setup_resources)(void);
+       void    (*release_resources)(void);
+       void    (*enable)(bool state);
+};
+
+#endif /* __LINUX_LP5521_H */
diff --git a/include/linux/leds-lp5523.h b/include/linux/leds-lp5523.h
new file mode 100644 (file)
index 0000000..7967476
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * LP5523 LED Driver
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 __LINUX_LP5523_H
+#define __LINUX_LP5523_H
+
+/* See Documentation/leds/leds-lp5523.txt */
+
+struct lp5523_led_config {
+       u8              chan_nr;
+       u8              led_current; /* mA x10, 0 if led is not connected */
+       u8              max_current;
+};
+
+#define LP5523_CLOCK_AUTO      0
+#define LP5523_CLOCK_INT       1
+#define LP5523_CLOCK_EXT       2
+
+struct lp5523_platform_data {
+       struct lp5523_led_config *led_config;
+       u8      num_channels;
+       u8      clock_mode;
+       int     (*setup_resources)(void);
+       void    (*release_resources)(void);
+       void    (*enable)(bool state);
+};
+
+#endif /* __LINUX_LP5523_H */
index ba6986a11663a417625a259a612019df46f0ad97..0f19df9e37b0fec0394d0350abf86a3aa63cc518 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
+#include <linux/timer.h>
 
 struct device;
 /*
@@ -45,10 +46,14 @@ struct led_classdev {
        /* Get LED brightness level */
        enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);
 
-       /* Activate hardware accelerated blink, delays are in
-        * miliseconds and if none is provided then a sensible default
-        * should be chosen. The call can adjust the timings if it can't
-        * match the values specified exactly. */
+       /*
+        * Activate hardware accelerated blink, delays are in milliseconds
+        * and if both are zero then a sensible default should be chosen.
+        * The call should adjust the timings in that case and if it can't
+        * match the values specified exactly.
+        * Deactivate blinking again when the brightness is set to a fixed
+        * value via the brightness_set() callback.
+        */
        int             (*blink_set)(struct led_classdev *led_cdev,
                                     unsigned long *delay_on,
                                     unsigned long *delay_off);
@@ -57,6 +62,10 @@ struct led_classdev {
        struct list_head         node;                  /* LED Device list */
        const char              *default_trigger;       /* Trigger to use */
 
+       unsigned long            blink_delay_on, blink_delay_off;
+       struct timer_list        blink_timer;
+       int                      blink_brightness;
+
 #ifdef CONFIG_LEDS_TRIGGERS
        /* Protects the trigger data below */
        struct rw_semaphore      trigger_lock;
@@ -73,6 +82,36 @@ extern void led_classdev_unregister(struct led_classdev *led_cdev);
 extern void led_classdev_suspend(struct led_classdev *led_cdev);
 extern void led_classdev_resume(struct led_classdev *led_cdev);
 
+/**
+ * led_blink_set - set blinking with software fallback
+ * @led_cdev: the LED to start blinking
+ * @delay_on: the time it should be on (in ms)
+ * @delay_off: the time it should ble off (in ms)
+ *
+ * This function makes the LED blink, attempting to use the
+ * hardware acceleration if possible, but falling back to
+ * software blinking if there is no hardware blinking or if
+ * the LED refuses the passed values.
+ *
+ * Note that if software blinking is active, simply calling
+ * led_cdev->brightness_set() will not stop the blinking,
+ * use led_classdev_brightness_set() instead.
+ */
+extern void led_blink_set(struct led_classdev *led_cdev,
+                         unsigned long *delay_on,
+                         unsigned long *delay_off);
+/**
+ * led_brightness_set - set LED brightness
+ * @led_cdev: the LED to set
+ * @brightness: the brightness to set it to
+ *
+ * Set an LED's brightness, and, if necessary, cancel the
+ * software blink timer that implements blinking when the
+ * hardware doesn't.
+ */
+extern void led_brightness_set(struct led_classdev *led_cdev,
+                              enum led_brightness brightness);
+
 /*
  * LED Triggers
  */
index d0f08018335d4a8144e9b524e93484beab39ebf0..1ff81b51b656a13f32c4d8b5253f803593cd033b 100644 (file)
@@ -12,7 +12,7 @@
 #define MARVELL_PHY_ID_88E1121R                0x01410cb0
 #define MARVELL_PHY_ID_88E1145         0x01410cd0
 #define MARVELL_PHY_ID_88E1240         0x01410e30
-#define MARVELL_PHY_ID_88EC048         0x01410e90
+#define MARVELL_PHY_ID_88E1318S                0x01410e90
 
 /* struct phy_device dev_flags definitions */
 #define MARVELL_PHY_M1145_FLAGS_RESISTANCE     0x00000001
index d19e2114fd867782dc8a71b7b12367a9eff561ad..5c99da1078aa2e2906e0cc8f06428c231f76970a 100644 (file)
@@ -59,19 +59,19 @@ struct sh_mmcif_plat_data {
 #define MMCIF_CE_HOST_STS2     0x0000004C
 #define MMCIF_CE_VERSION       0x0000007C
 
-extern inline u32 sh_mmcif_readl(void __iomem *addr, int reg)
+static inline u32 sh_mmcif_readl(void __iomem *addr, int reg)
 {
        return readl(addr + reg);
 }
 
-extern inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val)
+static inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val)
 {
        writel(val, addr + reg);
 }
 
 #define SH_MMCIF_BBS 512 /* boot block size */
 
-extern inline void sh_mmcif_boot_cmd_send(void __iomem *base,
+static inline void sh_mmcif_boot_cmd_send(void __iomem *base,
                                          unsigned long cmd, unsigned long arg)
 {
        sh_mmcif_writel(base, MMCIF_CE_INT, 0);
@@ -79,7 +79,7 @@ extern inline void sh_mmcif_boot_cmd_send(void __iomem *base,
        sh_mmcif_writel(base, MMCIF_CE_CMD_SET, cmd);
 }
 
-extern inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask)
+static inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask)
 {
        unsigned long tmp;
        int cnt;
@@ -95,14 +95,14 @@ extern inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask)
        return -1;
 }
 
-extern inline int sh_mmcif_boot_cmd(void __iomem *base,
+static inline int sh_mmcif_boot_cmd(void __iomem *base,
                                    unsigned long cmd, unsigned long arg)
 {
        sh_mmcif_boot_cmd_send(base, cmd, arg);
        return sh_mmcif_boot_cmd_poll(base, 0x00010000);
 }
 
-extern inline int sh_mmcif_boot_do_read_single(void __iomem *base,
+static inline int sh_mmcif_boot_do_read_single(void __iomem *base,
                                               unsigned int block_nr,
                                               unsigned long *buf)
 {
@@ -125,7 +125,7 @@ extern inline int sh_mmcif_boot_do_read_single(void __iomem *base,
        return 0;
 }
 
-extern inline int sh_mmcif_boot_do_read(void __iomem *base,
+static inline int sh_mmcif_boot_do_read(void __iomem *base,
                                        unsigned long first_block,
                                        unsigned long nr_blocks,
                                        void *buf)
@@ -143,7 +143,7 @@ extern inline int sh_mmcif_boot_do_read(void __iomem *base,
        return ret;
 }
 
-extern inline void sh_mmcif_boot_init(void __iomem *base)
+static inline void sh_mmcif_boot_init(void __iomem *base)
 {
        unsigned long tmp;
 
@@ -177,7 +177,7 @@ extern inline void sh_mmcif_boot_init(void __iomem *base)
        sh_mmcif_boot_cmd(base, 0x03400040, 0x00010000);
 }
 
-extern inline void sh_mmcif_boot_slurp(void __iomem *base,
+static inline void sh_mmcif_boot_slurp(void __iomem *base,
                                       unsigned char *buf,
                                       unsigned long no_bytes)
 {
index 7fa20beb2ab9e19786f1358d61afa02f0bf30e81..57cc0e63714f9651462450db8fbbc78df79b82f1 100644 (file)
@@ -84,7 +84,7 @@ struct nand_bbt_descr {
 #define NAND_BBT_PERCHIP       0x00000080
 /* bbt has a version counter at offset veroffs */
 #define NAND_BBT_VERSION       0x00000100
-/* Create a bbt if none axists */
+/* Create a bbt if none exists */
 #define NAND_BBT_CREATE                0x00000200
 /* Search good / bad pattern through all pages of a block */
 #define NAND_BBT_SCANALLPAGES  0x00000400
@@ -102,6 +102,8 @@ struct nand_bbt_descr {
 #define NAND_BBT_SCANBYTE1AND6 0x00100000
 /* The nand_bbt_descr was created dynamicaly and must be freed */
 #define NAND_BBT_DYNAMICSTRUCT 0x00200000
+/* The bad block table does not OOB for marker */
+#define NAND_BBT_NO_OOB                0x00400000
 
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS        4
index d2118b0eac9ae12fcfd7a7b8c951f3863b096a0a..4dd0c2cd7659e368d42483ba7d37ae702ed16e98 100644 (file)
@@ -289,6 +289,7 @@ struct cfi_private {
                                  must be of the same type. */
        int mfr, id;
        int numchips;
+       map_word sector_erase_cmd;
        unsigned long chipshift; /* Because they're of the same type */
        const char *im_name;     /* inter_module name for cmdset_setup */
        struct flchip chips[0];  /* per-chip data structure for each chip */
diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h
new file mode 100644 (file)
index 0000000..5d25567
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * incude/mtd/fsmc.h
+ *
+ * ST Microelectronics
+ * Flexible Static Memory Controller (FSMC)
+ * platform data interface and header file
+ *
+ * Copyright © 2010 ST Microelectronics
+ * Vipin Kumar <vipin.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MTD_FSMC_H
+#define __MTD_FSMC_H
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/types.h>
+#include <linux/mtd/partitions.h>
+#include <asm/param.h>
+
+#define FSMC_NAND_BW8          1
+#define FSMC_NAND_BW16         2
+
+/*
+ * The placement of the Command Latch Enable (CLE) and
+ * Address Latch Enable (ALE) is twised around in the
+ * SPEAR310 implementation.
+ */
+#if defined(CONFIG_MACH_SPEAR310)
+#define PLAT_NAND_CLE          (1 << 17)
+#define PLAT_NAND_ALE          (1 << 16)
+#else
+#define PLAT_NAND_CLE          (1 << 16)
+#define PLAT_NAND_ALE          (1 << 17)
+#endif
+
+#define FSMC_MAX_NOR_BANKS     4
+#define FSMC_MAX_NAND_BANKS    4
+
+#define FSMC_FLASH_WIDTH8      1
+#define FSMC_FLASH_WIDTH16     2
+
+struct fsmc_nor_bank_regs {
+       uint32_t ctrl;
+       uint32_t ctrl_tim;
+};
+
+/* ctrl register definitions */
+#define BANK_ENABLE            (1 << 0)
+#define MUXED                  (1 << 1)
+#define NOR_DEV                        (2 << 2)
+#define WIDTH_8                        (0 << 4)
+#define WIDTH_16               (1 << 4)
+#define RSTPWRDWN              (1 << 6)
+#define WPROT                  (1 << 7)
+#define WRT_ENABLE             (1 << 12)
+#define WAIT_ENB               (1 << 13)
+
+/* ctrl_tim register definitions */
+
+struct fsms_nand_bank_regs {
+       uint32_t pc;
+       uint32_t sts;
+       uint32_t comm;
+       uint32_t attrib;
+       uint32_t ioata;
+       uint32_t ecc1;
+       uint32_t ecc2;
+       uint32_t ecc3;
+};
+
+#define FSMC_NOR_REG_SIZE      0x40
+
+struct fsmc_regs {
+       struct fsmc_nor_bank_regs nor_bank_regs[FSMC_MAX_NOR_BANKS];
+       uint8_t reserved_1[0x40 - 0x20];
+       struct fsms_nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS];
+       uint8_t reserved_2[0xfe0 - 0xc0];
+       uint32_t peripid0;                      /* 0xfe0 */
+       uint32_t peripid1;                      /* 0xfe4 */
+       uint32_t peripid2;                      /* 0xfe8 */
+       uint32_t peripid3;                      /* 0xfec */
+       uint32_t pcellid0;                      /* 0xff0 */
+       uint32_t pcellid1;                      /* 0xff4 */
+       uint32_t pcellid2;                      /* 0xff8 */
+       uint32_t pcellid3;                      /* 0xffc */
+};
+
+#define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ)
+
+/* pc register definitions */
+#define FSMC_RESET             (1 << 0)
+#define FSMC_WAITON            (1 << 1)
+#define FSMC_ENABLE            (1 << 2)
+#define FSMC_DEVTYPE_NAND      (1 << 3)
+#define FSMC_DEVWID_8          (0 << 4)
+#define FSMC_DEVWID_16         (1 << 4)
+#define FSMC_ECCEN             (1 << 6)
+#define FSMC_ECCPLEN_512       (0 << 7)
+#define FSMC_ECCPLEN_256       (1 << 7)
+#define FSMC_TCLR_1            (1 << 9)
+#define FSMC_TAR_1             (1 << 13)
+
+/* sts register definitions */
+#define FSMC_CODE_RDY          (1 << 15)
+
+/* comm register definitions */
+#define FSMC_TSET_0            (0 << 0)
+#define FSMC_TWAIT_6           (6 << 8)
+#define FSMC_THOLD_4           (4 << 16)
+#define FSMC_THIZ_1            (1 << 24)
+
+/* peripid2 register definitions */
+#define FSMC_REVISION_MSK      (0xf)
+#define FSMC_REVISION_SHFT     (0x4)
+
+#define FSMC_VER1              1
+#define FSMC_VER2              2
+#define FSMC_VER3              3
+#define FSMC_VER4              4
+#define FSMC_VER5              5
+#define FSMC_VER6              6
+#define FSMC_VER7              7
+#define FSMC_VER8              8
+
+static inline uint32_t get_fsmc_version(struct fsmc_regs *regs)
+{
+       return (readl(&regs->peripid2) >> FSMC_REVISION_SHFT) &
+                               FSMC_REVISION_MSK;
+}
+
+/*
+ * There are 13 bytes of ecc for every 512 byte block in FSMC version 8
+ * and it has to be read consecutively and immediately after the 512
+ * byte data block for hardware to generate the error bit offsets
+ * Managing the ecc bytes in the following way is easier. This way is
+ * similar to oobfree structure maintained already in u-boot nand driver
+ */
+#define MAX_ECCPLACE_ENTRIES   32
+
+struct fsmc_nand_eccplace {
+       uint8_t offset;
+       uint8_t length;
+};
+
+struct fsmc_eccplace {
+       struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
+};
+
+/**
+ * fsmc_nand_platform_data - platform specific NAND controller config
+ * @partitions: partition table for the platform, use a default fallback
+ * if this is NULL
+ * @nr_partitions: the number of partitions in the previous entry
+ * @options: different options for the driver
+ * @width: bus width
+ * @bank: default bank
+ * @select_bank: callback to select a certain bank, this is
+ * platform-specific. If the controller only supports one bank
+ * this may be set to NULL
+ */
+struct fsmc_nand_platform_data {
+       struct mtd_partition    *partitions;
+       unsigned int            nr_partitions;
+       unsigned int            options;
+       unsigned int            width;
+       unsigned int            bank;
+       void                    (*select_bank)(uint32_t bank, uint32_t busw);
+};
+
+extern int __init fsmc_nor_init(struct platform_device *pdev,
+               unsigned long base, uint32_t bank, uint32_t width);
+extern void __init fsmc_init_board_info(struct platform_device *pdev,
+               struct mtd_partition *partitions, unsigned int nr_partitions,
+               unsigned int width);
+
+#endif /* __MTD_FSMC_H */
index 64ee53ce95a94cbe483ec39cbe8a5d50ecad3dd1..02cd5f9b79b875ed03e5b9042df1cf98eff60709 100644 (file)
@@ -37,14 +37,14 @@ struct INFTLrecord {
        __u16 firstEUN;
        __u16 lastEUN;
        __u16 numfreeEUNs;
-       __u16 LastFreeEUN;              /* To speed up finding a free EUN */
+       __u16 LastFreeEUN;              /* To speed up finding a free EUN */
        int head,sect,cyl;
-       __u16 *PUtable;                 /* Physical Unit Table  */
-       __u16 *VUtable;                 /* Virtual Unit Table */
-        unsigned int nb_blocks;                /* number of physical blocks */
-        unsigned int nb_boot_blocks;   /* number of blocks used by the bios */
-        struct erase_info instr;
-        struct nand_ecclayout oobinfo;
+       __u16 *PUtable;                 /* Physical Unit Table */
+       __u16 *VUtable;                 /* Virtual Unit Table */
+       unsigned int nb_blocks;         /* number of physical blocks */
+       unsigned int nb_boot_blocks;    /* number of blocks used by the bios */
+       struct erase_info instr;
+       struct nand_ecclayout oobinfo;
 };
 
 int INFTL_mount(struct INFTLrecord *s);
index 8485e42a9b092327e797383d7de8848dfb4d36cb..fe8d77ebec13fa5d1dc51f7a6222bf54164e8d02 100644 (file)
@@ -110,6 +110,21 @@ struct mtd_oob_ops {
        uint8_t         *oobbuf;
 };
 
+#define MTD_MAX_OOBFREE_ENTRIES_LARGE  32
+#define MTD_MAX_ECCPOS_ENTRIES_LARGE   448
+/*
+ * Internal ECC layout control structure. For historical reasons, there is a
+ * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained
+ * for export to user-space via the ECCGETLAYOUT ioctl.
+ * nand_ecclayout should be expandable in the future simply by the above macros.
+ */
+struct nand_ecclayout {
+       __u32 eccbytes;
+       __u32 eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
+       __u32 oobavail;
+       struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
+};
+
 struct mtd_info {
        u_char type;
        uint32_t flags;
index 102e12c58cb3bbef023e0802c81f532a8cf428b0..63e17d01fde94b5be8e80646e1aee1ea11665b0e 100644 (file)
 struct mtd_info;
 struct nand_flash_dev;
 /* Scan and identify a NAND device */
-extern int nand_scan (struct mtd_info *mtd, int max_chips);
-/* Separate phases of nand_scan(), allowing board driver to intervene
- * and override command or ECC setup according to flash type */
+extern int nand_scan(struct mtd_info *mtd, int max_chips);
+/*
+ * Separate phases of nand_scan(), allowing board driver to intervene
+ * and override command or ECC setup according to flash type.
+ */
 extern int nand_scan_ident(struct mtd_info *mtd, int max_chips,
                           struct nand_flash_dev *table);
 extern int nand_scan_tail(struct mtd_info *mtd);
 
 /* Free resources held by the NAND device */
-extern void nand_release (struct mtd_info *mtd);
+extern void nand_release(struct mtd_info *mtd);
 
 /* Internal helper for board drivers which need to override command function */
 extern void nand_wait_ready(struct mtd_info *mtd);
@@ -49,12 +51,13 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 /* The maximum number of NAND chips in an array */
 #define NAND_MAX_CHIPS         8
 
-/* This constant declares the max. oobsize / page, which
+/*
+ * This constant declares the max. oobsize / page, which
  * is supported now. If you add a chip with bigger oobsize/page
  * adjust this accordingly.
  */
-#define NAND_MAX_OOBSIZE       256
-#define NAND_MAX_PAGESIZE      4096
+#define NAND_MAX_OOBSIZE       576
+#define NAND_MAX_PAGESIZE      8192
 
 /*
  * Constants for hardware specific CLE/ALE/NCE function
@@ -88,6 +91,7 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 #define NAND_CMD_RNDIN         0x85
 #define NAND_CMD_READID                0x90
 #define NAND_CMD_ERASE2                0xd0
+#define NAND_CMD_PARAM         0xec
 #define NAND_CMD_RESET         0xff
 
 #define NAND_CMD_LOCK          0x2a
@@ -152,9 +156,10 @@ typedef enum {
 #define NAND_GET_DEVICE                0x80
 
 
-/* Option constants for bizarre disfunctionality and real
-*  features
-*/
+/*
+ * Option constants for bizarre disfunctionality and real
+ * features.
+ */
 /* Chip can not auto increment pages */
 #define NAND_NO_AUTOINCR       0x00000001
 /* Buswitdh is 16 bit */
@@ -165,19 +170,27 @@ typedef enum {
 #define NAND_CACHEPRG          0x00000008
 /* Chip has copy back function */
 #define NAND_COPYBACK          0x00000010
-/* AND Chip which has 4 banks and a confusing page / block
- * assignment. See Renesas datasheet for further information */
+/*
+ * AND Chip which has 4 banks and a confusing page / block
+ * assignment. See Renesas datasheet for further information.
+ */
 #define NAND_IS_AND            0x00000020
-/* Chip has a array of 4 pages which can be read without
- * additional ready /busy waits */
+/*
+ * Chip has a array of 4 pages which can be read without
+ * additional ready /busy waits.
+ */
 #define NAND_4PAGE_ARRAY       0x00000040
-/* Chip requires that BBT is periodically rewritten to prevent
+/*
+ * Chip requires that BBT is periodically rewritten to prevent
  * bits from adjacent blocks from 'leaking' in altering data.
- * This happens with the Renesas AG-AND chips, possibly others.  */
+ * This happens with the Renesas AG-AND chips, possibly others.
+ */
 #define BBT_AUTO_REFRESH       0x00000080
-/* Chip does not require ready check on read. True
+/*
+ * Chip does not require ready check on read. True
  * for all large page devices, as they do not support
- * autoincrement.*/
+ * autoincrement.
+ */
 #define NAND_NO_READRDY                0x00000100
 /* Chip does not allow subpage writes */
 #define NAND_NO_SUBPAGE_WRITE  0x00000200
@@ -205,16 +218,27 @@ typedef enum {
 #define NAND_CHIPOPTIONS_MSK   (0x0000ffff & ~NAND_NO_AUTOINCR)
 
 /* Non chip related options */
-/* Use a flash based bad block table. This option is passed to the
- * default bad block table function. */
+/*
+ * Use a flash based bad block table. OOB identifier is saved in OOB area.
+ * This option is passed to the default bad block table function.
+ */
 #define NAND_USE_FLASH_BBT     0x00010000
 /* This option skips the bbt scan during initialization. */
 #define NAND_SKIP_BBTSCAN      0x00020000
-/* This option is defined if the board driver allocates its own buffers
-   (e.g. because it needs them DMA-coherent */
+/*
+ * This option is defined if the board driver allocates its own buffers
+ * (e.g. because it needs them DMA-coherent).
+ */
 #define NAND_OWN_BUFFERS       0x00040000
 /* Chip may not exist, so silence any errors in scan */
 #define NAND_SCAN_SILENT_NODEV 0x00080000
+/*
+ * If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch
+ * the OOB area.
+ */
+#define NAND_USE_FLASH_BBT_NO_OOB      0x00100000
+/* Create an empty BBT with no vendor information if the BBT is available */
+#define NAND_CREATE_EMPTY_BBT          0x00200000
 
 /* Options set by nand scan */
 /* Nand scan has allocated controller struct */
@@ -227,15 +251,80 @@ typedef enum {
 /* Keep gcc happy */
 struct nand_chip;
 
+struct nand_onfi_params {
+       /* rev info and features block */
+       /* 'O' 'N' 'F' 'I'  */
+       u8 sig[4];
+       __le16 revision;
+       __le16 features;
+       __le16 opt_cmd;
+       u8 reserved[22];
+
+       /* manufacturer information block */
+       char manufacturer[12];
+       char model[20];
+       u8 jedec_id;
+       __le16 date_code;
+       u8 reserved2[13];
+
+       /* memory organization block */
+       __le32 byte_per_page;
+       __le16 spare_bytes_per_page;
+       __le32 data_bytes_per_ppage;
+       __le16 spare_bytes_per_ppage;
+       __le32 pages_per_block;
+       __le32 blocks_per_lun;
+       u8 lun_count;
+       u8 addr_cycles;
+       u8 bits_per_cell;
+       __le16 bb_per_lun;
+       __le16 block_endurance;
+       u8 guaranteed_good_blocks;
+       __le16 guaranteed_block_endurance;
+       u8 programs_per_page;
+       u8 ppage_attr;
+       u8 ecc_bits;
+       u8 interleaved_bits;
+       u8 interleaved_ops;
+       u8 reserved3[13];
+
+       /* electrical parameter block */
+       u8 io_pin_capacitance_max;
+       __le16 async_timing_mode;
+       __le16 program_cache_timing_mode;
+       __le16 t_prog;
+       __le16 t_bers;
+       __le16 t_r;
+       __le16 t_ccs;
+       __le16 src_sync_timing_mode;
+       __le16 src_ssync_features;
+       __le16 clk_pin_capacitance_typ;
+       __le16 io_pin_capacitance_typ;
+       __le16 input_pin_capacitance_typ;
+       u8 input_pin_capacitance_max;
+       u8 driver_strenght_support;
+       __le16 t_int_r;
+       __le16 t_ald;
+       u8 reserved4[7];
+
+       /* vendor */
+       u8 reserved5[90];
+
+       __le16 crc;
+} __attribute__((packed));
+
+#define ONFI_CRC_BASE  0x4F4E
+
 /**
  * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
  * @lock:               protection lock
  * @active:            the mtd device which holds the controller currently
- * @wq:                        wait queue to sleep on if a NAND operation is in progress
- *                      used instead of the per chip wait queue when a hw controller is available
+ * @wq:                        wait queue to sleep on if a NAND operation is in
+ *                     progress used instead of the per chip wait queue
+ *                     when a hw controller is available.
  */
 struct nand_hw_control {
-       spinlock_t       lock;
+       spinlock_t lock;
        struct nand_chip *active;
        wait_queue_head_t wq;
 };
@@ -256,51 +345,42 @@ struct nand_hw_control {
  * @correct:   function for ecc correction, matching to ecc generator (sw/hw)
  * @read_page_raw:     function to read a raw page without ECC
  * @write_page_raw:    function to write a raw page without ECC
- * @read_page: function to read a page according to the ecc generator requirements
+ * @read_page: function to read a page according to the ecc generator
+ *             requirements.
  * @read_subpage:      function to read parts of the page covered by ECC.
- * @write_page:        function to write a page according to the ecc generator requirements
+ * @write_page:        function to write a page according to the ecc generator
+ *             requirements.
  * @read_oob:  function to read chip OOB data
  * @write_oob: function to write chip OOB data
  */
 struct nand_ecc_ctrl {
-       nand_ecc_modes_t        mode;
-       int                     steps;
-       int                     size;
-       int                     bytes;
-       int                     total;
-       int                     prepad;
-       int                     postpad;
+       nand_ecc_modes_t mode;
+       int steps;
+       int size;
+       int bytes;
+       int total;
+       int prepad;
+       int postpad;
        struct nand_ecclayout   *layout;
-       void                    (*hwctl)(struct mtd_info *mtd, int mode);
-       int                     (*calculate)(struct mtd_info *mtd,
-                                            const uint8_t *dat,
-                                            uint8_t *ecc_code);
-       int                     (*correct)(struct mtd_info *mtd, uint8_t *dat,
-                                          uint8_t *read_ecc,
-                                          uint8_t *calc_ecc);
-       int                     (*read_page_raw)(struct mtd_info *mtd,
-                                                struct nand_chip *chip,
-                                                uint8_t *buf, int page);
-       void                    (*write_page_raw)(struct mtd_info *mtd,
-                                                 struct nand_chip *chip,
-                                                 const uint8_t *buf);
-       int                     (*read_page)(struct mtd_info *mtd,
-                                            struct nand_chip *chip,
-                                            uint8_t *buf, int page);
-       int                     (*read_subpage)(struct mtd_info *mtd,
-                                            struct nand_chip *chip,
-                                            uint32_t offs, uint32_t len,
-                                            uint8_t *buf);
-       void                    (*write_page)(struct mtd_info *mtd,
-                                             struct nand_chip *chip,
-                                             const uint8_t *buf);
-       int                     (*read_oob)(struct mtd_info *mtd,
-                                           struct nand_chip *chip,
-                                           int page,
-                                           int sndcmd);
-       int                     (*write_oob)(struct mtd_info *mtd,
-                                            struct nand_chip *chip,
-                                            int page);
+       void (*hwctl)(struct mtd_info *mtd, int mode);
+       int (*calculate)(struct mtd_info *mtd, const uint8_t *dat,
+                       uint8_t *ecc_code);
+       int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,
+                       uint8_t *calc_ecc);
+       int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+                       uint8_t *buf, int page);
+       void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+                       const uint8_t *buf);
+       int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
+                       uint8_t *buf, int page);
+       int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
+                       uint32_t offs, uint32_t len, uint8_t *buf);
+       void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+                       const uint8_t *buf);
+       int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page,
+                       int sndcmd);
+       int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip,
+                       int page);
 };
 
 /**
@@ -320,102 +400,132 @@ struct nand_buffers {
 
 /**
  * struct nand_chip - NAND Private Flash Chip Data
- * @IO_ADDR_R:         [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
- * @IO_ADDR_W:         [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
+ * @IO_ADDR_R:         [BOARDSPECIFIC] address to read the 8 I/O lines of the
+ *                     flash device
+ * @IO_ADDR_W:         [BOARDSPECIFIC] address to write the 8 I/O lines of the
+ *                     flash device.
  * @read_byte:         [REPLACEABLE] read one byte from the chip
  * @read_word:         [REPLACEABLE] read one word from the chip
  * @write_buf:         [REPLACEABLE] write data from the buffer to the chip
  * @read_buf:          [REPLACEABLE] read data from the chip into the buffer
- * @verify_buf:                [REPLACEABLE] verify buffer contents against the chip data
+ * @verify_buf:                [REPLACEABLE] verify buffer contents against the chip
+ *                     data.
  * @select_chip:       [REPLACEABLE] select chip nr
  * @block_bad:         [REPLACEABLE] check, if the block is bad
  * @block_markbad:     [REPLACEABLE] mark the block bad
  * @cmd_ctrl:          [BOARDSPECIFIC] hardwarespecific funtion for controlling
  *                     ALE/CLE/nCE. Also used to write command and address
- * @dev_ready:         [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line
- *                     If set to NULL no access to ready/busy is available and the ready/busy information
- *                     is read from the chip status register
- * @cmdfunc:           [REPLACEABLE] hardwarespecific function for writing commands to the chip
- * @waitfunc:          [REPLACEABLE] hardwarespecific function for wait on ready
+ * @init_size:         [BOARDSPECIFIC] hardwarespecific funtion for setting
+ *                     mtd->oobsize, mtd->writesize and so on.
+ *                     @id_data contains the 8 bytes values of NAND_CMD_READID.
+ *                     Return with the bus width.
+ * @dev_ready:         [BOARDSPECIFIC] hardwarespecific function for accesing
+ *                     device ready/busy line. If set to NULL no access to
+ *                     ready/busy is available and the ready/busy information
+ *                     is read from the chip status register.
+ * @cmdfunc:           [REPLACEABLE] hardwarespecific function for writing
+ *                     commands to the chip.
+ * @waitfunc:          [REPLACEABLE] hardwarespecific function for wait on
+ *                     ready.
  * @ecc:               [BOARDSPECIFIC] ecc control ctructure
  * @buffers:           buffer structure for read/write
  * @hwcontrol:         platform-specific hardware control structure
  * @ops:               oob operation operands
- * @erase_cmd:         [INTERN] erase command write function, selectable due to AND support
+ * @erase_cmd:         [INTERN] erase command write function, selectable due
+ *                     to AND support.
  * @scan_bbt:          [REPLACEABLE] function to scan bad block table
- * @chip_delay:                [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR)
+ * @chip_delay:                [BOARDSPECIFIC] chip dependent delay for transfering
+ *                     data from array to read regs (tR).
  * @state:             [INTERN] the current state of the NAND device
  * @oob_poi:           poison value buffer
- * @page_shift:                [INTERN] number of address bits in a page (column address bits)
+ * @page_shift:                [INTERN] number of address bits in a page (column
+ *                     address bits).
  * @phys_erase_shift:  [INTERN] number of address bits in a physical eraseblock
  * @bbt_erase_shift:   [INTERN] number of address bits in a bbt entry
  * @chip_shift:                [INTERN] number of address bits in one chip
- * @options:           [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about
- *                     special functionality. See the defines for further explanation
- * @badblockpos:       [INTERN] position of the bad block marker in the oob area
+ * @options:           [BOARDSPECIFIC] various chip options. They can partly
+ *                     be set to inform nand_scan about special functionality.
+ *                     See the defines for further explanation.
+ * @badblockpos:       [INTERN] position of the bad block marker in the oob
+ *                     area.
  * @cellinfo:          [INTERN] MLC/multichip data from chip ident
  * @numchips:          [INTERN] number of physical chips
  * @chipsize:          [INTERN] the size of one chip for multichip arrays
  * @pagemask:          [INTERN] page number mask = number of (pages / chip) - 1
- * @pagebuf:           [INTERN] holds the pagenumber which is currently in data_buf
+ * @pagebuf:           [INTERN] holds the pagenumber which is currently in
+ *                     data_buf.
  * @subpagesize:       [INTERN] holds the subpagesize
+ * @onfi_version:      [INTERN] holds the chip ONFI version (BCD encoded),
+ *                     non 0 if ONFI supported.
+ * @onfi_params:       [INTERN] holds the ONFI page parameter when ONFI is
+ *                     supported, 0 otherwise.
  * @ecclayout:         [REPLACEABLE] the default ecc placement scheme
  * @bbt:               [INTERN] bad block table pointer
- * @bbt_td:            [REPLACEABLE] bad block table descriptor for flash lookup
+ * @bbt_td:            [REPLACEABLE] bad block table descriptor for flash
+ *                     lookup.
  * @bbt_md:            [REPLACEABLE] bad block table mirror descriptor
- * @badblock_pattern:  [REPLACEABLE] bad block scan pattern used for initial bad block scan
- * @controller:                [REPLACEABLE] a pointer to a hardware controller structure
- *                     which is shared among multiple independend devices
+ * @badblock_pattern:  [REPLACEABLE] bad block scan pattern used for initial
+ *                     bad block scan.
+ * @controller:                [REPLACEABLE] a pointer to a hardware controller
+ *                     structure which is shared among multiple independend
+ *                     devices.
  * @priv:              [OPTIONAL] pointer to private chip date
- * @errstat:           [OPTIONAL] hardware specific function to perform additional error status checks
- *                     (determine if errors are correctable)
+ * @errstat:           [OPTIONAL] hardware specific function to perform
+ *                     additional error status checks (determine if errors are
+ *                     correctable).
  * @write_page:                [REPLACEABLE] High-level page write function
  */
 
 struct nand_chip {
-       void  __iomem   *IO_ADDR_R;
-       void  __iomem   *IO_ADDR_W;
-
-       uint8_t         (*read_byte)(struct mtd_info *mtd);
-       u16             (*read_word)(struct mtd_info *mtd);
-       void            (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
-       void            (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
-       int             (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
-       void            (*select_chip)(struct mtd_info *mtd, int chip);
-       int             (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
-       int             (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
-       void            (*cmd_ctrl)(struct mtd_info *mtd, int dat,
-                                   unsigned int ctrl);
-       int             (*dev_ready)(struct mtd_info *mtd);
-       void            (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
-       int             (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
-       void            (*erase_cmd)(struct mtd_info *mtd, int page);
-       int             (*scan_bbt)(struct mtd_info *mtd);
-       int             (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
-       int             (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
-                                     const uint8_t *buf, int page, int cached, int raw);
-
-       int             chip_delay;
-       unsigned int    options;
-
-       int             page_shift;
-       int             phys_erase_shift;
-       int             bbt_erase_shift;
-       int             chip_shift;
-       int             numchips;
-       uint64_t        chipsize;
-       int             pagemask;
-       int             pagebuf;
-       int             subpagesize;
-       uint8_t         cellinfo;
-       int             badblockpos;
-       int             badblockbits;
-
-       flstate_t       state;
-
-       uint8_t         *oob_poi;
-       struct nand_hw_control  *controller;
-       struct nand_ecclayout   *ecclayout;
+       void __iomem *IO_ADDR_R;
+       void __iomem *IO_ADDR_W;
+
+       uint8_t (*read_byte)(struct mtd_info *mtd);
+       u16 (*read_word)(struct mtd_info *mtd);
+       void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
+       void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
+       int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
+       void (*select_chip)(struct mtd_info *mtd, int chip);
+       int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
+       int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
+       void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
+       int (*init_size)(struct mtd_info *mtd, struct nand_chip *this,
+                       u8 *id_data);
+       int (*dev_ready)(struct mtd_info *mtd);
+       void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column,
+                       int page_addr);
+       int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
+       void (*erase_cmd)(struct mtd_info *mtd, int page);
+       int (*scan_bbt)(struct mtd_info *mtd);
+       int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
+                       int status, int page);
+       int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+                       const uint8_t *buf, int page, int cached, int raw);
+
+       int chip_delay;
+       unsigned int options;
+
+       int page_shift;
+       int phys_erase_shift;
+       int bbt_erase_shift;
+       int chip_shift;
+       int numchips;
+       uint64_t chipsize;
+       int pagemask;
+       int pagebuf;
+       int subpagesize;
+       uint8_t cellinfo;
+       int badblockpos;
+       int badblockbits;
+
+       int onfi_version;
+       struct nand_onfi_params onfi_params;
+
+       flstate_t state;
+
+       uint8_t *oob_poi;
+       struct nand_hw_control *controller;
+       struct nand_ecclayout *ecclayout;
 
        struct nand_ecc_ctrl ecc;
        struct nand_buffers *buffers;
@@ -423,13 +533,13 @@ struct nand_chip {
 
        struct mtd_oob_ops ops;
 
-       uint8_t         *bbt;
-       struct nand_bbt_descr   *bbt_td;
-       struct nand_bbt_descr   *bbt_md;
+       uint8_t *bbt;
+       struct nand_bbt_descr *bbt_td;
+       struct nand_bbt_descr *bbt_md;
 
-       struct nand_bbt_descr   *badblock_pattern;
+       struct nand_bbt_descr *badblock_pattern;
 
-       void            *priv;
+       void *priv;
 };
 
 /*
@@ -473,7 +583,7 @@ struct nand_flash_dev {
 */
 struct nand_manufacturers {
        int id;
-       char * name;
+       char *name;
 };
 
 extern struct nand_flash_dev nand_flash_ids[];
@@ -486,7 +596,7 @@ extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
 extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
                           int allowbbt);
 extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
-                       size_t * retlen, uint8_t * buf);
+                       size_t *retlen, uint8_t *buf);
 
 /**
  * struct platform_nand_chip - chip level device structure
@@ -502,17 +612,16 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
  * @priv:              hardware controller specific settings
  */
 struct platform_nand_chip {
-       int                     nr_chips;
-       int                     chip_offset;
-       int                     nr_partitions;
-       struct mtd_partition    *partitions;
-       struct nand_ecclayout   *ecclayout;
-       int                     chip_delay;
-       unsigned int            options;
-       const char              **part_probe_types;
-       void                    (*set_parts)(uint64_t size,
-                                       struct platform_nand_chip *chip);
-       void                    *priv;
+       int nr_chips;
+       int chip_offset;
+       int nr_partitions;
+       struct mtd_partition *partitions;
+       struct nand_ecclayout *ecclayout;
+       int chip_delay;
+       unsigned int options;
+       const char **part_probe_types;
+       void (*set_parts)(uint64_t size, struct platform_nand_chip *chip);
+       void *priv;
 };
 
 /* Keep gcc happy */
@@ -534,18 +643,15 @@ struct platform_device;
  * All fields are optional and depend on the hardware driver requirements
  */
 struct platform_nand_ctrl {
-       int             (*probe)(struct platform_device *pdev);
-       void            (*remove)(struct platform_device *pdev);
-       void            (*hwcontrol)(struct mtd_info *mtd, int cmd);
-       int             (*dev_ready)(struct mtd_info *mtd);
-       void            (*select_chip)(struct mtd_info *mtd, int chip);
-       void            (*cmd_ctrl)(struct mtd_info *mtd, int dat,
-                                   unsigned int ctrl);
-       void            (*write_buf)(struct mtd_info *mtd,
-                                   const uint8_t *buf, int len);
-       void            (*read_buf)(struct mtd_info *mtd,
-                                   uint8_t *buf, int len);
-       void            *priv;
+       int (*probe)(struct platform_device *pdev);
+       void (*remove)(struct platform_device *pdev);
+       void (*hwcontrol)(struct mtd_info *mtd, int cmd);
+       int (*dev_ready)(struct mtd_info *mtd);
+       void (*select_chip)(struct mtd_info *mtd, int chip);
+       void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
+       void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
+       void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
+       void *priv;
 };
 
 /**
@@ -554,8 +660,8 @@ struct platform_nand_ctrl {
  * @ctrl:              controller level device structure
  */
 struct platform_nand_data {
-       struct platform_nand_chip       chip;
-       struct platform_nand_ctrl       ctrl;
+       struct platform_nand_chip chip;
+       struct platform_nand_ctrl ctrl;
 };
 
 /* Some helpers to access the data structures */
index 274b6196091df019e9e2fb65214a8fdbeafeca15..2b54316591d2b4231070a08dec7b6ad33a061ad3 100644 (file)
@@ -39,7 +39,7 @@ struct mtd_partition {
        uint64_t size;                  /* partition size */
        uint64_t offset;                /* offset within the master MTD space */
        uint32_t mask_flags;            /* master MTD flags to mask out for this partition */
-       struct nand_ecclayout *ecclayout;       /* out of band layout for this partition (NAND only)*/
+       struct nand_ecclayout *ecclayout;       /* out of band layout for this partition (NAND only) */
 };
 
 #define MTDPART_OFS_NXTBLK     (-2)
@@ -89,4 +89,9 @@ static inline int mtd_has_cmdlinepart(void) { return 1; }
 static inline int mtd_has_cmdlinepart(void) { return 0; }
 #endif
 
+int mtd_is_master(struct mtd_info *mtd);
+int mtd_add_partition(struct mtd_info *master, char *name,
+                     long long offset, long long length);
+int mtd_del_partition(struct mtd_info *master, int partno);
+
 #endif
index 4016dd6fe336dfd0fbd81f371649f80b573ac851..f456230f9330b0c5bef26a4010e8f524eb38dbc2 100644 (file)
 #include <linux/fs.h>
 #include <linux/mount.h>
 
-extern int get_sb_mtd(struct file_system_type *fs_type, int flags,
+extern struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
                      const char *dev_name, void *data,
-                     int (*fill_super)(struct super_block *, void *, int),
-                     struct vfsmount *mnt);
+                     int (*fill_super)(struct super_block *, void *, int));
 extern void kill_mtd_super(struct super_block *sb);
 
 
index 072652d94d9f5afe908f982c1acce9339bfbfc32..d8fd2c23a1b994ec10e0a204820d6c7daf7dca0e 100644 (file)
@@ -1554,6 +1554,11 @@ static inline void netif_tx_wake_all_queues(struct net_device *dev)
 
 static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue)
 {
+       if (WARN_ON(!dev_queue)) {
+               printk(KERN_INFO "netif_stop_queue() cannot be called before "
+                      "register_netdev()");
+               return;
+       }
        set_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
 }
 
index 89341c32631a5f965b1a65f757db1d7fb004cc30..03317c8d4077a6488148b646ee9327b05a7dcec1 100644 (file)
@@ -215,7 +215,7 @@ NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb,
        int ret;
 
        if (!cond ||
-           (ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN) == 1))
+           ((ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN)) == 1))
                ret = okfn(skb);
        return ret;
 }
index 87e2c2e7aed3757748ca69c8b22a96c5ee1d5752..c6bcfe93b9cab9deeab76844ce8b76e2a2adf5bb 100644 (file)
 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS  0x1c22
 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN        0x1c41
 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX        0x1c5f
+#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS     0x1d22
 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC       0x1d40
 #define PCI_DEVICE_ID_INTEL_82801AA_0  0x2410
 #define PCI_DEVICE_ID_INTEL_82801AA_1  0x2411
index 057bf22a8323463a6bd9279d6928d3fea7ed8eb8..40150f345982cd4fd40e8b80470505e569f05b03 100644 (file)
@@ -747,6 +747,16 @@ struct perf_event {
        u64                             tstamp_running;
        u64                             tstamp_stopped;
 
+       /*
+        * timestamp shadows the actual context timing but it can
+        * be safely used in NMI interrupt context. It reflects the
+        * context time as it was when the event was last scheduled in.
+        *
+        * ctx_time already accounts for ctx->timestamp. Therefore to
+        * compute ctx_time for a sample, simply add perf_clock().
+        */
+       u64                             shadow_ctx_time;
+
        struct perf_event_attr          attr;
        struct hw_perf_event            hw;
 
diff --git a/include/linux/printk.h b/include/linux/printk.h
new file mode 100644 (file)
index 0000000..b772ca5
--- /dev/null
@@ -0,0 +1,248 @@
+#ifndef __KERNEL_PRINTK__
+#define __KERNEL_PRINTK__
+
+extern const char linux_banner[];
+extern const char linux_proc_banner[];
+
+#define        KERN_EMERG      "<0>"   /* system is unusable                   */
+#define        KERN_ALERT      "<1>"   /* action must be taken immediately     */
+#define        KERN_CRIT       "<2>"   /* critical conditions                  */
+#define        KERN_ERR        "<3>"   /* error conditions                     */
+#define        KERN_WARNING    "<4>"   /* warning conditions                   */
+#define        KERN_NOTICE     "<5>"   /* normal but significant condition     */
+#define        KERN_INFO       "<6>"   /* informational                        */
+#define        KERN_DEBUG      "<7>"   /* debug-level messages                 */
+
+/* Use the default kernel loglevel */
+#define KERN_DEFAULT   "<d>"
+/*
+ * Annotation for a "continued" line of log printout (only done after a
+ * line that had no enclosing \n). Only to be used by core/arch code
+ * during early bootup (a continued line is not SMP-safe otherwise).
+ */
+#define        KERN_CONT       "<c>"
+
+extern int console_printk[];
+
+#define console_loglevel (console_printk[0])
+#define default_message_loglevel (console_printk[1])
+#define minimum_console_loglevel (console_printk[2])
+#define default_console_loglevel (console_printk[3])
+
+struct va_format {
+       const char *fmt;
+       va_list *va;
+};
+
+/*
+ * FW_BUG
+ * Add this to a message where you are sure the firmware is buggy or behaves
+ * really stupid or out of spec. Be aware that the responsible BIOS developer
+ * should be able to fix this issue or at least get a concrete idea of the
+ * problem by reading your message without the need of looking at the kernel
+ * code.
+ *
+ * Use it for definite and high priority BIOS bugs.
+ *
+ * FW_WARN
+ * Use it for not that clear (e.g. could the kernel messed up things already?)
+ * and medium priority BIOS bugs.
+ *
+ * FW_INFO
+ * Use this one if you want to tell the user or vendor about something
+ * suspicious, but generally harmless related to the firmware.
+ *
+ * Use it for information or very low priority BIOS bugs.
+ */
+#define FW_BUG         "[Firmware Bug]: "
+#define FW_WARN                "[Firmware Warn]: "
+#define FW_INFO                "[Firmware Info]: "
+
+/*
+ * HW_ERR
+ * Add this to a message for hardware errors, so that user can report
+ * it to hardware vendor instead of LKML or software vendor.
+ */
+#define HW_ERR         "[Hardware Error]: "
+
+#ifdef CONFIG_PRINTK
+asmlinkage int vprintk(const char *fmt, va_list args)
+       __attribute__ ((format (printf, 1, 0)));
+asmlinkage int printk(const char * fmt, ...)
+       __attribute__ ((format (printf, 1, 2))) __cold;
+
+/*
+ * Please don't use printk_ratelimit(), because it shares ratelimiting state
+ * with all other unrelated printk_ratelimit() callsites.  Instead use
+ * printk_ratelimited() or plain old __ratelimit().
+ */
+extern int __printk_ratelimit(const char *func);
+#define printk_ratelimit() __printk_ratelimit(__func__)
+extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
+                                  unsigned int interval_msec);
+
+extern int printk_delay_msec;
+extern int dmesg_restrict;
+
+/*
+ * Print a one-time message (analogous to WARN_ONCE() et al):
+ */
+#define printk_once(x...) ({                   \
+       static bool __print_once;               \
+                                               \
+       if (!__print_once) {                    \
+               __print_once = true;            \
+               printk(x);                      \
+       }                                       \
+})
+
+void log_buf_kexec_setup(void);
+#else
+static inline int vprintk(const char *s, va_list args)
+       __attribute__ ((format (printf, 1, 0)));
+static inline int vprintk(const char *s, va_list args) { return 0; }
+static inline int printk(const char *s, ...)
+       __attribute__ ((format (printf, 1, 2)));
+static inline int __cold printk(const char *s, ...) { return 0; }
+static inline int printk_ratelimit(void) { return 0; }
+static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \
+                                         unsigned int interval_msec)   \
+               { return false; }
+
+/* No effect, but we still get type checking even in the !PRINTK case: */
+#define printk_once(x...) printk(x)
+
+static inline void log_buf_kexec_setup(void)
+{
+}
+#endif
+
+/*
+ * Dummy printk for disabled debugging statements to use whilst maintaining
+ * gcc's format and side-effect checking.
+ */
+static inline __attribute__ ((format (printf, 1, 2)))
+int no_printk(const char *s, ...) { return 0; }
+
+extern int printk_needs_cpu(int cpu);
+extern void printk_tick(void);
+
+extern void asmlinkage __attribute__((format(printf, 1, 2)))
+       early_printk(const char *fmt, ...);
+
+static inline void console_silent(void)
+{
+       console_loglevel = 0;
+}
+
+static inline void console_verbose(void)
+{
+       if (console_loglevel)
+               console_loglevel = 15;
+}
+
+extern void dump_stack(void) __cold;
+
+enum {
+       DUMP_PREFIX_NONE,
+       DUMP_PREFIX_ADDRESS,
+       DUMP_PREFIX_OFFSET
+};
+extern void hex_dump_to_buffer(const void *buf, size_t len,
+                               int rowsize, int groupsize,
+                               char *linebuf, size_t linebuflen, bool ascii);
+extern void print_hex_dump(const char *level, const char *prefix_str,
+                               int prefix_type, int rowsize, int groupsize,
+                               const void *buf, size_t len, bool ascii);
+extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
+                       const void *buf, size_t len);
+
+#ifndef pr_fmt
+#define pr_fmt(fmt) fmt
+#endif
+
+#define pr_emerg(fmt, ...) \
+        printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_alert(fmt, ...) \
+        printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_crit(fmt, ...) \
+        printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_err(fmt, ...) \
+        printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_warning(fmt, ...) \
+        printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_warn pr_warning
+#define pr_notice(fmt, ...) \
+        printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_info(fmt, ...) \
+        printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_cont(fmt, ...) \
+       printk(KERN_CONT fmt, ##__VA_ARGS__)
+
+/* pr_devel() should produce zero code unless DEBUG is defined */
+#ifdef DEBUG
+#define pr_devel(fmt, ...) \
+       printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
+#else
+#define pr_devel(fmt, ...) \
+       ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; })
+#endif
+
+/* If you are writing a driver, please use dev_dbg instead */
+#if defined(DEBUG)
+#define pr_debug(fmt, ...) \
+       printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
+#elif defined(CONFIG_DYNAMIC_DEBUG)
+/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
+#define pr_debug(fmt, ...) \
+       dynamic_pr_debug(fmt, ##__VA_ARGS__)
+#else
+#define pr_debug(fmt, ...) \
+       ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; })
+#endif
+
+/*
+ * ratelimited messages with local ratelimit_state,
+ * no local ratelimit_state used in the !PRINTK case
+ */
+#ifdef CONFIG_PRINTK
+#define printk_ratelimited(fmt, ...)  ({                               \
+       static DEFINE_RATELIMIT_STATE(_rs,                              \
+                                     DEFAULT_RATELIMIT_INTERVAL,       \
+                                     DEFAULT_RATELIMIT_BURST);         \
+                                                                       \
+       if (__ratelimit(&_rs))                                          \
+               printk(fmt, ##__VA_ARGS__);                             \
+})
+#else
+/* No effect, but we still get type checking even in the !PRINTK case: */
+#define printk_ratelimited printk
+#endif
+
+#define pr_emerg_ratelimited(fmt, ...) \
+       printk_ratelimited(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_alert_ratelimited(fmt, ...) \
+       printk_ratelimited(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_crit_ratelimited(fmt, ...) \
+       printk_ratelimited(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_err_ratelimited(fmt, ...) \
+       printk_ratelimited(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_warning_ratelimited(fmt, ...) \
+       printk_ratelimited(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_warn_ratelimited pr_warning_ratelimited
+#define pr_notice_ratelimited(fmt, ...) \
+       printk_ratelimited(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_info_ratelimited(fmt, ...) \
+       printk_ratelimited(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
+/* no pr_cont_ratelimited, don't do that... */
+/* If you are writing a driver, please use dev_dbg instead */
+#if defined(DEBUG)
+#define pr_debug_ratelimited(fmt, ...) \
+       printk_ratelimited(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
+#else
+#define pr_debug_ratelimited(fmt, ...) \
+       ({ if (0) printk_ratelimited(KERN_DEBUG pr_fmt(fmt), \
+                                    ##__VA_ARGS__); 0; })
+#endif
+
+#endif
index 01b3d759f1fccec7f88e1b276973aa6f70e5bae5..e031e1a486d9fc8e7d7d6539c75d39df1235d2c2 100644 (file)
@@ -8,6 +8,7 @@ struct platform_pwm_backlight_data {
        int pwm_id;
        unsigned int max_brightness;
        unsigned int dft_brightness;
+       unsigned int lth_brightness;
        unsigned int pwm_period_ns;
        int (*init)(struct device *dev);
        int (*notify)(struct device *dev, int brightness);
index a39cbed9ee17a5d771f7c3e7ca129e3a05171220..ab2baa5c488453cba50bf564d6220038d0224867 100644 (file)
  * needed for RCU lookups (because root->height is unreliable). The only
  * time callers need worry about this is when doing a lookup_slot under
  * RCU.
+ *
+ * Indirect pointer in fact is also used to tag the last pointer of a node
+ * when it is shrunk, before we rcu free the node. See shrink code for
+ * details.
  */
 #define RADIX_TREE_INDIRECT_PTR        1
-#define RADIX_TREE_RETRY ((void *)-1UL)
-
-static inline void *radix_tree_ptr_to_indirect(void *ptr)
-{
-       return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR);
-}
 
-static inline void *radix_tree_indirect_to_ptr(void *ptr)
-{
-       return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR);
-}
 #define radix_tree_indirect_to_ptr(ptr) \
        radix_tree_indirect_to_ptr((void __force *)(ptr))
 
@@ -140,16 +134,29 @@ do {                                                                      \
  *             removed.
  *
  * For use with radix_tree_lookup_slot().  Caller must hold tree at least read
- * locked across slot lookup and dereference.  More likely, will be used with
- * radix_tree_replace_slot(), as well, so caller will hold tree write locked.
+ * locked across slot lookup and dereference. Not required if write lock is
+ * held (ie. items cannot be concurrently inserted).
+ *
+ * radix_tree_deref_retry must be used to confirm validity of the pointer if
+ * only the read lock is held.
  */
 static inline void *radix_tree_deref_slot(void **pslot)
 {
-       void *ret = rcu_dereference(*pslot);
-       if (unlikely(radix_tree_is_indirect_ptr(ret)))
-               ret = RADIX_TREE_RETRY;
-       return ret;
+       return rcu_dereference(*pslot);
 }
+
+/**
+ * radix_tree_deref_retry      - check radix_tree_deref_slot
+ * @arg:       pointer returned by radix_tree_deref_slot
+ * Returns:    0 if retry is not required, otherwise retry is required
+ *
+ * radix_tree_deref_retry must be used with radix_tree_deref_slot.
+ */
+static inline int radix_tree_deref_retry(void *arg)
+{
+       return unlikely((unsigned long)arg & RADIX_TREE_INDIRECT_PTR);
+}
+
 /**
  * radix_tree_replace_slot     - replace item in a slot
  * @pslot:     pointer to slot, returned by radix_tree_lookup_slot
index e7320b5e82fb4ac956f1cd0951488ddf1bc44637..3a8f0c9b29336f09acbd70ec1bbb01ce3ac5dfb1 100644 (file)
@@ -3,8 +3,8 @@
 
 struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir,
         int mode, dev_t dev);
-extern int ramfs_get_sb(struct file_system_type *fs_type,
-        int flags, const char *dev_name, void *data, struct vfsmount *mnt);
+extern struct dentry *ramfs_mount(struct file_system_type *fs_type,
+        int flags, const char *dev_name, void *data);
 
 #ifndef CONFIG_MMU
 extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
index 88d36f9145bacfa34ee6c32823413b09715e6ef2..d01c96c1966e2724460eeaaef3bdd6c522fc7bda 100644 (file)
@@ -2,6 +2,7 @@
 #define _LINUX_RESOURCE_H
 
 #include <linux/time.h>
+#include <linux/types.h>
 
 /*
  * Resource control/accounting header file for linux
index be7adb7588e5e5519c45caff28534cb3e2476b72..d0036e52a24a1c28eaef9e60bb5aa100aaa18af1 100644 (file)
@@ -672,6 +672,9 @@ struct user_struct {
        atomic_t inotify_watches; /* How many inotify watches does this user have? */
        atomic_t inotify_devs;  /* How many inotify devs does this user have opened? */
 #endif
+#ifdef CONFIG_FANOTIFY
+       atomic_t fanotify_listeners;
+#endif
 #ifdef CONFIG_EPOLL
        atomic_t epoll_watches; /* The number of file descriptors currently watched */
 #endif
@@ -1080,7 +1083,7 @@ struct sched_class {
                                         struct task_struct *task);
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-       void (*moved_group) (struct task_struct *p, int on_rq);
+       void (*task_move_group) (struct task_struct *p, int on_rq);
 #endif
 };
 
index b8246a8df7d2dc2ecc864ac192d694b369dd12d6..fd4d55fb884539fa0954937b0bbf5945e8bd5a6b 100644 (file)
@@ -77,7 +77,6 @@ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
 extern int cap_task_setscheduler(struct task_struct *p);
 extern int cap_task_setioprio(struct task_struct *p, int ioprio);
 extern int cap_task_setnice(struct task_struct *p, int nice);
-extern int cap_syslog(int type, bool from_file);
 extern int cap_vm_enough_memory(struct mm_struct *mm, long pages);
 
 struct msghdr;
@@ -1388,7 +1387,7 @@ struct security_operations {
        int (*sysctl) (struct ctl_table *table, int op);
        int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
        int (*quota_on) (struct dentry *dentry);
-       int (*syslog) (int type, bool from_file);
+       int (*syslog) (int type);
        int (*settime) (struct timespec *ts, struct timezone *tz);
        int (*vm_enough_memory) (struct mm_struct *mm, long pages);
 
@@ -1671,7 +1670,7 @@ int security_real_capable_noaudit(struct task_struct *tsk, int cap);
 int security_sysctl(struct ctl_table *table, int op);
 int security_quotactl(int cmds, int type, int id, struct super_block *sb);
 int security_quota_on(struct dentry *dentry);
-int security_syslog(int type, bool from_file);
+int security_syslog(int type);
 int security_settime(struct timespec *ts, struct timezone *tz);
 int security_vm_enough_memory(long pages);
 int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
@@ -1901,9 +1900,9 @@ static inline int security_quota_on(struct dentry *dentry)
        return 0;
 }
 
-static inline int security_syslog(int type, bool from_file)
+static inline int security_syslog(int type)
 {
-       return cap_syslog(type, from_file);
+       return 0;
 }
 
 static inline int security_settime(struct timespec *ts, struct timezone *tz)
index 5310d27abd2a503ad523059ea4832f34ecfbb194..39fa04966aa892f220dded471b54e4b8930cd3e2 100644 (file)
@@ -29,9 +29,6 @@ struct semaphore {
 #define DEFINE_SEMAPHORE(name) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)
 
-#define DECLARE_MUTEX(name)    \
-       struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)
-
 static inline void sema_init(struct semaphore *sem, int val)
 {
        static struct lock_class_key __key;
@@ -39,9 +36,6 @@ static inline void sema_init(struct semaphore *sem, int val)
        lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0);
 }
 
-#define init_MUTEX(sem)                sema_init(sem, 1)
-#define init_MUTEX_LOCKED(sem) sema_init(sem, 0)
-
 extern void down(struct semaphore *sem);
 extern int __must_check down_interruptible(struct semaphore *sem);
 extern int __must_check down_killable(struct semaphore *sem);
index 4dca992f3093771993ac9d98d1233df5e2f33cfa..cea0c38e7a63dfad2544043c49fca25aea9a7563 100644 (file)
@@ -122,6 +122,10 @@ int clk_rate_table_find(struct clk *clk,
 long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,
                              unsigned int div_max, unsigned long rate);
 
+long clk_round_parent(struct clk *clk, unsigned long target,
+                     unsigned long *best_freq, unsigned long *parent_freq,
+                     unsigned int div_min, unsigned int div_max);
+
 #define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags)       \
 {                                                                      \
        .parent         = _parent,                                      \
index f656d1a43dc0219ebfd43fddc7cfe2b86eded613..5812fefbcedf1ac2685760c1d40fff52076cf054 100644 (file)
@@ -79,7 +79,7 @@ struct intc_hw_desc {
        unsigned int nr_subgroups;
 };
 
-#define _INTC_ARRAY(a) a, a == NULL ? 0 : sizeof(a)/sizeof(*a)
+#define _INTC_ARRAY(a) a, __same_type(a, NULL) ? 0 : sizeof(a)/sizeof(*a)
 
 #define INTC_HW_DESC(vectors, groups, mask_regs,       \
                     prio_regs, sense_regs, ack_regs)   \
index 864bd56bd3b0ba08a84958ff5d06e647d643e208..4d9dcd1383150088f598f0d0d58f7d51e7400046 100644 (file)
@@ -5,7 +5,6 @@ struct sh_timer_config {
        char *name;
        long channel_offset;
        int timer_bit;
-       char *clk;
        unsigned long clockevent_rating;
        unsigned long clocksource_rating;
 };
index 5146b50202cefabcb4604d94dd83af4bb8863ac9..86b652fabf6e306d51e832d4bf7beb1412939cce 100644 (file)
@@ -322,7 +322,7 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
                                          int offset, 
                                          unsigned int len, __wsum *csump);
 
-extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
+extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
 extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
 extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
                             int offset, int len);
index 92e52a1e6af3fd8478bb451f04d34a3c63b1625f..b4d7710bc38d2b26effd6025243150490e0a26a9 100644 (file)
@@ -204,6 +204,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
 /**
  * struct spi_master - interface to SPI master controller
  * @dev: device interface to this driver
+ * @list: link with the global spi_master list
  * @bus_num: board-specific (and often SOC-specific) identifier for a
  *     given SPI controller.
  * @num_chipselect: chipselects are used to distinguish individual
@@ -238,6 +239,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
 struct spi_master {
        struct device   dev;
 
+       struct list_head list;
+
        /* other than negative (== assign one dynamically), bus_num is fully
         * board-specific.  usually that simplifies to being SOC-specific.
         * example:  one SOC has three SPI controllers, numbered 0..2,
index bbdb680ffbe9d46f31de3f88d82d48869543920f..aea0d438e3c716b3a0f62612f15e43b9abe1e2d8 100644 (file)
@@ -82,18 +82,28 @@ struct svc_xprt {
        struct net              *xpt_net;
 };
 
-static inline void register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
+static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
 {
        spin_lock(&xpt->xpt_lock);
-       list_add(&u->list, &xpt->xpt_users);
+       list_del_init(&u->list);
        spin_unlock(&xpt->xpt_lock);
 }
 
-static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
+static inline int register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
 {
        spin_lock(&xpt->xpt_lock);
-       list_del_init(&u->list);
+       if (test_bit(XPT_CLOSE, &xpt->xpt_flags)) {
+               /*
+                * The connection is about to be deleted soon (or,
+                * worse, may already be deleted--in which case we've
+                * already notified the xpt_users).
+                */
+               spin_unlock(&xpt->xpt_lock);
+               return -ENOTCONN;
+       }
+       list_add(&u->list, &xpt->xpt_users);
        spin_unlock(&xpt->xpt_lock);
+       return 0;
 }
 
 int    svc_reg_xprt_class(struct svc_xprt_class *);
index e500171c745f2e574a2f199fcdd5c92931e2095f..c7ea9bc8897cb638208a88bcb6352814b4639dc8 100644 (file)
@@ -50,7 +50,7 @@
 #define N_V253         19      /* Codec control over voice modem */
 #define N_CAIF         20      /* CAIF protocol for talking to modems */
 #define N_GSM0710      21      /* GSM 0710 Mux */
-#define N_TI_WL        22      /* for TI's WL BT, FM, GPS combo chips */
+#define N_TI_WL                22      /* for TI's WL BT, FM, GPS combo chips */
 
 /*
  * This character is the same as _POSIX_VDISABLE: it cannot be used as
@@ -541,8 +541,8 @@ extern void tty_audit_exit(void);
 extern void tty_audit_fork(struct signal_struct *sig);
 extern void tty_audit_tiocsti(struct tty_struct *tty, char ch);
 extern void tty_audit_push(struct tty_struct *tty);
-extern void tty_audit_push_task(struct task_struct *tsk,
-                                       uid_t loginuid, u32 sessionid);
+extern int tty_audit_push_task(struct task_struct *tsk,
+                              uid_t loginuid, u32 sessionid);
 #else
 static inline void tty_audit_add_data(struct tty_struct *tty,
                                      unsigned char *data, size_t size)
@@ -560,9 +560,10 @@ static inline void tty_audit_fork(struct signal_struct *sig)
 static inline void tty_audit_push(struct tty_struct *tty)
 {
 }
-static inline void tty_audit_push_task(struct task_struct *tsk,
-                                       uid_t loginuid, u32 sessionid)
+static inline int tty_audit_push_task(struct task_struct *tsk,
+                                     uid_t loginuid, u32 sessionid)
 {
+       return 0;
 }
 #endif
 
index 35fe6ab222bbb8c1247ab73fa7ccad96289b13f6..24300d8a1bc16eaf18c647056842102b47283980 100644 (file)
@@ -797,7 +797,7 @@ struct usbdrv_wrap {
  * @disconnect: Called when the interface is no longer accessible, usually
  *     because its device has been (or is being) disconnected or the
  *     driver module is being unloaded.
- * @ioctl: Used for drivers that want to talk to userspace through
+ * @unlocked_ioctl: Used for drivers that want to talk to userspace through
  *     the "usbfs" filesystem.  This lets devices provide ways to
  *     expose information to user space regardless of where they
  *     do (or don't) show up otherwise in the filesystem.
index ee2dd1d506ed575cd795963dc8cad50c7aefa419..2387f9fc81381dd517c7d3008de21aeb5790c0da 100644 (file)
@@ -89,6 +89,8 @@ struct musb_hdrc_config {
        /* A GPIO controlling VRSEL in Blackfin */
        unsigned int    gpio_vrsel;
        unsigned int    gpio_vrsel_active;
+       /* musb CLKIN in Blackfin in MHZ */
+       unsigned char   clkin;
 #endif
 
 };
index 09eec350054d0259fb36f2e1b1447f6b5a0bde72..0ead399e08b5cfc549d1debf26f8e7915c7c9904 100644 (file)
@@ -58,7 +58,9 @@ struct writeback_control {
 struct bdi_writeback;
 int inode_wait(void *);
 void writeback_inodes_sb(struct super_block *);
+void writeback_inodes_sb_nr(struct super_block *, unsigned long nr);
 int writeback_inodes_sb_if_idle(struct super_block *);
+int writeback_inodes_sb_nr_if_idle(struct super_block *, unsigned long nr);
 void sync_inodes_sb(struct super_block *);
 void writeback_inodes_wb(struct bdi_writeback *wb,
                struct writeback_control *wbc);
index 4debb451463474a30da023f25161b4077e58f6c0..2f7d45bcbd243c1b13e726c726dd887ba0c787d2 100644 (file)
@@ -52,6 +52,7 @@ struct mtd_oob_buf64 {
 #define MTD_NANDFLASH          4
 #define MTD_DATAFLASH          6
 #define MTD_UBIVOLUME          7
+#define MTD_MLCNANDFLASH       8
 
 #define MTD_WRITEABLE          0x400   /* Device is writeable */
 #define MTD_BIT_WRITEABLE      0x800   /* Single bits can be flipped */
@@ -119,7 +120,7 @@ struct otp_info {
 #define OTPGETREGIONCOUNT      _IOW('M', 14, int)
 #define OTPGETREGIONINFO       _IOW('M', 15, struct otp_info)
 #define OTPLOCK                        _IOR('M', 16, struct otp_info)
-#define ECCGETLAYOUT           _IOR('M', 17, struct nand_ecclayout)
+#define ECCGETLAYOUT           _IOR('M', 17, struct nand_ecclayout_user)
 #define ECCGETSTATS            _IOR('M', 18, struct mtd_ecc_stats)
 #define MTDFILEMODE            _IO('M', 19)
 #define MEMERASE64             _IOW('M', 20, struct erase_info_user64)
@@ -144,13 +145,18 @@ struct nand_oobfree {
 };
 
 #define MTD_MAX_OOBFREE_ENTRIES        8
+#define MTD_MAX_ECCPOS_ENTRIES 64
 /*
- * ECC layout control structure. Exported to userspace for
- * diagnosis and to allow creation of raw images
+ * OBSOLETE: ECC layout control structure. Exported to user-space via ioctl
+ * ECCGETLAYOUT for backwards compatbility and should not be mistaken as a
+ * complete set of ECC information. The ioctl truncates the larger internal
+ * structure to retain binary compatibility with the static declaration of the
+ * ioctl. Note that the "MTD_MAX_..._ENTRIES" macros represent the max size of
+ * the user struct, not the MAX size of the internal struct nand_ecclayout.
  */
-struct nand_ecclayout {
+struct nand_ecclayout_user {
        __u32 eccbytes;
-       __u32 eccpos[64];
+       __u32 eccpos[MTD_MAX_ECCPOS_ENTRIES];
        __u32 oobavail;
        struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
 };
index aa3c2f86a91335e2e755d54399c852d954771141..83327c808c861938dfa36f6b7d7762656b811309 100644 (file)
@@ -29,6 +29,6 @@ typedef struct mtd_info_user mtd_info_t;
 typedef struct erase_info_user erase_info_t;
 typedef struct region_info_user region_info_t;
 typedef struct nand_oobinfo nand_oobinfo_t;
-typedef struct nand_ecclayout nand_ecclayout_t;
+typedef struct nand_ecclayout_user nand_ecclayout_t;
 
 #endif /* __MTD_USER_H__ */
index 6da573c75d54cfdde09f449f6cd3dd617c49fa20..8eff83b95366049b6f55d9efd268952453329227 100644 (file)
@@ -28,7 +28,7 @@ struct caif_param {
  * @sockaddr:          Socket address to connect.
  * @priority:          Priority of the connection.
  * @link_selector:     Link selector (high bandwidth or low latency)
- * @link_name:         Name of the CAIF Link Layer to use.
+ * @ifindex:           kernel index of the interface.
  * @param:             Connect Request parameters (CAIF_SO_REQ_PARAM).
  *
  * This struct is used when connecting a CAIF channel.
@@ -39,7 +39,7 @@ struct caif_connect_request {
        struct sockaddr_caif sockaddr;
        enum caif_channel_priority priority;
        enum caif_link_selector link_selector;
-       char link_name[16];
+       int ifindex;
        struct caif_param param;
 };
 
index ce4570dff020720c2ca6d5e22a0202a78c5c42c5..87c3d11b8e555ff2ebd9a07f504cd8ab2b5fcebd 100644 (file)
@@ -121,6 +121,8 @@ struct cfspi {
        wait_queue_head_t wait;
        spinlock_t lock;
        bool flow_stop;
+       bool slave;
+       bool slave_talked;
 #ifdef CONFIG_DEBUG_FS
        enum cfspi_state dbg_state;
        u16 pcmd;
index bd646faffa47bd8cd46ed4f15e1988c7bfac8247..f688478bfb84a4afc62039e57e212978ab24929b 100644 (file)
@@ -139,10 +139,10 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
                     enum cfcnfg_phy_preference phy_pref);
 
 /**
- * cfcnfg_get_named() - Get the Physical Identifier of CAIF Link Layer
+ * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex,
+ *                     it matches caif physical id with the kernel interface id.
  * @cnfg:      Configuration object
- * @name:      Name of the Physical Layer (Caif Link Layer)
+ * @ifi:       ifindex obtained from socket.c bindtodevice.
  */
-int cfcnfg_get_named(struct cfcnfg *cnfg, char *name);
-
+int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi);
 #endif                         /* CFCNFG_H_ */
index e5469f7b67a3b17d7916188a822348214120a81e..a514a3cf45730df7083e8c2169e90d3a4bc9084e 100644 (file)
@@ -225,7 +225,7 @@ extern int decnet_di_count;
 extern int decnet_dr_count;
 extern int decnet_no_fc_max_cwnd;
 
-extern int sysctl_decnet_mem[3];
+extern long sysctl_decnet_mem[3];
 extern int sysctl_decnet_wmem[3];
 extern int sysctl_decnet_rmem[3];
 
index 1fa5306e3e230d8340b3d01fb5ce5f99a679a6fd..51665b3461b8f9ba501c296d8a2259ecb92ae92c 100644 (file)
@@ -2,6 +2,7 @@
 #define _NET_DST_OPS_H
 #include <linux/types.h>
 #include <linux/percpu_counter.h>
+#include <linux/cache.h>
 
 struct dst_entry;
 struct kmem_cachep;
index ba3666d31766864b354687cc543d9ba3a365193d..07bdb5e9e8ac0b80628400d4b79e7e5041ce8199 100644 (file)
@@ -158,6 +158,8 @@ extern int fib_table_flush(struct fib_table *table);
 extern void fib_table_select_default(struct fib_table *table,
                                     const struct flowi *flp,
                                     struct fib_result *res);
+extern void fib_free_table(struct fib_table *tb);
+
 
 
 #ifndef CONFIG_IP_MULTIPLE_TABLES
index f3b201d335b3532858c846a8aadb1672de80dce3..9801c55de5d64e5357006f9cfb129bce139572dd 100644 (file)
@@ -384,7 +384,7 @@ static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen,
  *
  * Returns the first attribute which matches the specified type.
  */
-static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh,
+static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh,
                                             int hdrlen, int attrtype)
 {
        return nla_find(nlmsg_attrdata(nlh, hdrlen),
index c7a736228ca2dcab930f7f4a9f07d5fda2858c7c..a6338d039857bf6b00bcff087f974ebf46ae0875 100644 (file)
@@ -762,7 +762,7 @@ struct proto {
 
        /* Memory pressure */
        void                    (*enter_memory_pressure)(struct sock *sk);
-       atomic_t                *memory_allocated;      /* Current allocated memory. */
+       atomic_long_t           *memory_allocated;      /* Current allocated memory. */
        struct percpu_counter   *sockets_allocated;     /* Current number of sockets. */
        /*
         * Pressure flag: try to collapse.
@@ -771,7 +771,7 @@ struct proto {
         * is strict, actions are advisory and have some latency.
         */
        int                     *memory_pressure;
-       int                     *sysctl_mem;
+       long                    *sysctl_mem;
        int                     *sysctl_wmem;
        int                     *sysctl_rmem;
        int                     max_header;
index 4fee0424af7eff7a053f0eef9376ad2644b2b723..e36c874c7fb16c47138428d4ecc106800c5fe48f 100644 (file)
@@ -224,7 +224,7 @@ extern int sysctl_tcp_fack;
 extern int sysctl_tcp_reordering;
 extern int sysctl_tcp_ecn;
 extern int sysctl_tcp_dsack;
-extern int sysctl_tcp_mem[3];
+extern long sysctl_tcp_mem[3];
 extern int sysctl_tcp_wmem[3];
 extern int sysctl_tcp_rmem[3];
 extern int sysctl_tcp_app_win;
@@ -247,7 +247,7 @@ extern int sysctl_tcp_cookie_size;
 extern int sysctl_tcp_thin_linear_timeouts;
 extern int sysctl_tcp_thin_dupack;
 
-extern atomic_t tcp_memory_allocated;
+extern atomic_long_t tcp_memory_allocated;
 extern struct percpu_counter tcp_sockets_allocated;
 extern int tcp_memory_pressure;
 
@@ -280,7 +280,7 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
        }
 
        if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
-           atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])
+           atomic_long_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])
                return true;
        return false;
 }
index 200b82848c9a3606b0076c3f8621fb63342af6a9..bb967dd59bf74fa5abac83964486fabc4398cabd 100644 (file)
@@ -105,10 +105,10 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table,
 
 extern struct proto udp_prot;
 
-extern atomic_t udp_memory_allocated;
+extern atomic_long_t udp_memory_allocated;
 
 /* sysctl variables for udp */
-extern int sysctl_udp_mem[3];
+extern long sysctl_udp_mem[3];
 extern int sysctl_udp_rmem_min;
 extern int sysctl_udp_wmem_min;
 
index 14be49b44e841ff22aa66e5b291a6ed5b00978c3..f986ab7ffe6f040e9e00ac23d404bd8ad31e1f4e 100644 (file)
@@ -721,7 +721,7 @@ struct libfc_function_template {
  * struct fc_disc - Discovery context
  * @retry_count:   Number of retries
  * @pending:       1 if discovery is pending, 0 if not
- * @requesting:    1 if discovery has been requested, 0 if not
+ * @requested:     1 if discovery has been requested, 0 if not
  * @seq_count:     Number of sequences used for discovery
  * @buf_len:       Length of the discovery buffer
  * @disc_id:       Discovery ID
index a8f37012663209020b30baeecabde62512465993..53a9e886612b8c30fd4b4fc3d2814a9433bb551b 100644 (file)
@@ -137,7 +137,7 @@ struct osd_request {
                void *buff;
                unsigned alloc_size; /* 0 here means: don't call kfree */
                unsigned total_bytes;
-       } set_attr, enc_get_attr, get_attr;
+       } cdb_cont, set_attr, enc_get_attr, get_attr;
 
        struct _osd_io_info {
                struct bio *bio;
@@ -448,6 +448,20 @@ void osd_req_read(struct osd_request *or,
 int osd_req_read_kern(struct osd_request *or,
        const struct osd_obj_id *obj, u64 offset, void *buff, u64 len);
 
+/* Scatter/Gather write/read commands */
+int osd_req_write_sg(struct osd_request *or,
+       const struct osd_obj_id *obj, struct bio *bio,
+       const struct osd_sg_entry *sglist, unsigned numentries);
+int osd_req_read_sg(struct osd_request *or,
+       const struct osd_obj_id *obj, struct bio *bio,
+       const struct osd_sg_entry *sglist, unsigned numentries);
+int osd_req_write_sg_kern(struct osd_request *or,
+       const struct osd_obj_id *obj, void **buff,
+       const struct osd_sg_entry *sglist, unsigned numentries);
+int osd_req_read_sg_kern(struct osd_request *or,
+       const struct osd_obj_id *obj, void **buff,
+       const struct osd_sg_entry *sglist, unsigned numentries);
+
 /*
  * Root/Partition/Collection/Object Attributes commands
  */
index 685661283540f64beb081b291dc6689c0a255fc0..a6026da25f3e0bf5787d479e1511da85c1175299 100644 (file)
@@ -631,4 +631,46 @@ static inline void osd_sec_set_caps(struct osd_capability_head *cap,
        put_unaligned_le16(bit_mask, &cap->permissions_bit_mask);
 }
 
+/* osd2r05a sec 5.3: CDB continuation segment formats */
+enum osd_continuation_segment_format {
+       CDB_CONTINUATION_FORMAT_V2 = 0x01,
+};
+
+struct osd_continuation_segment_header {
+       u8      format;
+       u8      reserved1;
+       __be16  service_action;
+       __be32  reserved2;
+       u8      integrity_check[OSDv2_CRYPTO_KEYID_SIZE];
+} __packed;
+
+/* osd2r05a sec 5.4.1: CDB continuation descriptors */
+enum osd_continuation_descriptor_type {
+       NO_MORE_DESCRIPTORS = 0x0000,
+       SCATTER_GATHER_LIST = 0x0001,
+       QUERY_LIST = 0x0002,
+       USER_OBJECT = 0x0003,
+       COPY_USER_OBJECT_SOURCE = 0x0101,
+       EXTENSION_CAPABILITIES = 0xFFEE
+};
+
+struct osd_continuation_descriptor_header {
+       __be16  type;
+       u8      reserved;
+       u8      pad_length;
+       __be32  length;
+} __packed;
+
+
+/* osd2r05a sec 5.4.2: Scatter/gather list */
+struct osd_sg_list_entry {
+       __be64 offset;
+       __be64 len;
+};
+
+struct osd_sg_continuation_descriptor {
+       struct osd_continuation_descriptor_header hdr;
+       struct osd_sg_list_entry entries[];
+};
+
 #endif /* ndef __OSD_PROTOCOL_H__ */
index 3f5e88cc75c0b8a1d54b25902e82017f5bfd51f5..bd0be7ed4bcf619ca4aea8cfa3abc6d86d9c7aec 100644 (file)
@@ -37,4 +37,9 @@ struct osd_attr {
        void *val_ptr;          /* in network order */
 };
 
+struct osd_sg_entry {
+       u64 offset;
+       u64 len;
+};
+
 #endif /* ndef __OSD_TYPES_H__ */
index 289010d3270bfa99191cfbdfa95a02564b6638bf..e5e345fb2a5c37db45de06bcdf02f3796aec64c4 100644 (file)
@@ -98,6 +98,103 @@ TRACE_EVENT(ext4_allocate_inode,
                  (unsigned long) __entry->dir, __entry->mode)
 );
 
+TRACE_EVENT(ext4_evict_inode,
+       TP_PROTO(struct inode *inode),
+
+       TP_ARGS(inode),
+
+       TP_STRUCT__entry(
+               __field(        int,   dev_major                )
+               __field(        int,   dev_minor                )
+               __field(        ino_t,  ino                     )
+               __field(        int,    nlink                   )
+       ),
+
+       TP_fast_assign(
+               __entry->dev_major = MAJOR(inode->i_sb->s_dev);
+               __entry->dev_minor = MINOR(inode->i_sb->s_dev);
+               __entry->ino    = inode->i_ino;
+               __entry->nlink  = inode->i_nlink;
+       ),
+
+       TP_printk("dev %d,%d ino %lu nlink %d",
+                 __entry->dev_major, __entry->dev_minor,
+                 (unsigned long) __entry->ino, __entry->nlink)
+);
+
+TRACE_EVENT(ext4_drop_inode,
+       TP_PROTO(struct inode *inode, int drop),
+
+       TP_ARGS(inode, drop),
+
+       TP_STRUCT__entry(
+               __field(        int,    dev_major               )
+               __field(        int,    dev_minor               )
+               __field(        ino_t,  ino                     )
+               __field(        int,    drop                    )
+       ),
+
+       TP_fast_assign(
+               __entry->dev_major = MAJOR(inode->i_sb->s_dev);
+               __entry->dev_minor = MINOR(inode->i_sb->s_dev);
+               __entry->ino    = inode->i_ino;
+               __entry->drop   = drop;
+       ),
+
+       TP_printk("dev %d,%d ino %lu drop %d",
+                 __entry->dev_major, __entry->dev_minor,
+                 (unsigned long) __entry->ino, __entry->drop)
+);
+
+TRACE_EVENT(ext4_mark_inode_dirty,
+       TP_PROTO(struct inode *inode, unsigned long IP),
+
+       TP_ARGS(inode, IP),
+
+       TP_STRUCT__entry(
+               __field(        int,    dev_major               )
+               __field(        int,    dev_minor               )
+               __field(        ino_t,  ino                     )
+               __field(unsigned long,  ip                      )
+       ),
+
+       TP_fast_assign(
+               __entry->dev_major = MAJOR(inode->i_sb->s_dev);
+               __entry->dev_minor = MINOR(inode->i_sb->s_dev);
+               __entry->ino    = inode->i_ino;
+               __entry->ip     = IP;
+       ),
+
+       TP_printk("dev %d,%d ino %lu caller %pF",
+                 __entry->dev_major, __entry->dev_minor,
+                 (unsigned long) __entry->ino, (void *)__entry->ip)
+);
+
+TRACE_EVENT(ext4_begin_ordered_truncate,
+       TP_PROTO(struct inode *inode, loff_t new_size),
+
+       TP_ARGS(inode, new_size),
+
+       TP_STRUCT__entry(
+               __field(        int,    dev_major               )
+               __field(        int,    dev_minor               )
+               __field(        ino_t,  ino                     )
+               __field(        loff_t, new_size                )
+       ),
+
+       TP_fast_assign(
+               __entry->dev_major      = MAJOR(inode->i_sb->s_dev);
+               __entry->dev_minor      = MINOR(inode->i_sb->s_dev);
+               __entry->ino            = inode->i_ino;
+               __entry->new_size       = new_size;
+       ),
+
+       TP_printk("dev %d,%d ino %lu new_size %lld",
+                 __entry->dev_major, __entry->dev_minor,
+                 (unsigned long) __entry->ino,
+                 (long long) __entry->new_size)
+);
+
 DECLARE_EVENT_CLASS(ext4__write_begin,
 
        TP_PROTO(struct inode *inode, loff_t pos, unsigned int len,
index 55d700e8566e6fe1dcb8f1c6ec3e35ff37678c7f..daabae5817c63e1bdd33cbcf23e026154d937da5 100644 (file)
@@ -49,7 +49,9 @@ struct sh_mobile_lcdc_sys_bus_ops {
        unsigned long (*read_data)(void *handle);
 };
 
+struct module;
 struct sh_mobile_lcdc_board_cfg {
+       struct module *owner;
        void *board_data;
        int (*setup_sys)(void *board_data, void *sys_ops_handle,
                         struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
@@ -70,7 +72,8 @@ struct sh_mobile_lcdc_chan_cfg {
        int interface_type; /* selects RGBn or SYSn I/F, see above */
        int clock_divider;
        unsigned long flags; /* LCDC_FLAGS_... */
-       struct fb_videomode lcd_cfg;
+       const struct fb_videomode *lcd_cfg;
+       int num_cfg;
        struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg;
        struct sh_mobile_lcdc_board_cfg board_cfg;
        struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
index b42cdfd92fee5becfa065aeaeec36b743b9664e8..17857fb4d5509b24a475609e2806af53c79d5317 100644 (file)
 #define __LINUX_PUBLIC_PRIVCMD_H__
 
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 typedef unsigned long xen_pfn_t;
 
-#ifndef __user
-#define __user
-#endif
-
 struct privcmd_hypercall {
        __u64 op;
        __u64 arg[5];
index 3a61ffefe88472af269e0bc218d6f8eb2959a1c9..035f4399edbcb8fd277285ac283db95c4188f8d5 100644 (file)
@@ -211,13 +211,13 @@ out:
        return error;
 }
 
-static int mqueue_get_sb(struct file_system_type *fs_type,
+static struct dentry *mqueue_mount(struct file_system_type *fs_type,
                         int flags, const char *dev_name,
-                        void *data, struct vfsmount *mnt)
+                        void *data)
 {
        if (!(flags & MS_KERNMOUNT))
                data = current->nsproxy->ipc_ns;
-       return get_sb_ns(fs_type, flags, data, mqueue_fill_super, mnt);
+       return mount_ns(fs_type, flags, data, mqueue_fill_super);
 }
 
 static void init_once(void *foo)
@@ -1232,7 +1232,7 @@ static const struct super_operations mqueue_super_ops = {
 
 static struct file_system_type mqueue_fs_type = {
        .name = "mqueue",
-       .get_sb = mqueue_get_sb,
+       .mount = mqueue_mount,
        .kill_sb = kill_litter_super,
 };
 
index fd658a1c2b88d43f565baaeb3666cc583caaef28..7d3bb22a93022e4911028bffd6710f1426e7b0e8 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -479,6 +479,7 @@ static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_
            {
                struct shmid_ds out;
 
+               memset(&out, 0, sizeof(out));
                ipc64_perm_to_ipc_perm(&in->shm_perm, &out.shm_perm);
                out.shm_segsz   = in->shm_segsz;
                out.shm_atime   = in->shm_atime;
index d96045789b546116ba69417c1f7166d3a86bb1c1..77770a034d59c57e3926536b2a64c7afca500198 100644 (file)
@@ -467,23 +467,16 @@ static int audit_prepare_user_tty(pid_t pid, uid_t loginuid, u32 sessionid)
        struct task_struct *tsk;
        int err;
 
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        tsk = find_task_by_vpid(pid);
-       err = -ESRCH;
-       if (!tsk)
-               goto out;
-       err = 0;
-
-       spin_lock_irq(&tsk->sighand->siglock);
-       if (!tsk->signal->audit_tty)
-               err = -EPERM;
-       spin_unlock_irq(&tsk->sighand->siglock);
-       if (err)
-               goto out;
-
-       tty_audit_push_task(tsk, loginuid, sessionid);
-out:
-       read_unlock(&tasklist_lock);
+       if (!tsk) {
+               rcu_read_unlock();
+               return -ESRCH;
+       }
+       get_task_struct(tsk);
+       rcu_read_unlock();
+       err = tty_audit_push_task(tsk, loginuid, sessionid);
+       put_task_struct(tsk);
        return err;
 }
 
@@ -506,7 +499,7 @@ int audit_send_list(void *_dest)
 }
 
 struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
-                                int multi, void *payload, int size)
+                                int multi, const void *payload, int size)
 {
        struct sk_buff  *skb;
        struct nlmsghdr *nlh;
@@ -555,8 +548,8 @@ static int audit_send_reply_thread(void *arg)
  * Allocates an skb, builds the netlink message, and sends it to the pid.
  * No failure notifications.
  */
-void audit_send_reply(int pid, int seq, int type, int done, int multi,
-                     void *payload, int size)
+static void audit_send_reply(int pid, int seq, int type, int done, int multi,
+                            const void *payload, int size)
 {
        struct sk_buff *skb;
        struct task_struct *tsk;
@@ -880,40 +873,40 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        case AUDIT_TTY_GET: {
                struct audit_tty_status s;
                struct task_struct *tsk;
+               unsigned long flags;
 
-               read_lock(&tasklist_lock);
+               rcu_read_lock();
                tsk = find_task_by_vpid(pid);
-               if (!tsk)
-                       err = -ESRCH;
-               else {
-                       spin_lock_irq(&tsk->sighand->siglock);
+               if (tsk && lock_task_sighand(tsk, &flags)) {
                        s.enabled = tsk->signal->audit_tty != 0;
-                       spin_unlock_irq(&tsk->sighand->siglock);
-               }
-               read_unlock(&tasklist_lock);
-               audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_TTY_GET, 0, 0,
-                                &s, sizeof(s));
+                       unlock_task_sighand(tsk, &flags);
+               } else
+                       err = -ESRCH;
+               rcu_read_unlock();
+
+               if (!err)
+                       audit_send_reply(NETLINK_CB(skb).pid, seq,
+                                        AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
                break;
        }
        case AUDIT_TTY_SET: {
                struct audit_tty_status *s;
                struct task_struct *tsk;
+               unsigned long flags;
 
                if (nlh->nlmsg_len < sizeof(struct audit_tty_status))
                        return -EINVAL;
                s = data;
                if (s->enabled != 0 && s->enabled != 1)
                        return -EINVAL;
-               read_lock(&tasklist_lock);
+               rcu_read_lock();
                tsk = find_task_by_vpid(pid);
-               if (!tsk)
-                       err = -ESRCH;
-               else {
-                       spin_lock_irq(&tsk->sighand->siglock);
+               if (tsk && lock_task_sighand(tsk, &flags)) {
                        tsk->signal->audit_tty = s->enabled != 0;
-                       spin_unlock_irq(&tsk->sighand->siglock);
-               }
-               read_unlock(&tasklist_lock);
+                       unlock_task_sighand(tsk, &flags);
+               } else
+                       err = -ESRCH;
+               rcu_read_unlock();
                break;
        }
        default:
index f7206db4e13dd52bf1dca608aad98460ec03be03..91e7071c4d2c4f06376e7ad5c485a2aa98294edd 100644 (file)
@@ -84,10 +84,7 @@ extern int audit_compare_dname_path(const char *dname, const char *path,
                                    int *dirlen);
 extern struct sk_buff *            audit_make_reply(int pid, int seq, int type,
                                             int done, int multi,
-                                            void *payload, int size);
-extern void                audit_send_reply(int pid, int seq, int type,
-                                            int done, int multi,
-                                            void *payload, int size);
+                                            const void *payload, int size);
 extern void                audit_panic(const char *message);
 
 struct audit_netlink_list {
index 7f18d3a4527ea210b253eddca60c8d8ed25a5e0a..37b2bea170c898986e894fdadcd4a3f282fcca13 100644 (file)
@@ -223,7 +223,7 @@ static void untag_chunk(struct node *p)
 {
        struct audit_chunk *chunk = find_chunk(p);
        struct fsnotify_mark *entry = &chunk->mark;
-       struct audit_chunk *new;
+       struct audit_chunk *new = NULL;
        struct audit_tree *owner;
        int size = chunk->count - 1;
        int i, j;
@@ -232,9 +232,14 @@ static void untag_chunk(struct node *p)
 
        spin_unlock(&hash_lock);
 
+       if (size)
+               new = alloc_chunk(size);
+
        spin_lock(&entry->lock);
        if (chunk->dead || !entry->i.inode) {
                spin_unlock(&entry->lock);
+               if (new)
+                       free_chunk(new);
                goto out;
        }
 
@@ -255,9 +260,9 @@ static void untag_chunk(struct node *p)
                goto out;
        }
 
-       new = alloc_chunk(size);
        if (!new)
                goto Fallback;
+
        fsnotify_duplicate_mark(&new->mark, entry);
        if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) {
                free_chunk(new);
index f0c9b2e7542dfd5b2980164a2f5ccedbcd2bb0d1..d2e3c786646055e1bbf5442b7d68090dc02b5681 100644 (file)
@@ -60,7 +60,7 @@ struct audit_parent {
 };
 
 /* fsnotify handle. */
-struct fsnotify_group *audit_watch_group;
+static struct fsnotify_group *audit_watch_group;
 
 /* fsnotify events we care about. */
 #define AUDIT_FS_WATCH (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\
@@ -123,7 +123,7 @@ void audit_put_watch(struct audit_watch *watch)
        }
 }
 
-void audit_remove_watch(struct audit_watch *watch)
+static void audit_remove_watch(struct audit_watch *watch)
 {
        list_del(&watch->wlist);
        audit_put_parent(watch->parent);
index eb7675499fb5de7e59058478efbe221fa6f054f6..add2819af71bb2a050907a49c2d228fbf0c1d00d 100644 (file)
@@ -1252,6 +1252,18 @@ static int audit_filter_user_rules(struct netlink_skb_parms *cb,
                case AUDIT_LOGINUID:
                        result = audit_comparator(cb->loginuid, f->op, f->val);
                        break;
+               case AUDIT_SUBJ_USER:
+               case AUDIT_SUBJ_ROLE:
+               case AUDIT_SUBJ_TYPE:
+               case AUDIT_SUBJ_SEN:
+               case AUDIT_SUBJ_CLR:
+                       if (f->lsm_rule)
+                               result = security_audit_rule_match(cb->sid,
+                                                                  f->type,
+                                                                  f->op,
+                                                                  f->lsm_rule,
+                                                                  NULL);
+                       break;
                }
 
                if (!result)
index 1b31c130d0349faee4dc5ac7a219a3a27ff5e031..f49a0318c2ed750437dd3ca810ff90e119994f68 100644 (file)
@@ -241,6 +241,10 @@ struct audit_context {
                        pid_t                   pid;
                        struct audit_cap_data   cap;
                } capset;
+               struct {
+                       int                     fd;
+                       int                     flags;
+               } mmap;
        };
        int fds[2];
 
@@ -1305,6 +1309,10 @@ static void show_special(struct audit_context *context, int *call_panic)
                audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted);
                audit_log_cap(ab, "cap_pe", &context->capset.cap.effective);
                break; }
+       case AUDIT_MMAP: {
+               audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd,
+                                context->mmap.flags);
+               break; }
        }
        audit_log_end(ab);
 }
@@ -2476,6 +2484,14 @@ void __audit_log_capset(pid_t pid,
        context->type = AUDIT_CAPSET;
 }
 
+void __audit_mmap_fd(int fd, int flags)
+{
+       struct audit_context *context = current->audit_context;
+       context->mmap.fd = fd;
+       context->mmap.flags = flags;
+       context->type = AUDIT_MMAP;
+}
+
 /**
  * audit_core_dumps - record information about processes that end abnormally
  * @signr: signal value
index 5cf366965d0ca5ec8766781367135838f3b2eac0..66a416b42c18bf01aaa61fecbad64c965c530e45 100644 (file)
@@ -1460,9 +1460,9 @@ static int cgroup_get_rootdir(struct super_block *sb)
        return 0;
 }
 
-static int cgroup_get_sb(struct file_system_type *fs_type,
+static struct dentry *cgroup_mount(struct file_system_type *fs_type,
                         int flags, const char *unused_dev_name,
-                        void *data, struct vfsmount *mnt)
+                        void *data)
 {
        struct cgroup_sb_opts opts;
        struct cgroupfs_root *root;
@@ -1596,10 +1596,9 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
                drop_parsed_module_refcounts(opts.subsys_bits);
        }
 
-       simple_set_mnt(mnt, sb);
        kfree(opts.release_agent);
        kfree(opts.name);
-       return 0;
+       return dget(sb->s_root);
 
  drop_new_super:
        deactivate_locked_super(sb);
@@ -1608,7 +1607,7 @@ static int cgroup_get_sb(struct file_system_type *fs_type,
  out_err:
        kfree(opts.release_agent);
        kfree(opts.name);
-       return ret;
+       return ERR_PTR(ret);
 }
 
 static void cgroup_kill_sb(struct super_block *sb) {
@@ -1658,7 +1657,7 @@ static void cgroup_kill_sb(struct super_block *sb) {
 
 static struct file_system_type cgroup_fs_type = {
        .name = "cgroup",
-       .get_sb = cgroup_get_sb,
+       .mount = cgroup_mount,
        .kill_sb = cgroup_kill_sb,
 };
 
index 51b143e2a07a49603d9aa462728f6a45032c01d9..4349935c2ad8b1a252e18ce18a2be8b638a6a075 100644 (file)
@@ -231,18 +231,17 @@ static DEFINE_SPINLOCK(cpuset_buffer_lock);
  * users. If someone tries to mount the "cpuset" filesystem, we
  * silently switch it to mount "cgroup" instead
  */
-static int cpuset_get_sb(struct file_system_type *fs_type,
-                        int flags, const char *unused_dev_name,
-                        void *data, struct vfsmount *mnt)
+static struct dentry *cpuset_mount(struct file_system_type *fs_type,
+                        int flags, const char *unused_dev_name, void *data)
 {
        struct file_system_type *cgroup_fs = get_fs_type("cgroup");
-       int ret = -ENODEV;
+       struct dentry *ret = ERR_PTR(-ENODEV);
        if (cgroup_fs) {
                char mountopts[] =
                        "cpuset,noprefix,"
                        "release_agent=/sbin/cpuset_release_agent";
-               ret = cgroup_fs->get_sb(cgroup_fs, flags,
-                                          unused_dev_name, mountopts, mnt);
+               ret = cgroup_fs->mount(cgroup_fs, flags,
+                                          unused_dev_name, mountopts);
                put_filesystem(cgroup_fs);
        }
        return ret;
@@ -250,7 +249,7 @@ static int cpuset_get_sb(struct file_system_type *fs_type,
 
 static struct file_system_type cpuset_fs_type = {
        .name = "cpuset",
-       .get_sb = cpuset_get_sb,
+       .mount = cpuset_mount,
 };
 
 /*
index fec596da9bd0c19b2e6959098e7cb50ed0564d79..cefd4a11f6d9e27b2ae146ef0be6bf940bf41587 100644 (file)
@@ -209,18 +209,6 @@ int __weak kgdb_skipexception(int exception, struct pt_regs *regs)
        return 0;
 }
 
-/**
- *     kgdb_disable_hw_debug - Disable hardware debugging while we in kgdb.
- *     @regs: Current &struct pt_regs.
- *
- *     This function will be called if the particular architecture must
- *     disable hardware debugging while it is processing gdb packets or
- *     handling exception.
- */
-void __weak kgdb_disable_hw_debug(struct pt_regs *regs)
-{
-}
-
 /*
  * Some architectures need cache flushes when we set/clear a
  * breakpoint:
@@ -484,7 +472,9 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
                atomic_inc(&masters_in_kgdb);
        else
                atomic_inc(&slaves_in_kgdb);
-       kgdb_disable_hw_debug(ks->linux_regs);
+
+       if (arch_kgdb_ops.disable_hw_break)
+               arch_kgdb_ops.disable_hw_break(regs);
 
 acquirelock:
        /*
index d7bda21a106b572ee95c22fd1e59524914944ed4..37755d621924e5256b3494d5e94b57415be5a3f1 100644 (file)
@@ -1127,7 +1127,7 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
                /* special case below */
        } else {
                kdb_printf("\nEntering kdb (current=0x%p, pid %d) ",
-                          kdb_current, kdb_current->pid);
+                          kdb_current, kdb_current ? kdb_current->pid : 0);
 #if defined(CONFIG_SMP)
                kdb_printf("on processor %d ", raw_smp_processor_id());
 #endif
@@ -2603,20 +2603,17 @@ static int kdb_summary(int argc, const char **argv)
  */
 static int kdb_per_cpu(int argc, const char **argv)
 {
-       char buf[256], fmtstr[64];
-       kdb_symtab_t symtab;
-       cpumask_t suppress = CPU_MASK_NONE;
-       int cpu, diag;
-       unsigned long addr, val, bytesperword = 0, whichcpu = ~0UL;
+       char fmtstr[64];
+       int cpu, diag, nextarg = 1;
+       unsigned long addr, symaddr, val, bytesperword = 0, whichcpu = ~0UL;
 
        if (argc < 1 || argc > 3)
                return KDB_ARGCOUNT;
 
-       snprintf(buf, sizeof(buf), "per_cpu__%s", argv[1]);
-       if (!kdbgetsymval(buf, &symtab)) {
-               kdb_printf("%s is not a per_cpu variable\n", argv[1]);
-               return KDB_BADADDR;
-       }
+       diag = kdbgetaddrarg(argc, argv, &nextarg, &symaddr, NULL, NULL);
+       if (diag)
+               return diag;
+
        if (argc >= 2) {
                diag = kdbgetularg(argv[2], &bytesperword);
                if (diag)
@@ -2649,46 +2646,25 @@ static int kdb_per_cpu(int argc, const char **argv)
 #define KDB_PCU(cpu) 0
 #endif
 #endif
-
        for_each_online_cpu(cpu) {
+               if (KDB_FLAG(CMD_INTERRUPT))
+                       return 0;
+
                if (whichcpu != ~0UL && whichcpu != cpu)
                        continue;
-               addr = symtab.sym_start + KDB_PCU(cpu);
+               addr = symaddr + KDB_PCU(cpu);
                diag = kdb_getword(&val, addr, bytesperword);
                if (diag) {
                        kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to "
                                   "read, diag=%d\n", cpu, addr, diag);
                        continue;
                }
-#ifdef CONFIG_SMP
-               if (!val) {
-                       cpu_set(cpu, suppress);
-                       continue;
-               }
-#endif /* CONFIG_SMP */
                kdb_printf("%5d ", cpu);
                kdb_md_line(fmtstr, addr,
                        bytesperword == KDB_WORD_SIZE,
                        1, bytesperword, 1, 1, 0);
        }
-       if (cpus_weight(suppress) == 0)
-               return 0;
-       kdb_printf("Zero suppressed cpu(s):");
-       for (cpu = first_cpu(suppress); cpu < num_possible_cpus();
-            cpu = next_cpu(cpu, suppress)) {
-               kdb_printf(" %d", cpu);
-               if (cpu == num_possible_cpus() - 1 ||
-                   next_cpu(cpu, suppress) != cpu + 1)
-                       continue;
-               while (cpu < num_possible_cpus() &&
-                      next_cpu(cpu, suppress) == cpu + 1)
-                       ++cpu;
-               kdb_printf("-%d", cpu);
-       }
-       kdb_printf("\n");
-
 #undef KDB_PCU
-
        return 0;
 }
 
index b194febf5799bab766e5aef261e566902a086b28..21aa7b3001fb49edce43446dd85898f62ab33d98 100644 (file)
@@ -95,6 +95,14 @@ static void __exit_signal(struct task_struct *tsk)
                tty = sig->tty;
                sig->tty = NULL;
        } else {
+               /*
+                * This can only happen if the caller is de_thread().
+                * FIXME: this is the temporary hack, we should teach
+                * posix-cpu-timers to handle this case correctly.
+                */
+               if (unlikely(has_group_leader_pid(tsk)))
+                       posix_cpu_timers_exit_group(tsk);
+
                /*
                 * If there is any task waiting for the group exit
                 * then notify it:
index 644e8d5fa367e74c3cc06a2114f2e283c701b0e6..5f92acc5f952e0afb0489017c265a943a4a7d464 100644 (file)
@@ -324,6 +324,10 @@ void enable_irq(unsigned int irq)
        if (!desc)
                return;
 
+       if (WARN(!desc->irq_data.chip || !desc->irq_data.chip->irq_enable,
+           KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq))
+               return;
+
        chip_bus_lock(desc);
        raw_spin_lock_irqsave(&desc->lock, flags);
        __enable_irq(desc, irq, false);
index 7be868bf25c69268e78c7eb7b50a7fb0d83dd1b4..3b79bd9383307a2b5a8325f53ed4ca472c77d9f8 100644 (file)
@@ -39,6 +39,16 @@ struct jump_label_module_entry {
        struct module *mod;
 };
 
+void jump_label_lock(void)
+{
+       mutex_lock(&jump_label_mutex);
+}
+
+void jump_label_unlock(void)
+{
+       mutex_unlock(&jump_label_mutex);
+}
+
 static int jump_label_cmp(const void *a, const void *b)
 {
        const struct jump_entry *jea = a;
@@ -152,7 +162,7 @@ void jump_label_update(unsigned long key, enum jump_label_type type)
        struct jump_label_module_entry *e_module;
        int count;
 
-       mutex_lock(&jump_label_mutex);
+       jump_label_lock();
        entry = get_jump_label_entry((jump_label_t)key);
        if (entry) {
                count = entry->nr_entries;
@@ -168,13 +178,14 @@ void jump_label_update(unsigned long key, enum jump_label_type type)
                        count = e_module->nr_entries;
                        iter = e_module->table;
                        while (count--) {
-                               if (kernel_text_address(iter->code))
+                               if (iter->key &&
+                                               kernel_text_address(iter->code))
                                        arch_jump_label_transform(iter, type);
                                iter++;
                        }
                }
        }
-       mutex_unlock(&jump_label_mutex);
+       jump_label_unlock();
 }
 
 static int addr_conflict(struct jump_entry *entry, void *start, void *end)
@@ -231,6 +242,7 @@ out:
  * overlaps with any of the jump label patch addresses. Code
  * that wants to modify kernel text should first verify that
  * it does not overlap with any of the jump label addresses.
+ * Caller must hold jump_label_mutex.
  *
  * returns 1 if there is an overlap, 0 otherwise
  */
@@ -241,7 +253,6 @@ int jump_label_text_reserved(void *start, void *end)
        struct jump_entry *iter_stop = __start___jump_table;
        int conflict = 0;
 
-       mutex_lock(&jump_label_mutex);
        iter = iter_start;
        while (iter < iter_stop) {
                if (addr_conflict(iter, start, end)) {
@@ -256,10 +267,16 @@ int jump_label_text_reserved(void *start, void *end)
        conflict = module_conflict(start, end);
 #endif
 out:
-       mutex_unlock(&jump_label_mutex);
        return conflict;
 }
 
+/*
+ * Not all archs need this.
+ */
+void __weak arch_jump_label_text_poke_early(jump_label_t addr)
+{
+}
+
 static __init int init_jump_label(void)
 {
        int ret;
@@ -267,7 +284,7 @@ static __init int init_jump_label(void)
        struct jump_entry *iter_stop = __stop___jump_table;
        struct jump_entry *iter;
 
-       mutex_lock(&jump_label_mutex);
+       jump_label_lock();
        ret = build_jump_label_hashtable(__start___jump_table,
                                         __stop___jump_table);
        iter = iter_start;
@@ -275,7 +292,7 @@ static __init int init_jump_label(void)
                arch_jump_label_text_poke_early(iter->code);
                iter++;
        }
-       mutex_unlock(&jump_label_mutex);
+       jump_label_unlock();
        return ret;
 }
 early_initcall(init_jump_label);
@@ -366,6 +383,39 @@ static void remove_jump_label_module(struct module *mod)
        }
 }
 
+static void remove_jump_label_module_init(struct module *mod)
+{
+       struct hlist_head *head;
+       struct hlist_node *node, *node_next, *module_node, *module_node_next;
+       struct jump_label_entry *e;
+       struct jump_label_module_entry *e_module;
+       struct jump_entry *iter;
+       int i, count;
+
+       /* if the module doesn't have jump label entries, just return */
+       if (!mod->num_jump_entries)
+               return;
+
+       for (i = 0; i < JUMP_LABEL_TABLE_SIZE; i++) {
+               head = &jump_label_table[i];
+               hlist_for_each_entry_safe(e, node, node_next, head, hlist) {
+                       hlist_for_each_entry_safe(e_module, module_node,
+                                                 module_node_next,
+                                                 &(e->modules), hlist) {
+                               if (e_module->mod != mod)
+                                       continue;
+                               count = e_module->nr_entries;
+                               iter = e_module->table;
+                               while (count--) {
+                                       if (within_module_init(iter->code, mod))
+                                               iter->key = 0;
+                                       iter++;
+                               }
+                       }
+               }
+       }
+}
+
 static int
 jump_label_module_notify(struct notifier_block *self, unsigned long val,
                         void *data)
@@ -375,16 +425,21 @@ jump_label_module_notify(struct notifier_block *self, unsigned long val,
 
        switch (val) {
        case MODULE_STATE_COMING:
-               mutex_lock(&jump_label_mutex);
+               jump_label_lock();
                ret = add_jump_label_module(mod);
                if (ret)
                        remove_jump_label_module(mod);
-               mutex_unlock(&jump_label_mutex);
+               jump_label_unlock();
                break;
        case MODULE_STATE_GOING:
-               mutex_lock(&jump_label_mutex);
+               jump_label_lock();
                remove_jump_label_module(mod);
-               mutex_unlock(&jump_label_mutex);
+               jump_label_unlock();
+               break;
+       case MODULE_STATE_LIVE:
+               jump_label_lock();
+               remove_jump_label_module_init(mod);
+               jump_label_unlock();
                break;
        }
        return ret;
index 99865c33a60d6347f48d46976e75d2baee579156..9737a76e106ff1554ecc2174f0e49a92b5badf45 100644 (file)
@@ -1145,14 +1145,13 @@ int __kprobes register_kprobe(struct kprobe *p)
        if (ret)
                return ret;
 
+       jump_label_lock();
        preempt_disable();
        if (!kernel_text_address((unsigned long) p->addr) ||
            in_kprobes_functions((unsigned long) p->addr) ||
            ftrace_text_reserved(p->addr, p->addr) ||
-           jump_label_text_reserved(p->addr, p->addr)) {
-               preempt_enable();
-               return -EINVAL;
-       }
+           jump_label_text_reserved(p->addr, p->addr))
+               goto fail_with_jump_label;
 
        /* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */
        p->flags &= KPROBE_FLAG_DISABLED;
@@ -1166,10 +1165,9 @@ int __kprobes register_kprobe(struct kprobe *p)
                 * We must hold a refcount of the probed module while updating
                 * its code to prohibit unexpected unloading.
                 */
-               if (unlikely(!try_module_get(probed_mod))) {
-                       preempt_enable();
-                       return -EINVAL;
-               }
+               if (unlikely(!try_module_get(probed_mod)))
+                       goto fail_with_jump_label;
+
                /*
                 * If the module freed .init.text, we couldn't insert
                 * kprobes in there.
@@ -1177,16 +1175,18 @@ int __kprobes register_kprobe(struct kprobe *p)
                if (within_module_init((unsigned long)p->addr, probed_mod) &&
                    probed_mod->state != MODULE_STATE_COMING) {
                        module_put(probed_mod);
-                       preempt_enable();
-                       return -EINVAL;
+                       goto fail_with_jump_label;
                }
        }
        preempt_enable();
+       jump_label_unlock();
 
        p->nmissed = 0;
        INIT_LIST_HEAD(&p->list);
        mutex_lock(&kprobe_mutex);
 
+       jump_label_lock(); /* needed to call jump_label_text_reserved() */
+
        get_online_cpus();      /* For avoiding text_mutex deadlock. */
        mutex_lock(&text_mutex);
 
@@ -1214,12 +1214,18 @@ int __kprobes register_kprobe(struct kprobe *p)
 out:
        mutex_unlock(&text_mutex);
        put_online_cpus();
+       jump_label_unlock();
        mutex_unlock(&kprobe_mutex);
 
        if (probed_mod)
                module_put(probed_mod);
 
        return ret;
+
+fail_with_jump_label:
+       preempt_enable();
+       jump_label_unlock();
+       return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(register_kprobe);
 
index 877fb306d4154465e184e19b73ca1984a179aece..17110a4a4fc28c68bf7993b9248432c0dd957d4f 100644 (file)
@@ -194,14 +194,7 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter)
 
        account_global_scheduler_latency(tsk, &lat);
 
-       /*
-        * short term hack; if we're > 32 we stop; future we recycle:
-        */
-       tsk->latency_record_count++;
-       if (tsk->latency_record_count >= LT_SAVECOUNT)
-               goto out_unlock;
-
-       for (i = 0; i < LT_SAVECOUNT; i++) {
+       for (i = 0; i < tsk->latency_record_count; i++) {
                struct latency_record *mylat;
                int same = 1;
 
@@ -227,8 +220,14 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter)
                }
        }
 
+       /*
+        * short term hack; if we're > 32 we stop; future we recycle:
+        */
+       if (tsk->latency_record_count >= LT_SAVECOUNT)
+               goto out_unlock;
+
        /* Allocated a new one: */
-       i = tsk->latency_record_count;
+       i = tsk->latency_record_count++;
        memcpy(&tsk->latency_record[i], &lat, sizeof(struct latency_record));
 
 out_unlock:
index 517d827f498281da50210aa76a02b4693116154a..cb6c0d2af68f64b16bd0557f3c7fb7001151b71d 100644 (file)
@@ -674,6 +674,8 @@ event_sched_in(struct perf_event *event,
 
        event->tstamp_running += ctx->time - event->tstamp_stopped;
 
+       event->shadow_ctx_time = ctx->time - ctx->timestamp;
+
        if (!is_software_event(event))
                cpuctx->active_oncpu++;
        ctx->nr_active++;
@@ -3396,7 +3398,8 @@ static u32 perf_event_tid(struct perf_event *event, struct task_struct *p)
 }
 
 static void perf_output_read_one(struct perf_output_handle *handle,
-                                struct perf_event *event)
+                                struct perf_event *event,
+                                u64 enabled, u64 running)
 {
        u64 read_format = event->attr.read_format;
        u64 values[4];
@@ -3404,11 +3407,11 @@ static void perf_output_read_one(struct perf_output_handle *handle,
 
        values[n++] = perf_event_count(event);
        if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
-               values[n++] = event->total_time_enabled +
+               values[n++] = enabled +
                        atomic64_read(&event->child_total_time_enabled);
        }
        if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
-               values[n++] = event->total_time_running +
+               values[n++] = running +
                        atomic64_read(&event->child_total_time_running);
        }
        if (read_format & PERF_FORMAT_ID)
@@ -3421,7 +3424,8 @@ static void perf_output_read_one(struct perf_output_handle *handle,
  * XXX PERF_FORMAT_GROUP vs inherited events seems difficult.
  */
 static void perf_output_read_group(struct perf_output_handle *handle,
-                           struct perf_event *event)
+                           struct perf_event *event,
+                           u64 enabled, u64 running)
 {
        struct perf_event *leader = event->group_leader, *sub;
        u64 read_format = event->attr.read_format;
@@ -3431,10 +3435,10 @@ static void perf_output_read_group(struct perf_output_handle *handle,
        values[n++] = 1 + leader->nr_siblings;
 
        if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
-               values[n++] = leader->total_time_enabled;
+               values[n++] = enabled;
 
        if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
-               values[n++] = leader->total_time_running;
+               values[n++] = running;
 
        if (leader != event)
                leader->pmu->read(leader);
@@ -3459,13 +3463,35 @@ static void perf_output_read_group(struct perf_output_handle *handle,
        }
 }
 
+#define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\
+                                PERF_FORMAT_TOTAL_TIME_RUNNING)
+
 static void perf_output_read(struct perf_output_handle *handle,
                             struct perf_event *event)
 {
+       u64 enabled = 0, running = 0, now, ctx_time;
+       u64 read_format = event->attr.read_format;
+
+       /*
+        * compute total_time_enabled, total_time_running
+        * based on snapshot values taken when the event
+        * was last scheduled in.
+        *
+        * we cannot simply called update_context_time()
+        * because of locking issue as we are called in
+        * NMI context
+        */
+       if (read_format & PERF_FORMAT_TOTAL_TIMES) {
+               now = perf_clock();
+               ctx_time = event->shadow_ctx_time + now;
+               enabled = ctx_time - event->tstamp_enabled;
+               running = ctx_time - event->tstamp_running;
+       }
+
        if (event->attr.read_format & PERF_FORMAT_GROUP)
-               perf_output_read_group(handle, event);
+               perf_output_read_group(handle, event, enabled, running);
        else
-               perf_output_read_one(handle, event);
+               perf_output_read_one(handle, event, enabled, running);
 }
 
 void perf_output_sample(struct perf_output_handle *handle,
index b2ebaee8c377d2aa92c073e772748242b5ce5c90..9a2264fc42cafac30d9264d569e4e673e9617f19 100644 (file)
@@ -261,6 +261,12 @@ static inline void boot_delay_msec(void)
 }
 #endif
 
+#ifdef CONFIG_SECURITY_DMESG_RESTRICT
+int dmesg_restrict = 1;
+#else
+int dmesg_restrict;
+#endif
+
 int do_syslog(int type, char __user *buf, int len, bool from_file)
 {
        unsigned i, j, limit, count;
@@ -268,7 +274,20 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
        char c;
        int error = 0;
 
-       error = security_syslog(type, from_file);
+       /*
+        * If this is from /proc/kmsg we only do the capabilities checks
+        * at open time.
+        */
+       if (type == SYSLOG_ACTION_OPEN || !from_file) {
+               if (dmesg_restrict && !capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               if ((type != SYSLOG_ACTION_READ_ALL &&
+                    type != SYSLOG_ACTION_SIZE_BUFFER) &&
+                   !capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+       }
+
+       error = security_syslog(type);
        if (error)
                return error;
 
index 471b66acabb57e770dd552bfc5a9edae356acfd7..37fa9b99ad588356534b1457b7241d97573705b8 100644 (file)
@@ -119,7 +119,7 @@ static int cmp_range(const void *x1, const void *x2)
 
 int clean_sort_range(struct range *range, int az)
 {
-       int i, j, k = az - 1, nr_range = 0;
+       int i, j, k = az - 1, nr_range = az;
 
        for (i = 0; i < k; i++) {
                if (range[i].end)
index c7cf397fb92958bbcbd2772e13a8d4a4d9c00b6d..859ea5a9605fa40fe47aedcb865ab08c66a43797 100644 (file)
@@ -70,17 +70,10 @@ static const struct vm_operations_struct relay_file_mmap_ops = {
  */
 static struct page **relay_alloc_page_array(unsigned int n_pages)
 {
-       struct page **array;
-       size_t pa_size = n_pages * sizeof(struct page *);
-
-       if (pa_size > PAGE_SIZE) {
-               array = vmalloc(pa_size);
-               if (array)
-                       memset(array, 0, pa_size);
-       } else {
-               array = kzalloc(pa_size, GFP_KERNEL);
-       }
-       return array;
+       const size_t pa_size = n_pages * sizeof(struct page *);
+       if (pa_size > PAGE_SIZE)
+               return vzalloc(pa_size);
+       return kzalloc(pa_size, GFP_KERNEL);
 }
 
 /*
index d42992bccdfae88569559f3e88f81bbcea8e9494..aa14a56f9d037cde21ae19ef86b142e1c23fe736 100644 (file)
@@ -8510,12 +8510,12 @@ void sched_move_task(struct task_struct *tsk)
        if (unlikely(running))
                tsk->sched_class->put_prev_task(rq, tsk);
 
-       set_task_rq(tsk, task_cpu(tsk));
-
 #ifdef CONFIG_FAIR_GROUP_SCHED
-       if (tsk->sched_class->moved_group)
-               tsk->sched_class->moved_group(tsk, on_rq);
+       if (tsk->sched_class->task_move_group)
+               tsk->sched_class->task_move_group(tsk, on_rq);
+       else
 #endif
+               set_task_rq(tsk, task_cpu(tsk));
 
        if (unlikely(running))
                tsk->sched_class->set_curr_task(rq);
index 933f3d1b62ea0affb63767f87152545f7659dc6f..f4f6a8326dd01ffc0353b369bbfddf5a4f0e2fde 100644 (file)
@@ -3869,13 +3869,26 @@ static void set_curr_task_fair(struct rq *rq)
 }
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-static void moved_group_fair(struct task_struct *p, int on_rq)
+static void task_move_group_fair(struct task_struct *p, int on_rq)
 {
-       struct cfs_rq *cfs_rq = task_cfs_rq(p);
-
-       update_curr(cfs_rq);
+       /*
+        * If the task was not on the rq at the time of this cgroup movement
+        * it must have been asleep, sleeping tasks keep their ->vruntime
+        * absolute on their old rq until wakeup (needed for the fair sleeper
+        * bonus in place_entity()).
+        *
+        * If it was on the rq, we've just 'preempted' it, which does convert
+        * ->vruntime to a relative base.
+        *
+        * Make sure both cases convert their relative position when migrating
+        * to another cgroup's rq. This does somewhat interfere with the
+        * fair sleeper stuff for the first placement, but who cares.
+        */
+       if (!on_rq)
+               p->se.vruntime -= cfs_rq_of(&p->se)->min_vruntime;
+       set_task_rq(p, task_cpu(p));
        if (!on_rq)
-               place_entity(cfs_rq, &p->se, 1);
+               p->se.vruntime += cfs_rq_of(&p->se)->min_vruntime;
 }
 #endif
 
@@ -3927,7 +3940,7 @@ static const struct sched_class fair_sched_class = {
        .get_rr_interval        = get_rr_interval_fair,
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-       .moved_group            = moved_group_fair,
+       .task_move_group        = task_move_group_fair,
 #endif
 };
 
index 25c2f962f6fcb3b545719e4a8871c991bdbeb37f..48ddf431db0ee4da60025e364e0b2a64e459508f 100644 (file)
@@ -157,15 +157,7 @@ static inline void sched_info_reset_dequeued(struct task_struct *t)
 }
 
 /*
- * Called when a process is dequeued from the active array and given
- * the cpu.  We should note that with the exception of interactive
- * tasks, the expired queue will become the active queue after the active
- * queue is empty, without explicitly dequeuing and requeuing tasks in the
- * expired queue.  (Interactive tasks may be requeued directly to the
- * active queue, thus delaying tasks in the expired queue from running;
- * see scheduler_tick()).
- *
- * Though we are interested in knowing how long it was from the *first* time a
+ * We are interested in knowing how long it was from the *first* time a
  * task was queued to the time that it finally hit a cpu, we call this routine
  * from dequeue_task() to account for possible rq->clock skew across cpus. The
  * delta taken on each cpu would annul the skew.
@@ -203,16 +195,6 @@ static void sched_info_arrive(struct task_struct *t)
 }
 
 /*
- * Called when a process is queued into either the active or expired
- * array.  The time is noted and later used to determine how long we
- * had to wait for us to reach the cpu.  Since the expired queue will
- * become the active queue after active queue is empty, without dequeuing
- * and requeuing any tasks, we are interested in queuing to either. It
- * is unusual but not impossible for tasks to be dequeued and immediately
- * requeued in the same or another array: this can happen in sched_yield(),
- * set_user_nice(), and even load_balance() as it moves tasks from runqueue
- * to runqueue.
- *
  * This function is only called from enqueue_task(), but also only updates
  * the timestamp if it is already not set.  It's assumed that
  * sched_info_dequeued() will clear that stamp when appropriate.
index c33a1edb799fda6db2e16fdf9d1d0401a9f78278..b65bf634035ed0684693b9c7c02b3229c8d68e0d 100644 (file)
@@ -703,6 +703,15 @@ static struct ctl_table kern_table[] = {
                .extra2         = &ten_thousand,
        },
 #endif
+       {
+               .procname       = "dmesg_restrict",
+               .data           = &dmesg_restrict,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &one,
+       },
        {
                .procname       = "ngroups_max",
                .data           = &ngroups_max,
index bc251ed667248fb8c72a0dd59ddf3a9a42e1c23d..7b8ec02815482773bc0eccb3918e207934f46419 100644 (file)
@@ -168,7 +168,6 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
 static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ),
                                 BLK_TC_ACT(BLK_TC_WRITE) };
 
-#define BLK_TC_HARDBARRIER     BLK_TC_BARRIER
 #define BLK_TC_RAHEAD          BLK_TC_AHEAD
 
 /* The ilog2() calls fall out because they're constant */
@@ -196,7 +195,6 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
                return;
 
        what |= ddir_act[rw & WRITE];
-       what |= MASK_TC_BIT(rw, HARDBARRIER);
        what |= MASK_TC_BIT(rw, SYNC);
        what |= MASK_TC_BIT(rw, RAHEAD);
        what |= MASK_TC_BIT(rw, META);
@@ -1807,8 +1805,6 @@ void blk_fill_rwbs(char *rwbs, u32 rw, int bytes)
 
        if (rw & REQ_RAHEAD)
                rwbs[i++] = 'A';
-       if (rw & REQ_HARDBARRIER)
-               rwbs[i++] = 'B';
        if (rw & REQ_SYNC)
                rwbs[i++] = 'S';
        if (rw & REQ_META)
index bafba687a6d849a11f0201acd3d7ae5e63e9301e..6e3c41a4024c1cc66be01218e2c37498498f2469 100644 (file)
@@ -43,7 +43,7 @@ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved);
 static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
 #endif
 
-static int __initdata no_watchdog;
+static int no_watchdog;
 
 
 /* boot commands */
index 6f412ab4c24f812fc8b7290c4a1e06cc0250ea62..5086bb962b4dd9ca6471afb76f0698facb914816 100644 (file)
@@ -82,6 +82,16 @@ struct radix_tree_preload {
 };
 static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
 
+static inline void *ptr_to_indirect(void *ptr)
+{
+       return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR);
+}
+
+static inline void *indirect_to_ptr(void *ptr)
+{
+       return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR);
+}
+
 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
 {
        return root->gfp_mask & __GFP_BITS_MASK;
@@ -265,7 +275,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
                        return -ENOMEM;
 
                /* Increase the height.  */
-               node->slots[0] = radix_tree_indirect_to_ptr(root->rnode);
+               node->slots[0] = indirect_to_ptr(root->rnode);
 
                /* Propagate the aggregated tag info into the new root */
                for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) {
@@ -276,7 +286,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
                newheight = root->height+1;
                node->height = newheight;
                node->count = 1;
-               node = radix_tree_ptr_to_indirect(node);
+               node = ptr_to_indirect(node);
                rcu_assign_pointer(root->rnode, node);
                root->height = newheight;
        } while (height > root->height);
@@ -309,7 +319,7 @@ int radix_tree_insert(struct radix_tree_root *root,
                        return error;
        }
 
-       slot = radix_tree_indirect_to_ptr(root->rnode);
+       slot = indirect_to_ptr(root->rnode);
 
        height = root->height;
        shift = (height-1) * RADIX_TREE_MAP_SHIFT;
@@ -325,8 +335,7 @@ int radix_tree_insert(struct radix_tree_root *root,
                                rcu_assign_pointer(node->slots[offset], slot);
                                node->count++;
                        } else
-                               rcu_assign_pointer(root->rnode,
-                                       radix_tree_ptr_to_indirect(slot));
+                               rcu_assign_pointer(root->rnode, ptr_to_indirect(slot));
                }
 
                /* Go a level down */
@@ -374,7 +383,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root,
                        return NULL;
                return is_slot ? (void *)&root->rnode : node;
        }
-       node = radix_tree_indirect_to_ptr(node);
+       node = indirect_to_ptr(node);
 
        height = node->height;
        if (index > radix_tree_maxindex(height))
@@ -393,7 +402,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root,
                height--;
        } while (height > 0);
 
-       return is_slot ? (void *)slot:node;
+       return is_slot ? (void *)slot : indirect_to_ptr(node);
 }
 
 /**
@@ -455,7 +464,7 @@ void *radix_tree_tag_set(struct radix_tree_root *root,
        height = root->height;
        BUG_ON(index > radix_tree_maxindex(height));
 
-       slot = radix_tree_indirect_to_ptr(root->rnode);
+       slot = indirect_to_ptr(root->rnode);
        shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
 
        while (height > 0) {
@@ -509,7 +518,7 @@ void *radix_tree_tag_clear(struct radix_tree_root *root,
 
        shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
        pathp->node = NULL;
-       slot = radix_tree_indirect_to_ptr(root->rnode);
+       slot = indirect_to_ptr(root->rnode);
 
        while (height > 0) {
                int offset;
@@ -579,7 +588,7 @@ int radix_tree_tag_get(struct radix_tree_root *root,
 
        if (!radix_tree_is_indirect_ptr(node))
                return (index == 0);
-       node = radix_tree_indirect_to_ptr(node);
+       node = indirect_to_ptr(node);
 
        height = node->height;
        if (index > radix_tree_maxindex(height))
@@ -666,7 +675,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
        }
 
        shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
-       slot = radix_tree_indirect_to_ptr(root->rnode);
+       slot = indirect_to_ptr(root->rnode);
 
        /*
         * we fill the path from (root->height - 2) to 0, leaving the index at
@@ -897,7 +906,7 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
                results[0] = node;
                return 1;
        }
-       node = radix_tree_indirect_to_ptr(node);
+       node = indirect_to_ptr(node);
 
        max_index = radix_tree_maxindex(node->height);
 
@@ -916,7 +925,8 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
                        slot = *(((void ***)results)[ret + i]);
                        if (!slot)
                                continue;
-                       results[ret + nr_found] = rcu_dereference_raw(slot);
+                       results[ret + nr_found] =
+                               indirect_to_ptr(rcu_dereference_raw(slot));
                        nr_found++;
                }
                ret += nr_found;
@@ -965,7 +975,7 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results,
                results[0] = (void **)&root->rnode;
                return 1;
        }
-       node = radix_tree_indirect_to_ptr(node);
+       node = indirect_to_ptr(node);
 
        max_index = radix_tree_maxindex(node->height);
 
@@ -1090,7 +1100,7 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
                results[0] = node;
                return 1;
        }
-       node = radix_tree_indirect_to_ptr(node);
+       node = indirect_to_ptr(node);
 
        max_index = radix_tree_maxindex(node->height);
 
@@ -1109,7 +1119,8 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
                        slot = *(((void ***)results)[ret + i]);
                        if (!slot)
                                continue;
-                       results[ret + nr_found] = rcu_dereference_raw(slot);
+                       results[ret + nr_found] =
+                               indirect_to_ptr(rcu_dereference_raw(slot));
                        nr_found++;
                }
                ret += nr_found;
@@ -1159,7 +1170,7 @@ radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results,
                results[0] = (void **)&root->rnode;
                return 1;
        }
-       node = radix_tree_indirect_to_ptr(node);
+       node = indirect_to_ptr(node);
 
        max_index = radix_tree_maxindex(node->height);
 
@@ -1195,7 +1206,7 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)
                void *newptr;
 
                BUG_ON(!radix_tree_is_indirect_ptr(to_free));
-               to_free = radix_tree_indirect_to_ptr(to_free);
+               to_free = indirect_to_ptr(to_free);
 
                /*
                 * The candidate node has more than one child, or its child
@@ -1208,16 +1219,39 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)
 
                /*
                 * We don't need rcu_assign_pointer(), since we are simply
-                * moving the node from one part of the tree to another. If
-                * it was safe to dereference the old pointer to it
+                * moving the node from one part of the tree to another: if it
+                * was safe to dereference the old pointer to it
                 * (to_free->slots[0]), it will be safe to dereference the new
-                * one (root->rnode).
+                * one (root->rnode) as far as dependent read barriers go.
                 */
                newptr = to_free->slots[0];
                if (root->height > 1)
-                       newptr = radix_tree_ptr_to_indirect(newptr);
+                       newptr = ptr_to_indirect(newptr);
                root->rnode = newptr;
                root->height--;
+
+               /*
+                * We have a dilemma here. The node's slot[0] must not be
+                * NULLed in case there are concurrent lookups expecting to
+                * find the item. However if this was a bottom-level node,
+                * then it may be subject to the slot pointer being visible
+                * to callers dereferencing it. If item corresponding to
+                * slot[0] is subsequently deleted, these callers would expect
+                * their slot to become empty sooner or later.
+                *
+                * For example, lockless pagecache will look up a slot, deref
+                * the page pointer, and if the page is 0 refcount it means it
+                * was concurrently deleted from pagecache so try the deref
+                * again. Fortunately there is already a requirement for logic
+                * to retry the entire slot lookup -- the indirect pointer
+                * problem (replacing direct root node with an indirect pointer
+                * also results in a stale slot). So tag the slot as indirect
+                * to force callers to retry.
+                */
+               if (root->height == 0)
+                       *((unsigned long *)&to_free->slots[0]) |=
+                                               RADIX_TREE_INDIRECT_PTR;
+
                radix_tree_node_free(to_free);
        }
 }
@@ -1254,7 +1288,7 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
                root->rnode = NULL;
                goto out;
        }
-       slot = radix_tree_indirect_to_ptr(slot);
+       slot = indirect_to_ptr(slot);
 
        shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
        pathp->node = NULL;
@@ -1296,8 +1330,7 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
                        radix_tree_node_free(to_free);
 
                if (pathp->node->count) {
-                       if (pathp->node ==
-                                       radix_tree_indirect_to_ptr(root->rnode))
+                       if (pathp->node == indirect_to_ptr(root->rnode))
                                radix_tree_shrink(root);
                        goto out;
                }
index 75572b5f23746a4b47a42920980a22e6a5251fe7..ea89840fc65fa2b499ce3c19c657e9e8a680b240 100644 (file)
@@ -644,7 +644,9 @@ repeat:
        pagep = radix_tree_lookup_slot(&mapping->page_tree, offset);
        if (pagep) {
                page = radix_tree_deref_slot(pagep);
-               if (unlikely(!page || page == RADIX_TREE_RETRY))
+               if (unlikely(!page))
+                       goto out;
+               if (radix_tree_deref_retry(page))
                        goto repeat;
 
                if (!page_cache_get_speculative(page))
@@ -660,6 +662,7 @@ repeat:
                        goto repeat;
                }
        }
+out:
        rcu_read_unlock();
 
        return page;
@@ -777,12 +780,11 @@ repeat:
                page = radix_tree_deref_slot((void **)pages[i]);
                if (unlikely(!page))
                        continue;
-               /*
-                * this can only trigger if nr_found == 1, making livelock
-                * a non issue.
-                */
-               if (unlikely(page == RADIX_TREE_RETRY))
+               if (radix_tree_deref_retry(page)) {
+                       if (ret)
+                               start = pages[ret-1]->index;
                        goto restart;
+               }
 
                if (!page_cache_get_speculative(page))
                        goto repeat;
@@ -830,11 +832,7 @@ repeat:
                page = radix_tree_deref_slot((void **)pages[i]);
                if (unlikely(!page))
                        continue;
-               /*
-                * this can only trigger if nr_found == 1, making livelock
-                * a non issue.
-                */
-               if (unlikely(page == RADIX_TREE_RETRY))
+               if (radix_tree_deref_retry(page))
                        goto restart;
 
                if (page->mapping == NULL || page->index != index)
@@ -887,11 +885,7 @@ repeat:
                page = radix_tree_deref_slot((void **)pages[i]);
                if (unlikely(!page))
                        continue;
-               /*
-                * this can only trigger if nr_found == 1, making livelock
-                * a non issue.
-                */
-               if (unlikely(page == RADIX_TREE_RETRY))
+               if (radix_tree_deref_retry(page))
                        goto restart;
 
                if (!page_cache_get_speculative(page))
@@ -1029,6 +1023,9 @@ find_page:
                                goto page_not_up_to_date;
                        if (!trylock_page(page))
                                goto page_not_up_to_date;
+                       /* Did it get truncated before we got the lock? */
+                       if (!page->mapping)
+                               goto page_not_up_to_date_locked;
                        if (!mapping->a_ops->is_partially_uptodate(page,
                                                                desc, offset))
                                goto page_not_up_to_date_locked;
@@ -1563,8 +1560,10 @@ retry_find:
                        goto no_cached_page;
        }
 
-       if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags))
+       if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags)) {
+               page_cache_release(page);
                return ret | VM_FAULT_RETRY;
+       }
 
        /* Did it get truncated? */
        if (unlikely(page->mapping != mapping)) {
index 9a99cfaf0a19025f6020c106d56e1ce28d6499b4..2efa8ea07ff7d931577da964c190f5524088da3d 100644 (file)
@@ -4208,15 +4208,17 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
 
        memset(mem, 0, size);
        mem->stat = alloc_percpu(struct mem_cgroup_stat_cpu);
-       if (!mem->stat) {
-               if (size < PAGE_SIZE)
-                       kfree(mem);
-               else
-                       vfree(mem);
-               mem = NULL;
-       }
+       if (!mem->stat)
+               goto out_free;
        spin_lock_init(&mem->pcp_counter_lock);
        return mem;
+
+out_free:
+       if (size < PAGE_SIZE)
+               kfree(mem);
+       else
+               vfree(mem);
+       return NULL;
 }
 
 /*
index 00161a48a45100c611ebaa053f0b1f1486d09f29..b179abb1474ae41bff47060b5241045d3b1b12ad 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -28,6 +28,7 @@
 #include <linux/rmap.h>
 #include <linux/mmu_notifier.h>
 #include <linux/perf_event.h>
+#include <linux/audit.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -1108,6 +1109,7 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
        unsigned long retval = -EBADF;
 
        if (!(flags & MAP_ANONYMOUS)) {
+               audit_mmap_fd(fd, flags);
                if (unlikely(flags & MAP_HUGETLB))
                        return -EINVAL;
                file = fget(fd);
index 2d1bf7cf885179af5144f41998d95dc2d2b72981..4c51338730977604266bab4e67ef0251aba69638 100644 (file)
@@ -211,6 +211,7 @@ success:
        mmu_notifier_invalidate_range_end(mm, start, end);
        vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
        vm_stat_account(mm, newflags, vma->vm_file, nrpages);
+       perf_event_mmap(vma);
        return 0;
 
 fail:
@@ -299,7 +300,6 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
                error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
                if (error)
                        goto out;
-               perf_event_mmap(vma);
                nstart = tmp;
 
                if (nstart < prev->vm_end)
index 30b5c20eec15e6761bad5dd4815e69ebae1d7dc2..3613517c75929b17e1b3d93a650e5d9957c2315a 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/personality.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
+#include <linux/audit.h>
 
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
@@ -1458,6 +1459,7 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
        struct file *file = NULL;
        unsigned long retval = -EBADF;
 
+       audit_mmap_fd(fd, flags);
        if (!(flags & MAP_ANONYMOUS)) {
                file = fget(fd);
                if (!file)
index f6d350e8adc56da67313a782569e81c34af27286..47fdeeb9d63685e708d2775216768dfc49f735dc 100644 (file)
@@ -2538,16 +2538,16 @@ static const struct vm_operations_struct shmem_vm_ops = {
 };
 
 
-static int shmem_get_sb(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *shmem_mount(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data)
 {
-       return get_sb_nodev(fs_type, flags, data, shmem_fill_super, mnt);
+       return mount_nodev(fs_type, flags, data, shmem_fill_super);
 }
 
 static struct file_system_type tmpfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "tmpfs",
-       .get_sb         = shmem_get_sb,
+       .mount          = shmem_mount,
        .kill_sb        = kill_litter_super,
 };
 
@@ -2643,7 +2643,7 @@ out:
 
 static struct file_system_type tmpfs_fs_type = {
        .name           = "tmpfs",
-       .get_sb         = ramfs_get_sb,
+       .mount          = ramfs_mount,
        .kill_sb        = kill_litter_super,
 };
 
index 8fd5401bb0717f3cfc73141bdad1c901e92764a7..981fb730aa04d82ef7b739497beb22d10fe9f98c 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3273,9 +3273,9 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
                kfree(n);
                kfree(s);
        }
+err:
        up_write(&slub_lock);
 
-err:
        if (flags & SLAB_PANIC)
                panic("Cannot create slabcache %s\n", name);
        else
@@ -3862,6 +3862,7 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
                        x += sprintf(buf + x, " N%d=%lu",
                                        node, nodes[node]);
 #endif
+       up_read(&slub_lock);
        kfree(nodes);
        return x + sprintf(buf + x, "\n");
 }
index b8a6fdc2131258db15321021375117cae27cec0d..d31d7ce52c0ea2dbbf85b26019c9fdd70fab624a 100644 (file)
@@ -913,7 +913,7 @@ keep_lumpy:
         * back off and wait for congestion to clear because further reclaim
         * will encounter the same problem
         */
-       if (nr_dirty == nr_congested)
+       if (nr_dirty == nr_congested && nr_dirty != 0)
                zone_set_flag(zone, ZONE_CONGESTED);
 
        free_page_list(&free_pages);
index cd2e42be7b68f73dc60f40631f2b9f87708d3b47..42eac4d33216b81c307a87016e821051bc86146e 100644 (file)
@@ -949,7 +949,7 @@ static void *vmstat_start(struct seq_file *m, loff_t *pos)
        v[PGPGIN] /= 2;         /* sectors -> kbytes */
        v[PGPGOUT] /= 2;
 #endif
-       return m->private + *pos;
+       return (unsigned long *)m->private + *pos;
 }
 
 static void *vmstat_next(struct seq_file *m, void *arg, loff_t *pos)
index 26eaebf4aaa9b11c3b9d8820b835ae07c50219e2..bb86d2932394aa9b1176ccfbba7a13102c0a3d20 100644 (file)
@@ -1392,6 +1392,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
        ax25_cb *ax25;
        int err = 0;
 
+       memset(fsa, 0, sizeof(fsa));
        lock_sock(sk);
        ax25 = ax25_sk(sk);
 
@@ -1403,7 +1404,6 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
 
                fsa->fsa_ax25.sax25_family = AF_AX25;
                fsa->fsa_ax25.sax25_call   = ax25->dest_addr;
-               fsa->fsa_ax25.sax25_ndigis = 0;
 
                if (ax25->digipeat != NULL) {
                        ndigi = ax25->digipeat->ndigi;
index bfef5bae0b3a83487c8894e171cf7fe6f447e651..84093b0000b9e0eb0107d22dd0503e699d36eff8 100644 (file)
@@ -1175,6 +1175,12 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
                                hci_send_cmd(hdev,
                                        HCI_OP_READ_REMOTE_EXT_FEATURES,
                                                        sizeof(cp), &cp);
+                       } else if (!ev->status && conn->out &&
+                                       conn->sec_level == BT_SECURITY_HIGH) {
+                               struct hci_cp_auth_requested cp;
+                               cp.handle = ev->handle;
+                               hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
+                                                       sizeof(cp), &cp);
                        } else {
                                conn->state = BT_CONNECTED;
                                hci_proto_connect_cfm(conn, ev->status);
index 98fdfa1fbddda7054b84e67d3e10bda033e80a4b..86a91543172a7e1ddcd88538d13c4750599bfdbb 100644 (file)
@@ -1,6 +1,6 @@
 config BT_HIDP
        tristate "HIDP protocol support"
-       depends on BT && BT_L2CAP && INPUT
+       depends on BT && BT_L2CAP && INPUT && HID_SUPPORT
        select HID
        help
          HIDP (Human Interface Device Protocol) is a transport layer
index daa7a988d9a6b4de7c7767748f1f18e1524cb78f..cd8f6ea038414ce21794f05f219f37716eea43e0 100644 (file)
@@ -2421,11 +2421,11 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned
                break;
 
        case 2:
-               *val = __le16_to_cpu(*((__le16 *) opt->val));
+               *val = get_unaligned_le16(opt->val);
                break;
 
        case 4:
-               *val = __le32_to_cpu(*((__le32 *) opt->val));
+               *val = get_unaligned_le32(opt->val);
                break;
 
        default:
@@ -2452,11 +2452,11 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
                break;
 
        case 2:
-               *((__le16 *) opt->val) = cpu_to_le16(val);
+               put_unaligned_le16(val, opt->val);
                break;
 
        case 4:
-               *((__le32 *) opt->val) = cpu_to_le32(val);
+               put_unaligned_le32(val, opt->val);
                break;
 
        default:
index 39a5d87e33b4221b7657933da0a1e2e1b5fe1784..fa642aa652bdba0d4b0b3f47c77dc9e55571c19f 100644 (file)
@@ -79,7 +79,10 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
 
 static void rfcomm_process_connect(struct rfcomm_session *s);
 
-static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
+static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
+                                                       bdaddr_t *dst,
+                                                       u8 sec_level,
+                                                       int *err);
 static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
 static void rfcomm_session_del(struct rfcomm_session *s);
 
@@ -401,7 +404,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
 
        s = rfcomm_session_get(src, dst);
        if (!s) {
-               s = rfcomm_session_create(src, dst, &err);
+               s = rfcomm_session_create(src, dst, d->sec_level, &err);
                if (!s)
                        return err;
        }
@@ -679,7 +682,10 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err)
        rfcomm_session_put(s);
 }
 
-static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
+static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
+                                                       bdaddr_t *dst,
+                                                       u8 sec_level,
+                                                       int *err)
 {
        struct rfcomm_session *s = NULL;
        struct sockaddr_l2 addr;
@@ -704,6 +710,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
        sk = sock->sk;
        lock_sock(sk);
        l2cap_pi(sk)->imtu = l2cap_mtu;
+       l2cap_pi(sk)->sec_level = sec_level;
        if (l2cap_ertm)
                l2cap_pi(sk)->mode = L2CAP_MODE_ERTM;
        release_sock(sk);
index 76ae68303d3a3675265e61eccc213a0c4526d4e1..d522d8c1703e761eb27b4e2375eff9851b06690e 100644 (file)
@@ -16,11 +16,18 @@ int connect_req_to_link_param(struct cfcnfg *cnfg,
 {
        struct dev_info *dev_info;
        enum cfcnfg_phy_preference pref;
+       int res;
+
        memset(l, 0, sizeof(*l));
-       l->priority = s->priority;
+       /* In caif protocol low value is high priority */
+       l->priority = CAIF_PRIO_MAX - s->priority + 1;
 
-       if (s->link_name[0] != '\0')
-               l->phyid = cfcnfg_get_named(cnfg, s->link_name);
+       if (s->ifindex != 0){
+               res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
+               if (res < 0)
+                       return res;
+               l->phyid = res;
+       }
        else {
                switch (s->link_selector) {
                case CAIF_LINK_HIGH_BANDW:
index b99369a055d13df6414421a28cfaee5d000c6c72..a42a408306e4a1c038aa6ad0d8fb3d0e2f923aa9 100644 (file)
@@ -307,6 +307,8 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
 
        case NETDEV_UNREGISTER:
                caifd = caif_get(dev);
+               if (caifd == NULL)
+                       break;
                netdev_info(dev, "unregister\n");
                atomic_set(&caifd->state, what);
                caif_device_destroy(dev);
index 2eca2dd0000fd7dce7fc614ed5e476f0ca886874..1bf0cf503796f27668d8dc8c1e9a733fd6e76bdd 100644 (file)
@@ -716,8 +716,7 @@ static int setsockopt(struct socket *sock,
 {
        struct sock *sk = sock->sk;
        struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
-       int prio, linksel;
-       struct ifreq ifreq;
+       int linksel;
 
        if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED)
                return -ENOPROTOOPT;
@@ -735,33 +734,6 @@ static int setsockopt(struct socket *sock,
                release_sock(&cf_sk->sk);
                return 0;
 
-       case SO_PRIORITY:
-               if (lvl != SOL_SOCKET)
-                       goto bad_sol;
-               if (ol < sizeof(int))
-                       return -EINVAL;
-               if (copy_from_user(&prio, ov, sizeof(int)))
-                       return -EINVAL;
-               lock_sock(&(cf_sk->sk));
-               cf_sk->conn_req.priority = prio;
-               release_sock(&cf_sk->sk);
-               return 0;
-
-       case SO_BINDTODEVICE:
-               if (lvl != SOL_SOCKET)
-                       goto bad_sol;
-               if (ol < sizeof(struct ifreq))
-                       return -EINVAL;
-               if (copy_from_user(&ifreq, ov, sizeof(ifreq)))
-                       return -EFAULT;
-               lock_sock(&(cf_sk->sk));
-               strncpy(cf_sk->conn_req.link_name, ifreq.ifr_name,
-                       sizeof(cf_sk->conn_req.link_name));
-               cf_sk->conn_req.link_name
-                       [sizeof(cf_sk->conn_req.link_name)-1] = 0;
-               release_sock(&cf_sk->sk);
-               return 0;
-
        case CAIFSO_REQ_PARAM:
                if (lvl != SOL_CAIF)
                        goto bad_sol;
@@ -880,6 +852,18 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
        sock->state = SS_CONNECTING;
        sk->sk_state = CAIF_CONNECTING;
 
+       /* Check priority value comming from socket */
+       /* if priority value is out of range it will be ajusted */
+       if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX)
+               cf_sk->conn_req.priority = CAIF_PRIO_MAX;
+       else if (cf_sk->sk.sk_priority < CAIF_PRIO_MIN)
+               cf_sk->conn_req.priority = CAIF_PRIO_MIN;
+       else
+               cf_sk->conn_req.priority = cf_sk->sk.sk_priority;
+
+       /*ifindex = id of the interface.*/
+       cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if;
+
        dbfs_atomic_inc(&cnt.num_connect_req);
        cf_sk->layer.receive = caif_sktrecv_cb;
        err = caif_connect_client(&cf_sk->conn_req,
@@ -905,6 +889,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
        cf_sk->maxframe = mtu - (headroom + tailroom);
        if (cf_sk->maxframe < 1) {
                pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu);
+               err = -ENODEV;
                goto out;
        }
 
@@ -1142,7 +1127,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
        set_rx_flow_on(cf_sk);
 
        /* Set default options on configuration */
-       cf_sk->conn_req.priority = CAIF_PRIO_NORMAL;
+       cf_sk->sk.sk_priority= CAIF_PRIO_NORMAL;
        cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY;
        cf_sk->conn_req.protocol = protocol;
        /* Increase the number of sockets created. */
index 41adafd1891422ab1aa32a95a46aee7d9ae77b82..21ede141018abf698a58bcf946e0058d6d06c499 100644 (file)
@@ -173,18 +173,15 @@ static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg,
        return NULL;
 }
 
-int cfcnfg_get_named(struct cfcnfg *cnfg, char *name)
+
+int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
 {
        int i;
-
-       /* Try to match with specified name */
-       for (i = 0; i < MAX_PHY_LAYERS; i++) {
-               if (cnfg->phy_layers[i].frm_layer != NULL
-                   && strcmp(cnfg->phy_layers[i].phy_layer->name,
-                             name) == 0)
-                       return cnfg->phy_layers[i].frm_layer->id;
-       }
-       return 0;
+       for (i = 0; i < MAX_PHY_LAYERS; i++)
+               if (cnfg->phy_layers[i].frm_layer != NULL &&
+                               cnfg->phy_layers[i].ifindex == ifi)
+                       return i;
+       return -ENODEV;
 }
 
 int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
index 08f267a109aa3c677efc4a6795ccfea31fc8d581..3cd8f978e3098288d9d1e114347e1ba2c0e4936c 100644 (file)
@@ -361,11 +361,10 @@ void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer)
        struct cfctrl_request_info *p, *tmp;
        struct cfctrl *ctrl = container_obj(layr);
        spin_lock(&ctrl->info_list_lock);
-       pr_warn("enter\n");
 
        list_for_each_entry_safe(p, tmp, &ctrl->list, list) {
                if (p->client_layer == adap_layer) {
-                       pr_warn("cancel req :%d\n", p->sequence_no);
+                       pr_debug("cancel req :%d\n", p->sequence_no);
                        list_del(&p->list);
                        kfree(p);
                }
index 496fda9ac66f56bee42568e8c0386566c3208be4..11a2af4c162ab6a8324ebaf6b8063ced01b1aea6 100644 (file)
@@ -12,6 +12,8 @@
 #include <net/caif/cfsrvl.h>
 #include <net/caif/cfpkt.h>
 
+#define container_obj(layr) ((struct cfsrvl *) layr)
+
 static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt);
 static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt);
 
@@ -38,5 +40,17 @@ static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt)
 
 static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt)
 {
+       struct cfsrvl *service = container_obj(layr);
+       struct caif_payload_info *info;
+       int ret;
+
+       if (!cfsrvl_ready(service, &ret))
+               return ret;
+
+       /* Add info for MUX-layer to route the packet out */
+       info = cfpkt_info(pkt);
+       info->channel_id = service->layer.id;
+       info->dev_info = &service->dev_info;
+
        return layr->dn->transmit(layr->dn, pkt);
 }
index bde8481e8d2574dd939f84595f8e4354370aa5a7..e2fb5fa757951a46e8d6be9326ffc1659f943232 100644 (file)
@@ -193,7 +193,7 @@ out:
 
 static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt)
 {
-       caif_assert(cfpkt_getlen(pkt) >= rfml->fragment_size);
+       caif_assert(cfpkt_getlen(pkt) < rfml->fragment_size);
 
        /* Add info for MUX-layer to route the packet out. */
        cfpkt_info(pkt)->channel_id = rfml->serv.layer.id;
index 08ffe9e4be20aa49ab2bba82c36c5e988a4880fd..6faa8256e10ca22d6fb0b2005d74c5c5580a404d 100644 (file)
@@ -125,7 +125,7 @@ struct bcm_sock {
        struct list_head tx_ops;
        unsigned long dropped_usr_msgs;
        struct proc_dir_entry *bcm_proc_read;
-       char procname [9]; /* pointer printed in ASCII with \0 */
+       char procname [20]; /* pointer printed in ASCII with \0 */
 };
 
 static inline struct bcm_sock *bcm_sk(const struct sock *sk)
index 63d260e8147290520212f50f1df27e638af9fe9e..3649d58953615fea0c0e1d1b5ba8882632df7676 100644 (file)
@@ -41,10 +41,12 @@ static inline int iov_from_user_compat_to_kern(struct iovec *kiov,
                compat_size_t len;
 
                if (get_user(len, &uiov32->iov_len) ||
-                  get_user(buf, &uiov32->iov_base)) {
-                       tot_len = -EFAULT;
-                       break;
-               }
+                   get_user(buf, &uiov32->iov_base))
+                       return -EFAULT;
+
+               if (len > INT_MAX - tot_len)
+                       len = INT_MAX - tot_len;
+
                tot_len += len;
                kiov->iov_base = compat_ptr(buf);
                kiov->iov_len = (__kernel_size_t) len;
index 35dfb83184833302e616dca6b0985faeb533897d..0dd54a69dace255fcdf54732d982e8c521c574a5 100644 (file)
@@ -2131,7 +2131,7 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
        } else {
                struct sock *sk = skb->sk;
                queue_index = sk_tx_queue_get(sk);
-               if (queue_index < 0) {
+               if (queue_index < 0 || queue_index >= dev->real_num_tx_queues) {
 
                        queue_index = 0;
                        if (dev->real_num_tx_queues > 1)
index 8abe628b79f173f96fc9e2372f442c91dacc2984..b99c7c7ffce2b72b0089ba8c53d4de6e5b131059 100644 (file)
@@ -370,6 +370,7 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event,
 
 static struct notifier_block dst_dev_notifier = {
        .notifier_call  = dst_dev_event,
+       .priority = -10, /* must be called after other network notifiers */
 };
 
 void __init dst_init(void)
index 7beaec36b541274bcd1d62c9fe8376b368ab3386..23e9b2a6b4c8ade67fff929c78cea57483b49964 100644 (file)
@@ -112,39 +112,41 @@ EXPORT_SYMBOL(sk_filter);
  */
 unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
 {
-       struct sock_filter *fentry;     /* We walk down these */
        void *ptr;
        u32 A = 0;                      /* Accumulator */
        u32 X = 0;                      /* Index Register */
        u32 mem[BPF_MEMWORDS];          /* Scratch Memory Store */
+       unsigned long memvalid = 0;
        u32 tmp;
        int k;
        int pc;
 
+       BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG);
        /*
         * Process array of filter instructions.
         */
        for (pc = 0; pc < flen; pc++) {
-               fentry = &filter[pc];
+               const struct sock_filter *fentry = &filter[pc];
+               u32 f_k = fentry->k;
 
                switch (fentry->code) {
                case BPF_S_ALU_ADD_X:
                        A += X;
                        continue;
                case BPF_S_ALU_ADD_K:
-                       A += fentry->k;
+                       A += f_k;
                        continue;
                case BPF_S_ALU_SUB_X:
                        A -= X;
                        continue;
                case BPF_S_ALU_SUB_K:
-                       A -= fentry->k;
+                       A -= f_k;
                        continue;
                case BPF_S_ALU_MUL_X:
                        A *= X;
                        continue;
                case BPF_S_ALU_MUL_K:
-                       A *= fentry->k;
+                       A *= f_k;
                        continue;
                case BPF_S_ALU_DIV_X:
                        if (X == 0)
@@ -152,49 +154,49 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
                        A /= X;
                        continue;
                case BPF_S_ALU_DIV_K:
-                       A /= fentry->k;
+                       A /= f_k;
                        continue;
                case BPF_S_ALU_AND_X:
                        A &= X;
                        continue;
                case BPF_S_ALU_AND_K:
-                       A &= fentry->k;
+                       A &= f_k;
                        continue;
                case BPF_S_ALU_OR_X:
                        A |= X;
                        continue;
                case BPF_S_ALU_OR_K:
-                       A |= fentry->k;
+                       A |= f_k;
                        continue;
                case BPF_S_ALU_LSH_X:
                        A <<= X;
                        continue;
                case BPF_S_ALU_LSH_K:
-                       A <<= fentry->k;
+                       A <<= f_k;
                        continue;
                case BPF_S_ALU_RSH_X:
                        A >>= X;
                        continue;
                case BPF_S_ALU_RSH_K:
-                       A >>= fentry->k;
+                       A >>= f_k;
                        continue;
                case BPF_S_ALU_NEG:
                        A = -A;
                        continue;
                case BPF_S_JMP_JA:
-                       pc += fentry->k;
+                       pc += f_k;
                        continue;
                case BPF_S_JMP_JGT_K:
-                       pc += (A > fentry->k) ? fentry->jt : fentry->jf;
+                       pc += (A > f_k) ? fentry->jt : fentry->jf;
                        continue;
                case BPF_S_JMP_JGE_K:
-                       pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
+                       pc += (A >= f_k) ? fentry->jt : fentry->jf;
                        continue;
                case BPF_S_JMP_JEQ_K:
-                       pc += (A == fentry->k) ? fentry->jt : fentry->jf;
+                       pc += (A == f_k) ? fentry->jt : fentry->jf;
                        continue;
                case BPF_S_JMP_JSET_K:
-                       pc += (A & fentry->k) ? fentry->jt : fentry->jf;
+                       pc += (A & f_k) ? fentry->jt : fentry->jf;
                        continue;
                case BPF_S_JMP_JGT_X:
                        pc += (A > X) ? fentry->jt : fentry->jf;
@@ -209,7 +211,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
                        pc += (A & X) ? fentry->jt : fentry->jf;
                        continue;
                case BPF_S_LD_W_ABS:
-                       k = fentry->k;
+                       k = f_k;
 load_w:
                        ptr = load_pointer(skb, k, 4, &tmp);
                        if (ptr != NULL) {
@@ -218,7 +220,7 @@ load_w:
                        }
                        break;
                case BPF_S_LD_H_ABS:
-                       k = fentry->k;
+                       k = f_k;
 load_h:
                        ptr = load_pointer(skb, k, 2, &tmp);
                        if (ptr != NULL) {
@@ -227,7 +229,7 @@ load_h:
                        }
                        break;
                case BPF_S_LD_B_ABS:
-                       k = fentry->k;
+                       k = f_k;
 load_b:
                        ptr = load_pointer(skb, k, 1, &tmp);
                        if (ptr != NULL) {
@@ -242,32 +244,34 @@ load_b:
                        X = skb->len;
                        continue;
                case BPF_S_LD_W_IND:
-                       k = X + fentry->k;
+                       k = X + f_k;
                        goto load_w;
                case BPF_S_LD_H_IND:
-                       k = X + fentry->k;
+                       k = X + f_k;
                        goto load_h;
                case BPF_S_LD_B_IND:
-                       k = X + fentry->k;
+                       k = X + f_k;
                        goto load_b;
                case BPF_S_LDX_B_MSH:
-                       ptr = load_pointer(skb, fentry->k, 1, &tmp);
+                       ptr = load_pointer(skb, f_k, 1, &tmp);
                        if (ptr != NULL) {
                                X = (*(u8 *)ptr & 0xf) << 2;
                                continue;
                        }
                        return 0;
                case BPF_S_LD_IMM:
-                       A = fentry->k;
+                       A = f_k;
                        continue;
                case BPF_S_LDX_IMM:
-                       X = fentry->k;
+                       X = f_k;
                        continue;
                case BPF_S_LD_MEM:
-                       A = mem[fentry->k];
+                       A = (memvalid & (1UL << f_k)) ?
+                               mem[f_k] : 0;
                        continue;
                case BPF_S_LDX_MEM:
-                       X = mem[fentry->k];
+                       X = (memvalid & (1UL << f_k)) ?
+                               mem[f_k] : 0;
                        continue;
                case BPF_S_MISC_TAX:
                        X = A;
@@ -276,14 +280,16 @@ load_b:
                        A = X;
                        continue;
                case BPF_S_RET_K:
-                       return fentry->k;
+                       return f_k;
                case BPF_S_RET_A:
                        return A;
                case BPF_S_ST:
-                       mem[fentry->k] = A;
+                       memvalid |= 1UL << f_k;
+                       mem[f_k] = A;
                        continue;
                case BPF_S_STX:
-                       mem[fentry->k] = X;
+                       memvalid |= 1UL << f_k;
+                       mem[f_k] = X;
                        continue;
                default:
                        WARN_ON(1);
index 72aceb1fe4fae6c072b12e5acc4c97bc4ed73cf7..c40f27e7d2089f713f5e2dac80d0940a7095156a 100644 (file)
  *     in any case.
  */
 
-long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
+int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
 {
-       int size, ct;
-       long err;
+       int size, ct, err;
 
        if (m->msg_namelen) {
                if (mode == VERIFY_READ) {
@@ -62,14 +61,13 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address,
        err = 0;
 
        for (ct = 0; ct < m->msg_iovlen; ct++) {
-               err += iov[ct].iov_len;
-               /*
-                * Goal is not to verify user data, but to prevent returning
-                * negative value, which is interpreted as errno.
-                * Overflow is still possible, but it is harmless.
-                */
-               if (err < 0)
-                       return -EMSGSIZE;
+               size_t len = iov[ct].iov_len;
+
+               if (len > INT_MAX - err) {
+                       len = INT_MAX - err;
+                       iov[ct].iov_len = len;
+               }
+               err += len;
        }
 
        return err;
index 679b797d06b1028888bdc9590a1f741918eece6c..33bc3823ac6fce64b227fafe670f2b12e3816a86 100644 (file)
@@ -887,10 +887,11 @@ static ssize_t pktgen_if_write(struct file *file,
        i += len;
 
        if (debug) {
-               char tb[count + 1];
-               if (copy_from_user(tb, user_buffer, count))
+               size_t copy = min_t(size_t, count, 1023);
+               char tb[copy + 1];
+               if (copy_from_user(tb, user_buffer, copy))
                        return -EFAULT;
-               tb[count] = 0;
+               tb[copy] = 0;
                printk(KERN_DEBUG "pktgen: %s,%lu  buffer -:%s:-\n", name,
                       (unsigned long)count, tb);
        }
@@ -2611,8 +2612,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
        /* Update any of the values, used when we're incrementing various
         * fields.
         */
-       queue_map = pkt_dev->cur_queue_map;
        mod_cur_headers(pkt_dev);
+       queue_map = pkt_dev->cur_queue_map;
 
        datalen = (odev->hard_header_len + 16) & ~0xf;
 
@@ -2975,8 +2976,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
        /* Update any of the values, used when we're incrementing various
         * fields.
         */
-       queue_map = pkt_dev->cur_queue_map;
        mod_cur_headers(pkt_dev);
+       queue_map = pkt_dev->cur_queue_map;
 
        skb = __netdev_alloc_skb(odev,
                                 pkt_dev->cur_pkt_size + 64
index 8121268ddbddfcd2da9845c8254fe0406b031be9..841c287ef40a4706c3465425880f95abd608e954 100644 (file)
@@ -347,16 +347,17 @@ static size_t rtnl_link_get_size(const struct net_device *dev)
        if (!ops)
                return 0;
 
-       size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
-              nlmsg_total_size(strlen(ops->kind) + 1);  /* IFLA_INFO_KIND */
+       size = nla_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
+              nla_total_size(strlen(ops->kind) + 1);  /* IFLA_INFO_KIND */
 
        if (ops->get_size)
                /* IFLA_INFO_DATA + nested data */
-               size += nlmsg_total_size(sizeof(struct nlattr)) +
+               size += nla_total_size(sizeof(struct nlattr)) +
                        ops->get_size(dev);
 
        if (ops->get_xstats_size)
-               size += ops->get_xstats_size(dev);      /* IFLA_INFO_XSTATS */
+               /* IFLA_INFO_XSTATS */
+               size += nla_total_size(ops->get_xstats_size(dev));
 
        return size;
 }
index 3eed5424e659a1ab130324d16bfe3c0af4ab2feb..fb6080111461546953b34979db77f5e2d516e060 100644 (file)
@@ -1653,10 +1653,10 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind)
 {
        struct proto *prot = sk->sk_prot;
        int amt = sk_mem_pages(size);
-       int allocated;
+       long allocated;
 
        sk->sk_forward_alloc += amt * SK_MEM_QUANTUM;
-       allocated = atomic_add_return(amt, prot->memory_allocated);
+       allocated = atomic_long_add_return(amt, prot->memory_allocated);
 
        /* Under limit. */
        if (allocated <= prot->sysctl_mem[0]) {
@@ -1714,7 +1714,7 @@ suppress_allocation:
 
        /* Alas. Undo changes. */
        sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM;
-       atomic_sub(amt, prot->memory_allocated);
+       atomic_long_sub(amt, prot->memory_allocated);
        return 0;
 }
 EXPORT_SYMBOL(__sk_mem_schedule);
@@ -1727,12 +1727,12 @@ void __sk_mem_reclaim(struct sock *sk)
 {
        struct proto *prot = sk->sk_prot;
 
-       atomic_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT,
+       atomic_long_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT,
                   prot->memory_allocated);
        sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1;
 
        if (prot->memory_pressure && *prot->memory_pressure &&
-           (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0]))
+           (atomic_long_read(prot->memory_allocated) < prot->sysctl_mem[0]))
                *prot->memory_pressure = 0;
 }
 EXPORT_SYMBOL(__sk_mem_reclaim);
@@ -2452,12 +2452,12 @@ static char proto_method_implemented(const void *method)
 
 static void proto_seq_printf(struct seq_file *seq, struct proto *proto)
 {
-       seq_printf(seq, "%-9s %4u %6d  %6d   %-3s %6u   %-3s  %-10s "
+       seq_printf(seq, "%-9s %4u %6d  %6ld   %-3s %6u   %-3s  %-10s "
                        "%2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c\n",
                   proto->name,
                   proto->obj_size,
                   sock_prot_inuse_get(seq_file_net(seq), proto),
-                  proto->memory_allocated != NULL ? atomic_read(proto->memory_allocated) : -1,
+                  proto->memory_allocated != NULL ? atomic_long_read(proto->memory_allocated) : -1L,
                   proto->memory_pressure != NULL ? *proto->memory_pressure ? "yes" : "no" : "NI",
                   proto->max_header,
                   proto->slab == NULL ? "no" : "yes",
index 117fb093dcafeebab54ee687e6d50317b4e88239..75c3582a7678ab418771b2a5ad5fd3c069a9e512 100644 (file)
@@ -134,13 +134,41 @@ static inline int ccid_get_current_tx_ccid(struct dccp_sock *dp)
 extern void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk);
 extern void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk);
 
+/*
+ * Congestion control of queued data packets via CCID decision.
+ *
+ * The TX CCID performs its congestion-control by indicating whether and when a
+ * queued packet may be sent, using the return code of ccid_hc_tx_send_packet().
+ * The following modes are supported via the symbolic constants below:
+ * - timer-based pacing    (CCID returns a delay value in milliseconds);
+ * - autonomous dequeueing (CCID internally schedules dccps_xmitlet).
+ */
+
+enum ccid_dequeueing_decision {
+       CCID_PACKET_SEND_AT_ONCE =       0x00000,  /* "green light": no delay */
+       CCID_PACKET_DELAY_MAX =          0x0FFFF,  /* maximum delay in msecs  */
+       CCID_PACKET_DELAY =              0x10000,  /* CCID msec-delay mode */
+       CCID_PACKET_WILL_DEQUEUE_LATER = 0x20000,  /* CCID autonomous mode */
+       CCID_PACKET_ERR =                0xF0000,  /* error condition */
+};
+
+static inline int ccid_packet_dequeue_eval(const int return_code)
+{
+       if (return_code < 0)
+               return CCID_PACKET_ERR;
+       if (return_code == 0)
+               return CCID_PACKET_SEND_AT_ONCE;
+       if (return_code <= CCID_PACKET_DELAY_MAX)
+               return CCID_PACKET_DELAY;
+       return return_code;
+}
+
 static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk,
                                         struct sk_buff *skb)
 {
-       int rc = 0;
        if (ccid->ccid_ops->ccid_hc_tx_send_packet != NULL)
-               rc = ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb);
-       return rc;
+               return ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb);
+       return CCID_PACKET_SEND_AT_ONCE;
 }
 
 static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk,
index d850e291f87c8b23defdba15d89849892038b251..6576eae9e7792499f962592ce66cebf8c8d34fe7 100644 (file)
@@ -78,12 +78,9 @@ static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hc)
 
 static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
 {
-       struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
-
-       if (hc->tx_pipe < hc->tx_cwnd)
-               return 0;
-
-       return 1; /* XXX CCID should dequeue when ready instead of polling */
+       if (ccid2_cwnd_network_limited(ccid2_hc_tx_sk(sk)))
+               return CCID_PACKET_WILL_DEQUEUE_LATER;
+       return CCID_PACKET_SEND_AT_ONCE;
 }
 
 static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
@@ -115,6 +112,7 @@ static void ccid2_hc_tx_rto_expire(unsigned long data)
 {
        struct sock *sk = (struct sock *)data;
        struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
+       const bool sender_was_blocked = ccid2_cwnd_network_limited(hc);
 
        bh_lock_sock(sk);
        if (sock_owned_by_user(sk)) {
@@ -129,8 +127,6 @@ static void ccid2_hc_tx_rto_expire(unsigned long data)
        if (hc->tx_rto > DCCP_RTO_MAX)
                hc->tx_rto = DCCP_RTO_MAX;
 
-       sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
-
        /* adjust pipe, cwnd etc */
        hc->tx_ssthresh = hc->tx_cwnd / 2;
        if (hc->tx_ssthresh < 2)
@@ -146,6 +142,12 @@ static void ccid2_hc_tx_rto_expire(unsigned long data)
        hc->tx_rpseq    = 0;
        hc->tx_rpdupack = -1;
        ccid2_change_l_ack_ratio(sk, 1);
+
+       /* if we were blocked before, we may now send cwnd=1 packet */
+       if (sender_was_blocked)
+               tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet);
+       /* restart backed-off timer */
+       sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
 out:
        bh_unlock_sock(sk);
        sock_put(sk);
@@ -434,6 +436,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct dccp_sock *dp = dccp_sk(sk);
        struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
+       const bool sender_was_blocked = ccid2_cwnd_network_limited(hc);
        u64 ackno, seqno;
        struct ccid2_seq *seqp;
        unsigned char *vector;
@@ -631,6 +634,10 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                sk_stop_timer(sk, &hc->tx_rtotimer);
        else
                sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
+
+       /* check if incoming Acks allow pending packets to be sent */
+       if (sender_was_blocked && !ccid2_cwnd_network_limited(hc))
+               tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet);
 }
 
 static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
index 9731c2dc148715eacace932c37f695989f526450..25cb6b216eda52e3e3d51163405471418438f40d 100644 (file)
@@ -81,6 +81,11 @@ struct ccid2_hc_tx_sock {
        u64                     tx_high_ack;
 };
 
+static inline bool ccid2_cwnd_network_limited(struct ccid2_hc_tx_sock *hc)
+{
+       return hc->tx_pipe >= hc->tx_cwnd;
+}
+
 struct ccid2_hc_rx_sock {
        int     rx_data;
 };
index 3060a60ed5abd7f6212f6ccd7fa76b9ffe88bc01..3d604e1349c0b0e5d94ff755a90c7dd395b92a24 100644 (file)
@@ -268,11 +268,11 @@ out:
        sock_put(sk);
 }
 
-/*
- * returns
- *   > 0: delay (in msecs) that should pass before actually sending
- *   = 0: can send immediately
- *   < 0: error condition; do not send packet
+/**
+ * ccid3_hc_tx_send_packet  -  Delay-based dequeueing of TX packets
+ * @skb: next packet candidate to send on @sk
+ * This function uses the convention of ccid_packet_dequeue_eval() and
+ * returns a millisecond-delay value between 0 and t_mbi = 64000 msec.
  */
 static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
 {
@@ -348,7 +348,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
 
        /* set the nominal send time for the next following packet */
        hc->tx_t_nom = ktime_add_us(hc->tx_t_nom, hc->tx_t_ipi);
-       return 0;
+       return CCID_PACKET_SEND_AT_ONCE;
 }
 
 static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len)
index 3eb264b608239c74c16d27625cc4b3b5199a3ef8..a8ed459508b294feb774c1597e788fa38313e995 100644 (file)
@@ -243,8 +243,9 @@ extern void dccp_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
 extern void dccp_send_sync(struct sock *sk, const u64 seq,
                           const enum dccp_pkt_type pkt_type);
 
-extern void dccp_write_xmit(struct sock *sk, int block);
-extern void dccp_write_space(struct sock *sk);
+extern void   dccp_write_xmit(struct sock *sk);
+extern void   dccp_write_space(struct sock *sk);
+extern void   dccp_flush_write_queue(struct sock *sk, long *time_budget);
 
 extern void dccp_init_xmit_timers(struct sock *sk);
 static inline void dccp_clear_xmit_timers(struct sock *sk)
index a988fe9ffcbafdf74b6e90b24f4e8b8caa57591d..45b91853f5aee3d452d5795da832b9e1f04651ed 100644 (file)
@@ -209,108 +209,150 @@ void dccp_write_space(struct sock *sk)
 }
 
 /**
- * dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet
+ * dccp_wait_for_ccid  -  Await CCID send permission
  * @sk:    socket to wait for
- * @skb:   current skb to pass on for waiting
- * @delay: sleep timeout in milliseconds (> 0)
- * This function is called by default when the socket is closed, and
- * when a non-zero linger time is set on the socket. For consistency
+ * @delay: timeout in jiffies
+ * This is used by CCIDs which need to delay the send time in process context.
  */
-static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, int delay)
+static int dccp_wait_for_ccid(struct sock *sk, unsigned long delay)
 {
-       struct dccp_sock *dp = dccp_sk(sk);
        DEFINE_WAIT(wait);
-       unsigned long jiffdelay;
-       int rc;
+       long remaining;
+
+       prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+       sk->sk_write_pending++;
+       release_sock(sk);
+
+       remaining = schedule_timeout(delay);
+
+       lock_sock(sk);
+       sk->sk_write_pending--;
+       finish_wait(sk_sleep(sk), &wait);
+
+       if (signal_pending(current) || sk->sk_err)
+               return -1;
+       return remaining;
+}
+
+/**
+ * dccp_xmit_packet  -  Send data packet under control of CCID
+ * Transmits next-queued payload and informs CCID to account for the packet.
+ */
+static void dccp_xmit_packet(struct sock *sk)
+{
+       int err, len;
+       struct dccp_sock *dp = dccp_sk(sk);
+       struct sk_buff *skb = skb_dequeue(&sk->sk_write_queue);
 
-       do {
-               dccp_pr_debug("delayed send by %d msec\n", delay);
-               jiffdelay = msecs_to_jiffies(delay);
+       if (unlikely(skb == NULL))
+               return;
+       len = skb->len;
 
-               prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+       if (sk->sk_state == DCCP_PARTOPEN) {
+               const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD;
+               /*
+                * See 8.1.5 - Handshake Completion.
+                *
+                * For robustness we resend Confirm options until the client has
+                * entered OPEN. During the initial feature negotiation, the MPS
+                * is smaller than usual, reduced by the Change/Confirm options.
+                */
+               if (!list_empty(&dp->dccps_featneg) && len > cur_mps) {
+                       DCCP_WARN("Payload too large (%d) for featneg.\n", len);
+                       dccp_send_ack(sk);
+                       dccp_feat_list_purge(&dp->dccps_featneg);
+               }
 
-               sk->sk_write_pending++;
-               release_sock(sk);
-               schedule_timeout(jiffdelay);
-               lock_sock(sk);
-               sk->sk_write_pending--;
+               inet_csk_schedule_ack(sk);
+               inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
+                                             inet_csk(sk)->icsk_rto,
+                                             DCCP_RTO_MAX);
+               DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK;
+       } else if (dccp_ack_pending(sk)) {
+               DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK;
+       } else {
+               DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATA;
+       }
+
+       err = dccp_transmit_skb(sk, skb);
+       if (err)
+               dccp_pr_debug("transmit_skb() returned err=%d\n", err);
+       /*
+        * Register this one as sent even if an error occurred. To the remote
+        * end a local packet drop is indistinguishable from network loss, i.e.
+        * any local drop will eventually be reported via receiver feedback.
+        */
+       ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len);
+}
 
-               if (sk->sk_err)
-                       goto do_error;
-               if (signal_pending(current))
-                       goto do_interrupted;
+/**
+ * dccp_flush_write_queue  -  Drain queue at end of connection
+ * Since dccp_sendmsg queues packets without waiting for them to be sent, it may
+ * happen that the TX queue is not empty at the end of a connection. We give the
+ * HC-sender CCID a grace period of up to @time_budget jiffies. If this function
+ * returns with a non-empty write queue, it will be purged later.
+ */
+void dccp_flush_write_queue(struct sock *sk, long *time_budget)
+{
+       struct dccp_sock *dp = dccp_sk(sk);
+       struct sk_buff *skb;
+       long delay, rc;
 
+       while (*time_budget > 0 && (skb = skb_peek(&sk->sk_write_queue))) {
                rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
-       } while ((delay = rc) > 0);
-out:
-       finish_wait(sk_sleep(sk), &wait);
-       return rc;
-
-do_error:
-       rc = -EPIPE;
-       goto out;
-do_interrupted:
-       rc = -EINTR;
-       goto out;
+
+               switch (ccid_packet_dequeue_eval(rc)) {
+               case CCID_PACKET_WILL_DEQUEUE_LATER:
+                       /*
+                        * If the CCID determines when to send, the next sending
+                        * time is unknown or the CCID may not even send again
+                        * (e.g. remote host crashes or lost Ack packets).
+                        */
+                       DCCP_WARN("CCID did not manage to send all packets\n");
+                       return;
+               case CCID_PACKET_DELAY:
+                       delay = msecs_to_jiffies(rc);
+                       if (delay > *time_budget)
+                               return;
+                       rc = dccp_wait_for_ccid(sk, delay);
+                       if (rc < 0)
+                               return;
+                       *time_budget -= (delay - rc);
+                       /* check again if we can send now */
+                       break;
+               case CCID_PACKET_SEND_AT_ONCE:
+                       dccp_xmit_packet(sk);
+                       break;
+               case CCID_PACKET_ERR:
+                       skb_dequeue(&sk->sk_write_queue);
+                       kfree_skb(skb);
+                       dccp_pr_debug("packet discarded due to err=%ld\n", rc);
+               }
+       }
 }
 
-void dccp_write_xmit(struct sock *sk, int block)
+void dccp_write_xmit(struct sock *sk)
 {
        struct dccp_sock *dp = dccp_sk(sk);
        struct sk_buff *skb;
 
        while ((skb = skb_peek(&sk->sk_write_queue))) {
-               int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
-
-               if (err > 0) {
-                       if (!block) {
-                               sk_reset_timer(sk, &dp->dccps_xmit_timer,
-                                               msecs_to_jiffies(err)+jiffies);
-                               break;
-                       } else
-                               err = dccp_wait_for_ccid(sk, skb, err);
-                       if (err && err != -EINTR)
-                               DCCP_BUG("err=%d after dccp_wait_for_ccid", err);
-               }
+               int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
 
-               skb_dequeue(&sk->sk_write_queue);
-               if (err == 0) {
-                       struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
-                       const int len = skb->len;
-
-                       if (sk->sk_state == DCCP_PARTOPEN) {
-                               const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD;
-                               /*
-                                * See 8.1.5 - Handshake Completion.
-                                *
-                                * For robustness we resend Confirm options until the client has
-                                * entered OPEN. During the initial feature negotiation, the MPS
-                                * is smaller than usual, reduced by the Change/Confirm options.
-                                */
-                               if (!list_empty(&dp->dccps_featneg) && len > cur_mps) {
-                                       DCCP_WARN("Payload too large (%d) for featneg.\n", len);
-                                       dccp_send_ack(sk);
-                                       dccp_feat_list_purge(&dp->dccps_featneg);
-                               }
-
-                               inet_csk_schedule_ack(sk);
-                               inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
-                                                 inet_csk(sk)->icsk_rto,
-                                                 DCCP_RTO_MAX);
-                               dcb->dccpd_type = DCCP_PKT_DATAACK;
-                       } else if (dccp_ack_pending(sk))
-                               dcb->dccpd_type = DCCP_PKT_DATAACK;
-                       else
-                               dcb->dccpd_type = DCCP_PKT_DATA;
-
-                       err = dccp_transmit_skb(sk, skb);
-                       ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len);
-                       if (err)
-                               DCCP_BUG("err=%d after ccid_hc_tx_packet_sent",
-                                        err);
-               } else {
-                       dccp_pr_debug("packet discarded due to err=%d\n", err);
+               switch (ccid_packet_dequeue_eval(rc)) {
+               case CCID_PACKET_WILL_DEQUEUE_LATER:
+                       return;
+               case CCID_PACKET_DELAY:
+                       sk_reset_timer(sk, &dp->dccps_xmit_timer,
+                                      jiffies + msecs_to_jiffies(rc));
+                       return;
+               case CCID_PACKET_SEND_AT_ONCE:
+                       dccp_xmit_packet(sk);
+                       break;
+               case CCID_PACKET_ERR:
+                       skb_dequeue(&sk->sk_write_queue);
                        kfree_skb(skb);
+                       dccp_pr_debug("packet discarded due to err=%d\n", rc);
                }
        }
 }
@@ -622,7 +664,6 @@ void dccp_send_close(struct sock *sk, const int active)
                DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE;
 
        if (active) {
-               dccp_write_xmit(sk, 1);
                dccp_skb_entail(sk, skb);
                dccp_transmit_skb(sk, skb_clone(skb, prio));
                /*
index 7e5fc04eb6d1989986b7c7241f0e5cb2106ce4d8..ef343d53fcea22edf7d7bb2be677f349ec63f547 100644 (file)
@@ -726,7 +726,13 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                goto out_discard;
 
        skb_queue_tail(&sk->sk_write_queue, skb);
-       dccp_write_xmit(sk,0);
+       /*
+        * The xmit_timer is set if the TX CCID is rate-based and will expire
+        * when congestion control permits to release further packets into the
+        * network. Window-based CCIDs do not use this timer.
+        */
+       if (!timer_pending(&dp->dccps_xmit_timer))
+               dccp_write_xmit(sk);
 out_release:
        release_sock(sk);
        return rc ? : len;
@@ -951,9 +957,22 @@ void dccp_close(struct sock *sk, long timeout)
                /* Check zero linger _after_ checking for unread data. */
                sk->sk_prot->disconnect(sk, 0);
        } else if (sk->sk_state != DCCP_CLOSED) {
+               /*
+                * Normal connection termination. May need to wait if there are
+                * still packets in the TX queue that are delayed by the CCID.
+                */
+               dccp_flush_write_queue(sk, &timeout);
                dccp_terminate_connection(sk);
        }
 
+       /*
+        * Flush write queue. This may be necessary in several cases:
+        * - we have been closed by the peer but still have application data;
+        * - abortive termination (unread data or zero linger time),
+        * - normal termination but queue could not be flushed within time limit
+        */
+       __skb_queue_purge(&sk->sk_write_queue);
+
        sk_stream_wait_close(sk, timeout);
 
 adjudge_to_death:
index 1a9aa05d4dc4c399952cb9932d728768aa619e2d..7587870b7040d0d997a54efd4d2c0786a1bb8a7d 100644 (file)
@@ -237,32 +237,35 @@ out:
        sock_put(sk);
 }
 
-/* Transmit-delay timer: used by the CCIDs to delay actual send time */
-static void dccp_write_xmit_timer(unsigned long data)
+/**
+ * dccp_write_xmitlet  -  Workhorse for CCID packet dequeueing interface
+ * See the comments above %ccid_dequeueing_decision for supported modes.
+ */
+static void dccp_write_xmitlet(unsigned long data)
 {
        struct sock *sk = (struct sock *)data;
-       struct dccp_sock *dp = dccp_sk(sk);
 
        bh_lock_sock(sk);
        if (sock_owned_by_user(sk))
-               sk_reset_timer(sk, &dp->dccps_xmit_timer, jiffies+1);
+               sk_reset_timer(sk, &dccp_sk(sk)->dccps_xmit_timer, jiffies + 1);
        else
-               dccp_write_xmit(sk, 0);
+               dccp_write_xmit(sk);
        bh_unlock_sock(sk);
-       sock_put(sk);
 }
 
-static void dccp_init_write_xmit_timer(struct sock *sk)
+static void dccp_write_xmit_timer(unsigned long data)
 {
-       struct dccp_sock *dp = dccp_sk(sk);
-
-       setup_timer(&dp->dccps_xmit_timer, dccp_write_xmit_timer,
-                       (unsigned long)sk);
+       dccp_write_xmitlet(data);
+       sock_put((struct sock *)data);
 }
 
 void dccp_init_xmit_timers(struct sock *sk)
 {
-       dccp_init_write_xmit_timer(sk);
+       struct dccp_sock *dp = dccp_sk(sk);
+
+       tasklet_init(&dp->dccps_xmitlet, dccp_write_xmitlet, (unsigned long)sk);
+       setup_timer(&dp->dccps_xmit_timer, dccp_write_xmit_timer,
+                                                            (unsigned long)sk);
        inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer,
                                  &dccp_keepalive_timer);
 }
index d6b93d19790f003b92935c1b1da7700e8d788787..a76b78de679fa7e928cfae7b62c0a7e73c2256dd 100644 (file)
@@ -155,7 +155,7 @@ static const struct proto_ops dn_proto_ops;
 static DEFINE_RWLOCK(dn_hash_lock);
 static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
 static struct hlist_head dn_wild_sk;
-static atomic_t decnet_memory_allocated;
+static atomic_long_t decnet_memory_allocated;
 
 static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags);
 static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
index be3eb8e23288ed078e947a3ef8e78d671666b9be..28f8b5e5f73b20fcee72b7aa536f1fdd04dc95c9 100644 (file)
@@ -38,7 +38,7 @@ int decnet_log_martians = 1;
 int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW;
 
 /* Reasonable defaults, I hope, based on tcp's defaults */
-int sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 };
+long sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 };
 int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
 int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 };
 
@@ -324,7 +324,7 @@ static ctl_table dn_table[] = {
                .data = &sysctl_decnet_mem,
                .maxlen = sizeof(sysctl_decnet_mem),
                .mode = 0644,
-               .proc_handler = proc_dointvec,
+               .proc_handler = proc_doulongvec_minmax
        },
        {
                .procname = "decnet_rmem",
index 36e27c2107de9f8286e7848c9b0dfe3560ab2907..eb6f69a8f27aff4db2de494389dd7d9584b93ece 100644 (file)
@@ -1052,7 +1052,7 @@ static void ip_fib_net_exit(struct net *net)
                hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) {
                        hlist_del(node);
                        fib_table_flush(tb);
-                       kfree(tb);
+                       fib_free_table(tb);
                }
        }
        kfree(net->ipv4.fib_table_hash);
index b232375a0b75f4f3108284c9bcb4b993b415ebdc..b3acb0417b21f69b754003f76168f30f78b85700 100644 (file)
@@ -716,6 +716,24 @@ int fib_table_flush(struct fib_table *tb)
        return found;
 }
 
+void fib_free_table(struct fib_table *tb)
+{
+       struct fn_hash *table = (struct fn_hash *) tb->tb_data;
+       struct fn_zone *fz, *next;
+
+       next = table->fn_zone_list;
+       while (next != NULL) {
+               fz = next;
+               next = fz->fz_next;
+
+               if (fz->fz_hash != fz->fz_embedded_hash)
+                       fz_hash_free(fz->fz_hash, fz->fz_divisor);
+
+               kfree(fz);
+       }
+
+       kfree(tb);
+}
 
 static inline int
 fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
index a29edf2219c8437b811bcce27fdd2cd9fca0a9fc..c079cc0ec6515fe212aecd27303c2b5671a5d60d 100644 (file)
@@ -47,11 +47,8 @@ extern int fib_detect_death(struct fib_info *fi, int order,
 static inline void fib_result_assign(struct fib_result *res,
                                     struct fib_info *fi)
 {
-       if (res->fi != NULL)
-               fib_info_put(res->fi);
+       /* we used to play games with refcounts, but we now use RCU */
        res->fi = fi;
-       if (fi != NULL)
-               atomic_inc(&fi->fib_clntref);
 }
 
 #endif /* _FIB_LOOKUP_H */
index b14450895102ae385f2c603eb1b591bc3170f994..200eb538fbb3f77101fe9646893dddbd9e83117b 100644 (file)
@@ -1797,6 +1797,11 @@ int fib_table_flush(struct fib_table *tb)
        return found;
 }
 
+void fib_free_table(struct fib_table *tb)
+{
+       kfree(tb);
+}
+
 void fib_table_select_default(struct fib_table *tb,
                              const struct flowi *flp,
                              struct fib_result *res)
index c8877c6c72164ccaee2af4def0025f8300bc7e80..3c53c2d89e3b47b3e42629bfe37086aeeeda7aa8 100644 (file)
@@ -2306,10 +2306,8 @@ void ip_mc_drop_socket(struct sock *sk)
 
                in_dev = inetdev_by_index(net, iml->multi.imr_ifindex);
                (void) ip_mc_leave_src(sk, iml, in_dev);
-               if (in_dev != NULL) {
+               if (in_dev != NULL)
                        ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
-                       in_dev_put(in_dev);
-               }
                /* decrease mem now to avoid the memleak warning */
                atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
                call_rcu(&iml->rcu, ip_mc_socklist_reclaim);
index ba80426658498ba4082c54a19c5af2d2c00cdb10..2ada17129fce6ac9a7285f6033e30d0a9bc4b98a 100644 (file)
@@ -490,9 +490,11 @@ static int inet_csk_diag_dump(struct sock *sk,
 {
        struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
 
-       if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
+       if (nlmsg_attrlen(cb->nlh, sizeof(*r))) {
                struct inet_diag_entry entry;
-               struct rtattr *bc = (struct rtattr *)(r + 1);
+               const struct nlattr *bc = nlmsg_find_attr(cb->nlh,
+                                                         sizeof(*r),
+                                                         INET_DIAG_REQ_BYTECODE);
                struct inet_sock *inet = inet_sk(sk);
 
                entry.family = sk->sk_family;
@@ -512,7 +514,7 @@ static int inet_csk_diag_dump(struct sock *sk,
                entry.dport = ntohs(inet->inet_dport);
                entry.userlocks = sk->sk_userlocks;
 
-               if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry))
+               if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry))
                        return 0;
        }
 
@@ -527,9 +529,11 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
 {
        struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
 
-       if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
+       if (nlmsg_attrlen(cb->nlh, sizeof(*r))) {
                struct inet_diag_entry entry;
-               struct rtattr *bc = (struct rtattr *)(r + 1);
+               const struct nlattr *bc = nlmsg_find_attr(cb->nlh,
+                                                         sizeof(*r),
+                                                         INET_DIAG_REQ_BYTECODE);
 
                entry.family = tw->tw_family;
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
@@ -548,7 +552,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
                entry.dport = ntohs(tw->tw_dport);
                entry.userlocks = 0;
 
-               if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry))
+               if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry))
                        return 0;
        }
 
@@ -618,7 +622,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
        struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct listen_sock *lopt;
-       struct rtattr *bc = NULL;
+       const struct nlattr *bc = NULL;
        struct inet_sock *inet = inet_sk(sk);
        int j, s_j;
        int reqnum, s_reqnum;
@@ -638,8 +642,9 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
        if (!lopt || !lopt->qlen)
                goto out;
 
-       if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
-               bc = (struct rtattr *)(r + 1);
+       if (nlmsg_attrlen(cb->nlh, sizeof(*r))) {
+               bc = nlmsg_find_attr(cb->nlh, sizeof(*r),
+                                    INET_DIAG_REQ_BYTECODE);
                entry.sport = inet->inet_num;
                entry.userlocks = sk->sk_userlocks;
        }
@@ -672,8 +677,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
                                        &ireq->rmt_addr;
                                entry.dport = ntohs(ireq->rmt_port);
 
-                               if (!inet_diag_bc_run(RTA_DATA(bc),
-                                                   RTA_PAYLOAD(bc), &entry))
+                               if (!inet_diag_bc_run(nla_data(bc),
+                                                     nla_len(bc), &entry))
                                        continue;
                        }
 
index 01087e035b7d6632f9543d36ebfbf025212fc8a9..70ff77f02eee3b345fa94efd35563a95b2b582ef 100644 (file)
@@ -1325,7 +1325,6 @@ static void ipgre_fb_tunnel_init(struct net_device *dev)
 {
        struct ip_tunnel *tunnel = netdev_priv(dev);
        struct iphdr *iph = &tunnel->parms.iph;
-       struct ipgre_net *ign = net_generic(dev_net(dev), ipgre_net_id);
 
        tunnel->dev = dev;
        strcpy(tunnel->parms.name, dev->name);
@@ -1336,7 +1335,6 @@ static void ipgre_fb_tunnel_init(struct net_device *dev)
        tunnel->hlen            = sizeof(struct iphdr) + 4;
 
        dev_hold(dev);
-       rcu_assign_pointer(ign->tunnels_wc[0], tunnel);
 }
 
 
@@ -1383,10 +1381,12 @@ static int __net_init ipgre_init_net(struct net *net)
        if ((err = register_netdev(ign->fb_tunnel_dev)))
                goto err_reg_dev;
 
+       rcu_assign_pointer(ign->tunnels_wc[0],
+                          netdev_priv(ign->fb_tunnel_dev));
        return 0;
 
 err_reg_dev:
-       free_netdev(ign->fb_tunnel_dev);
+       ipgre_dev_free(ign->fb_tunnel_dev);
 err_alloc_dev:
        return err;
 }
index 3cad2591ace0c15fdad446ab528b0f40c2624d09..3fac340a28d5394bd95bd649d5bcee3dcb3d24df 100644 (file)
@@ -927,6 +927,7 @@ static int get_info(struct net *net, void __user *user,
                        private = &tmp;
                }
 #endif
+               memset(&info, 0, sizeof(info));
                info.valid_hooks = t->valid_hooks;
                memcpy(info.hook_entry, private->hook_entry,
                       sizeof(info.hook_entry));
index d31b007a6d80dcda45f7f7913ec72af7556b79bf..a846d633b3b6f04a3ed72be1d884e484d3efa030 100644 (file)
@@ -1124,6 +1124,7 @@ static int get_info(struct net *net, void __user *user,
                        private = &tmp;
                }
 #endif
+               memset(&info, 0, sizeof(info));
                info.valid_hooks = t->valid_hooks;
                memcpy(info.hook_entry, private->hook_entry,
                       sizeof(info.hook_entry));
index 295c97431e4358408dc45fc7c493536bb41434fc..c04787ce1a71203e1346830450b0a130e358defc 100644 (file)
@@ -47,26 +47,6 @@ __nf_nat_proto_find(u_int8_t protonum)
        return rcu_dereference(nf_nat_protos[protonum]);
 }
 
-static const struct nf_nat_protocol *
-nf_nat_proto_find_get(u_int8_t protonum)
-{
-       const struct nf_nat_protocol *p;
-
-       rcu_read_lock();
-       p = __nf_nat_proto_find(protonum);
-       if (!try_module_get(p->me))
-               p = &nf_nat_unknown_protocol;
-       rcu_read_unlock();
-
-       return p;
-}
-
-static void
-nf_nat_proto_put(const struct nf_nat_protocol *p)
-{
-       module_put(p->me);
-}
-
 /* We keep an extra hash for each conntrack, for fast searching. */
 static inline unsigned int
 hash_by_src(const struct net *net, u16 zone,
@@ -588,6 +568,26 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nfnetlink_conntrack.h>
 
+static const struct nf_nat_protocol *
+nf_nat_proto_find_get(u_int8_t protonum)
+{
+       const struct nf_nat_protocol *p;
+
+       rcu_read_lock();
+       p = __nf_nat_proto_find(protonum);
+       if (!try_module_get(p->me))
+               p = &nf_nat_unknown_protocol;
+       rcu_read_unlock();
+
+       return p;
+}
+
+static void
+nf_nat_proto_put(const struct nf_nat_protocol *p)
+{
+       module_put(p->me);
+}
+
 static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
        [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
        [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
index 4ae1f203f7cbb5daf7c07bea4a062c352c83700d..1b48eb1ed4531d3fd037e7ee9aa6367b6cb575f3 100644 (file)
@@ -59,13 +59,13 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
        local_bh_enable();
 
        socket_seq_show(seq);
-       seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n",
+       seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n",
                   sock_prot_inuse_get(net, &tcp_prot), orphans,
                   tcp_death_row.tw_count, sockets,
-                  atomic_read(&tcp_memory_allocated));
-       seq_printf(seq, "UDP: inuse %d mem %d\n",
+                  atomic_long_read(&tcp_memory_allocated));
+       seq_printf(seq, "UDP: inuse %d mem %ld\n",
                   sock_prot_inuse_get(net, &udp_prot),
-                  atomic_read(&udp_memory_allocated));
+                  atomic_long_read(&udp_memory_allocated));
        seq_printf(seq, "UDPLITE: inuse %d\n",
                   sock_prot_inuse_get(net, &udplite_prot));
        seq_printf(seq, "RAW: inuse %d\n",
index d96c1da4b17cf97790bb2a426abbe5eb4582356d..e91911d7aae26656f940a747a6d0ccb91739f39a 100644 (file)
@@ -398,7 +398,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_mem,
                .maxlen         = sizeof(sysctl_tcp_mem),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec
+               .proc_handler   = proc_doulongvec_minmax
        },
        {
                .procname       = "tcp_wmem",
@@ -602,8 +602,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_udp_mem,
                .maxlen         = sizeof(sysctl_udp_mem),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec_minmax,
-               .extra1         = &zero
+               .proc_handler   = proc_doulongvec_minmax,
        },
        {
                .procname       = "udp_rmem_min",
index 1664a0590bb8f28fe5662e2cfdbc3a6d660d4549..0814199694854e534eb4ff12671e02313dced8e9 100644 (file)
@@ -282,7 +282,7 @@ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
 struct percpu_counter tcp_orphan_count;
 EXPORT_SYMBOL_GPL(tcp_orphan_count);
 
-int sysctl_tcp_mem[3] __read_mostly;
+long sysctl_tcp_mem[3] __read_mostly;
 int sysctl_tcp_wmem[3] __read_mostly;
 int sysctl_tcp_rmem[3] __read_mostly;
 
@@ -290,7 +290,7 @@ EXPORT_SYMBOL(sysctl_tcp_mem);
 EXPORT_SYMBOL(sysctl_tcp_rmem);
 EXPORT_SYMBOL(sysctl_tcp_wmem);
 
-atomic_t tcp_memory_allocated; /* Current allocated memory. */
+atomic_long_t tcp_memory_allocated;    /* Current allocated memory. */
 EXPORT_SYMBOL(tcp_memory_allocated);
 
 /*
@@ -2246,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
                /* Values greater than interface MTU won't take effect. However
                 * at the point when this call is done we typically don't yet
                 * know which interface is going to be used */
-               if (val < 8 || val > MAX_TCP_WINDOW) {
+               if (val < 64 || val > MAX_TCP_WINDOW) {
                        err = -EINVAL;
                        break;
                }
index 3357f69e353d445b51c3178899609245b6720404..6d8ab1c4efc3ea59c4848c74ae367f872cd6505e 100644 (file)
@@ -259,8 +259,11 @@ static void tcp_fixup_sndbuf(struct sock *sk)
        int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 +
                     sizeof(struct sk_buff);
 
-       if (sk->sk_sndbuf < 3 * sndmem)
-               sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]);
+       if (sk->sk_sndbuf < 3 * sndmem) {
+               sk->sk_sndbuf = 3 * sndmem;
+               if (sk->sk_sndbuf > sysctl_tcp_wmem[2])
+                       sk->sk_sndbuf = sysctl_tcp_wmem[2];
+       }
 }
 
 /* 2. Tuning advertised window (window_clamp, rcv_ssthresh)
@@ -396,7 +399,7 @@ static void tcp_clamp_window(struct sock *sk)
        if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] &&
            !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
            !tcp_memory_pressure &&
-           atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
+           atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
                sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc),
                                    sysctl_tcp_rmem[2]);
        }
@@ -4861,7 +4864,7 @@ static int tcp_should_expand_sndbuf(struct sock *sk)
                return 0;
 
        /* If we are under soft global TCP memory pressure, do not expand.  */
-       if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0])
+       if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0])
                return 0;
 
        /* If we filled the congestion window, do not expand.  */
index 8f8527d4168225be9429766df1d1e2c085057868..69ccbc1dde9cdfed2719e243fd6091cc9781a876 100644 (file)
@@ -415,6 +415,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
                    !icsk->icsk_backoff)
                        break;
 
+               if (sock_owned_by_user(sk))
+                       break;
+
                icsk->icsk_backoff--;
                inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) <<
                                         icsk->icsk_backoff;
@@ -429,11 +432,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
                if (remaining) {
                        inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
                                                  remaining, TCP_RTO_MAX);
-               } else if (sock_owned_by_user(sk)) {
-                       /* RTO revert clocked out retransmission,
-                        * but socket is locked. Will defer. */
-                       inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-                                                 HZ/20, TCP_RTO_MAX);
                } else {
                        /* RTO revert clocked out retransmission.
                         * Will retransmit now */
index 28cb2d733a3cf6a9dd8e65a8dd2de0b44caae782..5e0a3a582a59a05466468b244371dc5675bedc67 100644 (file)
 struct udp_table udp_table __read_mostly;
 EXPORT_SYMBOL(udp_table);
 
-int sysctl_udp_mem[3] __read_mostly;
+long sysctl_udp_mem[3] __read_mostly;
 EXPORT_SYMBOL(sysctl_udp_mem);
 
 int sysctl_udp_rmem_min __read_mostly;
@@ -119,7 +119,7 @@ EXPORT_SYMBOL(sysctl_udp_rmem_min);
 int sysctl_udp_wmem_min __read_mostly;
 EXPORT_SYMBOL(sysctl_udp_wmem_min);
 
-atomic_t udp_memory_allocated;
+atomic_long_t udp_memory_allocated;
 EXPORT_SYMBOL(udp_memory_allocated);
 
 #define MAX_UDP_PORTS 65536
index e048ec62d109f8f2024c113c4aa3c52d984d084c..b41ce0f0d514154597753d549b5a29a3bc7e7ae0 100644 (file)
@@ -2740,10 +2740,6 @@ static int addrconf_ifdown(struct net_device *dev, int how)
                        /* Flag it for later restoration when link comes up */
                        ifa->flags |= IFA_F_TENTATIVE;
                        ifa->state = INET6_IFADDR_STATE_DAD;
-
-                       write_unlock_bh(&idev->lock);
-
-                       in6_ifa_hold(ifa);
                } else {
                        list_del(&ifa->if_list);
 
@@ -2758,19 +2754,15 @@ static int addrconf_ifdown(struct net_device *dev, int how)
                        ifa->state = INET6_IFADDR_STATE_DEAD;
                        spin_unlock_bh(&ifa->state_lock);
 
-                       if (state == INET6_IFADDR_STATE_DEAD)
-                               goto put_ifa;
+                       if (state == INET6_IFADDR_STATE_DEAD) {
+                               in6_ifa_put(ifa);
+                       } else {
+                               __ipv6_ifa_notify(RTM_DELADDR, ifa);
+                               atomic_notifier_call_chain(&inet6addr_chain,
+                                                          NETDEV_DOWN, ifa);
+                       }
+                       write_lock_bh(&idev->lock);
                }
-
-               __ipv6_ifa_notify(RTM_DELADDR, ifa);
-               if (ifa->state == INET6_IFADDR_STATE_DEAD)
-                       atomic_notifier_call_chain(&inet6addr_chain,
-                                                  NETDEV_DOWN, ifa);
-
-put_ifa:
-               in6_ifa_put(ifa);
-
-               write_lock_bh(&idev->lock);
        }
 
        list_splice(&keep_list, &idev->addr_list);
index 51df035897e77dfa5b89e6328817cfcb638702cb..455582384eced0b9242a40ea523ac31c8d6e08f4 100644 (file)
@@ -1137,6 +1137,7 @@ static int get_info(struct net *net, void __user *user,
                        private = &tmp;
                }
 #endif
+               memset(&info, 0, sizeof(info));
                info.valid_hooks = t->valid_hooks;
                memcpy(info.hook_entry, private->hook_entry,
                       sizeof(info.hook_entry));
index 3a3f129a44cb3561dd3e135164626f8352c565b7..79d43aa8fa8da80b405689bf7c751d7a9cc89ad4 100644 (file)
@@ -286,7 +286,7 @@ found:
 
        /* Check for overlap with preceding fragment. */
        if (prev &&
-           (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset > 0)
+           (NFCT_FRAG6_CB(prev)->offset + prev->len) > offset)
                goto discard_fq;
 
        /* Look for overlap with succeeding segment. */
index d082eaeefa25a039b5af47f4715e05f08e4ce813..24b3558b8e673cfe64d9528df5000260d68f82c5 100644 (file)
@@ -126,6 +126,8 @@ static const struct snmp_mib snmp6_udp6_list[] = {
        SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS),
        SNMP_MIB_ITEM("Udp6InErrors", UDP_MIB_INERRORS),
        SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
+       SNMP_MIB_ITEM("Udp6RcvbufErrors", UDP_MIB_RCVBUFERRORS),
+       SNMP_MIB_ITEM("Udp6SndbufErrors", UDP_MIB_SNDBUFERRORS),
        SNMP_MIB_SENTINEL
 };
 
@@ -134,6 +136,8 @@ static const struct snmp_mib snmp6_udplite6_list[] = {
        SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS),
        SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS),
        SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
+       SNMP_MIB_ITEM("UdpLite6RcvbufErrors", UDP_MIB_RCVBUFERRORS),
+       SNMP_MIB_ITEM("UdpLite6SndbufErrors", UDP_MIB_SNDBUFERRORS),
        SNMP_MIB_SENTINEL
 };
 
index c7ba3149633fcf79160849498d87ae5e53f695b1..0f276645375969054b36aea6c8fcb7a80666921c 100644 (file)
@@ -349,7 +349,7 @@ found:
 
        /* Check for overlap with preceding fragment. */
        if (prev &&
-           (FRAG6_CB(prev)->offset + prev->len) - offset > 0)
+           (FRAG6_CB(prev)->offset + prev->len) > offset)
                goto discard_fq;
 
        /* Look for overlap with succeeding segment. */
index 25661f968f3fb2c2976575f4233fd03c42edb863..96455ffb76fb8b92aa90c3a711aa6635d45b91fa 100644 (file)
@@ -1945,8 +1945,12 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
        struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
        struct neighbour *neigh;
 
-       if (rt == NULL)
+       if (rt == NULL) {
+               if (net_ratelimit())
+                       pr_warning("IPv6:  Maximum number of routes reached,"
+                                  " consider increasing route/max_size.\n");
                return ERR_PTR(-ENOMEM);
+       }
 
        dev_hold(net->loopback_dev);
        in6_dev_hold(idev);
@@ -2741,6 +2745,7 @@ static void __net_exit ip6_route_net_exit(struct net *net)
        kfree(net->ipv6.ip6_prohibit_entry);
        kfree(net->ipv6.ip6_blk_hole_entry);
 #endif
+       dst_entries_destroy(&net->ipv6.ip6_dst_ops);
 }
 
 static struct pernet_operations ip6_route_net_ops = {
@@ -2832,5 +2837,6 @@ void ip6_route_cleanup(void)
        xfrm6_fini();
        fib6_gc_cleanup();
        unregister_pernet_subsys(&ip6_route_net_ops);
+       dst_entries_destroy(&ip6_dst_blackhole_ops);
        kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep);
 }
index 104ec3b283d4159f610ef61548beb512d053dcd3..b8dbae82fab8612974d603c42b4cbac3b0509165 100644 (file)
@@ -249,7 +249,7 @@ static int l2tp_dfs_seq_open(struct inode *inode, struct file *file)
        struct seq_file *seq;
        int rc = -ENOMEM;
 
-       pd = kzalloc(GFP_KERNEL, sizeof(*pd));
+       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
        if (pd == NULL)
                goto out;
 
index 4aa47d074a7964cd8e47f85d1f003c393a9efe24..1243d1db5c59c842d843a265a1b7fe5131df36e1 100644 (file)
@@ -203,9 +203,13 @@ static ssize_t key_key_read(struct file *file, char __user *userbuf,
                            size_t count, loff_t *ppos)
 {
        struct ieee80211_key *key = file->private_data;
-       int i, res, bufsize = 2 * key->conf.keylen + 2;
+       int i, bufsize = 2 * key->conf.keylen + 2;
        char *buf = kmalloc(bufsize, GFP_KERNEL);
        char *p = buf;
+       ssize_t res;
+
+       if (!buf)
+               return -ENOMEM;
 
        for (i = 0; i < key->conf.keylen; i++)
                p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]);
index f9163b12c7f17aca87970366d3069f563b8a6655..7aa85591dbe764ca8b485759a94922ab4b58520b 100644 (file)
@@ -391,6 +391,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        u32 hw_reconf_flags = 0;
        int i;
 
+       if (local->scan_sdata == sdata)
+               ieee80211_scan_cancel(local);
+
        clear_bit(SDATA_STATE_RUNNING, &sdata->state);
 
        /*
@@ -523,9 +526,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                synchronize_rcu();
                skb_queue_purge(&sdata->skb_queue);
 
-               if (local->scan_sdata == sdata)
-                       ieee80211_scan_cancel(local);
-
                /*
                 * Disable beaconing here for mesh only, AP and IBSS
                 * are already taken care of.
index 6b322fa681f55e3a675af149cbd6cfcae7189382..107a0cbe52acc5380a0eed9887853c582d61f44a 100644 (file)
@@ -677,10 +677,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        /*
         * Calculate scan IE length -- we need this to alloc
         * memory and to subtract from the driver limit. It
-        * includes the (extended) supported rates and HT
+        * includes the DS Params, (extended) supported rates, and HT
         * information -- SSID is the driver's responsibility.
         */
-       local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */
+       local->scan_ies_len = 4 + max_bitrates /* (ext) supp rates */ +
+               3 /* DS Params */;
        if (supp_ht)
                local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
 
index 1eacf8d9966aa292f7f051964f822a00c0ab6605..27a5ea6b6a0ff1a644205ca705f717c78b4dcc84 100644 (file)
@@ -1312,7 +1312,8 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls)
        if (!hash) {
                *vmalloced = 1;
                printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
-               hash = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
+               hash = __vmalloc(sz, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
+                                PAGE_KERNEL);
        }
 
        if (hash && nulls)
index ed6d929580236c1b4aa77a42db959c9e522f2fc5..dc7bb74110df22818b42222450f0141068b79b6d 100644 (file)
@@ -292,6 +292,12 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
 
                for (i = 0; i < MAX_NF_CT_PROTO; i++)
                        proto_array[i] = &nf_conntrack_l4proto_generic;
+
+               /* Before making proto_array visible to lockless readers,
+                * we must make sure its content is committed to memory.
+                */
+               smp_wmb();
+
                nf_ct_protos[l4proto->l3proto] = proto_array;
        } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] !=
                                        &nf_conntrack_l4proto_generic) {
index d94a858dc52a1960f33fd7c1243c04a3428bb110..00d6ae838303f1dc0904b5a0aba543fbc32d200b 100644 (file)
@@ -195,7 +195,7 @@ socket_mt4_v1(const struct sk_buff *skb, struct xt_action_param *par)
 static int
 extract_icmp6_fields(const struct sk_buff *skb,
                     unsigned int outside_hdrlen,
-                    u8 *protocol,
+                    int *protocol,
                     struct in6_addr **raddr,
                     struct in6_addr **laddr,
                     __be16 *rport,
@@ -252,8 +252,7 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
        struct sock *sk;
        struct in6_addr *daddr, *saddr;
        __be16 dport, sport;
-       int thoff;
-       u8 tproto;
+       int thoff, tproto;
        const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
 
        tproto = ipv6_find_hdr(skb, &thoff, -1, NULL);
@@ -305,7 +304,7 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
                        sk = NULL;
        }
 
-       pr_debug("proto %hhu %pI6:%hu -> %pI6:%hu "
+       pr_debug("proto %hhd %pI6:%hu -> %pI6:%hu "
                 "(orig %pI6:%hu) sock %p\n",
                 tproto, saddr, ntohs(sport),
                 daddr, ntohs(dport),
index 3616f27b9d46c08e0f750b47865cc17c3130c5f2..8298e676f5a015f58d1b6005cf85938f8c8e142a 100644 (file)
@@ -1610,9 +1610,11 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                err = -EINVAL;
                vnet_hdr_len = sizeof(vnet_hdr);
-               if ((len -= vnet_hdr_len) < 0)
+               if (len < vnet_hdr_len)
                        goto out_free;
 
+               len -= vnet_hdr_len;
+
                if (skb_is_gso(skb)) {
                        struct skb_shared_info *sinfo = skb_shinfo(skb);
 
@@ -1719,7 +1721,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
        rcu_read_lock();
        dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex);
        if (dev)
-               strlcpy(uaddr->sa_data, dev->name, 15);
+               strncpy(uaddr->sa_data, dev->name, 14);
        else
                memset(uaddr->sa_data, 0, 14);
        rcu_read_unlock();
@@ -1742,6 +1744,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
        sll->sll_family = AF_PACKET;
        sll->sll_ifindex = po->ifindex;
        sll->sll_protocol = po->num;
+       sll->sll_pkttype = 0;
        rcu_read_lock();
        dev = dev_get_by_index_rcu(sock_net(sk), po->ifindex);
        if (dev) {
index c390156b426fc936c6b05fd607f4c32ddb1e3a81..aeec1d483b17e6f65c858e1510c7752965e35260 100644 (file)
@@ -134,8 +134,12 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 static void rds_loop_conn_free(void *arg)
 {
        struct rds_loop_connection *lc = arg;
+       unsigned long flags;
+
        rdsdebug("lc %p\n", lc);
+       spin_lock_irqsave(&loop_conns_lock, flags);
        list_del(&lc->loop_node);
+       spin_unlock_irqrestore(&loop_conns_lock, flags);
        kfree(lc);
 }
 
index a84545dae3709bc0140b65f8acd7648852d89935..1fd3d29023d7684d524cff00a2da35b2eb03b2b4 100644 (file)
@@ -224,6 +224,9 @@ struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents)
        WARN_ON(rm->m_used_sgs + nents > rm->m_total_sgs);
        WARN_ON(!nents);
 
+       if (rm->m_used_sgs + nents > rm->m_total_sgs)
+               return NULL;
+
        sg_ret = &sg_first[rm->m_used_sgs];
        sg_init_table(sg_ret, nents);
        rm->m_used_sgs += nents;
@@ -246,6 +249,10 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
        rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len);
        rm->data.op_nents = ceil(total_len, PAGE_SIZE);
        rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs);
+       if (!rm->data.op_sg) {
+               rds_message_put(rm);
+               return ERR_PTR(-ENOMEM);
+       }
 
        for (i = 0; i < rm->data.op_nents; ++i) {
                sg_set_page(&rm->data.op_sg[i],
index 1a41debca1ce6aa6d57d7c6fda1e135c7babdf30..8920f2a83327a42f10d20acdfb651f9c1b9620a3 100644 (file)
@@ -479,13 +479,38 @@ void rds_atomic_free_op(struct rm_atomic_op *ao)
 
 
 /*
- * Count the number of pages needed to describe an incoming iovec.
+ * Count the number of pages needed to describe an incoming iovec array.
  */
-static int rds_rdma_pages(struct rds_rdma_args *args)
+static int rds_rdma_pages(struct rds_iovec iov[], int nr_iovecs)
+{
+       int tot_pages = 0;
+       unsigned int nr_pages;
+       unsigned int i;
+
+       /* figure out the number of pages in the vector */
+       for (i = 0; i < nr_iovecs; i++) {
+               nr_pages = rds_pages_in_vec(&iov[i]);
+               if (nr_pages == 0)
+                       return -EINVAL;
+
+               tot_pages += nr_pages;
+
+               /*
+                * nr_pages for one entry is limited to (UINT_MAX>>PAGE_SHIFT)+1,
+                * so tot_pages cannot overflow without first going negative.
+                */
+               if (tot_pages < 0)
+                       return -EINVAL;
+       }
+
+       return tot_pages;
+}
+
+int rds_rdma_extra_size(struct rds_rdma_args *args)
 {
        struct rds_iovec vec;
        struct rds_iovec __user *local_vec;
-       unsigned int tot_pages = 0;
+       int tot_pages = 0;
        unsigned int nr_pages;
        unsigned int i;
 
@@ -502,14 +527,16 @@ static int rds_rdma_pages(struct rds_rdma_args *args)
                        return -EINVAL;
 
                tot_pages += nr_pages;
-       }
 
-       return tot_pages;
-}
+               /*
+                * nr_pages for one entry is limited to (UINT_MAX>>PAGE_SHIFT)+1,
+                * so tot_pages cannot overflow without first going negative.
+                */
+               if (tot_pages < 0)
+                       return -EINVAL;
+       }
 
-int rds_rdma_extra_size(struct rds_rdma_args *args)
-{
-       return rds_rdma_pages(args) * sizeof(struct scatterlist);
+       return tot_pages * sizeof(struct scatterlist);
 }
 
 /*
@@ -520,13 +547,12 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
                          struct cmsghdr *cmsg)
 {
        struct rds_rdma_args *args;
-       struct rds_iovec vec;
        struct rm_rdma_op *op = &rm->rdma;
        int nr_pages;
        unsigned int nr_bytes;
        struct page **pages = NULL;
-       struct rds_iovec __user *local_vec;
-       unsigned int nr;
+       struct rds_iovec iovstack[UIO_FASTIOV], *iovs = iovstack;
+       int iov_size;
        unsigned int i, j;
        int ret = 0;
 
@@ -546,9 +572,26 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
                goto out;
        }
 
-       nr_pages = rds_rdma_pages(args);
-       if (nr_pages < 0)
+       /* Check whether to allocate the iovec area */
+       iov_size = args->nr_local * sizeof(struct rds_iovec);
+       if (args->nr_local > UIO_FASTIOV) {
+               iovs = sock_kmalloc(rds_rs_to_sk(rs), iov_size, GFP_KERNEL);
+               if (!iovs) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+       }
+
+       if (copy_from_user(iovs, (struct rds_iovec __user *)(unsigned long) args->local_vec_addr, iov_size)) {
+               ret = -EFAULT;
+               goto out;
+       }
+
+       nr_pages = rds_rdma_pages(iovs, args->nr_local);
+       if (nr_pages < 0) {
+               ret = -EINVAL;
                goto out;
+       }
 
        pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL);
        if (!pages) {
@@ -564,6 +607,10 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
        op->op_recverr = rs->rs_recverr;
        WARN_ON(!nr_pages);
        op->op_sg = rds_message_alloc_sgs(rm, nr_pages);
+       if (!op->op_sg) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
        if (op->op_notify || op->op_recverr) {
                /* We allocate an uninitialized notifier here, because
@@ -597,50 +644,40 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
               (unsigned long long)args->remote_vec.addr,
               op->op_rkey);
 
-       local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr;
-
        for (i = 0; i < args->nr_local; i++) {
-               if (copy_from_user(&vec, &local_vec[i],
-                                  sizeof(struct rds_iovec))) {
-                       ret = -EFAULT;
-                       goto out;
-               }
-
-               nr = rds_pages_in_vec(&vec);
-               if (nr == 0) {
-                       ret = -EINVAL;
-                       goto out;
-               }
+               struct rds_iovec *iov = &iovs[i];
+               /* don't need to check, rds_rdma_pages() verified nr will be +nonzero */
+               unsigned int nr = rds_pages_in_vec(iov);
 
-               rs->rs_user_addr = vec.addr;
-               rs->rs_user_bytes = vec.bytes;
+               rs->rs_user_addr = iov->addr;
+               rs->rs_user_bytes = iov->bytes;
 
                /* If it's a WRITE operation, we want to pin the pages for reading.
                 * If it's a READ operation, we need to pin the pages for writing.
                 */
-               ret = rds_pin_pages(vec.addr, nr, pages, !op->op_write);
+               ret = rds_pin_pages(iov->addr, nr, pages, !op->op_write);
                if (ret < 0)
                        goto out;
 
-               rdsdebug("RDS: nr_bytes %u nr %u vec.bytes %llu vec.addr %llx\n",
-                      nr_bytes, nr, vec.bytes, vec.addr);
+               rdsdebug("RDS: nr_bytes %u nr %u iov->bytes %llu iov->addr %llx\n",
+                        nr_bytes, nr, iov->bytes, iov->addr);
 
-               nr_bytes += vec.bytes;
+               nr_bytes += iov->bytes;
 
                for (j = 0; j < nr; j++) {
-                       unsigned int offset = vec.addr & ~PAGE_MASK;
+                       unsigned int offset = iov->addr & ~PAGE_MASK;
                        struct scatterlist *sg;
 
                        sg = &op->op_sg[op->op_nents + j];
                        sg_set_page(sg, pages[j],
-                                       min_t(unsigned int, vec.bytes, PAGE_SIZE - offset),
+                                       min_t(unsigned int, iov->bytes, PAGE_SIZE - offset),
                                        offset);
 
-                       rdsdebug("RDS: sg->offset %x sg->len %x vec.addr %llx vec.bytes %llu\n",
-                              sg->offset, sg->length, vec.addr, vec.bytes);
+                       rdsdebug("RDS: sg->offset %x sg->len %x iov->addr %llx iov->bytes %llu\n",
+                              sg->offset, sg->length, iov->addr, iov->bytes);
 
-                       vec.addr += sg->length;
-                       vec.bytes -= sg->length;
+                       iov->addr += sg->length;
+                       iov->bytes -= sg->length;
                }
 
                op->op_nents += nr;
@@ -655,13 +692,14 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
        }
        op->op_bytes = nr_bytes;
 
-       ret = 0;
 out:
+       if (iovs != iovstack)
+               sock_kfree_s(rds_rs_to_sk(rs), iovs, iov_size);
        kfree(pages);
        if (ret)
                rds_rdma_free_op(op);
-
-       rds_stats_inc(s_send_rdma);
+       else
+               rds_stats_inc(s_send_rdma);
 
        return ret;
 }
@@ -773,6 +811,10 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm,
        rm->atomic.op_active = 1;
        rm->atomic.op_recverr = rs->rs_recverr;
        rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1);
+       if (!rm->atomic.op_sg) {
+               ret = -ENOMEM;
+               goto err;
+       }
 
        /* verify 8 byte-aligned */
        if (args->local_addr & 0x7) {
index 0bc9db17a87dd216bcc5ae914dbae20d0953ac89..35b9c2e9caf1bc79235b9b43732d398a325d42f4 100644 (file)
@@ -973,6 +973,10 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
        /* Attach data to the rm */
        if (payload_len) {
                rm->data.op_sg = rds_message_alloc_sgs(rm, ceil(payload_len, PAGE_SIZE));
+               if (!rm->data.op_sg) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
                ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len);
                if (ret)
                        goto out;
index 08a8c6cf2d100f8f05a6c932d8190326277747e9..8e0a32001c90c531a2ad8361dc4bb0c399b812fe 100644 (file)
@@ -221,7 +221,13 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp)
 static void rds_tcp_conn_free(void *arg)
 {
        struct rds_tcp_connection *tc = arg;
+       unsigned long flags;
        rdsdebug("freeing tc %p\n", tc);
+
+       spin_lock_irqsave(&rds_tcp_conn_lock, flags);
+       list_del(&tc->t_tcp_node);
+       spin_unlock_irqrestore(&rds_tcp_conn_lock, flags);
+
        kmem_cache_free(rds_tcp_conn_slab, tc);
 }
 
index efd4f95fd0507d1d114db3683805cf08a61762f7..f23d9155b1efc94cdf7a2d2a65b7abcfc6ec0a77 100644 (file)
@@ -268,6 +268,10 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
                goto nla_put_failure;
 
        nla_nest_end(skb, nest);
+
+       if (tcf_exts_dump_stats(skb, &f->exts, &basic_ext_map) < 0)
+               goto nla_put_failure;
+
        return skb->len;
 
 nla_put_failure:
index 37dff78e9cb17c6fcf35e5302d57b84dd5e9f5f9..d49c40fb7e0960daa905353e714e9317dd38088b 100644 (file)
@@ -34,8 +34,6 @@ struct cgroup_subsys net_cls_subsys = {
        .populate       = cgrp_populate,
 #ifdef CONFIG_NET_CLS_CGROUP
        .subsys_id      = net_cls_subsys_id,
-#else
-#define net_cls_subsys_id net_cls_subsys.subsys_id
 #endif
        .module         = THIS_MODULE,
 };
index 763253257411af1db91b3e25a78af8e687523342..ea8f566e720c7bd9ed508647c080c5c554edba2b 100644 (file)
@@ -103,7 +103,8 @@ retry:
 
 static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
 {
-       textsearch_destroy(EM_TEXT_PRIV(m)->config);
+       if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config)
+               textsearch_destroy(EM_TEXT_PRIV(m)->config);
 }
 
 static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m)
index 1ef29c74d85ead34a6c0dd5cb03954e91677ae00..e58f9476f29c571cb516acd53516bdc46707a416 100644 (file)
@@ -92,7 +92,7 @@ static struct sctp_af *sctp_af_v6_specific;
 struct kmem_cache *sctp_chunk_cachep __read_mostly;
 struct kmem_cache *sctp_bucket_cachep __read_mostly;
 
-int sysctl_sctp_mem[3];
+long sysctl_sctp_mem[3];
 int sysctl_sctp_rmem[3];
 int sysctl_sctp_wmem[3];
 
index e34ca9cc11675e249cd703ea58ba4fe2e5feeb82..6bd554323a342d4db49be267766b87492bd2e584 100644 (file)
@@ -111,12 +111,12 @@ static void sctp_sock_migrate(struct sock *, struct sock *,
 static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG;
 
 extern struct kmem_cache *sctp_bucket_cachep;
-extern int sysctl_sctp_mem[3];
+extern long sysctl_sctp_mem[3];
 extern int sysctl_sctp_rmem[3];
 extern int sysctl_sctp_wmem[3];
 
 static int sctp_memory_pressure;
-static atomic_t sctp_memory_allocated;
+static atomic_long_t sctp_memory_allocated;
 struct percpu_counter sctp_sockets_allocated;
 
 static void sctp_enter_memory_pressure(struct sock *sk)
index 832590bbe0c046ec83fcb58af7c98605fefec342..50cb57f0919e780bed02f6f963e62faf6d13144e 100644 (file)
@@ -54,7 +54,7 @@ static int sack_timer_max = 500;
 static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
 static int rwnd_scale_max = 16;
 
-extern int sysctl_sctp_mem[3];
+extern long sysctl_sctp_mem[3];
 extern int sysctl_sctp_rmem[3];
 extern int sysctl_sctp_wmem[3];
 
@@ -203,7 +203,7 @@ static ctl_table sctp_table[] = {
                .data           = &sysctl_sctp_mem,
                .maxlen         = sizeof(sysctl_sctp_mem),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_doulongvec_minmax
        },
        {
                .procname       = "sctp_rmem",
index ee3cd280c76e9cfb58024fa22f3017352f0467bc..3ca2fd9e37200e3e12f6606065acb8c982f25528 100644 (file)
@@ -305,19 +305,17 @@ static const struct super_operations sockfs_ops = {
        .statfs         = simple_statfs,
 };
 
-static int sockfs_get_sb(struct file_system_type *fs_type,
-                        int flags, const char *dev_name, void *data,
-                        struct vfsmount *mnt)
+static struct dentry *sockfs_mount(struct file_system_type *fs_type,
+                        int flags, const char *dev_name, void *data)
 {
-       return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC,
-                            mnt);
+       return mount_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
 }
 
 static struct vfsmount *sock_mnt __read_mostly;
 
 static struct file_system_type sock_fs_type = {
        .name =         "sockfs",
-       .get_sb =       sockfs_get_sb,
+       .mount =        sockfs_mount,
        .kill_sb =      kill_anon_super,
 };
 
@@ -1654,6 +1652,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
        struct iovec iov;
        int fput_needed;
 
+       if (len > INT_MAX)
+               len = INT_MAX;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
@@ -1711,6 +1711,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
        int err, err2;
        int fput_needed;
 
+       if (size > INT_MAX)
+               size = INT_MAX;
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
index 7df92d237cb8103171a892f49a98aaca1cd05e49..10a17a37ec4e90c683588de990670288136cc793 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/sunrpc/cache.h>
 
-static struct vfsmount *rpc_mount __read_mostly;
+static struct vfsmount *rpc_mnt __read_mostly;
 static int rpc_mount_count;
 
 static struct file_system_type rpc_pipe_fs_type;
@@ -417,16 +417,16 @@ struct vfsmount *rpc_get_mount(void)
 {
        int err;
 
-       err = simple_pin_fs(&rpc_pipe_fs_type, &rpc_mount, &rpc_mount_count);
+       err = simple_pin_fs(&rpc_pipe_fs_type, &rpc_mnt, &rpc_mount_count);
        if (err != 0)
                return ERR_PTR(err);
-       return rpc_mount;
+       return rpc_mnt;
 }
 EXPORT_SYMBOL_GPL(rpc_get_mount);
 
 void rpc_put_mount(void)
 {
-       simple_release_fs(&rpc_mount, &rpc_mount_count);
+       simple_release_fs(&rpc_mnt, &rpc_mount_count);
 }
 EXPORT_SYMBOL_GPL(rpc_put_mount);
 
@@ -1018,17 +1018,17 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 }
 
-static int
-rpc_get_sb(struct file_system_type *fs_type,
-               int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+static struct dentry *
+rpc_mount(struct file_system_type *fs_type,
+               int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, rpc_fill_super, mnt);
+       return mount_single(fs_type, flags, data, rpc_fill_super);
 }
 
 static struct file_system_type rpc_pipe_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "rpc_pipefs",
-       .get_sb         = rpc_get_sb,
+       .mount          = rpc_mount,
        .kill_sb        = kill_litter_super,
 };
 
index 33217fc3d697436cc5a82643a9d1fecb0986aac0..e9f0d500448341e0981fbb742b9fa098dc83a8ce 100644 (file)
@@ -396,6 +396,7 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
        struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
        struct tipc_sock *tsock = tipc_sk(sock->sk);
 
+       memset(addr, 0, sizeof(*addr));
        if (peer) {
                if ((sock->state != SS_CONNECTED) &&
                        ((peer != 2) || (sock->state != SS_DISCONNECTING)))
index c506241f863706426e76d66736d0258eda34d769..4e78e3f26798378bad69630679565b1909bfb370 100644 (file)
@@ -224,8 +224,8 @@ static int nl80211_prepare_netdev_dump(struct sk_buff *skb,
        }
 
        *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
-       if (IS_ERR(dev)) {
-               err = PTR_ERR(dev);
+       if (IS_ERR(*rdev)) {
+               err = PTR_ERR(*rdev);
                goto out_rtnl;
        }
 
index 771bab00754b0baff1a5c7a95892028857c8b84d..55187c8f64209c8c096fac54c88e7771834cbe3f 100644 (file)
@@ -61,6 +61,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
        while (len > 0) {
                switch (*p & X25_FAC_CLASS_MASK) {
                case X25_FAC_CLASS_A:
+                       if (len < 2)
+                               return 0;
                        switch (*p) {
                        case X25_FAC_REVERSE:
                                if((p[1] & 0x81) == 0x81) {
@@ -104,6 +106,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                        len -= 2;
                        break;
                case X25_FAC_CLASS_B:
+                       if (len < 3)
+                               return 0;
                        switch (*p) {
                        case X25_FAC_PACKET_SIZE:
                                facilities->pacsize_in  = p[1];
@@ -125,6 +129,8 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                        len -= 3;
                        break;
                case X25_FAC_CLASS_C:
+                       if (len < 4)
+                               return 0;
                        printk(KERN_DEBUG "X.25: unknown facility %02X, "
                               "values %02X, %02X, %02X\n",
                               p[0], p[1], p[2], p[3]);
@@ -132,26 +138,26 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                        len -= 4;
                        break;
                case X25_FAC_CLASS_D:
+                       if (len < p[1] + 2)
+                               return 0;
                        switch (*p) {
                        case X25_FAC_CALLING_AE:
-                               if (p[1] > X25_MAX_DTE_FACIL_LEN)
-                                       break;
+                               if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
+                                       return 0;
                                dte_facs->calling_len = p[2];
                                memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
                                *vc_fac_mask |= X25_MASK_CALLING_AE;
                                break;
                        case X25_FAC_CALLED_AE:
-                               if (p[1] > X25_MAX_DTE_FACIL_LEN)
-                                       break;
+                               if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
+                                       return 0;
                                dte_facs->called_len = p[2];
                                memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
                                *vc_fac_mask |= X25_MASK_CALLED_AE;
                                break;
                        default:
                                printk(KERN_DEBUG "X.25: unknown facility %02X,"
-                                       "length %d, values %02X, %02X, "
-                                       "%02X, %02X\n",
-                                       p[0], p[1], p[2], p[3], p[4], p[5]);
+                                       "length %d\n", p[0], p[1]);
                                break;
                        }
                        len -= p[1] + 2;
index 63178961efac00488d36e7c8fc3d21f00e036e2e..f729f022be69bc8c32b1008e8943c92cf36c1e28 100644 (file)
@@ -119,6 +119,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                                                &x25->vc_facil_mask);
                        if (len > 0)
                                skb_pull(skb, len);
+                       else
+                               return -1;
                        /*
                         *      Copy any Call User Data.
                         */
index 954a1d550c5f04cf4e344c1dc5e47b8708d044d8..e03cf0e374d7e85e72ec93f8ae23e1d5cb480544 100644 (file)
@@ -54,4 +54,11 @@ config SAMPLE_KFIFO
 
          If in doubt, say "N" here.
 
+config SAMPLE_KDB
+       tristate "Build kdb command exmaple -- loadable modules only"
+       depends on KGDB_KDB && m
+       help
+         Build an example of how to dynamically add the hello
+         command to the kdb shell.
+
 endif # SAMPLES
index 76b3c3455c292b844c1cc14ec138cddf58d46a20..f26c0959fd861645ae2b179af02534b71ef4da2d 100644 (file)
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)  += kobject/ kprobes/ tracepoints/ trace_events/ \
-                          hw_breakpoint/ kfifo/
+                          hw_breakpoint/ kfifo/ kdb/
diff --git a/samples/kdb/Makefile b/samples/kdb/Makefile
new file mode 100644 (file)
index 0000000..fbedf39
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_SAMPLE_KDB) += kdb_hello.o
diff --git a/samples/kdb/kdb_hello.c b/samples/kdb/kdb_hello.c
new file mode 100644 (file)
index 0000000..c1c2fa0
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Created by: Jason Wessel <jason.wessel@windriver.com>
+ *
+ * Copyright (c) 2010 Wind River Systems, Inc.  All Rights Reserved.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/kdb.h>
+
+/*
+ * All kdb shell command call backs receive argc and argv, where
+ * argv[0] is the command the end user typed
+ */
+static int kdb_hello_cmd(int argc, const char **argv)
+{
+       if (argc > 1)
+               return KDB_ARGCOUNT;
+
+       if (argc)
+               kdb_printf("Hello %s.\n", argv[1]);
+       else
+               kdb_printf("Hello world!\n");
+
+       return 0;
+}
+
+
+static int __init kdb_hello_cmd_init(void)
+{
+       /*
+        * Registration of a dynamically added kdb command is done with
+        * kdb_register() with the arguments being:
+        *   1: The name of the shell command
+        *   2: The function that processes the command
+        *   3: Description of the usage of any arguments
+        *   4: Descriptive text when you run help
+        *   5: Number of characters to complete the command
+        *      0 == type the whole command
+        *      1 == match both "g" and "go" for example
+        */
+       kdb_register("hello", kdb_hello_cmd, "[string]",
+                    "Say Hello World or Hello [string]", 0);
+       return 0;
+}
+
+static void __exit kdb_hello_cmd_exit(void)
+{
+       kdb_unregister("hello");
+}
+
+module_init(kdb_hello_cmd_init);
+module_exit(kdb_hello_cmd_exit);
+
+MODULE_AUTHOR("WindRiver");
+MODULE_DESCRIPTION("KDB example to add a hello command");
+MODULE_LICENSE("GPL");
index 90b54d4697fd2de9ae1dcecc80fc25cdcab63d21..e3c7fc0dca382492f1714f4879abb37b63cc07f2 100755 (executable)
@@ -2794,12 +2794,8 @@ sub process {
                        WARN("__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
                }
 
-# check for semaphores used as mutexes
-               if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) {
-                       WARN("mutexes are preferred for single holder semaphores\n" . $herecurr);
-               }
-# check for semaphores used as mutexes
-               if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) {
+# check for semaphores initialized locked
+               if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
                        WARN("consider using a completion\n" . $herecurr);
 
                }
index c70a27d924f0a74ae01762ff9e048847d1e5aa44..fd81fc33d6338858fc8352c82034937f26010ce8 100644 (file)
@@ -42,6 +42,8 @@
 #    mv config_strip .config
 #    make oldconfig
 #
+use strict;
+
 my $config = ".config";
 
 my $uname = `uname -r`;
@@ -123,7 +125,6 @@ my %selects;
 my %prompts;
 my %objects;
 my $var;
-my $cont = 0;
 my $iflevel = 0;
 my @ifdeps;
 
@@ -137,19 +138,45 @@ sub read_kconfig {
     my $config;
     my @kconfigs;
 
-    open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig";
+    my $cont = 0;
+    my $line;
+
+    my $source = "$ksource/$kconfig";
+    my $last_source = "";
+
+    # Check for any environment variables used
+    while ($source =~ /\$(\w+)/ && $last_source ne $source) {
+       my $env = $1;
+       $last_source = $source;
+       $source =~ s/\$$env/$ENV{$env}/;
+    }
+
+    open(KIN, "$source") || die "Can't open $kconfig";
     while (<KIN>) {
        chomp;
 
+       # Make sure that lines ending with \ continue
+       if ($cont) {
+           $_ = $line . " " . $_;
+       }
+
+       if (s/\\$//) {
+           $cont = 1;
+           $line = $_;
+           next;
+       }
+
+       $cont = 0;
+
        # collect any Kconfig sources
        if (/^source\s*"(.*)"/) {
            $kconfigs[$#kconfigs+1] = $1;
        }
 
        # configs found
-       if (/^\s*config\s+(\S+)\s*$/) {
+       if (/^\s*(menu)?config\s+(\S+)\s*$/) {
            $state = "NEW";
-           $config = $1;
+           $config = $2;
 
            for (my $i = 0; $i < $iflevel; $i++) {
                if ($i) {
@@ -178,7 +205,7 @@ sub read_kconfig {
        # configs without prompts must be selected
        } elsif ($state ne "NONE" && /^\s*tristate\s\S/) {
            # note if the config has a prompt
-           $prompt{$config} = 1;
+           $prompts{$config} = 1;
 
        # Check for if statements
        } elsif (/^if\s+(.*\S)\s*$/) {
@@ -218,6 +245,8 @@ if ($kconfig) {
 # Read all Makefiles to map the configs to the objects
 foreach my $makefile (@makefiles) {
 
+    my $cont = 0;
+
     open(MIN,$makefile) || die "Can't open $makefile";
     while (<MIN>) {
        my $objs;
@@ -281,7 +310,7 @@ if (defined($lsmod_file)) {
     # see what modules are loaded on this system
     my $lsmod;
 
-    foreach $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) {
+    foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) {
        if ( -x "$dir/lsmod" ) {
            $lsmod = "$dir/lsmod";
            last;
@@ -363,7 +392,7 @@ while ($repeat) {
            parse_config_dep_select $depends{$config};
        }
 
-       if (defined($prompt{$config}) || !defined($selects{$config})) {
+       if (defined($prompts{$config}) || !defined($selects{$config})) {
            next;
        }
 
index c0efe102d655c40547afe92014cec1c74b70b3c2..af6e9f3de9503b033a69a3eba7c2ecd212fef747 100644 (file)
@@ -875,7 +875,7 @@ const char *sym_expand_string_value(const char *in)
                        symval = sym_get_string_value(sym);
                }
 
-               newlen = strlen(res) + strlen(symval) + strlen(src);
+               newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
                if (newlen > reslen) {
                        reslen = newlen;
                        res = realloc(res, reslen);
index 26e1271259ba51d27343d8a946fe47526e9c2e94..f2f32eee2c5bbff3880b52be0769ca8a78cd171a 100644 (file)
@@ -217,6 +217,39 @@ is_mcounted_section_name(char const *const txtname)
 #define RECORD_MCOUNT_64
 #include "recordmcount.h"
 
+/* 64-bit EM_MIPS has weird ELF64_Rela.r_info.
+ * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
+ * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40]
+ * to imply the order of the members; the spec does not say so.
+ *     typedef unsigned char Elf64_Byte;
+ * fails on MIPS64 because their <elf.h> already has it!
+ */
+
+typedef uint8_t myElf64_Byte;          /* Type for a 8-bit quantity.  */
+
+union mips_r_info {
+       Elf64_Xword r_info;
+       struct {
+               Elf64_Word r_sym;               /* Symbol index.  */
+               myElf64_Byte r_ssym;            /* Special symbol.  */
+               myElf64_Byte r_type3;           /* Third relocation.  */
+               myElf64_Byte r_type2;           /* Second relocation.  */
+               myElf64_Byte r_type;            /* First relocation.  */
+       } r_mips;
+};
+
+static uint64_t MIPS64_r_sym(Elf64_Rel const *rp)
+{
+       return w(((union mips_r_info){ .r_info = rp->r_info }).r_mips.r_sym);
+}
+
+static void MIPS64_r_info(Elf64_Rel *const rp, unsigned sym, unsigned type)
+{
+       rp->r_info = ((union mips_r_info){
+               .r_mips = { .r_sym = w(sym), .r_type = type }
+       }).r_info;
+}
+
 static void
 do_file(char const *const fname)
 {
@@ -268,6 +301,7 @@ do_file(char const *const fname)
        case EM_386:     reltype = R_386_32;                   break;
        case EM_ARM:     reltype = R_ARM_ABS32;                break;
        case EM_IA_64:   reltype = R_IA64_IMM64;   gpfx = '_'; break;
+       case EM_MIPS:    /* reltype: e_class    */ gpfx = '_'; break;
        case EM_PPC:     reltype = R_PPC_ADDR32;   gpfx = '_'; break;
        case EM_PPC64:   reltype = R_PPC64_ADDR64; gpfx = '_'; break;
        case EM_S390:    /* reltype: e_class    */ gpfx = '_'; break;
@@ -291,6 +325,10 @@ do_file(char const *const fname)
                }
                if (EM_S390 == w2(ehdr->e_machine))
                        reltype = R_390_32;
+               if (EM_MIPS == w2(ehdr->e_machine)) {
+                       reltype = R_MIPS_32;
+                       is_fake_mcount32 = MIPS32_is_fake_mcount;
+               }
                do32(ehdr, fname, reltype);
        } break;
        case ELFCLASS64: {
@@ -303,6 +341,12 @@ do_file(char const *const fname)
                }
                if (EM_S390 == w2(ghdr->e_machine))
                        reltype = R_390_64;
+               if (EM_MIPS == w2(ghdr->e_machine)) {
+                       reltype = R_MIPS_64;
+                       Elf64_r_sym = MIPS64_r_sym;
+                       Elf64_r_info = MIPS64_r_info;
+                       is_fake_mcount64 = MIPS64_is_fake_mcount;
+               }
                do64(ghdr, fname, reltype);
        } break;
        }  /* end switch */
index 7f39d0943d2d93099068114605da1f1508eafedc..58e933a20544a2cd379446661d01f3755494bf97 100644 (file)
  * Licensed under the GNU General Public License, version 2 (GPLv2).
  */
 #undef append_func
+#undef is_fake_mcount
+#undef fn_is_fake_mcount
+#undef MIPS_is_fake_mcount
 #undef sift_rel_mcount
 #undef find_secsym_ndx
 #undef __has_rel_mcount
 #undef has_rel_mcount
 #undef tot_relsize
 #undef do_func
+#undef Elf_Addr
 #undef Elf_Ehdr
 #undef Elf_Shdr
 #undef Elf_Rel
 #undef Elf_Rela
 #undef Elf_Sym
 #undef ELF_R_SYM
+#undef Elf_r_sym
 #undef ELF_R_INFO
+#undef Elf_r_info
 #undef ELF_ST_BIND
+#undef fn_ELF_R_SYM
+#undef fn_ELF_R_INFO
 #undef uint_t
 #undef _w
 #undef _align
 # define has_rel_mcount                has64_rel_mcount
 # define tot_relsize           tot64_relsize
 # define do_func               do64
+# define is_fake_mcount                is_fake_mcount64
+# define fn_is_fake_mcount     fn_is_fake_mcount64
+# define MIPS_is_fake_mcount   MIPS64_is_fake_mcount
+# define Elf_Addr              Elf64_Addr
 # define Elf_Ehdr              Elf64_Ehdr
 # define Elf_Shdr              Elf64_Shdr
 # define Elf_Rel               Elf64_Rel
 # define Elf_Rela              Elf64_Rela
 # define Elf_Sym               Elf64_Sym
 # define ELF_R_SYM             ELF64_R_SYM
+# define Elf_r_sym             Elf64_r_sym
 # define ELF_R_INFO            ELF64_R_INFO
+# define Elf_r_info            Elf64_r_info
 # define ELF_ST_BIND           ELF64_ST_BIND
+# define fn_ELF_R_SYM          fn_ELF64_R_SYM
+# define fn_ELF_R_INFO         fn_ELF64_R_INFO
 # define uint_t                        uint64_t
 # define _w                    w8
 # define _align                        7u
 # define has_rel_mcount                has32_rel_mcount
 # define tot_relsize           tot32_relsize
 # define do_func               do32
+# define is_fake_mcount                is_fake_mcount32
+# define fn_is_fake_mcount     fn_is_fake_mcount32
+# define MIPS_is_fake_mcount   MIPS32_is_fake_mcount
+# define Elf_Addr              Elf32_Addr
 # define Elf_Ehdr              Elf32_Ehdr
 # define Elf_Shdr              Elf32_Shdr
 # define Elf_Rel               Elf32_Rel
 # define Elf_Rela              Elf32_Rela
 # define Elf_Sym               Elf32_Sym
 # define ELF_R_SYM             ELF32_R_SYM
+# define Elf_r_sym             Elf32_r_sym
 # define ELF_R_INFO            ELF32_R_INFO
+# define Elf_r_info            Elf32_r_info
 # define ELF_ST_BIND           ELF32_ST_BIND
+# define fn_ELF_R_SYM          fn_ELF32_R_SYM
+# define fn_ELF_R_INFO         fn_ELF32_R_INFO
 # define uint_t                        uint32_t
 # define _w                    w
 # define _align                        3u
 # define _size                 4
 #endif
 
+/* Functions and pointers that do_file() may override for specific e_machine. */
+static int fn_is_fake_mcount(Elf_Rel const *rp)
+{
+       return 0;
+}
+static int (*is_fake_mcount)(Elf_Rel const *rp) = fn_is_fake_mcount;
+
+static uint_t fn_ELF_R_SYM(Elf_Rel const *rp)
+{
+       return ELF_R_SYM(_w(rp->r_info));
+}
+static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM;
+
+static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
+{
+       rp->r_info = ELF_R_INFO(sym, type);
+}
+static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO;
+
+/*
+ * MIPS mcount long call has 2 _mcount symbols, only the position of the 1st
+ * _mcount symbol is needed for dynamic function tracer, with it, to disable
+ * tracing(ftrace_make_nop), the instruction in the position is replaced with
+ * the "b label" instruction, to enable tracing(ftrace_make_call), replace the
+ * instruction back. So, here, we set the 2nd one as fake and filter it.
+ *
+ * c:  3c030000        lui     v1,0x0          <-->    b       label
+ *             c: R_MIPS_HI16  _mcount
+ *             c: R_MIPS_NONE  *ABS*
+ *             c: R_MIPS_NONE  *ABS*
+ * 10: 64630000        daddiu  v1,v1,0
+ *             10: R_MIPS_LO16 _mcount
+ *             10: R_MIPS_NONE *ABS*
+ *             10: R_MIPS_NONE *ABS*
+ * 14: 03e0082d        move    at,ra
+ * 18: 0060f809        jalr    v1
+ * label:
+ */
+#define MIPS_FAKEMCOUNT_OFFSET 4
+
+static int MIPS_is_fake_mcount(Elf_Rel const *rp)
+{
+       static Elf_Addr old_r_offset;
+       Elf_Addr current_r_offset = _w(rp->r_offset);
+       int is_fake;
+
+       is_fake = old_r_offset &&
+               (current_r_offset - old_r_offset == MIPS_FAKEMCOUNT_OFFSET);
+       old_r_offset = current_r_offset;
+
+       return is_fake;
+}
+
 /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */
 static void append_func(Elf_Ehdr *const ehdr,
                        Elf_Shdr *const shstr,
@@ -157,7 +234,6 @@ static void append_func(Elf_Ehdr *const ehdr,
        uwrite(fd_map, ehdr, sizeof(*ehdr));
 }
 
-
 /*
  * Look at the relocations in order to find the calls to mcount.
  * Accumulate the section offsets that are found, and their relocation info,
@@ -197,22 +273,22 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,
        for (t = nrel; t; --t) {
                if (!mcountsym) {
                        Elf_Sym const *const symp =
-                               &sym0[ELF_R_SYM(_w(relp->r_info))];
+                               &sym0[Elf_r_sym(relp)];
                        char const *symname = &str0[w(symp->st_name)];
 
                        if ('.' == symname[0])
                                ++symname;  /* ppc64 hack */
                        if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"),
                                        symname))
-                               mcountsym = ELF_R_SYM(_w(relp->r_info));
+                               mcountsym = Elf_r_sym(relp);
                }
 
-               if (mcountsym == ELF_R_SYM(_w(relp->r_info))) {
+               if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) {
                        uint_t const addend = _w(_w(relp->r_offset) - recval);
 
                        mrelp->r_offset = _w(offbase
                                + ((void *)mlocp - (void *)mloc0));
-                       mrelp->r_info = _w(ELF_R_INFO(recsym, reltype));
+                       Elf_r_info(mrelp, recsym, reltype);
                        if (sizeof(Elf_Rela) == rel_entsize) {
                                ((Elf_Rela *)mrelp)->r_addend = addend;
                                *mlocp++ = 0;
index bd72ae6234947e424885f3808dbec54bddad244c..e80da955e6876aeb550bec75d3d99643020034eb 100644 (file)
@@ -39,6 +39,18 @@ config KEYS_DEBUG_PROC_KEYS
 
          If you are unsure as to whether this is required, answer N.
 
+config SECURITY_DMESG_RESTRICT
+       bool "Restrict unprivileged access to the kernel syslog"
+       default n
+       help
+         This enforces restrictions on unprivileged users reading the kernel
+         syslog via dmesg(8).
+
+         If this option is not selected, no restrictions will be enforced
+         unless the dmesg_restrict sysctl is explicitly set to (1).
+
+         If you are unsure how to answer this question, answer N.
+
 config SECURITY
        bool "Enable different security models"
        depends on SYSFS
index cf1de4462ccd3fb297f48bf351dd3494804f22c1..b7106f192b75d5d382e806d303a9b2f6bb879747 100644 (file)
@@ -922,7 +922,7 @@ static int __init apparmor_init(void)
        error = register_security(&apparmor_ops);
        if (error) {
                AA_ERROR("Unable to register AppArmor\n");
-               goto register_security_out;
+               goto set_init_cxt_out;
        }
 
        /* Report that AppArmor successfully initialized */
@@ -936,6 +936,9 @@ static int __init apparmor_init(void)
 
        return error;
 
+set_init_cxt_out:
+       aa_free_task_context(current->real_cred->security);
+
 register_security_out:
        aa_free_root_ns();
 
@@ -944,7 +947,6 @@ alloc_out:
 
        apparmor_enabled = 0;
        return error;
-
 }
 
 security_initcall(apparmor_init);
index 52cc865f1464574e696fd28eca6a6e0eed326d68..4f0eadee78b8d9295f0da93c32a7321a70055392 100644 (file)
@@ -306,7 +306,7 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
        return ns;
 
 fail_unconfined:
-       kzfree(ns->base.name);
+       kzfree(ns->base.hname);
 fail_ns:
        kzfree(ns);
        return NULL;
index 30ae00fbecd591591acb55c1431d62a1bbbac427..c773635ca3a0e1b6de3e03d46fe38dd928a62a45 100644 (file)
@@ -17,6 +17,11 @@ static int cap_sysctl(ctl_table *table, int op)
        return 0;
 }
 
+static int cap_syslog(int type)
+{
+       return 0;
+}
+
 static int cap_quotactl(int cmds, int type, int id, struct super_block *sb)
 {
        return 0;
index 5e632b4857e443d8031eaa17c0e2bd7e877b3d14..64c2ed9c90158d1b7df59eff08595566d3dc1927 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/sched.h>
 #include <linux/prctl.h>
 #include <linux/securebits.h>
-#include <linux/syslog.h>
 
 /*
  * If a non-root user executes a setuid-root binary in
@@ -883,24 +882,6 @@ error:
        return error;
 }
 
-/**
- * cap_syslog - Determine whether syslog function is permitted
- * @type: Function requested
- * @from_file: Whether this request came from an open file (i.e. /proc)
- *
- * Determine whether the current process is permitted to use a particular
- * syslog function, returning 0 if permission is granted, -ve if not.
- */
-int cap_syslog(int type, bool from_file)
-{
-       if (type != SYSLOG_ACTION_OPEN && from_file)
-               return 0;
-       if ((type != SYSLOG_ACTION_READ_ALL &&
-            type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       return 0;
-}
-
 /**
  * cap_vm_enough_memory - Determine whether a new virtual mapping is permitted
  * @mm: The VM space in which the new mapping is to be made
index cb8f47c66a58bb7eb11c0a75319f378261393f14..c4df2fbebe6b34aa1789bd6a82450196f8ebf365 100644 (file)
@@ -131,17 +131,17 @@ static int fill_super(struct super_block *sb, void *data, int silent)
        return simple_fill_super(sb, SECURITYFS_MAGIC, files);
 }
 
-static int get_sb(struct file_system_type *fs_type,
+static struct dentry *get_sb(struct file_system_type *fs_type,
                  int flags, const char *dev_name,
-                 void *data, struct vfsmount *mnt)
+                 void *data)
 {
-       return get_sb_single(fs_type, flags, data, fill_super, mnt);
+       return mount_single(fs_type, flags, data, fill_super);
 }
 
 static struct file_system_type fs_type = {
        .owner =        THIS_MODULE,
        .name =         "securityfs",
-       .get_sb =       get_sb,
+       .mount =        get_sb,
        .kill_sb =      kill_litter_super,
 };
 
index 3ef5e2a7a741aca4b13cd08b571e0a0ca0ee7d72..1b798d3df71057720d799f5d3e1382880fde8f78 100644 (file)
@@ -197,9 +197,9 @@ int security_quota_on(struct dentry *dentry)
        return security_ops->quota_on(dentry);
 }
 
-int security_syslog(int type, bool from_file)
+int security_syslog(int type)
 {
-       return security_ops->syslog(type, from_file);
+       return security_ops->syslog(type);
 }
 
 int security_settime(struct timespec *ts, struct timezone *tz)
index d9154cf90ae19cd4eb5f40d65882abb60781da3d..65fa8bf596f591d12c2e0c22bafe5824522c34ee 100644 (file)
@@ -1973,14 +1973,10 @@ static int selinux_quota_on(struct dentry *dentry)
        return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
 }
 
-static int selinux_syslog(int type, bool from_file)
+static int selinux_syslog(int type)
 {
        int rc;
 
-       rc = cap_syslog(type, from_file);
-       if (rc)
-               return rc;
-
        switch (type) {
        case SYSLOG_ACTION_READ_ALL:    /* Read last kernel messages */
        case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
index 55a755c1a1bd9546a4655e83351cc93bc92cf655..073fd5b0a53ad3cc7324e83bfaec6275633977f4 100644 (file)
@@ -1909,16 +1909,15 @@ err:
        goto out;
 }
 
-static int sel_get_sb(struct file_system_type *fs_type,
-                     int flags, const char *dev_name, void *data,
-                     struct vfsmount *mnt)
+static struct dentry *sel_mount(struct file_system_type *fs_type,
+                     int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, sel_fill_super, mnt);
+       return mount_single(fs_type, flags, data, sel_fill_super);
 }
 
 static struct file_system_type sel_fs_type = {
        .name           = "selinuxfs",
-       .get_sb         = sel_get_sb,
+       .mount          = sel_mount,
        .kill_sb        = kill_litter_super,
 };
 
index bc39f4067af668874312af4187ad6f21dbdbb113..489a85afa477bbd4d833fb167b3c6e71be049d86 100644 (file)
@@ -157,15 +157,11 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
  *
  * Returns 0 on success, error code otherwise.
  */
-static int smack_syslog(int type, bool from_file)
+static int smack_syslog(int typefrom_file)
 {
-       int rc;
+       int rc = 0;
        char *sp = current_security();
 
-       rc = cap_syslog(type, from_file);
-       if (rc != 0)
-               return rc;
-
        if (capable(CAP_MAC_OVERRIDE))
                return 0;
 
index 7512502d0162b6be0afc54f874e88f407b8470c6..dc1fd6239f243ad1f4e254db0ead6707a1d7c077 100644 (file)
@@ -1310,27 +1310,25 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
 }
 
 /**
- * smk_get_sb - get the smackfs superblock
+ * smk_mount - get the smackfs superblock
  * @fs_type: passed along without comment
  * @flags: passed along without comment
  * @dev_name: passed along without comment
  * @data: passed along without comment
- * @mnt: passed along without comment
  *
  * Just passes everything along.
  *
  * Returns what the lower level code does.
  */
-static int smk_get_sb(struct file_system_type *fs_type,
-                     int flags, const char *dev_name, void *data,
-                     struct vfsmount *mnt)
+static struct dentry *smk_mount(struct file_system_type *fs_type,
+                     int flags, const char *dev_name, void *data)
 {
-       return get_sb_single(fs_type, flags, data, smk_fill_super, mnt);
+       return mount_single(fs_type, flags, data, smk_fill_super);
 }
 
 static struct file_system_type smk_fs_type = {
        .name           = "smackfs",
-       .get_sb         = smk_get_sb,
+       .mount          = smk_mount,
        .kill_sb        = kill_litter_super,
 };
 
index f7e374ec44144763feb215890c73714b32a17a22..1b9bf9395cfe820f87b34fa14d57d5a667a67217 100644 (file)
@@ -625,6 +625,8 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
                        control_cache_size, (struct hpi_control_cache_info *)
                        &phw->control_cache[0]
                        );
+               if (!phw->p_cache)
+                       pao->has_control_cache = 0;
        } else
                pao->has_control_cache = 0;
 
index 22c5fc6255335ac94aca5ac297432f16b0950c4e..2672f6591ceb7246b9a0a24ecbfa8f4cf2c46288 100644 (file)
@@ -644,6 +644,8 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
                                interface->control_cache.size_in_bytes,
                                (struct hpi_control_cache_info *)
                                p_control_cache_virtual);
+                       if (!phw->p_cache)
+                               err = HPI_ERROR_MEMORY_ALLOC;
                }
                if (!err) {
                        err = hpios_locked_mem_get_phys_addr(&phw->
index dda4f1c6f65847504a71016b1064d0039c65e8a3..d67f4d3db911dd9685d24e08f29d6b6bc23f16f9 100644 (file)
@@ -571,14 +571,20 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32
 {
        struct hpi_control_cache *p_cache =
                kmalloc(sizeof(*p_cache), GFP_KERNEL);
+       if (!p_cache)
+               return NULL;
+       p_cache->p_info =
+               kmalloc(sizeof(*p_cache->p_info) * number_of_controls,
+                       GFP_KERNEL);
+       if (!p_cache->p_info) {
+               kfree(p_cache);
+               return NULL;
+       }
        p_cache->cache_size_in_bytes = size_in_bytes;
        p_cache->control_count = number_of_controls;
        p_cache->p_cache =
                (struct hpi_control_cache_single *)pDSP_control_buffer;
        p_cache->init = 0;
-       p_cache->p_info =
-               kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count,
-               GFP_KERNEL);
        return p_cache;
 }
 
index 3e5ca8fb519ff1ae5d2c03cf7f2beb8700b1745d..e377287192aae954aa42d153cb9931f0934f67b4 100644 (file)
@@ -225,39 +225,25 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip)
 {
        struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL);
 
-       if (ins == NULL) 
+       if (ins == NULL)
                return NULL;
 
        /* better to use vmalloc for this big table */
-       ins->symbol_table.nsymbols = 0;
        ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) *
                                            DSP_MAX_SYMBOLS);
-       ins->symbol_table.highest_frag_index = 0;
-
-       if (ins->symbol_table.symbols == NULL) {
+       ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL);
+       ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL);
+       if (!ins->symbol_table.symbols || !ins->code.data || !ins->modules) {
                cs46xx_dsp_spos_destroy(chip);
                goto error;
        }
-
+       ins->symbol_table.nsymbols = 0;
+       ins->symbol_table.highest_frag_index = 0;
        ins->code.offset = 0;
        ins->code.size = 0;
-       ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL);
-
-       if (ins->code.data == NULL) {
-               cs46xx_dsp_spos_destroy(chip);
-               goto error;
-       }
-
        ins->nscb = 0;
        ins->ntask = 0;
-
        ins->nmodules = 0;
-       ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL);
-
-       if (ins->modules == NULL) {
-               cs46xx_dsp_spos_destroy(chip);
-               goto error;
-       }
 
        /* default SPDIF input sample rate
           to 48000 khz */
@@ -271,8 +257,8 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip)
 
        /* set left and right validity bits and
           default channel status */
-       ins->spdif_csuv_default = 
-               ins->spdif_csuv_stream =  
+       ins->spdif_csuv_default =
+               ins->spdif_csuv_stream =
         /* byte 0 */  ((unsigned int)_wrap_all_bits(  (SNDRV_PCM_DEFAULT_CON_SPDIF        & 0xff)) << 24) |
         /* byte 1 */  ((unsigned int)_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 8) & 0xff)) << 16) |
         /* byte 3 */   (unsigned int)_wrap_all_bits(  (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) |
@@ -281,6 +267,9 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip)
        return ins;
 
 error:
+       kfree(ins->modules);
+       kfree(ins->code.data);
+       vfree(ins->symbol_table.symbols);
        kfree(ins);
        return NULL;
 }
index 460fb2ef7e394614a4045a51d4306c429e818d6a..18af38ebf7579f5507fca391f66ba9280844ccf4 100644 (file)
@@ -1166,6 +1166,7 @@ static const char *cs420x_models[CS420X_MODELS] = {
 
 static struct snd_pci_quirk cs420x_cfg_tbl[] = {
        SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53),
+       SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
        SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
        SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55),
        SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),
index ef9af3f4ace2f6fda837a89e4ea46ff8821fd86c..1bd7a540fd49dfa64918e4d533a3d80cbb8fb4af 100644 (file)
@@ -425,7 +425,7 @@ exit:
 static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream)
 {
        struct snd_pcm_substream *substream = lx_stream->stream;
-       const int is_capture = lx_stream->is_capture;
+       const unsigned int is_capture = lx_stream->is_capture;
 
        int err;
 
@@ -473,7 +473,7 @@ static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream)
 
 static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream)
 {
-       const int is_capture = lx_stream->is_capture;
+       const unsigned int is_capture = lx_stream->is_capture;
        int err;
 
        snd_printd(LXP "stopping: stopping stream\n");
index 51afc048961d9855c39e321e523f9f526bd8acd3..aea621eafbb56799385e0e2188a5b3e1130f21d2 100644 (file)
@@ -60,7 +60,7 @@ struct lx_stream {
        snd_pcm_uframes_t          frame_pos;
        enum lx_stream_status      status; /* free, open, running, draining
                                            * pause */
-       int                        is_capture:1;
+       unsigned int               is_capture:1;
 };
 
 
index 3086b751da4a59271b497e1a8605c3664d15a2ff..617f98b0cbae47ce9c76265f50590f88a83c187d 100644 (file)
@@ -1152,7 +1152,7 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip,
                                           struct lx_stream *lx_stream)
 {
        struct snd_pcm_substream *substream = lx_stream->stream;
-       int is_capture = lx_stream->is_capture;
+       const unsigned int is_capture = lx_stream->is_capture;
        int err;
        unsigned long flags;
 
index 94a9d06b90277797215e299907444a85ca3f379a..3b5690d28b8bb080e1c6da2658f3017abcfd6f57 100644 (file)
@@ -25,8 +25,9 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
        select SND_SOC_CS42L51 if I2C
        select SND_SOC_CS4270 if I2C
+       select SND_SOC_CX20442
        select SND_SOC_DA7210 if I2C
-       select SND_SOC_JZ4740 if SOC_JZ4740
+       select SND_SOC_JZ4740_CODEC if SOC_JZ4740
        select SND_SOC_MAX98088 if I2C
        select SND_SOC_MAX9877 if I2C
        select SND_SOC_PCM3008
index d251ff54a2d36f8b691b4aca2073d74adb010673..c5ab8c8057714871e13ad249805f60877ff32f5d 100644 (file)
@@ -58,7 +58,7 @@
        (1000000000 / ((rate * 1000) / samples))
 
 #define US_TO_SAMPLES(rate, us) \
-       (rate / (1000000 / us))
+       (rate / (1000000 / (us < 1000000 ? us : 1000000)))
 
 #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
        ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate)))
@@ -200,7 +200,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
                      u8 *value)
 {
        struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
-       int val;
+       int val, ret = 0;
 
        *value = reg & 0xff;
 
@@ -210,6 +210,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
                if (val < 0) {
                        dev_err(codec->dev, "Read failed (%d)\n", val);
                        value[0] = dac33_read_reg_cache(codec, reg);
+                       ret = val;
                } else {
                        value[0] = val;
                        dac33_write_reg_cache(codec, reg, val);
@@ -218,7 +219,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
                value[0] = dac33_read_reg_cache(codec, reg);
        }
 
-       return 0;
+       return ret;
 }
 
 static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
@@ -329,13 +330,18 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
                    dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL));
 }
 
-static inline void dac33_read_id(struct snd_soc_codec *codec)
+static inline int dac33_read_id(struct snd_soc_codec *codec)
 {
+       int i, ret = 0;
        u8 reg;
 
-       dac33_read(codec, DAC33_DEVICE_ID_MSB, &reg);
-       dac33_read(codec, DAC33_DEVICE_ID_LSB, &reg);
-       dac33_read(codec, DAC33_DEVICE_REV_ID, &reg);
+       for (i = 0; i < 3; i++) {
+               ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, &reg);
+               if (ret < 0)
+                       break;
+       }
+
+       return ret;
 }
 
 static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
@@ -1076,6 +1082,9 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
                /* Number of samples under i2c latency */
                dac33->alarm_threshold = US_TO_SAMPLES(rate,
                                                dac33->mode1_latency);
+               nsample_limit = DAC33_BUFFER_SIZE_SAMPLES -
+                               dac33->alarm_threshold;
+
                if (dac33->auto_fifo_config) {
                        if (period_size <= dac33->alarm_threshold)
                                /*
@@ -1086,6 +1095,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
                                       ((dac33->alarm_threshold / period_size) +
                                       (dac33->alarm_threshold % period_size ?
                                       1 : 0));
+                       else if (period_size > nsample_limit)
+                               dac33->nsample = nsample_limit;
                        else
                                dac33->nsample = period_size;
                } else {
@@ -1097,8 +1108,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
                         */
                        dac33->nsample_max = substream->runtime->buffer_size -
                                                period_size;
-                       nsample_limit = DAC33_BUFFER_SIZE_SAMPLES -
-                                       dac33->alarm_threshold;
+
                        if (dac33->nsample_max > nsample_limit)
                                dac33->nsample_max = nsample_limit;
 
@@ -1414,9 +1424,15 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
                dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
                goto err_power;
        }
-       dac33_read_id(codec);
+       ret = dac33_read_id(codec);
        dac33_hard_power(codec, 0);
 
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to read chip ID: %d\n", ret);
+               ret = -ENODEV;
+               goto err_power;
+       }
+
        /* Check if the IRQ number is valid and request it */
        if (dac33->irq >= 0) {
                ret = request_irq(dac33->irq, dac33_interrupt_handler,
index 329acc1a207457942a560e86d7f990a2fc44ffd8..ee4fb201de60ca9ceb969fd00ce1292aad0a9330 100644 (file)
@@ -119,13 +119,13 @@ static int tpa6130a2_power(int power)
 {
        struct  tpa6130a2_data *data;
        u8      val;
-       int     ret;
+       int     ret = 0;
 
        BUG_ON(tpa6130a2_client == NULL);
        data = i2c_get_clientdata(tpa6130a2_client);
 
        mutex_lock(&data->mutex);
-       if (power) {
+       if (power && !data->power_state) {
                /* Power on */
                if (data->power_gpio >= 0)
                        gpio_set_value(data->power_gpio, 1);
@@ -153,7 +153,7 @@ static int tpa6130a2_power(int power)
                val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
                val &= ~TPA6130A2_SWS;
                tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
-       } else {
+       } else if (!power && data->power_state) {
                /* set SWS */
                val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
                val |= TPA6130A2_SWS;
index b4f11724a63ffc771c1a1d83909e31ae5cccaab7..aca4b1ea10bb710cd733ea730d22171895df620e 100644 (file)
@@ -186,7 +186,6 @@ static int wm8900_volatile_register(unsigned int reg)
 {
        switch (reg) {
        case WM8900_REG_ID:
-       case WM8900_REG_POWER1:
                return 1;
        default:
                return 0;
@@ -1200,11 +1199,6 @@ static int wm8900_probe(struct snd_soc_codec *codec)
                return -ENODEV;
        }
 
-       /* Read back from the chip */
-       reg = snd_soc_read(codec, WM8900_REG_POWER1);
-       reg = (reg >> 12) & 0xf;
-       dev_info(codec->dev, "WM8900 revision %d\n", reg);
-
        wm8900_reset(codec);
 
        /* Turn the chip on */
index 2cb81538cd9194c9cc278515171d67a45ac39ca6..19ca782ac970f1956243862534e5df1df12a3113 100644 (file)
@@ -123,7 +123,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
                        reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
                        break;
                default:
-                       WARN(1, "Unknown DCS readback method");
+                       WARN(1, "Unknown DCS readback method\n");
                        break;
                }
 
index a3bfb2e8b70fb6946739837126dc49fed237f658..73d0edd8ded9de053db82b27c60433fe1a7b8686 100644 (file)
@@ -79,7 +79,7 @@ static void tosa_ext_control(struct snd_soc_codec *codec)
 static int tosa_startup(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->card->codec;
+       struct snd_soc_codec *codec = rtd->codec;
 
        /* check the jack status at stream startup */
        tosa_ext_control(codec);
index 1c8f3f507f54e7d1fc469ff03a2fdbf787640e3a..614a8b30d87bdefdb99414f06d1d74438e60cd18 100644 (file)
@@ -165,8 +165,11 @@ static ssize_t pmdown_time_set(struct device *dev,
 {
        struct snd_soc_pcm_runtime *rtd =
                        container_of(dev, struct snd_soc_pcm_runtime, dev);
+       int ret;
 
-       strict_strtol(buf, 10, &rtd->pmdown_time);
+       ret = strict_strtol(buf, 10, &rtd->pmdown_time);
+       if (ret)
+               return ret;
 
        return count;
 }
index 7dae05d8783e4274266bb5c867e534b342e18614..782f741cd00a4e3bb97317d05827f8c3134299bc 100644 (file)
@@ -60,7 +60,7 @@ static const struct rc_config {
        { USB_ID(0x041e, 0x3000), 0, 1, 2, 1,  18, 0x0013 }, /* Extigy       */
        { USB_ID(0x041e, 0x3020), 2, 1, 6, 6,  18, 0x0013 }, /* Audigy 2 NX  */
        { USB_ID(0x041e, 0x3040), 2, 2, 6, 6,  2,  0x6e91 }, /* Live! 24-bit */
-       { USB_ID(0x041e, 0x3042), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi */
+       { USB_ID(0x041e, 0x3042), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi S51 */
        { USB_ID(0x041e, 0x3048), 2, 2, 6, 6,  2,  0x6e91 }, /* Toshiba SB0500 */
 };
 
@@ -183,7 +183,13 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
        if (value > 1)
                return -EINVAL;
        changed = value != mixer->audigy2nx_leds[index];
-       err = snd_usb_ctl_msg(mixer->chip->dev,
+       if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
+               err = snd_usb_ctl_msg(mixer->chip->dev,
+                             usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
+                             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+                             !value, 0, NULL, 0, 100);
+       else
+               err = snd_usb_ctl_msg(mixer->chip->dev,
                              usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
                              value, index + 2, NULL, 0, 100);
@@ -225,8 +231,12 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
        int i, err;
 
        for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
+               /* USB X-Fi S51 doesn't have a CMSS LED */
+               if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
+                       continue;
                if (i > 1 && /* Live24ext has 2 LEDs only */
                        (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
+                        mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
                         mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
                        break; 
                err = snd_ctl_add(mixer->chip->card,
@@ -365,6 +375,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 
        if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
            mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
+           mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
            mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
                if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
                        return err;
index cff3a3c465d736f17d73a4cf6c01c54c936469c3..4132522ac90f8c88da831b68f9cbdf777131de8e 100644 (file)
@@ -676,8 +676,10 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
        if (!needs_knot)
                return 0;
 
-       subs->rate_list.count = count;
        subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
+       if (!subs->rate_list.list)
+               return -ENOMEM;
+       subs->rate_list.count = count;
        subs->rate_list.mask = 0;
        count = 0;
        list_for_each_entry(fp, &subs->fmt_list, list) {
index 122ec9dc4853d079903d566a219a9e48d8a6a465..26aff6bf9e500d0d6699e968a789db651deb9722 100644 (file)
@@ -8,7 +8,11 @@ perf-trace - Read perf.data (created by perf record) and display trace output
 SYNOPSIS
 --------
 [verse]
-'perf trace' {record <script> | report <script> [args] }
+'perf trace' [<options>]
+'perf trace' [<options>] record <script> [<record-options>] <command>
+'perf trace' [<options>] report <script> [script-args]
+'perf trace' [<options>] <script> <required-script-args> [<record-options>] <command>
+'perf trace' [<options>] <top-script> [script-args]
 
 DESCRIPTION
 -----------
@@ -24,23 +28,53 @@ There are several variants of perf trace:
   available via 'perf trace -l').  The following variants allow you to
   record and run those scripts:
 
-  'perf trace record <script>' to record the events required for 'perf
-  trace report'.  <script> is the name displayed in the output of
-  'perf trace --list' i.e. the actual script name minus any language
-  extension.
+  'perf trace record <script> <command>' to record the events required
+  for 'perf trace report'.  <script> is the name displayed in the
+  output of 'perf trace --list' i.e. the actual script name minus any
+  language extension.  If <command> is not specified, the events are
+  recorded using the -a (system-wide) 'perf record' option.
 
-  'perf trace report <script>' to run and display the results of
-  <script>.  <script> is the name displayed in the output of 'perf
+  'perf trace report <script> [args]' to run and display the results
+  of <script>.  <script> is the name displayed in the output of 'perf
   trace --list' i.e. the actual script name minus any language
   extension.  The perf.data output from a previous run of 'perf trace
   record <script>' is used and should be present for this command to
-  succeed.
+  succeed.  [args] refers to the (mainly optional) args expected by
+  the script.
+
+  'perf trace <script> <required-script-args> <command>' to both
+  record the events required for <script> and to run the <script>
+  using 'live-mode' i.e. without writing anything to disk.  <script>
+  is the name displayed in the output of 'perf trace --list' i.e. the
+  actual script name minus any language extension.  If <command> is
+  not specified, the events are recorded using the -a (system-wide)
+  'perf record' option.  If <script> has any required args, they
+  should be specified before <command>.  This mode doesn't allow for
+  optional script args to be specified; if optional script args are
+  desired, they can be specified using separate 'perf trace record'
+  and 'perf trace report' commands, with the stdout of the record step
+  piped to the stdin of the report script, using the '-o -' and '-i -'
+  options of the corresponding commands.
+
+  'perf trace <top-script>' to both record the events required for
+  <top-script> and to run the <top-script> using 'live-mode'
+  i.e. without writing anything to disk.  <top-script> is the name
+  displayed in the output of 'perf trace --list' i.e. the actual
+  script name minus any language extension; a <top-script> is defined
+  as any script name ending with the string 'top'.
+
+  [<record-options>] can be passed to the record steps of 'perf trace
+  record' and 'live-mode' variants; this isn't possible however for
+  <top-script> 'live-mode' or 'perf trace report' variants.
 
   See the 'SEE ALSO' section for links to language-specific
   information on how to write and run your own trace scripts.
 
 OPTIONS
 -------
+<command>...::
+       Any command you can specify in a shell.
+
 -D::
 --dump-raw-trace=::
         Display verbose dump of the trace data.
@@ -64,6 +98,13 @@ OPTIONS
         Generate perf-trace.[ext] starter script for given language,
         using current perf.data.
 
+-a::
+        Force system-wide collection.  Scripts run without a <command>
+        normally use -a by default, while scripts run with a <command>
+        normally don't - this option allows the latter to be run in
+        system-wide mode.
+
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-trace-perl[1],
index 4e75583ddd6d9605b96256264c4e5ca900670d3e..93bd2ff001fb113ff11159e419269942ac4e3743 100644 (file)
@@ -790,7 +790,7 @@ static const char * const record_usage[] = {
 
 static bool force, append_file;
 
-static const struct option options[] = {
+const struct option record_options[] = {
        OPT_CALLBACK('e', "event", NULL, "event",
                     "event selector. use 'perf list' to list available events",
                     parse_events),
@@ -839,16 +839,16 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
 {
        int i, j, err = -ENOMEM;
 
-       argc = parse_options(argc, argv, options, record_usage,
+       argc = parse_options(argc, argv, record_options, record_usage,
                            PARSE_OPT_STOP_AT_NON_OPTION);
        if (!argc && target_pid == -1 && target_tid == -1 &&
                !system_wide && !cpu_list)
-               usage_with_options(record_usage, options);
+               usage_with_options(record_usage, record_options);
 
        if (force && append_file) {
                fprintf(stderr, "Can't overwrite and append at the same time."
                                " You need to choose between -f and -A");
-               usage_with_options(record_usage, options);
+               usage_with_options(record_usage, record_options);
        } else if (append_file) {
                write_mode = WRITE_APPEND;
        } else {
@@ -871,7 +871,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
                if (thread_num <= 0) {
                        fprintf(stderr, "Can't find all threads of pid %d\n",
                                        target_pid);
-                       usage_with_options(record_usage, options);
+                       usage_with_options(record_usage, record_options);
                }
        } else {
                all_tids=malloc(sizeof(pid_t));
index b513e40974f46bf45f816d658d78d574762f5b17..dd625808c2a5332c4f733a59acfb1ee881faae3f 100644 (file)
@@ -69,7 +69,6 @@ static int                    target_tid                      =     -1;
 static pid_t                   *all_tids                       =      NULL;
 static int                     thread_num                      =      0;
 static bool                    inherit                         =  false;
-static int                     profile_cpu                     =     -1;
 static int                     nr_cpus                         =      0;
 static int                     realtime_prio                   =      0;
 static bool                    group                           =  false;
@@ -558,13 +557,13 @@ static void print_sym_table(void)
        else
                printf(" (all");
 
-       if (profile_cpu != -1)
-               printf(", cpu: %d)\n", profile_cpu);
+       if (cpu_list)
+               printf(", CPU%s: %s)\n", nr_cpus > 1 ? "s" : "", cpu_list);
        else {
                if (target_tid != -1)
                        printf(")\n");
                else
-                       printf(", %d CPUs)\n", nr_cpus);
+                       printf(", %d CPU%s)\n", nr_cpus, nr_cpus > 1 ? "s" : "");
        }
 
        printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
@@ -1187,11 +1186,10 @@ int group_fd;
 static void start_counter(int i, int counter)
 {
        struct perf_event_attr *attr;
-       int cpu;
+       int cpu = -1;
        int thread_index;
 
-       cpu = profile_cpu;
-       if (target_tid == -1 && profile_cpu == -1)
+       if (target_tid == -1)
                cpu = cpumap[i];
 
        attr = attrs + counter;
index 2f8df45c4dcbfe306080354dbfcfb073ac3ed0a0..86cfe3800e6bf5580718fd3df3c3788f9edbda31 100644 (file)
@@ -10,6 +10,7 @@
 #include "util/symbol.h"
 #include "util/thread.h"
 #include "util/trace-event.h"
+#include "util/parse-options.h"
 #include "util/util.h"
 
 static char const              *script_name;
@@ -17,6 +18,7 @@ static char const             *generate_script_lang;
 static bool                    debug_mode;
 static u64                     last_timestamp;
 static u64                     nr_unordered;
+extern const struct option     record_options[];
 
 static int default_start_script(const char *script __unused,
                                int argc __unused,
@@ -328,7 +330,7 @@ static struct script_desc *script_desc__new(const char *name)
 {
        struct script_desc *s = zalloc(sizeof(*s));
 
-       if (s != NULL)
+       if (s != NULL && name)
                s->name = strdup(name);
 
        return s;
@@ -337,6 +339,8 @@ static struct script_desc *script_desc__new(const char *name)
 static void script_desc__delete(struct script_desc *s)
 {
        free(s->name);
+       free(s->half_liner);
+       free(s->args);
        free(s);
 }
 
@@ -537,8 +541,40 @@ static char *get_script_path(const char *script_root, const char *suffix)
        return path;
 }
 
+static bool is_top_script(const char *script_path)
+{
+       return ends_with((char *)script_path, "top") == NULL ? false : true;
+}
+
+static int has_required_arg(char *script_path)
+{
+       struct script_desc *desc;
+       int n_args = 0;
+       char *p;
+
+       desc = script_desc__new(NULL);
+
+       if (read_script_info(desc, script_path))
+               goto out;
+
+       if (!desc->args)
+               goto out;
+
+       for (p = desc->args; *p; p++)
+               if (*p == '<')
+                       n_args++;
+out:
+       script_desc__delete(desc);
+
+       return n_args;
+}
+
 static const char * const trace_usage[] = {
-       "perf trace [<options>] <command>",
+       "perf trace [<options>]",
+       "perf trace [<options>] record <script> [<record-options>] <command>",
+       "perf trace [<options>] report <script> [script-args]",
+       "perf trace [<options>] <script> [<record-options>] <command>",
+       "perf trace [<options>] <top-script> [script-args]",
        NULL
 };
 
@@ -564,50 +600,81 @@ static const struct option options[] = {
        OPT_END()
 };
 
+static bool have_cmd(int argc, const char **argv)
+{
+       char **__argv = malloc(sizeof(const char *) * argc);
+
+       if (!__argv)
+               die("malloc");
+       memcpy(__argv, argv, sizeof(const char *) * argc);
+       argc = parse_options(argc, (const char **)__argv, record_options,
+                            NULL, PARSE_OPT_STOP_AT_NON_OPTION);
+       free(__argv);
+
+       return argc != 0;
+}
+
 int cmd_trace(int argc, const char **argv, const char *prefix __used)
 {
+       char *rec_script_path = NULL;
+       char *rep_script_path = NULL;
        struct perf_session *session;
-       const char *suffix = NULL;
+       char *script_path = NULL;
        const char **__argv;
-       char *script_path;
-       int i, err;
+       bool system_wide;
+       int i, j, err;
 
-       if (argc >= 2 && strncmp(argv[1], "rec", strlen("rec")) == 0) {
-               if (argc < 3) {
-                       fprintf(stderr,
-                               "Please specify a record script\n");
-                       return -1;
-               }
-               suffix = RECORD_SUFFIX;
+       setup_scripting();
+
+       argc = parse_options(argc, argv, options, trace_usage,
+                            PARSE_OPT_STOP_AT_NON_OPTION);
+
+       if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
+               rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
+               if (!rec_script_path)
+                       return cmd_record(argc, argv, NULL);
        }
 
-       if (argc >= 2 && strncmp(argv[1], "rep", strlen("rep")) == 0) {
-               if (argc < 3) {
+       if (argc > 1 && !strncmp(argv[0], "rep", strlen("rep"))) {
+               rep_script_path = get_script_path(argv[1], REPORT_SUFFIX);
+               if (!rep_script_path) {
                        fprintf(stderr,
-                               "Please specify a report script\n");
+                               "Please specify a valid report script"
+                               "(see 'perf trace -l' for listing)\n");
                        return -1;
                }
-               suffix = REPORT_SUFFIX;
        }
 
        /* make sure PERF_EXEC_PATH is set for scripts */
        perf_set_argv_exec_path(perf_exec_path());
 
-       if (!suffix && argc >= 2 && strncmp(argv[1], "-", strlen("-")) != 0) {
-               char *record_script_path, *report_script_path;
+       if (argc && !script_name && !rec_script_path && !rep_script_path) {
                int live_pipe[2];
+               int rep_args;
                pid_t pid;
 
-               record_script_path = get_script_path(argv[1], RECORD_SUFFIX);
-               if (!record_script_path) {
-                       fprintf(stderr, "record script not found\n");
-                       return -1;
+               rec_script_path = get_script_path(argv[0], RECORD_SUFFIX);
+               rep_script_path = get_script_path(argv[0], REPORT_SUFFIX);
+
+               if (!rec_script_path && !rep_script_path) {
+                       fprintf(stderr, " Couldn't find script %s\n\n See perf"
+                               " trace -l for available scripts.\n", argv[0]);
+                       usage_with_options(trace_usage, options);
                }
 
-               report_script_path = get_script_path(argv[1], REPORT_SUFFIX);
-               if (!report_script_path) {
-                       fprintf(stderr, "report script not found\n");
-                       return -1;
+               if (is_top_script(argv[0])) {
+                       rep_args = argc - 1;
+               } else {
+                       int rec_args;
+
+                       rep_args = has_required_arg(rep_script_path);
+                       rec_args = (argc - 1) - rep_args;
+                       if (rec_args < 0) {
+                               fprintf(stderr, " %s script requires options."
+                                       "\n\n See perf trace -l for available "
+                                       "scripts and options.\n", argv[0]);
+                               usage_with_options(trace_usage, options);
+                       }
                }
 
                if (pipe(live_pipe) < 0) {
@@ -622,60 +689,84 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
                }
 
                if (!pid) {
+                       system_wide = true;
+                       j = 0;
+
                        dup2(live_pipe[1], 1);
                        close(live_pipe[0]);
 
-                       __argv = malloc(6 * sizeof(const char *));
-                       __argv[0] = "/bin/sh";
-                       __argv[1] = record_script_path;
-                       __argv[2] = "-q";
-                       __argv[3] = "-o";
-                       __argv[4] = "-";
-                       __argv[5] = NULL;
+                       if (!is_top_script(argv[0]))
+                               system_wide = !have_cmd(argc - rep_args,
+                                                       &argv[rep_args]);
+
+                       __argv = malloc((argc + 6) * sizeof(const char *));
+                       if (!__argv)
+                               die("malloc");
+
+                       __argv[j++] = "/bin/sh";
+                       __argv[j++] = rec_script_path;
+                       if (system_wide)
+                               __argv[j++] = "-a";
+                       __argv[j++] = "-q";
+                       __argv[j++] = "-o";
+                       __argv[j++] = "-";
+                       for (i = rep_args + 1; i < argc; i++)
+                               __argv[j++] = argv[i];
+                       __argv[j++] = NULL;
 
                        execvp("/bin/sh", (char **)__argv);
+                       free(__argv);
                        exit(-1);
                }
 
                dup2(live_pipe[0], 0);
                close(live_pipe[1]);
 
-               __argv = malloc((argc + 3) * sizeof(const char *));
-               __argv[0] = "/bin/sh";
-               __argv[1] = report_script_path;
-               for (i = 2; i < argc; i++)
-                       __argv[i] = argv[i];
-               __argv[i++] = "-i";
-               __argv[i++] = "-";
-               __argv[i++] = NULL;
+               __argv = malloc((argc + 4) * sizeof(const char *));
+               if (!__argv)
+                       die("malloc");
+               j = 0;
+               __argv[j++] = "/bin/sh";
+               __argv[j++] = rep_script_path;
+               for (i = 1; i < rep_args + 1; i++)
+                       __argv[j++] = argv[i];
+               __argv[j++] = "-i";
+               __argv[j++] = "-";
+               __argv[j++] = NULL;
 
                execvp("/bin/sh", (char **)__argv);
+               free(__argv);
                exit(-1);
        }
 
-       if (suffix) {
-               script_path = get_script_path(argv[2], suffix);
-               if (!script_path) {
-                       fprintf(stderr, "script not found\n");
-                       return -1;
-               }
-
-               __argv = malloc((argc + 1) * sizeof(const char *));
-               __argv[0] = "/bin/sh";
-               __argv[1] = script_path;
-               for (i = 3; i < argc; i++)
-                       __argv[i - 1] = argv[i];
-               __argv[argc - 1] = NULL;
+       if (rec_script_path)
+               script_path = rec_script_path;
+       if (rep_script_path)
+               script_path = rep_script_path;
+
+       if (script_path) {
+               system_wide = false;
+               j = 0;
+
+               if (rec_script_path)
+                       system_wide = !have_cmd(argc - 1, &argv[1]);
+
+               __argv = malloc((argc + 2) * sizeof(const char *));
+               if (!__argv)
+                       die("malloc");
+               __argv[j++] = "/bin/sh";
+               __argv[j++] = script_path;
+               if (system_wide)
+                       __argv[j++] = "-a";
+               for (i = 2; i < argc; i++)
+                       __argv[j++] = argv[i];
+               __argv[j++] = NULL;
 
                execvp("/bin/sh", (char **)__argv);
+               free(__argv);
                exit(-1);
        }
 
-       setup_scripting();
-
-       argc = parse_options(argc, argv, options, trace_usage,
-                            PARSE_OPT_STOP_AT_NON_OPTION);
-
        if (symbol__init() < 0)
                return -1;
        if (!script_name)
index eb5846bcb565fe3c53599adf4fbe5d1bdb9bed8d..8104895a7b67d8b5324fa975a98f72cb0ccd2bd8 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -a -e raw_syscalls:sys_exit $@
+perf record -e raw_syscalls:sys_exit $@
index 5bfaae5a6cbae1b8a63283e9ba32f18269677dc7..33efc8673aae879daab6b97de3c1713ec09e3edd 100644 (file)
@@ -1,3 +1,3 @@
 #!/bin/bash
-perf record -a -e syscalls:sys_enter_read -e syscalls:sys_enter_write $@
+perf record -e syscalls:sys_enter_read -e syscalls:sys_enter_write $@
 
index 6e0b2f7755ac218098479958150f06129cc60ec4..7cb9db2304483a69543f14fddc8883dc3d964480 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -a -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@
+perf record -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@
index 6e0b2f7755ac218098479958150f06129cc60ec4..7cb9db2304483a69543f14fddc8883dc3d964480 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -a -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@
+perf record -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@
index 9f2acaaae9f0538fbdea692bbadd015965b48ae2..464251a1bd7e6a235d59579b85ff80d646aead50 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-perf record -a -e sched:sched_switch -e sched:sched_wakeup $@
+perf record -e sched:sched_switch -e sched:sched_wakeup $@
 
 
 
index 85301f2471ff59b774573142a4d4c3db5e40604d..8edda9078d5d3a4711f4039e01be86438774dcdf 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -a -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion $@
+perf record -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion $@
index eb5846bcb565fe3c53599adf4fbe5d1bdb9bed8d..8104895a7b67d8b5324fa975a98f72cb0ccd2bd8 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -a -e raw_syscalls:sys_exit $@
+perf record -e raw_syscalls:sys_exit $@
index 5ecbb433caf499d4103ad9a5561ebfa7eea86471..b1495c9a9b20e14ca2ad1ae62eafc13b741d2ca5 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -a -e syscalls:sys_enter_futex -e syscalls:sys_exit_futex $@
+perf record -e syscalls:sys_enter_futex -e syscalls:sys_exit_futex $@
index d931a828126b75d843f40fc2ad3eb1cebc3b43fd..558754b840a98293e31aeb4a70864dd75f3b3b2f 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-perf record -a -e net:net_dev_xmit -e net:net_dev_queue                \
+perf record -e net:net_dev_xmit -e net:net_dev_queue           \
                -e net:netif_receive_skb -e net:netif_rx                \
                -e skb:consume_skb -e skb:kfree_skb                     \
                -e skb:skb_copy_datagram_iovec -e napi:napi_poll        \
index 17a3e9bd9e8f0b6f34a2989e7a6d4cbd5ffe7090..7493fddbe99532db2b2c0c4ad3d7b469d29e1dda 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -m 16384 -a -e sched:sched_wakeup -e sched:sched_wakeup_new -e sched:sched_switch -e sched:sched_migrate_task $@
+perf record -m 16384 -e sched:sched_wakeup -e sched:sched_wakeup_new -e sched:sched_switch -e sched:sched_migrate_task $@
index 1fc5998b721d5f2a5f2a89e83ad90559f18439dd..4efbfaa7f6a5dc1deace4583c28f3e29fbf0c878 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -a -e raw_syscalls:sys_enter $@
+perf record -e raw_syscalls:sys_enter $@
index 1fc5998b721d5f2a5f2a89e83ad90559f18439dd..4efbfaa7f6a5dc1deace4583c28f3e29fbf0c878 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -a -e raw_syscalls:sys_enter $@
+perf record -e raw_syscalls:sys_enter $@
index 1fc5998b721d5f2a5f2a89e83ad90559f18439dd..4efbfaa7f6a5dc1deace4583c28f3e29fbf0c878 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -a -e raw_syscalls:sys_enter $@
+perf record -e raw_syscalls:sys_enter $@
index 9706d9d40279859321412b270c8ac3053141f4f9..056c69521a38098a8053d18f3e615d3a35390fd4 100644 (file)
@@ -104,9 +104,10 @@ out_destroy_form:
        return rc;
 }
 
+static const char yes[] = "Yes", no[] = "No";
+
 bool ui__dialog_yesno(const char *msg)
 {
        /* newtWinChoice should really be accepting const char pointers... */
-       char yes[] = "Yes", no[] = "No";
-       return newtWinChoice(NULL, yes, no, (char *)msg) == 1;
+       return newtWinChoice(NULL, (char *)yes, (char *)no, (char *)msg) == 1;
 }
index b9efed5e35cc222f3e7b34d922bbc1b90b29987b..792a750d9441af80cd16e4d797234159875babc4 100644 (file)
@@ -30,8 +30,8 @@ __irf_end:
 .section .init.ramfs.info,"a"
 .globl __initramfs_size
 __initramfs_size:
-#ifdef CONFIG_32BIT
-       .long __irf_end - __irf_start
-#else
+#ifdef CONFIG_64BIT
        .quad __irf_end - __irf_start
+#else
+       .long __irf_end - __irf_start
 #endif